ServerWindow.cpp:

* made MonitorWin thread wait until associated WinBorder is hidden
and RootLayer's lock is acquired.
RootLayer.cpp:
	* added 2 public methods for calculating visible regions.
ALL:
	* all previous 'Invalidate' methods now call RootLayer's ones.

	That's it, all region calculations are done in the context of the
high priority thread: WorkingThread.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10961 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adi Oanca
2005-01-22 20:51:12 +00:00
parent 61e1618dce
commit ed446d324d
4 changed files with 99 additions and 38 deletions
+2 -12
View File
@@ -685,12 +685,7 @@ void Layer::Show(bool invalidate)
fHidden = false; fHidden = false;
if(invalidate) if(invalidate)
{ GetRootLayer()->GoInvalidate(this, fFull);
if(fParent)
fParent->FullInvalidate( BRegion(fFull) );
else
FullInvalidate( BRegion(fFull) );
}
} }
/*! /*!
@@ -706,12 +701,7 @@ void Layer::Hide(bool invalidate)
fHidden = true; fHidden = true;
if(invalidate) if(invalidate)
{ GetRootLayer()->GoInvalidate(this, fFullVisible);
if(fParent)
fParent->FullInvalidate( BRegion(fFullVisible) );
else
FullInvalidate( BRegion(fFullVisible) );
}
} }
//! Returns true if the layer is hidden //! Returns true if the layer is hidden
+62 -8
View File
@@ -139,7 +139,7 @@ int32 RootLayer::WorkingThread(void *data)
// first make sure we are actualy visible // first make sure we are actualy visible
oneRootLayer->Lock(); oneRootLayer->Lock();
oneRootLayer->RebuildFullRegion(); oneRootLayer->RebuildFullRegion();
oneRootLayer->FullInvalidate(oneRootLayer->Bounds()); oneRootLayer->invalidate_layer(oneRootLayer, oneRootLayer->Bounds());
oneRootLayer->Unlock(); oneRootLayer->Unlock();
for(;;) for(;;)
@@ -181,16 +181,34 @@ int32 RootLayer::WorkingThread(void *data)
case AS_ROOTLAYER_SHOW_WINBORDER: case AS_ROOTLAYER_SHOW_WINBORDER:
{ {
WinBorder *winBorder = NULL; WinBorder *winBorder = NULL;
messageQueue.Read<WinBorder*>(&winBorder); messageQueue.Read<WinBorder*>(&winBorder);
oneRootLayer->show_winBorder(winBorder); oneRootLayer->show_winBorder(winBorder);
break; break;
} }
case AS_ROOTLAYER_HIDE_WINBORDER: case AS_ROOTLAYER_HIDE_WINBORDER:
{ {
WinBorder *winBorder = NULL; WinBorder *winBorder = NULL;
messageQueue.Read<WinBorder*>(&winBorder); messageQueue.Read<WinBorder*>(&winBorder);
oneRootLayer->hide_winBorder(winBorder); oneRootLayer->hide_winBorder(winBorder);
break;
}
case AS_ROOTLAYER_DO_INVALIDATE:
{
BRegion invalidRegion;
Layer *layer = NULL;
messageQueue.Read<Layer*>(&layer);
messageQueue.ReadRegion(&invalidRegion);
oneRootLayer->invalidate_layer(layer, invalidRegion);
break;
}
case AS_ROOTLAYER_DO_REDRAW:
{
BRegion redrawRegion;
Layer *layer = NULL;
messageQueue.Read<Layer*>(&layer);
messageQueue.ReadRegion(&redrawRegion);
oneRootLayer->redraw_layer(layer, redrawRegion);
break; break;
} }
default: default:
@@ -207,6 +225,43 @@ int32 RootLayer::WorkingThread(void *data)
return 0; return 0;
} }
void RootLayer::GoInvalidate(const Layer *layer, const BRegion &region)
{
BPortLink msg(fListenPort, -1);
msg.StartMessage(AS_ROOTLAYER_DO_INVALIDATE);
msg.Attach<const Layer*>(layer);
msg.AttachRegion(region);
msg.Flush();
}
void RootLayer::invalidate_layer(Layer *layer, const BRegion &region)
{
// NOTE: our thread (WorkingThread) is locked here.
if (layer->fParent)
layer = layer->fParent;
layer->FullInvalidate(region);
}
void RootLayer::GoRedraw(const Layer *layer, const BRegion &region)
{
BPortLink msg(fListenPort, -1);
msg.StartMessage(AS_ROOTLAYER_DO_REDRAW);
msg.Attach<const Layer*>(layer);
msg.AttachRegion(region);
msg.Flush();
}
void RootLayer::redraw_layer(Layer *layer, const BRegion &region)
{
// NOTE: our thread (WorkingThread) is locked here.
layer->Invalidate(region);
}
void RootLayer::MoveBy(float x, float y) void RootLayer::MoveBy(float x, float y)
{ {
} }
@@ -1616,7 +1671,6 @@ void RootLayer::hide_winBorder(WinBorder *winBorder)
ws->SearchAndSetNewFocus(winBorder); ws->SearchAndSetNewFocus(winBorder);
else{ else{
// TODO: RootLayer or Desktop class should take care of invalidating // TODO: RootLayer or Desktop class should take care of invalidating
// ws->Invalidate();
} }
} }
} }
+5
View File
@@ -115,6 +115,8 @@ 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(const Layer *layer, const BRegion &region);
void GoRedraw(const Layer *layer, const BRegion &region);
// Debug methods // Debug methods
void PrintToStream(void); void PrintToStream(void);
@@ -130,6 +132,9 @@ private:
void show_winBorder(WinBorder* winBorder); void show_winBorder(WinBorder* winBorder);
void hide_winBorder(WinBorder* winBorder); void hide_winBorder(WinBorder* winBorder);
void invalidate_layer(Layer *layer, const BRegion &region);
void redraw_layer(Layer *layer, const BRegion &region);
Desktop *fDesktop; Desktop *fDesktop;
BMessage *fDragMessage; BMessage *fDragMessage;
WinBorder *fMouseTarget; WinBorder *fMouseTarget;
+30 -18
View File
@@ -590,7 +590,9 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
printf("ServerWindow %s received unexpected code - message offset %ld before top_view attached.\n",fTitle.String(), code - SERVER_TRUE); printf("ServerWindow %s received unexpected code - message offset %ld before top_view attached.\n",fTitle.String(), code - SERVER_TRUE);
return; return;
} }
RootLayer *myRootLayer = fWinBorder->GetRootLayer();
switch(code) switch(code)
{ {
//--------- BView Messages ----------------- //--------- BView Messages -----------------
@@ -741,8 +743,7 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
cl->AddChild(newLayer, this); cl->AddChild(newLayer, this);
if (!(newLayer->IsHidden())){ if (!(newLayer->IsHidden())){
// cl is the parent of newLayer, so this call is OK. myRootLayer->GoInvalidate(newLayer, newLayer->fFull);
cl->FullInvalidate(BRegion(newLayer->fFull));
} }
break; break;
@@ -762,7 +763,8 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
cl->RemoveSelf(); cl->RemoveSelf();
cl->PruneTree(); cl->PruneTree();
parent->Invalidate(cl->Frame()); if (parent)
myRootLayer->GoInvalidate(parent, BRegion(cl->Frame()));
#ifdef DEBUG_SERVERWINDOW #ifdef DEBUG_SERVERWINDOW
parent->PrintTree(); parent->PrintTree();
@@ -1073,7 +1075,7 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
cl->fLayerData->viewcolor.SetColor(c); cl->fLayerData->viewcolor.SetColor(c);
cl->Invalidate(cl->fVisible); myRootLayer->GoRedraw(cl, cl->fVisible);
break; break;
} }
@@ -1215,7 +1217,7 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
// redraw if we previously had or if we have acquired a picture to clip to. // redraw if we previously had or if we have acquired a picture to clip to.
if (redraw) if (redraw)
cl->Invalidate(reg); myRootLayer->GoRedraw(cl, reg);
break; break;
} }
@@ -1321,12 +1323,7 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
cl->RebuildFullRegion(); cl->RebuildFullRegion();
if (!(cl->IsHidden())) if (!(cl->IsHidden()))
{ myRootLayer->GoInvalidate(cl, cl->fFull);
if (cl->fParent)
cl->fParent->FullInvalidate(BRegion(cl->fFull));
else
cl->FullInvalidate(BRegion(cl->fFull));
}
break; break;
} }
@@ -1338,8 +1335,8 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
BRect invalRect; BRect invalRect;
link.Read<BRect>(&invalRect); link.Read<BRect>(&invalRect);
cl->Invalidate(invalRect); myRootLayer->GoRedraw(cl, BRegion(invalRect));
break; break;
} }
@@ -1360,7 +1357,7 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
invalReg.Include(rect); invalReg.Include(rect);
} }
cl->Invalidate(invalReg); myRootLayer->GoRedraw(cl, invalReg);
break; break;
} }
@@ -2191,17 +2188,32 @@ int32 ServerWindow::MonitorWin(void *data)
{ {
// this means the client has been killed // this means the client has been killed
STRACE(("ServerWindow %s received 'AS_CLIENT_DEAD/AS_DELETE_WINDOW' message code\n",win->Title())); STRACE(("ServerWindow %s received 'AS_CLIENT_DEAD/AS_DELETE_WINDOW' message code\n",win->Title()));
RootLayer *myRootLayer = win->fWinBorder->GetRootLayer();
quitting = true; quitting = true;
// we are preparing to delete a ServerWindow, RootLayer should be aware
// of that and stop for a moment.
// also we must wait a bit for the associated WinBorder to become hidden
while(1)
{
myRootLayer->Lock();
if (win->IsHidden())
break;
else
myRootLayer->Unlock();
}
// ServerWindow's destructor takes care of pulling this object off the desktop. // ServerWindow's destructor takes care of pulling this object off the desktop.
delete win; delete win;
myRootLayer->Unlock();
exit_thread(0);
break; break;
} }
case B_QUIT_REQUESTED: case B_QUIT_REQUESTED:
{ {
STRACE(("ServerWindow %s received Quit request\n",win->Title())); STRACE(("ServerWindow %s received Quit request\n",win->Title()));
quitting = true; win->Quit();
delete win;
break; break;
} }
default: default: