Fixed invalidation with new clipping code. Only what's needed is
redrawn/invalidated now, with a single exception which I am working on(when changing the front window the whole window area is invalidated not just the region that became visible). The old Clipping code is broken now. I will remove it in the next days. Actual changes: * removed Layer::GetWantedRegion() - was badly implemented. * made Layer::_GetWantedRegion public and renamed it to: you guessed! :-) * introduced Layer::MarkForRebuild(), TriggerRebuild(). You want to calculate the new clipping regions, mark an area and then call TRiggerRebuild() which will rebuild the visible regions for the current Layer and all its descendants. * for a Layer to redraw some parts of it, use RootLayer::MarkForRedraw() to mark a region and then RootLayer::TriggerRedraw() to see the changes (or send _UPDATE_ message in case of a WinBorder). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14719 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+111
-52
@@ -21,7 +21,7 @@
|
|||||||
//
|
//
|
||||||
// File Name: Layer.cpp
|
// File Name: Layer.cpp
|
||||||
// Author: DarkWyrm <[email protected]>
|
// Author: DarkWyrm <[email protected]>
|
||||||
// Adi Oanca <adioanca@cotty.iren.ro>
|
// Adi Oanca <adioanca@gmail.com>
|
||||||
// Stephan Aßmus <[email protected]>
|
// Stephan Aßmus <[email protected]>
|
||||||
// Description: Class used for rendering to the frame buffer. One layer per
|
// Description: Class used for rendering to the frame buffer. One layer per
|
||||||
// view on screen and also for window decorators
|
// view on screen and also for window decorators
|
||||||
@@ -89,6 +89,7 @@ Layer::Layer(BRect frame, const char* name, int32 token,
|
|||||||
#else
|
#else
|
||||||
fVisible2(),
|
fVisible2(),
|
||||||
fFullVisible2(),
|
fFullVisible2(),
|
||||||
|
fDirtyForRebuild(),
|
||||||
fClipReg(&fVisible2),
|
fClipReg(&fVisible2),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -959,10 +960,17 @@ RebuildFullRegion();
|
|||||||
#else
|
#else
|
||||||
if (invalidate) {
|
if (invalidate) {
|
||||||
// compute the region this layer wants for itself
|
// compute the region this layer wants for itself
|
||||||
BRegion invalidRegion;
|
BRegion invalid;
|
||||||
_GetWantedRegion(invalidRegion);
|
GetWantedRegion(invalid);
|
||||||
if (invalidRegion.CountRects() > 0)
|
if (invalid.CountRects() > 0) {
|
||||||
GetRootLayer()->GoInvalidate(this, invalidRegion);
|
fParent->MarkForRebuild(invalid);
|
||||||
|
GetRootLayer()->MarkForRedraw(invalid);
|
||||||
|
|
||||||
|
fParent->TriggerRebuild();
|
||||||
|
GetRootLayer()->TriggerRedraw();
|
||||||
|
|
||||||
|
// GetRootLayer()->GoInvalidate(this, invalid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -988,7 +996,15 @@ Layer::Hide(bool invalidate)
|
|||||||
GetRootLayer()->GoInvalidate(this, fFullVisible);
|
GetRootLayer()->GoInvalidate(this, fFullVisible);
|
||||||
#else
|
#else
|
||||||
if (invalidate && fFullVisible2.CountRects() > 0) {
|
if (invalidate && fFullVisible2.CountRects() > 0) {
|
||||||
GetRootLayer()->GoInvalidate(this, fFullVisible2);
|
BRegion invalid(fFullVisible2);
|
||||||
|
|
||||||
|
fParent->MarkForRebuild(invalid);
|
||||||
|
GetRootLayer()->MarkForRedraw(invalid);
|
||||||
|
|
||||||
|
fParent->TriggerRebuild();
|
||||||
|
GetRootLayer()->TriggerRedraw();
|
||||||
|
|
||||||
|
// GetRootLayer()->GoInvalidate(this, fFullVisible2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1970,15 +1986,6 @@ Layer::ScrolledByHook(float dx, float dy)
|
|||||||
// empty.
|
// empty.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Layer::GetWantedRegion(BRegion& reg) const
|
|
||||||
{
|
|
||||||
// this is the same as get_user_region.
|
|
||||||
// because get_user_region modifies nothing.
|
|
||||||
const_cast<Layer*>(this)->Layer::_GetWantedRegion(reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! converts a point from local to parent's coordinate system
|
//! converts a point from local to parent's coordinate system
|
||||||
void
|
void
|
||||||
Layer::ConvertToParent2(BPoint* pt) const
|
Layer::ConvertToParent2(BPoint* pt) const
|
||||||
@@ -2121,8 +2128,13 @@ Layer::do_Hide()
|
|||||||
|
|
||||||
clear_visible_regions();
|
clear_visible_regions();
|
||||||
|
|
||||||
if (invalid.Frame().IsValid())
|
if (invalid.CountRects() > 0) {
|
||||||
fParent->do_Invalidate(invalid, this);
|
fParent->MarkForRebuild(invalid);
|
||||||
|
GetRootLayer()->MarkForRedraw(invalid);
|
||||||
|
|
||||||
|
fParent->TriggerRebuild();
|
||||||
|
GetRootLayer()->TriggerRedraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2134,41 +2146,18 @@ Layer::do_Show()
|
|||||||
if (fParent && !fParent->IsHidden() && GetRootLayer()) {
|
if (fParent && !fParent->IsHidden() && GetRootLayer()) {
|
||||||
BRegion invalid;
|
BRegion invalid;
|
||||||
|
|
||||||
_GetWantedRegion(invalid);
|
GetWantedRegion(invalid);
|
||||||
|
|
||||||
if (invalid.CountRects() > 0)
|
if (invalid.CountRects() > 0) {
|
||||||
fParent->do_Invalidate(invalid, this);
|
fParent->MarkForRebuild(invalid);
|
||||||
|
GetRootLayer()->MarkForRedraw(invalid);
|
||||||
|
|
||||||
|
fParent->TriggerRebuild();
|
||||||
|
GetRootLayer()->TriggerRedraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Layer::do_Invalidate(const BRegion &invalid, const Layer *startFrom)
|
|
||||||
{
|
|
||||||
BRegion localVisible(fFullVisible2);
|
|
||||||
localVisible.IntersectWith(&invalid);
|
|
||||||
rebuild_visible_regions(invalid, localVisible,
|
|
||||||
startFrom? startFrom: LastChild());
|
|
||||||
|
|
||||||
// add localVisible to our RootLayer's redraw region.
|
|
||||||
// GetRootLayer()->fRedrawReg.Include(&localVisible);
|
|
||||||
GetRootLayer()->fRedrawReg = localVisible;
|
|
||||||
GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, NULL);
|
|
||||||
// GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Layer::do_Redraw(const BRegion &invalid, const Layer *startFrom)
|
|
||||||
{
|
|
||||||
BRegion localVisible(fFullVisible2);
|
|
||||||
localVisible.IntersectWith(&invalid);
|
|
||||||
|
|
||||||
// add localVisible to our RootLayer's redraw region.
|
|
||||||
// GetRootLayer()->fRedrawReg.Include(&localVisible);
|
|
||||||
GetRootLayer()->fRedrawReg = localVisible;
|
|
||||||
GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, NULL);
|
|
||||||
// GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
Layer::resize_layer_frame_by(float x, float y)
|
Layer::resize_layer_frame_by(float x, float y)
|
||||||
{
|
{
|
||||||
@@ -2344,7 +2333,7 @@ Layer::do_ResizeBy(float dx, float dy)
|
|||||||
|
|
||||||
// we'll invalidate the old area and the new, maxmial one.
|
// we'll invalidate the old area and the new, maxmial one.
|
||||||
BRegion invalid;
|
BRegion invalid;
|
||||||
_GetWantedRegion(invalid);
|
GetWantedRegion(invalid);
|
||||||
invalid.Include(&fFullVisible2);
|
invalid.Include(&fFullVisible2);
|
||||||
|
|
||||||
clear_visible_regions();
|
clear_visible_regions();
|
||||||
@@ -2403,7 +2392,7 @@ void Layer::do_MoveBy(float dx, float dy)
|
|||||||
|
|
||||||
// we'll invalidate the old position and the new, maxmial one.
|
// we'll invalidate the old position and the new, maxmial one.
|
||||||
BRegion invalid;
|
BRegion invalid;
|
||||||
_GetWantedRegion(invalid);
|
GetWantedRegion(invalid);
|
||||||
invalid.Include(&fFullVisible2);
|
invalid.Include(&fFullVisible2);
|
||||||
|
|
||||||
clear_visible_regions();
|
clear_visible_regions();
|
||||||
@@ -2483,7 +2472,7 @@ Layer::do_ScrollBy(float dx, float dy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Layer::_GetWantedRegion(BRegion ®)
|
Layer::GetWantedRegion(BRegion ®)
|
||||||
{
|
{
|
||||||
// 1) set to frame in screen coords
|
// 1) set to frame in screen coords
|
||||||
BRect screenFrame(Bounds());
|
BRect screenFrame(Bounds());
|
||||||
@@ -2537,7 +2526,7 @@ Layer::rebuild_visible_regions(const BRegion &invalid,
|
|||||||
|
|
||||||
// intersect maximum wanted region with the invalid region
|
// intersect maximum wanted region with the invalid region
|
||||||
BRegion common;
|
BRegion common;
|
||||||
_GetWantedRegion(common);
|
GetWantedRegion(common);
|
||||||
common.IntersectWith(&invalid);
|
common.IntersectWith(&invalid);
|
||||||
|
|
||||||
// if the resulted region is not valid, this layer is not in the catchment area
|
// if the resulted region is not valid, this layer is not in the catchment area
|
||||||
@@ -2592,5 +2581,75 @@ Layer::clear_visible_regions()
|
|||||||
child->clear_visible_regions();
|
child->clear_visible_regions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mark a region dirty so that the next region rebuild for us
|
||||||
|
// and our children will take this into account
|
||||||
|
void
|
||||||
|
Layer::MarkForRebuild(const BRegion &dirty)
|
||||||
|
{
|
||||||
|
fDirtyForRebuild.Include(&dirty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this will trigger visible region recalculation for us and
|
||||||
|
// our descendants.
|
||||||
|
void
|
||||||
|
Layer::TriggerRebuild()
|
||||||
|
{
|
||||||
|
BRegion totalInvalidReg;
|
||||||
|
|
||||||
|
_GetAllRebuildDirty(&totalInvalidReg);
|
||||||
|
|
||||||
|
if (totalInvalidReg.CountRects() > 0) {
|
||||||
|
BRegion localFullVisible(fFullVisible2);
|
||||||
|
|
||||||
|
// localFullVisible.IntersectWith(&totalInvalidReg);
|
||||||
|
|
||||||
|
// clear_visible_regions();
|
||||||
|
|
||||||
|
rebuild_visible_regions(totalInvalidReg, localFullVisible, LastChild());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find out the region for which we must rebuild the visible regions
|
||||||
|
void
|
||||||
|
Layer::_GetAllRebuildDirty(BRegion *totalReg)
|
||||||
|
{
|
||||||
|
totalReg->Include(&fDirtyForRebuild);
|
||||||
|
|
||||||
|
for (Layer *child = LastChild(); child; child = PreviousChild())
|
||||||
|
child->_GetAllRebuildDirty(totalReg);
|
||||||
|
|
||||||
|
fDirtyForRebuild.MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Layer::_AllRedraw(const BRegion &invalid)
|
||||||
|
{
|
||||||
|
// couldn't find a simpler way to send _UPDATE_ message to client.
|
||||||
|
WinBorder *wb = dynamic_cast<WinBorder*>(this);
|
||||||
|
if (wb)
|
||||||
|
wb->RequestClientRedraw(invalid);
|
||||||
|
|
||||||
|
if (fVisible2.CountRects() > 0) {
|
||||||
|
BRegion updateReg(fVisible2);
|
||||||
|
updateReg.IntersectWith(&invalid);
|
||||||
|
|
||||||
|
if (updateReg.CountRects() > 0) {
|
||||||
|
fDriver->ConstrainClippingRegion(&updateReg);
|
||||||
|
Draw(updateReg.Frame());
|
||||||
|
fDriver->ConstrainClippingRegion(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Layer *lay = LastChild(); lay != NULL; lay = PreviousChild()) {
|
||||||
|
if (!(lay->IsHidden())) {
|
||||||
|
BRegion common(lay->fFullVisible2);
|
||||||
|
common.IntersectWith(&invalid);
|
||||||
|
|
||||||
|
if (common.CountRects() > 0)
|
||||||
|
lay->_AllRedraw(invalid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* DarkWyrm <[email protected]>
|
* DarkWyrm <[email protected]>
|
||||||
* Adi Oanca <adioanca@cotty.iren.com>
|
* Adi Oanca <adioanca@gmail.com>
|
||||||
* Stephan Aßmus <[email protected]>
|
* Stephan Aßmus <[email protected]>
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
@@ -248,7 +248,13 @@ class Layer {
|
|||||||
inline const BRegion& VisibleRegion() const { return fVisible2; }
|
inline const BRegion& VisibleRegion() const { return fVisible2; }
|
||||||
inline const BRegion& FullVisible() const { return fFullVisible2; }
|
inline const BRegion& FullVisible() const { return fFullVisible2; }
|
||||||
|
|
||||||
virtual void GetWantedRegion(BRegion& reg) const;
|
void MarkForRebuild(const BRegion &dirty);
|
||||||
|
void TriggerRebuild();
|
||||||
|
void _GetAllRebuildDirty(BRegion *totalReg);
|
||||||
|
void _AllRedraw(const BRegion &invalid);
|
||||||
|
|
||||||
|
|
||||||
|
virtual void GetWantedRegion(BRegion& reg);
|
||||||
|
|
||||||
virtual void MovedByHook(float dx, float dy);
|
virtual void MovedByHook(float dx, float dy);
|
||||||
virtual void ResizedByHook(float dx, float dy, bool automatic);
|
virtual void ResizedByHook(float dx, float dy, bool automatic);
|
||||||
@@ -277,18 +283,11 @@ class Layer {
|
|||||||
void do_ResizeBy(float dx, float dy);
|
void do_ResizeBy(float dx, float dy);
|
||||||
void do_ScrollBy(float dx, float dy);
|
void do_ScrollBy(float dx, float dy);
|
||||||
|
|
||||||
void do_Invalidate( const BRegion &invalid,
|
|
||||||
const Layer *startFrom = NULL);
|
|
||||||
|
|
||||||
void do_Redraw( const BRegion &invalid,
|
|
||||||
const Layer *startFrom = NULL);
|
|
||||||
|
|
||||||
void rebuild_visible_regions(const BRegion &invalid,
|
void rebuild_visible_regions(const BRegion &invalid,
|
||||||
const BRegion &parentLocalVisible,
|
const BRegion &parentLocalVisible,
|
||||||
const Layer *startFrom);
|
const Layer *startFrom);
|
||||||
|
|
||||||
virtual void _ReserveRegions(BRegion ®);
|
virtual void _ReserveRegions(BRegion ®);
|
||||||
virtual void _GetWantedRegion(BRegion ®);
|
|
||||||
|
|
||||||
void clear_visible_regions();
|
void clear_visible_regions();
|
||||||
void resize_layer_frame_by(float x, float y);
|
void resize_layer_frame_by(float x, float y);
|
||||||
@@ -342,6 +341,7 @@ class Layer {
|
|||||||
private:
|
private:
|
||||||
BRegion fVisible2;
|
BRegion fVisible2;
|
||||||
BRegion fFullVisible2;
|
BRegion fFullVisible2;
|
||||||
|
BRegion fDirtyForRebuild;
|
||||||
protected:
|
protected:
|
||||||
#endif
|
#endif
|
||||||
BRegion* fClipReg;
|
BRegion* fClipReg;
|
||||||
|
|||||||
+113
-53
@@ -68,6 +68,8 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
|||||||
fSavedEventOptions(0),
|
fSavedEventOptions(0),
|
||||||
fAllRegionsLock("root layer region lock"),
|
fAllRegionsLock("root layer region lock"),
|
||||||
|
|
||||||
|
fDirtyForRedraw(),
|
||||||
|
|
||||||
fThreadID(B_ERROR),
|
fThreadID(B_ERROR),
|
||||||
fListenPort(-1),
|
fListenPort(-1),
|
||||||
|
|
||||||
@@ -199,13 +201,15 @@ RootLayer::WorkingThread(void *data)
|
|||||||
oneRootLayer->RebuildFullRegion();
|
oneRootLayer->RebuildFullRegion();
|
||||||
oneRootLayer->GoInvalidate(oneRootLayer, oneRootLayer->Bounds());
|
oneRootLayer->GoInvalidate(oneRootLayer, oneRootLayer->Bounds());
|
||||||
#else
|
#else
|
||||||
oneRootLayer->rebuild_visible_regions(
|
// RootLayer starts with valid visible regions
|
||||||
BRegion(oneRootLayer->Bounds()),
|
oneRootLayer->fFullVisible2.Set(oneRootLayer->Bounds());
|
||||||
BRegion(oneRootLayer->Bounds()),
|
oneRootLayer->fVisible2.Set(oneRootLayer->Bounds());
|
||||||
oneRootLayer->LastChild());
|
|
||||||
|
|
||||||
oneRootLayer->fRedrawReg.Include(oneRootLayer->Bounds());
|
oneRootLayer->MarkForRebuild(oneRootLayer->Bounds());
|
||||||
oneRootLayer->RequestDraw(oneRootLayer->fRedrawReg, oneRootLayer->LastChild());
|
oneRootLayer->MarkForRedraw(oneRootLayer->Bounds());
|
||||||
|
|
||||||
|
oneRootLayer->TriggerRebuild();
|
||||||
|
oneRootLayer->TriggerRedraw();
|
||||||
#endif
|
#endif
|
||||||
oneRootLayer->Unlock();
|
oneRootLayer->Unlock();
|
||||||
|
|
||||||
@@ -277,38 +281,6 @@ RootLayer::WorkingThread(void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
RootLayer::GoInvalidate(Layer *layer, const BRegion ®ion)
|
|
||||||
{
|
|
||||||
BRegion invalidRegion(region);
|
|
||||||
|
|
||||||
Lock();
|
|
||||||
#ifndef NEW_CLIPPING
|
|
||||||
if (layer->fParent)
|
|
||||||
layer = layer->fParent;
|
|
||||||
|
|
||||||
layer->FullInvalidate(invalidRegion);
|
|
||||||
#else
|
|
||||||
layer->do_Invalidate(invalidRegion);
|
|
||||||
#endif
|
|
||||||
Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RootLayer::GoRedraw(Layer *layer, const BRegion ®ion)
|
|
||||||
{
|
|
||||||
BRegion redrawRegion(region);
|
|
||||||
|
|
||||||
Lock();
|
|
||||||
#ifndef NEW_CLIPPING
|
|
||||||
layer->Invalidate(redrawRegion);
|
|
||||||
#else
|
|
||||||
layer->do_Redraw(redrawRegion);
|
|
||||||
#endif
|
|
||||||
Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RootLayer::GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel)
|
RootLayer::GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel)
|
||||||
{
|
{
|
||||||
@@ -829,7 +801,7 @@ RootLayer::RevealNewWMState(Workspace::State &oldWMState)
|
|||||||
#ifndef NEW_CLIPPING
|
#ifndef NEW_CLIPPING
|
||||||
fRedrawReg.Include(&dirtyRegion);
|
fRedrawReg.Include(&dirtyRegion);
|
||||||
#else
|
#else
|
||||||
// TODO: code for new clipping engine!
|
MarkForRedraw(dirtyRegion);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -848,37 +820,98 @@ RootLayer::RevealNewWMState(Workspace::State &oldWMState)
|
|||||||
// clear visible areas for windows not visible anymore.
|
// clear visible areas for windows not visible anymore.
|
||||||
int32 oldWindowCount = oldWMState.WindowList.CountItems();
|
int32 oldWindowCount = oldWMState.WindowList.CountItems();
|
||||||
int32 newWindowCount = fWMState.WindowList.CountItems();
|
int32 newWindowCount = fWMState.WindowList.CountItems();
|
||||||
bool stillPresent;
|
BList oldStrippedList, newStrippedList;
|
||||||
Layer *layer;
|
for (int32 i = 0; i < oldWindowCount; ++i) {
|
||||||
for (int32 i = 0; i < oldWindowCount; i++)
|
Layer *layer = static_cast<Layer*>(oldWMState.WindowList.ItemAtFast(i));
|
||||||
{
|
if (!layer)
|
||||||
layer = static_cast<Layer*>(oldWMState.WindowList.ItemAtFast(i));
|
continue;
|
||||||
stillPresent = false;
|
|
||||||
for (int32 j = 0; j < newWindowCount; j++)
|
|
||||||
if (layer == fWMState.WindowList.ItemAtFast(j))
|
|
||||||
stillPresent = true;
|
|
||||||
|
|
||||||
if (!stillPresent && layer)
|
bool stillPresent = false;
|
||||||
|
for (int32 j = 0; j < newWindowCount; ++j)
|
||||||
|
if (layer == fWMState.WindowList.ItemAtFast(j)) {
|
||||||
|
stillPresent = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stillPresent) {
|
||||||
|
MarkForRebuild(layer->FullVisible());
|
||||||
|
MarkForRedraw(layer->FullVisible());
|
||||||
#ifndef NEW_CLIPPING
|
#ifndef NEW_CLIPPING
|
||||||
empty_visible_regions(layer);
|
empty_visible_regions(layer);
|
||||||
#else
|
#else
|
||||||
layer->clear_visible_regions();
|
layer->clear_visible_regions();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oldStrippedList.AddItem(layer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int32 i = 0; i < newWindowCount; ++i) {
|
||||||
|
Layer *layer = static_cast<Layer*>(fWMState.WindowList.ItemAtFast(i));
|
||||||
|
if (!layer)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool isNewWindow = true;
|
||||||
|
for (int32 j = 0; j < oldWindowCount; ++j)
|
||||||
|
if (layer == oldWMState.WindowList.ItemAtFast(j)) {
|
||||||
|
isNewWindow = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (isNewWindow) {
|
||||||
|
BRegion invalid;
|
||||||
|
layer->GetWantedRegion(invalid);
|
||||||
|
|
||||||
|
MarkForRebuild(invalid);
|
||||||
|
MarkForRedraw(invalid);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newStrippedList.AddItem(layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oldWindowCount = oldStrippedList.CountItems();
|
||||||
|
newWindowCount = newStrippedList.CountItems();
|
||||||
|
for (int32 i = 0; i < oldWindowCount; ++i) {
|
||||||
|
Layer *layer = static_cast<Layer*>(oldStrippedList.ItemAtFast(i));
|
||||||
|
if (!layer)
|
||||||
|
continue;
|
||||||
|
if (i < newStrippedList.IndexOf(layer)) {
|
||||||
|
BRegion invalid;
|
||||||
|
layer->GetWantedRegion(invalid);
|
||||||
|
|
||||||
|
// TODO: we need to invalidate only the ares that became visible
|
||||||
|
// not the whole surface of this layer!
|
||||||
|
// invalid.Exclude(&layer->FullVisible());
|
||||||
|
|
||||||
|
MarkForRebuild(invalid);
|
||||||
|
MarkForRedraw(invalid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// for debugging
|
||||||
|
GetDrawingEngine()->ConstrainClippingRegion(&fDirtyForRedraw);
|
||||||
|
RGBColor c(rand()%255,rand()%255,rand()%255);
|
||||||
|
GetDrawingEngine()->FillRect(BRect(0,0,800,600), c);
|
||||||
|
snooze(2000000);
|
||||||
|
GetDrawingEngine()->ConstrainClippingRegion(NULL);
|
||||||
|
*/
|
||||||
// redraw of focus change is automaticaly done
|
// redraw of focus change is automaticaly done
|
||||||
redraw = false;
|
redraw = false;
|
||||||
// trigger region rebuilding and redraw
|
// trigger region rebuilding and redraw
|
||||||
#ifndef NEW_CLIPPING
|
#ifndef NEW_CLIPPING
|
||||||
GoInvalidate(this, fFull);
|
GoInvalidate(this, fFull);
|
||||||
#else
|
#else
|
||||||
do_Invalidate(Bounds());
|
TriggerRebuild();
|
||||||
|
TriggerRedraw();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (redraw) {
|
else if (redraw) {
|
||||||
#ifndef NEW_CLIPPING
|
#ifndef NEW_CLIPPING
|
||||||
GoInvalidate(this, dirtyRegion);
|
GoInvalidate(this, dirtyRegion);
|
||||||
#else
|
#else
|
||||||
do_Redraw(dirtyRegion);
|
MarkForRedraw(dirtyRegion);
|
||||||
|
TriggerRedraw();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1402,7 +1435,7 @@ RootLayer::LayerRemoved(Layer* layer)
|
|||||||
{
|
{
|
||||||
if (layer == fNotifyLayer)
|
if (layer == fNotifyLayer)
|
||||||
fNotifyLayer = NULL;
|
fNotifyLayer = NULL;
|
||||||
|
// TODO: this must not happen!!! Fix this, quickly!
|
||||||
if (layer == fLastLayerUnderMouse)
|
if (layer == fLastLayerUnderMouse)
|
||||||
fLastLayerUnderMouse = NULL;
|
fLastLayerUnderMouse = NULL;
|
||||||
}
|
}
|
||||||
@@ -1611,7 +1644,8 @@ RootLayer::AddDebugInfo(const char* string)
|
|||||||
{
|
{
|
||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
fDebugInfo << string;
|
fDebugInfo << string;
|
||||||
GoRedraw(this, BRegion(fFrame));
|
MarkForRedraw(VisibleRegion());
|
||||||
|
TriggerRedraw();
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1683,3 +1717,29 @@ RootLayer::ConvertToMessage(void* raw, int32 code)
|
|||||||
|
|
||||||
return bmsg;
|
return bmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RootLayer::MarkForRedraw(const BRegion &dirty)
|
||||||
|
{
|
||||||
|
BAutolock locker(fAllRegionsLock);
|
||||||
|
|
||||||
|
fDirtyForRedraw.Include(&dirty);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RootLayer::TriggerRedraw()
|
||||||
|
{
|
||||||
|
BAutolock locker(fAllRegionsLock);
|
||||||
|
/*
|
||||||
|
// for debugging
|
||||||
|
GetDrawingEngine()->ConstrainClippingRegion(&fDirtyForRedraw);
|
||||||
|
RGBColor c(rand()%255,rand()%255,rand()%255);
|
||||||
|
GetDrawingEngine()->FillRect(BRect(0,0,800,600), c);
|
||||||
|
snooze(2000000);
|
||||||
|
GetDrawingEngine()->ConstrainClippingRegion(NULL);
|
||||||
|
*/
|
||||||
|
_AllRedraw(fDirtyForRedraw);
|
||||||
|
|
||||||
|
fDirtyForRedraw.MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,10 +131,12 @@ public:
|
|||||||
void Unlock() { fAllRegionsLock.Unlock(); }
|
void Unlock() { fAllRegionsLock.Unlock(); }
|
||||||
bool IsLocked() { return fAllRegionsLock.IsLocked(); }
|
bool IsLocked() { return fAllRegionsLock.IsLocked(); }
|
||||||
void RunThread();
|
void RunThread();
|
||||||
void GoInvalidate(Layer *layer, const BRegion ®ion);
|
|
||||||
void GoRedraw(Layer *layer, const BRegion ®ion);
|
|
||||||
void GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel);
|
void GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel);
|
||||||
|
|
||||||
|
void MarkForRedraw(const BRegion &dirty);
|
||||||
|
void TriggerRedraw();
|
||||||
|
|
||||||
virtual void Draw(const BRect &r);
|
virtual void Draw(const BRect &r);
|
||||||
|
|
||||||
thread_id LockingThread() { return fAllRegionsLock.LockingThread(); }
|
thread_id LockingThread() { return fAllRegionsLock.LockingThread(); }
|
||||||
@@ -186,6 +188,8 @@ friend class WinBorder; // temporarily, I need invalidate_layer()
|
|||||||
|
|
||||||
BLocker fAllRegionsLock;
|
BLocker fAllRegionsLock;
|
||||||
|
|
||||||
|
BRegion fDirtyForRedraw;
|
||||||
|
|
||||||
thread_id fThreadID;
|
thread_id fThreadID;
|
||||||
port_id fListenPort;
|
port_id fListenPort;
|
||||||
BMessageQueue fQueue;
|
BMessageQueue fQueue;
|
||||||
|
|||||||
@@ -654,7 +654,13 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
|||||||
{
|
{
|
||||||
BRegion invalidRegion;
|
BRegion invalidRegion;
|
||||||
newLayer->GetWantedRegion(invalidRegion);
|
newLayer->GetWantedRegion(invalidRegion);
|
||||||
myRootLayer->GoInvalidate(newLayer, invalidRegion);
|
parent->MarkForRebuild(invalidRegion);
|
||||||
|
parent->TriggerRebuild();
|
||||||
|
if (newLayer->VisibleRegion().Frame().IsValid()) {
|
||||||
|
myRootLayer->MarkForRedraw(newLayer->VisibleRegion());
|
||||||
|
myRootLayer->TriggerRedraw();
|
||||||
|
}
|
||||||
|
// myRootLayer->GoInvalidate(newLayer, invalidRegion);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
@@ -669,15 +675,19 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
|||||||
STRACE(("ServerWindow %s: AS_LAYER_DELETE(self)...\n", fTitle));
|
STRACE(("ServerWindow %s: AS_LAYER_DELETE(self)...\n", fTitle));
|
||||||
|
|
||||||
Layer *parent = fCurrentLayer->fParent;
|
Layer *parent = fCurrentLayer->fParent;
|
||||||
BRegion *invalidRegion = NULL;
|
// BRegion *invalidRegion = NULL;
|
||||||
|
|
||||||
if (!fCurrentLayer->IsHidden() && parent) {
|
if (!fCurrentLayer->IsHidden() && parent && myRootLayer) {
|
||||||
#ifndef NEW_CLIPPING
|
#ifndef NEW_CLIPPING
|
||||||
if (fCurrentLayer->fFullVisible.CountRects() > 0)
|
if (fCurrentLayer->fFullVisible.CountRects() > 0)
|
||||||
invalidRegion = new BRegion(fCurrentLayer->fFullVisible);
|
invalidRegion = new BRegion(fCurrentLayer->fFullVisible);
|
||||||
#else
|
#else
|
||||||
if (fCurrentLayer->FullVisible().Frame().IsValid())
|
if (fCurrentLayer->FullVisible().Frame().IsValid()) {
|
||||||
invalidRegion = new BRegion(fCurrentLayer->FullVisible());
|
parent->MarkForRebuild(fCurrentLayer->FullVisible());
|
||||||
|
myRootLayer->MarkForRedraw(fCurrentLayer->FullVisible());
|
||||||
|
|
||||||
|
// invalidRegion = new BRegion(fCurrentLayer->FullVisible());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -685,15 +695,12 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
|||||||
fCurrentLayer->RemoveSelf();
|
fCurrentLayer->RemoveSelf();
|
||||||
fCurrentLayer->PruneTree();
|
fCurrentLayer->PruneTree();
|
||||||
|
|
||||||
|
if (parent)
|
||||||
|
parent->TriggerRebuild();
|
||||||
|
|
||||||
if (myRootLayer) {
|
if (myRootLayer) {
|
||||||
|
|
||||||
myRootLayer->LayerRemoved(fCurrentLayer);
|
myRootLayer->LayerRemoved(fCurrentLayer);
|
||||||
|
myRootLayer->TriggerRedraw();
|
||||||
// trigger update
|
|
||||||
if (invalidRegion) {
|
|
||||||
myRootLayer->GoInvalidate(parent, *invalidRegion);
|
|
||||||
delete invalidRegion;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_SERVERWINDOW
|
#ifdef DEBUG_SERVERWINDOW
|
||||||
@@ -990,8 +997,13 @@ if (myRootLayer)
|
|||||||
if (myRootLayer)
|
if (myRootLayer)
|
||||||
myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->fVisible);
|
myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->fVisible);
|
||||||
#else
|
#else
|
||||||
if (myRootLayer)
|
if (myRootLayer) {
|
||||||
myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->VisibleRegion());
|
myRootLayer->MarkForRedraw(fCurrentLayer->VisibleRegion());
|
||||||
|
myRootLayer->TriggerRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (myRootLayer)
|
||||||
|
// myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->VisibleRegion());
|
||||||
#endif
|
#endif
|
||||||
if (myRootLayer)
|
if (myRootLayer)
|
||||||
myRootLayer->Unlock();
|
myRootLayer->Unlock();
|
||||||
@@ -1115,7 +1127,15 @@ if (myRootLayer)
|
|||||||
{
|
{
|
||||||
BRegion invalidRegion;
|
BRegion invalidRegion;
|
||||||
fCurrentLayer->GetWantedRegion(invalidRegion);
|
fCurrentLayer->GetWantedRegion(invalidRegion);
|
||||||
myRootLayer->GoInvalidate(fCurrentLayer, invalidRegion);
|
|
||||||
|
// TODO: this is broken! a smaller area may be invalidated!
|
||||||
|
|
||||||
|
fCurrentLayer->fParent->MarkForRebuild(invalidRegion);
|
||||||
|
fCurrentLayer->fParent->TriggerRebuild();
|
||||||
|
myRootLayer->MarkForRedraw(invalidRegion);
|
||||||
|
myRootLayer->TriggerRedraw();
|
||||||
|
|
||||||
|
// myRootLayer->GoInvalidate(fCurrentLayer, invalidRegion);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1206,8 +1226,9 @@ if (myRootLayer)
|
|||||||
#ifdef NEW_CLIPPING
|
#ifdef NEW_CLIPPING
|
||||||
invalidRegion.IntersectWith(&fCurrentLayer->fVisible2);
|
invalidRegion.IntersectWith(&fCurrentLayer->fVisible2);
|
||||||
#endif
|
#endif
|
||||||
myRootLayer->GoRedraw(fWinBorder, invalidRegion);
|
myRootLayer->MarkForRedraw(invalidRegion);
|
||||||
// myRootLayer->RequestDraw(invalidRegion, fWinBorder);
|
myRootLayer->TriggerRedraw();
|
||||||
|
// myRootLayer->GoRedraw(fWinBorder, invalidRegion);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1217,7 +1238,7 @@ if (myRootLayer)
|
|||||||
|
|
||||||
// TODO: handle transformation (origin and scale) prior to converting to top
|
// TODO: handle transformation (origin and scale) prior to converting to top
|
||||||
// TODO: Handle conversion to top
|
// TODO: Handle conversion to top
|
||||||
BRegion invalReg;
|
BRegion invalidReg;
|
||||||
int32 noOfRects;
|
int32 noOfRects;
|
||||||
BRect rect;
|
BRect rect;
|
||||||
|
|
||||||
@@ -1225,11 +1246,17 @@ if (myRootLayer)
|
|||||||
|
|
||||||
for (int i = 0; i < noOfRects; i++) {
|
for (int i = 0; i < noOfRects; i++) {
|
||||||
link.Read<BRect>(&rect);
|
link.Read<BRect>(&rect);
|
||||||
invalReg.Include(rect);
|
invalidReg.Include(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myRootLayer)
|
if (myRootLayer) {
|
||||||
myRootLayer->GoRedraw(fCurrentLayer, invalReg);
|
fCurrentLayer->ConvertToScreen2(&invalidReg);
|
||||||
|
|
||||||
|
myRootLayer->MarkForRedraw(invalidReg);
|
||||||
|
myRootLayer->TriggerRedraw();
|
||||||
|
|
||||||
|
// myRootLayer->GoRedraw(fCurrentLayer, invalReg);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -876,7 +876,7 @@ WinBorder::_ReserveRegions(BRegion ®)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WinBorder::_GetWantedRegion(BRegion ®)
|
WinBorder::GetWantedRegion(BRegion ®)
|
||||||
{
|
{
|
||||||
if (fRebuildDecRegion)
|
if (fRebuildDecRegion)
|
||||||
{
|
{
|
||||||
@@ -889,11 +889,49 @@ WinBorder::_GetWantedRegion(BRegion ®)
|
|||||||
ConvertToScreen2(&screenFrame);
|
ConvertToScreen2(&screenFrame);
|
||||||
reg.Set(screenFrame);
|
reg.Set(screenFrame);
|
||||||
|
|
||||||
|
reg.Include(&fDecRegion);
|
||||||
|
|
||||||
BRegion screenReg(GetRootLayer()->Bounds());
|
BRegion screenReg(GetRootLayer()->Bounds());
|
||||||
|
|
||||||
reg.IntersectWith(&screenReg);
|
reg.IntersectWith(&screenReg);
|
||||||
|
}
|
||||||
|
|
||||||
reg.Include(&fDecRegion);
|
void
|
||||||
|
WinBorder::RequestClientRedraw(const BRegion &invalid)
|
||||||
|
{
|
||||||
|
BRegion updateReg(fTopLayer->FullVisible());
|
||||||
|
|
||||||
|
updateReg.IntersectWith(&invalid);
|
||||||
|
|
||||||
|
if (updateReg.CountRects() > 0) {
|
||||||
|
fCumulativeRegion.Include(&updateReg);
|
||||||
|
if (fUpdateRequestsEnabled && !InUpdate() && !fRequestSent) {
|
||||||
|
fInUpdateRegion = fCumulativeRegion;
|
||||||
|
cnt++;
|
||||||
|
if (cnt != 1)
|
||||||
|
CRITICAL("WinBorder::RequestClientRedraw(): cnt != 1 -> Not Allowed!");
|
||||||
|
fRequestSent = true; // this is here to avoid a possible de-synchronization
|
||||||
|
|
||||||
|
BMessage msg;
|
||||||
|
msg.what = _UPDATE_;
|
||||||
|
#ifndef NEW_CLIPPING
|
||||||
|
msg.AddRect("_rect", ConvertFromTop(fInUpdateRegion.Frame()));
|
||||||
|
#else
|
||||||
|
BRect rect(fInUpdateRegion.Frame());
|
||||||
|
ConvertFromScreen2(&rect);
|
||||||
|
msg.AddRect("_rect", rect );
|
||||||
|
#endif
|
||||||
|
msg.AddRect("debug_rect", fInUpdateRegion.Frame());
|
||||||
|
|
||||||
|
if (Window()->SendMessageToClient(&msg) == B_OK) {
|
||||||
|
fCumulativeRegion.MakeEmpty();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fRequestSent = false;
|
||||||
|
fInUpdateRegion.MakeEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -60,8 +60,9 @@ class WinBorder : public Layer {
|
|||||||
|
|
||||||
#ifndef NEW_CLIPPING
|
#ifndef NEW_CLIPPING
|
||||||
virtual void RebuildFullRegion();
|
virtual void RebuildFullRegion();
|
||||||
|
#else
|
||||||
|
virtual void GetWantedRegion(BRegion ®);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void UpdateStart();
|
void UpdateStart();
|
||||||
void UpdateEnd();
|
void UpdateEnd();
|
||||||
inline bool InUpdate() const
|
inline bool InUpdate() const
|
||||||
@@ -126,10 +127,11 @@ class WinBorder : public Layer {
|
|||||||
virtual void MovedByHook(float dx, float dy);
|
virtual void MovedByHook(float dx, float dy);
|
||||||
virtual void ResizedByHook(float dx, float dy, bool automatic);
|
virtual void ResizedByHook(float dx, float dy, bool automatic);
|
||||||
|
|
||||||
|
void RequestClientRedraw(const BRegion &invalid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_decorator_region(BRect frame);
|
void set_decorator_region(BRect frame);
|
||||||
virtual void _ReserveRegions(BRegion ®);
|
virtual void _ReserveRegions(BRegion ®);
|
||||||
virtual void _GetWantedRegion(BRegion ®);
|
|
||||||
|
|
||||||
BRegion fDecRegion;
|
BRegion fDecRegion;
|
||||||
bool fRebuildDecRegion;
|
bool fRebuildDecRegion;
|
||||||
|
|||||||
Reference in New Issue
Block a user