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:
parent
9c91a5f9d6
commit
ac4f06c5c6
@ -21,7 +21,7 @@
|
||||
//
|
||||
// File Name: Layer.cpp
|
||||
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
// Adi Oanca <adioanca@cotty.iren.ro>
|
||||
// Adi Oanca <adioanca@gmail.com>
|
||||
// Stephan Aßmus <superstippi@gmx.de>
|
||||
// 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<Layer*>(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<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
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Authors:
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
* Adi Oanca <adioanca@cotty.iren.com>
|
||||
* Adi Oanca <adioanca@gmail.com>
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*
|
||||
* 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;
|
||||
|
@ -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<Layer*>(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<Layer*>(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<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 = 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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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<BRect>(&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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user