diff --git a/src/servers/app/server/Layer.cpp b/src/servers/app/server/Layer.cpp index f7e3d1acf3..af5c878580 100644 --- a/src/servers/app/server/Layer.cpp +++ b/src/servers/app/server/Layer.cpp @@ -64,10 +64,11 @@ Layer::Layer(BRect frame, const char *name, int32 token, uint32 resize, fFlags = flags; fAdFlags = 0; + fClassID = AS_LAYER_CLASS; fResizeMode = resize; fHidden = false; - fIsUpdating = false; + fInUpdate = false; fIsTopLayer = false; fLevel = 0; @@ -439,24 +440,61 @@ void Layer::RequestDraw(const BRegion ®, Layer *startFrom) { STRACE(("Layer(%s)::RequestDraw()\n", GetName())); + // do not redraw any child until you must int redraw = false; - if (startFrom == NULL) redraw = true; if (fVisible.CountRects() > 0) { - fUpdateReg = fVisible; - if (fFlags & B_FULL_UPDATE_ON_RESIZE){ } - else { fUpdateReg.IntersectWith(®); } - - if (fUpdateReg.CountRects() > 0){ - fDriver->ConstrainClippingRegion(&fUpdateReg); - Draw(fUpdateReg.Frame()); - fDriver->ConstrainClippingRegion(NULL); + // client side drawing. Send only one UPDATE message! + if (IsClientLayer()) + { + if (IsTopLayer()) + { + // calculate the minimum region/rectangle to be updated with + // a single message to the client. + fUpdateReg = fFullVisible; + if (fFlags & B_FULL_UPDATE_ON_RESIZE){ } + else { fUpdateReg.IntersectWith(®); } - // TODO: WARNING: For the Update code is MUST NOT be emptied - fUpdateReg.MakeEmpty(); + if (fUpdateReg.CountRects() > 0) + { + SendUpdateMsg(); + } + + // we're not that different than other. We too have an + // update region to which our drawing is restrincted. + } + + // calculate the update region, then... + fUpdateReg = fVisible; + if (fFlags & B_FULL_UPDATE_ON_RESIZE){ } + else { fUpdateReg.IntersectWith(®); } + + if (fUpdateReg.CountRects() > 0) + { + // clear background with viewColor. + fDriver->ConstrainClippingRegion(&fUpdateReg); + fDriver->FillRect(fUpdateReg.Frame(), fLayerData->viewcolor); + fDriver->ConstrainClippingRegion(NULL); + } + } + // server drawings are immediate. + // No IPC is needed so this is done in place. + else + { + fUpdateReg = fVisible; + if (fFlags & B_FULL_UPDATE_ON_RESIZE){ } + else { fUpdateReg.IntersectWith(®); } + + if (fUpdateReg.CountRects() > 0) + { + fDriver->ConstrainClippingRegion(&fUpdateReg); + Draw(fUpdateReg.Frame()); + fDriver->ConstrainClippingRegion(NULL); + fUpdateReg.MakeEmpty(); + } } } @@ -1071,6 +1109,20 @@ void Layer::ResizeBy(float x, float y) STRACE(("Layer(%s)::ResizeBy() END\n", GetName())); } +bool Layer::IsClientLayer() const { + switch (fClassID){ + case AS_WINBORDER_CLASS: + case AS_ROOTLAYER_CLASS: + return false; + default: + return true; + } +} + +bool Layer::IsServerLayer() const { + return !IsClientLayer(); +} + void Layer::PrintToStream(void) { printf("\n----------- Layer %s -----------\n",fName->String()); @@ -1226,6 +1278,19 @@ void Layer::SendViewMovedMsg() } } +void Layer::SendUpdateMsg() +{ + if( fServerWin ) + { + BMessage msg; + msg.what = _UPDATE_; + msg.AddRect( "_rect", ConvertFromTop(fUpdateReg.Frame()) ); + msg.AddRect( "debug_rect", fUpdateReg.Frame() ); + + fServerWin->SendMessageToClient( &msg ); + } +} + Layer *Layer::VirtualTopChild() const { fCurrent = fTopChild; diff --git a/src/servers/app/server/Layer.h b/src/servers/app/server/Layer.h index 46dd21e3d4..7bb8ba6991 100644 --- a/src/servers/app/server/Layer.h +++ b/src/servers/app/server/Layer.h @@ -24,6 +24,14 @@ enum B_LAYER_CHILDREN_DEPENDANT = 0x1000U, }; +// easy way to determine class type +enum +{ + AS_LAYER_CLASS = 1, + AS_WINBORDER_CLASS = 2, + AS_ROOTLAYER_CLASS = 3, +}; + class ServerWindow; class RootLayer; class DisplayDriver; @@ -70,9 +78,6 @@ public: virtual void Draw(const BRect &r); - void SendViewMovedMsg(void); - void SendViewResizedMsg(void); - virtual void Show(bool invalidate=true); virtual void Hide(bool invalidate=true); bool IsHidden(void) const; @@ -94,6 +99,8 @@ public: DisplayDriver *GetDisplayDriver(void) const { return fDriver; } ServerWindow *Window(void) const { return fServerWin; } + bool IsClientLayer() const; + bool IsServerLayer() const; void PruneTree(void); @@ -105,7 +112,11 @@ public: void SetRootLayer(RootLayer *rl){ fRootLayer = rl; } void SetServerWindow(ServerWindow *win); void SetAsTopLayer(bool option) { fIsTopLayer = option; } - + bool IsTopLayer() const { return fIsTopLayer; } + + void UpdateStart() { fInUpdate = true; } + void UpdateEnd() { fInUpdate = false; } + bool InUpdate() const { return fInUpdate; } protected: friend class RootLayer; @@ -140,9 +151,10 @@ protected: uint32 fFlags; uint32 fResizeMode; bool fHidden; - bool fIsUpdating; + bool fInUpdate; bool fIsTopLayer; uint16 fAdFlags; + int8 fClassID; DisplayDriver *fDriver; LayerData *fLayerData; @@ -154,6 +166,10 @@ private: void RequestDraw(const BRegion ®, Layer *startFrom); ServerWindow *SearchForServerWindow(void) const; + void Layer::SendUpdateMsg(); + void SendViewMovedMsg(void); + void SendViewResizedMsg(void); + }; #endif diff --git a/src/servers/app/server/RootLayer.cpp b/src/servers/app/server/RootLayer.cpp index 56938e8587..5f04f2d609 100644 --- a/src/servers/app/server/RootLayer.cpp +++ b/src/servers/app/server/RootLayer.cpp @@ -77,8 +77,9 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, fScreenXResolution = 0; fScreenYResolution = 0; fColorSpace = B_RGB32; - - fViewToken = 0; // is this used for WinBorders? + + // easy way to identify this class. + fClassID = AS_ROOTLAYER_CLASS; fHidden = false; } diff --git a/src/servers/app/server/WinBorder.cpp b/src/servers/app/server/WinBorder.cpp index 963da4d157..9a808e7e83 100644 --- a/src/servers/app/server/WinBorder.cpp +++ b/src/servers/app/server/WinBorder.cpp @@ -86,6 +86,7 @@ WinBorder::WinBorder(const BRect &r, const char *name, const int32 look, const i // unlike BViews, windows start off as hidden fHidden = true; fServerWin = win; + fClassID = AS_WINBORDER_CLASS; fMouseButtons = 0; fKeyModifiers = 0;