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:
@@ -685,12 +685,7 @@ void Layer::Show(bool invalidate)
|
||||
fHidden = false;
|
||||
|
||||
if(invalidate)
|
||||
{
|
||||
if(fParent)
|
||||
fParent->FullInvalidate( BRegion(fFull) );
|
||||
else
|
||||
FullInvalidate( BRegion(fFull) );
|
||||
}
|
||||
GetRootLayer()->GoInvalidate(this, fFull);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -706,12 +701,7 @@ void Layer::Hide(bool invalidate)
|
||||
fHidden = true;
|
||||
|
||||
if(invalidate)
|
||||
{
|
||||
if(fParent)
|
||||
fParent->FullInvalidate( BRegion(fFullVisible) );
|
||||
else
|
||||
FullInvalidate( BRegion(fFullVisible) );
|
||||
}
|
||||
GetRootLayer()->GoInvalidate(this, fFullVisible);
|
||||
}
|
||||
|
||||
//! Returns true if the layer is hidden
|
||||
|
||||
@@ -139,7 +139,7 @@ int32 RootLayer::WorkingThread(void *data)
|
||||
// first make sure we are actualy visible
|
||||
oneRootLayer->Lock();
|
||||
oneRootLayer->RebuildFullRegion();
|
||||
oneRootLayer->FullInvalidate(oneRootLayer->Bounds());
|
||||
oneRootLayer->invalidate_layer(oneRootLayer, oneRootLayer->Bounds());
|
||||
oneRootLayer->Unlock();
|
||||
|
||||
for(;;)
|
||||
@@ -181,16 +181,34 @@ int32 RootLayer::WorkingThread(void *data)
|
||||
|
||||
case AS_ROOTLAYER_SHOW_WINBORDER:
|
||||
{
|
||||
WinBorder *winBorder = NULL;
|
||||
messageQueue.Read<WinBorder*>(&winBorder);
|
||||
oneRootLayer->show_winBorder(winBorder);
|
||||
WinBorder *winBorder = NULL;
|
||||
messageQueue.Read<WinBorder*>(&winBorder);
|
||||
oneRootLayer->show_winBorder(winBorder);
|
||||
break;
|
||||
}
|
||||
case AS_ROOTLAYER_HIDE_WINBORDER:
|
||||
{
|
||||
WinBorder *winBorder = NULL;
|
||||
messageQueue.Read<WinBorder*>(&winBorder);
|
||||
oneRootLayer->hide_winBorder(winBorder);
|
||||
WinBorder *winBorder = NULL;
|
||||
messageQueue.Read<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;
|
||||
}
|
||||
default:
|
||||
@@ -207,6 +225,43 @@ int32 RootLayer::WorkingThread(void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RootLayer::GoInvalidate(const Layer *layer, const BRegion ®ion)
|
||||
{
|
||||
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 ®ion)
|
||||
{
|
||||
// NOTE: our thread (WorkingThread) is locked here.
|
||||
|
||||
if (layer->fParent)
|
||||
layer = layer->fParent;
|
||||
|
||||
layer->FullInvalidate(region);
|
||||
}
|
||||
|
||||
void RootLayer::GoRedraw(const Layer *layer, const BRegion ®ion)
|
||||
{
|
||||
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 ®ion)
|
||||
{
|
||||
// NOTE: our thread (WorkingThread) is locked here.
|
||||
|
||||
layer->Invalidate(region);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RootLayer::MoveBy(float x, float y)
|
||||
{
|
||||
}
|
||||
@@ -1616,7 +1671,6 @@ void RootLayer::hide_winBorder(WinBorder *winBorder)
|
||||
ws->SearchAndSetNewFocus(winBorder);
|
||||
else{
|
||||
// TODO: RootLayer or Desktop class should take care of invalidating
|
||||
// ws->Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,8 @@ public:
|
||||
void Unlock() { fAllRegionsLock.Unlock(); }
|
||||
bool IsLocked() { return fAllRegionsLock.IsLocked(); }
|
||||
void RunThread();
|
||||
void GoInvalidate(const Layer *layer, const BRegion ®ion);
|
||||
void GoRedraw(const Layer *layer, const BRegion ®ion);
|
||||
|
||||
// Debug methods
|
||||
void PrintToStream(void);
|
||||
@@ -130,6 +132,9 @@ private:
|
||||
void show_winBorder(WinBorder* winBorder);
|
||||
void hide_winBorder(WinBorder* winBorder);
|
||||
|
||||
void invalidate_layer(Layer *layer, const BRegion ®ion);
|
||||
void redraw_layer(Layer *layer, const BRegion ®ion);
|
||||
|
||||
Desktop *fDesktop;
|
||||
BMessage *fDragMessage;
|
||||
WinBorder *fMouseTarget;
|
||||
|
||||
@@ -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);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
RootLayer *myRootLayer = fWinBorder->GetRootLayer();
|
||||
|
||||
switch(code)
|
||||
{
|
||||
//--------- BView Messages -----------------
|
||||
@@ -741,8 +743,7 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
|
||||
cl->AddChild(newLayer, this);
|
||||
|
||||
if (!(newLayer->IsHidden())){
|
||||
// cl is the parent of newLayer, so this call is OK.
|
||||
cl->FullInvalidate(BRegion(newLayer->fFull));
|
||||
myRootLayer->GoInvalidate(newLayer, newLayer->fFull);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -762,7 +763,8 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
|
||||
cl->RemoveSelf();
|
||||
cl->PruneTree();
|
||||
|
||||
parent->Invalidate(cl->Frame());
|
||||
if (parent)
|
||||
myRootLayer->GoInvalidate(parent, BRegion(cl->Frame()));
|
||||
|
||||
#ifdef DEBUG_SERVERWINDOW
|
||||
parent->PrintTree();
|
||||
@@ -1073,7 +1075,7 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
|
||||
|
||||
cl->fLayerData->viewcolor.SetColor(c);
|
||||
|
||||
cl->Invalidate(cl->fVisible);
|
||||
myRootLayer->GoRedraw(cl, cl->fVisible);
|
||||
|
||||
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.
|
||||
if (redraw)
|
||||
cl->Invalidate(reg);
|
||||
myRootLayer->GoRedraw(cl, reg);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1321,12 +1323,7 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
|
||||
|
||||
cl->RebuildFullRegion();
|
||||
if (!(cl->IsHidden()))
|
||||
{
|
||||
if (cl->fParent)
|
||||
cl->fParent->FullInvalidate(BRegion(cl->fFull));
|
||||
else
|
||||
cl->FullInvalidate(BRegion(cl->fFull));
|
||||
}
|
||||
myRootLayer->GoInvalidate(cl, cl->fFull);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1338,8 +1335,8 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
|
||||
BRect invalRect;
|
||||
|
||||
link.Read<BRect>(&invalRect);
|
||||
|
||||
cl->Invalidate(invalRect);
|
||||
|
||||
myRootLayer->GoRedraw(cl, BRegion(invalRect));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1360,7 +1357,7 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
|
||||
invalReg.Include(rect);
|
||||
}
|
||||
|
||||
cl->Invalidate(invalReg);
|
||||
myRootLayer->GoRedraw(cl, invalReg);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -2191,17 +2188,32 @@ int32 ServerWindow::MonitorWin(void *data)
|
||||
{
|
||||
// this means the client has been killed
|
||||
STRACE(("ServerWindow %s received 'AS_CLIENT_DEAD/AS_DELETE_WINDOW' message code\n",win->Title()));
|
||||
RootLayer *myRootLayer = win->fWinBorder->GetRootLayer();
|
||||
|
||||
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.
|
||||
delete win;
|
||||
myRootLayer->Unlock();
|
||||
|
||||
exit_thread(0);
|
||||
break;
|
||||
}
|
||||
case B_QUIT_REQUESTED:
|
||||
{
|
||||
STRACE(("ServerWindow %s received Quit request\n",win->Title()));
|
||||
quitting = true;
|
||||
delete win;
|
||||
win->Quit();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user