From ac4f06c5c62815850056e5cba836e2676ffc761f Mon Sep 17 00:00:00 2001 From: Adi Oanca Date: Sun, 6 Nov 2005 17:47:06 +0000 Subject: [PATCH] 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 --- src/servers/app/Layer.cpp | 163 ++++++++++++++++++++---------- src/servers/app/Layer.h | 18 ++-- src/servers/app/RootLayer.cpp | 166 +++++++++++++++++++++---------- src/servers/app/RootLayer.h | 8 +- src/servers/app/ServerWindow.cpp | 69 +++++++++---- src/servers/app/WinBorder.cpp | 42 +++++++- src/servers/app/WinBorder.h | 6 +- 7 files changed, 331 insertions(+), 141 deletions(-) diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index 14eb39b837..d18bacff0d 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -21,7 +21,7 @@ // // File Name: Layer.cpp // Author: DarkWyrm -// Adi Oanca +// Adi Oanca // Stephan Aßmus // Description: Class used for rendering to the frame buffer. One layer per // view on screen and also for window decorators @@ -89,6 +89,7 @@ Layer::Layer(BRect frame, const char* name, int32 token, #else fVisible2(), fFullVisible2(), + fDirtyForRebuild(), fClipReg(&fVisible2), #endif @@ -959,10 +960,17 @@ RebuildFullRegion(); #else if (invalidate) { // compute the region this layer wants for itself - BRegion invalidRegion; - _GetWantedRegion(invalidRegion); - if (invalidRegion.CountRects() > 0) - GetRootLayer()->GoInvalidate(this, invalidRegion); + BRegion invalid; + GetWantedRegion(invalid); + if (invalid.CountRects() > 0) { + fParent->MarkForRebuild(invalid); + GetRootLayer()->MarkForRedraw(invalid); + + fParent->TriggerRebuild(); + GetRootLayer()->TriggerRedraw(); + +// GetRootLayer()->GoInvalidate(this, invalid); + } } #endif } @@ -988,7 +996,15 @@ Layer::Hide(bool invalidate) GetRootLayer()->GoInvalidate(this, fFullVisible); #else 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 } @@ -1970,15 +1986,6 @@ Layer::ScrolledByHook(float dx, float dy) // empty. } - -void -Layer::GetWantedRegion(BRegion& reg) const -{ - // this is the same as get_user_region. - // because get_user_region modifies nothing. - const_cast(this)->Layer::_GetWantedRegion(reg); -} - //! converts a point from local to parent's coordinate system void Layer::ConvertToParent2(BPoint* pt) const @@ -2121,8 +2128,13 @@ Layer::do_Hide() clear_visible_regions(); - if (invalid.Frame().IsValid()) - fParent->do_Invalidate(invalid, this); + if (invalid.CountRects() > 0) { + fParent->MarkForRebuild(invalid); + GetRootLayer()->MarkForRedraw(invalid); + + fParent->TriggerRebuild(); + GetRootLayer()->TriggerRedraw(); + } } } @@ -2134,41 +2146,18 @@ Layer::do_Show() if (fParent && !fParent->IsHidden() && GetRootLayer()) { BRegion invalid; - _GetWantedRegion(invalid); + GetWantedRegion(invalid); - if (invalid.CountRects() > 0) - fParent->do_Invalidate(invalid, this); + if (invalid.CountRects() > 0) { + 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 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. BRegion invalid; - _GetWantedRegion(invalid); + GetWantedRegion(invalid); invalid.Include(&fFullVisible2); 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. BRegion invalid; - _GetWantedRegion(invalid); + GetWantedRegion(invalid); invalid.Include(&fFullVisible2); clear_visible_regions(); @@ -2483,7 +2472,7 @@ Layer::do_ScrollBy(float dx, float dy) } void -Layer::_GetWantedRegion(BRegion ®) +Layer::GetWantedRegion(BRegion ®) { // 1) set to frame in screen coords BRect screenFrame(Bounds()); @@ -2537,7 +2526,7 @@ Layer::rebuild_visible_regions(const BRegion &invalid, // intersect maximum wanted region with the invalid region BRegion common; - _GetWantedRegion(common); + GetWantedRegion(common); common.IntersectWith(&invalid); // 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(); } +// 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(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 diff --git a/src/servers/app/Layer.h b/src/servers/app/Layer.h index 3366db0b02..ba0b3a59ca 100644 --- a/src/servers/app/Layer.h +++ b/src/servers/app/Layer.h @@ -4,7 +4,7 @@ * * Authors: * DarkWyrm - * Adi Oanca + * Adi Oanca * Stephan Aßmus * * Description: @@ -248,7 +248,13 @@ class Layer { inline const BRegion& VisibleRegion() const { return fVisible2; } 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 ResizedByHook(float dx, float dy, bool automatic); @@ -277,18 +283,11 @@ class Layer { void do_ResizeBy(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, const BRegion &parentLocalVisible, const Layer *startFrom); virtual void _ReserveRegions(BRegion ®); - virtual void _GetWantedRegion(BRegion ®); void clear_visible_regions(); void resize_layer_frame_by(float x, float y); @@ -342,6 +341,7 @@ class Layer { private: BRegion fVisible2; BRegion fFullVisible2; + BRegion fDirtyForRebuild; protected: #endif BRegion* fClipReg; diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index 1eef43cfc8..e17e7c0aaf 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -68,6 +68,8 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, fSavedEventOptions(0), fAllRegionsLock("root layer region lock"), + fDirtyForRedraw(), + fThreadID(B_ERROR), fListenPort(-1), @@ -199,13 +201,15 @@ RootLayer::WorkingThread(void *data) oneRootLayer->RebuildFullRegion(); oneRootLayer->GoInvalidate(oneRootLayer, oneRootLayer->Bounds()); #else - oneRootLayer->rebuild_visible_regions( - BRegion(oneRootLayer->Bounds()), - BRegion(oneRootLayer->Bounds()), - oneRootLayer->LastChild()); + // RootLayer starts with valid visible regions + oneRootLayer->fFullVisible2.Set(oneRootLayer->Bounds()); + oneRootLayer->fVisible2.Set(oneRootLayer->Bounds()); - oneRootLayer->fRedrawReg.Include(oneRootLayer->Bounds()); - oneRootLayer->RequestDraw(oneRootLayer->fRedrawReg, oneRootLayer->LastChild()); + oneRootLayer->MarkForRebuild(oneRootLayer->Bounds()); + oneRootLayer->MarkForRedraw(oneRootLayer->Bounds()); + + oneRootLayer->TriggerRebuild(); + oneRootLayer->TriggerRedraw(); #endif oneRootLayer->Unlock(); @@ -277,38 +281,6 @@ RootLayer::WorkingThread(void *data) 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 RootLayer::GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel) { @@ -829,7 +801,7 @@ RootLayer::RevealNewWMState(Workspace::State &oldWMState) #ifndef NEW_CLIPPING fRedrawReg.Include(&dirtyRegion); #else -// TODO: code for new clipping engine! + MarkForRedraw(dirtyRegion); #endif } } @@ -848,37 +820,98 @@ RootLayer::RevealNewWMState(Workspace::State &oldWMState) // clear visible areas for windows not visible anymore. int32 oldWindowCount = oldWMState.WindowList.CountItems(); int32 newWindowCount = fWMState.WindowList.CountItems(); - bool stillPresent; - Layer *layer; - for (int32 i = 0; i < oldWindowCount; i++) - { - layer = static_cast(oldWMState.WindowList.ItemAtFast(i)); - stillPresent = false; - for (int32 j = 0; j < newWindowCount; j++) - if (layer == fWMState.WindowList.ItemAtFast(j)) - stillPresent = true; + BList oldStrippedList, newStrippedList; + for (int32 i = 0; i < oldWindowCount; ++i) { + Layer *layer = static_cast(oldWMState.WindowList.ItemAtFast(i)); + if (!layer) + continue; - 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 empty_visible_regions(layer); #else layer->clear_visible_regions(); #endif + } + else { + oldStrippedList.AddItem(layer); + } } + + for (int32 i = 0; i < newWindowCount; ++i) { + Layer *layer = static_cast(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(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 = false; // trigger region rebuilding and redraw #ifndef NEW_CLIPPING GoInvalidate(this, fFull); #else - do_Invalidate(Bounds()); + TriggerRebuild(); + TriggerRedraw(); #endif } else if (redraw) { #ifndef NEW_CLIPPING GoInvalidate(this, dirtyRegion); #else - do_Redraw(dirtyRegion); + MarkForRedraw(dirtyRegion); + TriggerRedraw(); #endif } } @@ -1402,7 +1435,7 @@ RootLayer::LayerRemoved(Layer* layer) { if (layer == fNotifyLayer) fNotifyLayer = NULL; - +// TODO: this must not happen!!! Fix this, quickly! if (layer == fLastLayerUnderMouse) fLastLayerUnderMouse = NULL; } @@ -1611,7 +1644,8 @@ RootLayer::AddDebugInfo(const char* string) { if (Lock()) { fDebugInfo << string; - GoRedraw(this, BRegion(fFrame)); + MarkForRedraw(VisibleRegion()); + TriggerRedraw(); Unlock(); } } @@ -1683,3 +1717,29 @@ RootLayer::ConvertToMessage(void* raw, int32 code) 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(); +} + diff --git a/src/servers/app/RootLayer.h b/src/servers/app/RootLayer.h index e643537a9e..0a3099ed97 100644 --- a/src/servers/app/RootLayer.h +++ b/src/servers/app/RootLayer.h @@ -131,10 +131,12 @@ public: void Unlock() { fAllRegionsLock.Unlock(); } bool IsLocked() { return fAllRegionsLock.IsLocked(); } void RunThread(); - void GoInvalidate(Layer *layer, const BRegion ®ion); - void GoRedraw(Layer *layer, const BRegion ®ion); + void GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel); + void MarkForRedraw(const BRegion &dirty); + void TriggerRedraw(); + virtual void Draw(const BRect &r); thread_id LockingThread() { return fAllRegionsLock.LockingThread(); } @@ -186,6 +188,8 @@ friend class WinBorder; // temporarily, I need invalidate_layer() BLocker fAllRegionsLock; + BRegion fDirtyForRedraw; + thread_id fThreadID; port_id fListenPort; BMessageQueue fQueue; diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 7ac4bf9330..26f1fc3016 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -654,7 +654,13 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) { BRegion 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 break; @@ -669,15 +675,19 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) STRACE(("ServerWindow %s: AS_LAYER_DELETE(self)...\n", fTitle)); Layer *parent = fCurrentLayer->fParent; - BRegion *invalidRegion = NULL; +// BRegion *invalidRegion = NULL; - if (!fCurrentLayer->IsHidden() && parent) { + if (!fCurrentLayer->IsHidden() && parent && myRootLayer) { #ifndef NEW_CLIPPING if (fCurrentLayer->fFullVisible.CountRects() > 0) invalidRegion = new BRegion(fCurrentLayer->fFullVisible); #else - if (fCurrentLayer->FullVisible().Frame().IsValid()) - invalidRegion = new BRegion(fCurrentLayer->FullVisible()); + if (fCurrentLayer->FullVisible().Frame().IsValid()) { + parent->MarkForRebuild(fCurrentLayer->FullVisible()); + myRootLayer->MarkForRedraw(fCurrentLayer->FullVisible()); + +// invalidRegion = new BRegion(fCurrentLayer->FullVisible()); + } #endif } @@ -685,15 +695,12 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) fCurrentLayer->RemoveSelf(); fCurrentLayer->PruneTree(); + if (parent) + parent->TriggerRebuild(); + if (myRootLayer) { - myRootLayer->LayerRemoved(fCurrentLayer); - - // trigger update - if (invalidRegion) { - myRootLayer->GoInvalidate(parent, *invalidRegion); - delete invalidRegion; - } + myRootLayer->TriggerRedraw(); } #ifdef DEBUG_SERVERWINDOW @@ -990,8 +997,13 @@ if (myRootLayer) if (myRootLayer) myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->fVisible); #else - if (myRootLayer) - myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->VisibleRegion()); + if (myRootLayer) { + myRootLayer->MarkForRedraw(fCurrentLayer->VisibleRegion()); + myRootLayer->TriggerRedraw(); + } + +// if (myRootLayer) +// myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->VisibleRegion()); #endif if (myRootLayer) myRootLayer->Unlock(); @@ -1115,7 +1127,15 @@ if (myRootLayer) { BRegion 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 @@ -1206,8 +1226,9 @@ if (myRootLayer) #ifdef NEW_CLIPPING invalidRegion.IntersectWith(&fCurrentLayer->fVisible2); #endif - myRootLayer->GoRedraw(fWinBorder, invalidRegion); -// myRootLayer->RequestDraw(invalidRegion, fWinBorder); + myRootLayer->MarkForRedraw(invalidRegion); + myRootLayer->TriggerRedraw(); +// myRootLayer->GoRedraw(fWinBorder, invalidRegion); } break; } @@ -1217,7 +1238,7 @@ if (myRootLayer) // TODO: handle transformation (origin and scale) prior to converting to top // TODO: Handle conversion to top - BRegion invalReg; + BRegion invalidReg; int32 noOfRects; BRect rect; @@ -1225,11 +1246,17 @@ if (myRootLayer) for (int i = 0; i < noOfRects; i++) { link.Read(&rect); - invalReg.Include(rect); + invalidReg.Include(rect); } - if (myRootLayer) - myRootLayer->GoRedraw(fCurrentLayer, invalReg); + if (myRootLayer) { + fCurrentLayer->ConvertToScreen2(&invalidReg); + + myRootLayer->MarkForRedraw(invalidReg); + myRootLayer->TriggerRedraw(); + +// myRootLayer->GoRedraw(fCurrentLayer, invalReg); + } break; } diff --git a/src/servers/app/WinBorder.cpp b/src/servers/app/WinBorder.cpp index b3dbc4ac4d..f22d73f227 100644 --- a/src/servers/app/WinBorder.cpp +++ b/src/servers/app/WinBorder.cpp @@ -876,7 +876,7 @@ WinBorder::_ReserveRegions(BRegion ®) } void -WinBorder::_GetWantedRegion(BRegion ®) +WinBorder::GetWantedRegion(BRegion ®) { if (fRebuildDecRegion) { @@ -889,11 +889,49 @@ WinBorder::_GetWantedRegion(BRegion ®) ConvertToScreen2(&screenFrame); reg.Set(screenFrame); + reg.Include(&fDecRegion); + BRegion screenReg(GetRootLayer()->Bounds()); 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 diff --git a/src/servers/app/WinBorder.h b/src/servers/app/WinBorder.h index fe04963030..51478224d4 100644 --- a/src/servers/app/WinBorder.h +++ b/src/servers/app/WinBorder.h @@ -60,8 +60,9 @@ class WinBorder : public Layer { #ifndef NEW_CLIPPING virtual void RebuildFullRegion(); +#else + virtual void GetWantedRegion(BRegion ®); #endif - void UpdateStart(); void UpdateEnd(); inline bool InUpdate() const @@ -126,10 +127,11 @@ class WinBorder : public Layer { virtual void MovedByHook(float dx, float dy); virtual void ResizedByHook(float dx, float dy, bool automatic); + void RequestClientRedraw(const BRegion &invalid); + private: void set_decorator_region(BRect frame); virtual void _ReserveRegions(BRegion ®); - virtual void _GetWantedRegion(BRegion ®); BRegion fDecRegion; bool fRebuildDecRegion;