figured out and solved several problems:

* views are now correctly clipped when they are
  (partly) hidden under their parent(s)
* removed fIsTopView, the top view in a window
  simply has no parent
* introduced WindowLayer::CopyContents() which
  blits part of the contents to another location,
  while moving that part in the dirty regions. Since
  this is currently used from the Desktop thread,
  messing with the update session dirty regions
  requires now to lock the clipping
* that feature is now used for blitting a view to its
  new location in ViewLayer::MoveBy(), which
  works for right and/or bottom aligned views just fine
* I left the global dirty region in Desktop for now,
  moving it into each WindowLayer gave quite a slowdown
  and caused all kinds of other problems.
* a view is now cleared to the background color right
  before the first drawing command from the client
  is executed for that view, this reduces flickering
  a lot because the content is drawn much more shortly
  after the background is cleared.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15201 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-11-28 19:28:38 +00:00
parent 94dc3ed625
commit 748533bbf9
6 changed files with 273 additions and 154 deletions
@@ -159,13 +159,13 @@ Desktop::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
if (dx != 0 || dy != 0) { if (dx != 0 || dy != 0) {
if (fClickedWindow) { if (fClickedWindow) {
bigtime_t now = system_time(); //bigtime_t now = system_time();
if (fResizing) { if (fResizing) {
ResizeWindowBy(fClickedWindow, dx, dy); ResizeWindowBy(fClickedWindow, dx, dy);
printf("resizing: %lld\n", system_time() - now); //printf("resizing: %lld\n", system_time() - now);
} else { } else {
MoveWindowBy(fClickedWindow, dx, dy); MoveWindowBy(fClickedWindow, dx, dy);
printf("moving: %lld\n", system_time() - now); //printf("moving: %lld\n", system_time() - now);
} }
} }
} }
@@ -358,6 +358,9 @@ Desktop::BottomWindow() const
void void
Desktop::MoveWindowBy(WindowLayer* window, int32 x, int32 y) Desktop::MoveWindowBy(WindowLayer* window, int32 x, int32 y)
{ {
if (!Lock())
return;
if (LockClipping()) { if (LockClipping()) {
// the dirty region starts with the visible area of the window being moved // the dirty region starts with the visible area of the window being moved
BRegion newDirtyRegion(window->VisibleRegion()); BRegion newDirtyRegion(window->VisibleRegion());
@@ -403,12 +406,17 @@ Desktop::MoveWindowBy(WindowLayer* window, int32 x, int32 y)
UnlockClipping(); UnlockClipping();
} }
Unlock();
} }
// ResizeWindowBy // ResizeWindowBy
void void
Desktop::ResizeWindowBy(WindowLayer* window, int32 x, int32 y) Desktop::ResizeWindowBy(WindowLayer* window, int32 x, int32 y)
{ {
if (!Lock())
return;
if (LockClipping()) { if (LockClipping()) {
BRegion newDirtyRegion; BRegion newDirtyRegion;
BRegion previouslyOccupiedRegion(window->VisibleRegion()); BRegion previouslyOccupiedRegion(window->VisibleRegion());
@@ -428,6 +436,8 @@ Desktop::ResizeWindowBy(WindowLayer* window, int32 x, int32 y)
UnlockClipping(); UnlockClipping();
} }
Unlock();
} }
// BringToFront // BringToFront
+143 -121
View File
@@ -31,7 +31,6 @@ ViewLayer::ViewLayer(BRect frame, const char* name,
fWindow(NULL), fWindow(NULL),
fParent(NULL), fParent(NULL),
fIsTopLayer(false),
fFirstChild(NULL), fFirstChild(NULL),
fPreviousSibling(NULL), fPreviousSibling(NULL),
@@ -72,12 +71,23 @@ ViewLayer::Bounds() const
return bounds; return bounds;
} }
// ConvertToVisibleInTopView
void
ViewLayer::ConvertToVisibleInTopView(BRect* bounds) const
{
*bounds = *bounds & Bounds();
// NOTE: this step is necessary even if we don't have a parent!
ConvertToParent(bounds);
if (fParent)
fParent->ConvertToVisibleInTopView(bounds);
}
// AttachedToWindow // AttachedToWindow
void void
ViewLayer::AttachedToWindow(WindowLayer* window, bool topLayer) ViewLayer::AttachedToWindow(WindowLayer* window)
{ {
fWindow = window; fWindow = window;
fIsTopLayer = topLayer;
for (ViewLayer* child = FirstChild(); child; child = NextChild()) for (ViewLayer* child = FirstChild(); child; child = NextChild())
child->AttachedToWindow(window); child->AttachedToWindow(window);
@@ -211,13 +221,13 @@ ViewLayer::LastChild() const
ViewLayer* ViewLayer*
ViewLayer::TopLayer() ViewLayer::TopLayer()
{ {
if (fIsTopLayer) // returns the top level view of the hirarchy,
return this; // it doesn't have to be the top level of a window
if (fParent) if (fParent)
return fParent->TopLayer(); return fParent->TopLayer();
else
return NULL; return this;
} }
// CountChildren // CountChildren
@@ -328,6 +338,36 @@ ViewLayer::ConvertToTop(BRegion* region) const
fParent->ConvertToTop(region); fParent->ConvertToTop(region);
} }
// ConvertFromTop
void
ViewLayer::ConvertFromTop(BPoint* point) const
{
ConvertFromParent(point);
if (fParent)
fParent->ConvertFromTop(point);
}
// ConvertFromTop
void
ViewLayer::ConvertFromTop(BRect* rect) const
{
ConvertFromParent(rect);
if (fParent)
fParent->ConvertFromTop(rect);
}
// ConvertFromTop
void
ViewLayer::ConvertFromTop(BRegion* region) const
{
ConvertFromParent(region);
if (fParent)
fParent->ConvertFromTop(region);
}
// SetName // SetName
void void
ViewLayer::SetName(const char* string) ViewLayer::SetName(const char* string)
@@ -335,72 +375,7 @@ ViewLayer::SetName(const char* string)
fName.SetTo(string); fName.SetTo(string);
} }
#if 0 #pragma mark -
// MoveBy
void
ViewLayer::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
{
if (x == 0 && y == 0)
return;
if (!fIsTopLayer && fWindow) {
// blit to new location (children as well)
BRect screenRect;
if (fParent) {
screenRect = fFrame & fParent->Bounds();
fParent->ConvertToTop(&screenRect);
} else {
screenRect = Bounds();
ConvertToTop(&screenRect);
}
BRegion effectiveClippingRegion;
fWindow->GetContentRegion(&effectiveClippingRegion);
effectiveClippingRegion.IntersectWith(&fWindow->VisibleRegion());
BRegion copyRegion(screenRect);
copyRegion.IntersectWith(&effectiveClippingRegion);
copyRegion.OffsetBy(x, y);
copyRegion.IntersectWith(&effectiveClippingRegion);
BRegion alreadyDirty(screenRect);
{
BRegion windowDirty(fWindow->DirtyRegion());
alreadyDirty.IntersectWith(&windowDirty);
}
fFrame.OffsetBy(x, y);
_MoveScreenClipping(x, y, true);
if (fParent) {
screenRect = fFrame & fParent->Bounds();
fParent->ConvertToTop(&screenRect);
} else {
screenRect = Bounds();
ConvertToTop(&screenRect);
}
BRegion dirtyRegion(screenRect);
dirtyRegion.Exclude(&copyRegion);
alreadyDirty.OffsetBy(x, y);
dirtyRegion.Include(&alreadyDirty);
fWindow->MarkDirty(&dirtyRegion);
copyRegion.OffsetBy(-x, -y);
if (fWindow->GetDrawingEngine()->Lock()) {
fWindow->GetDrawingEngine()->CopyRegion(&copyRegion, x, y);
fWindow->GetDrawingEngine()->Unlock();
}
} else {
fFrame.OffsetBy(x, y);
_MoveScreenClipping(x, y, true);
}
fFrame.OffsetBy(x, y);
}
#else // 0
// MoveBy // MoveBy
void void
@@ -410,28 +385,64 @@ ViewLayer::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
return; return;
fFrame.OffsetBy(x, y); fFrame.OffsetBy(x, y);
InvalidateScreenClipping(true);
// to move on screen, we must not be hidden and we must have a parent // to move on screen, we must not be hidden and we must have a parent
if (!IsHidden() && fParent && !fIsTopLayer && dirtyRegion) { if (!IsHidden() && fParent && dirtyRegion) {
// clip to parent #if 0
BRect oldScreenRect(Bounds()); // based on redraw on new location
oldScreenRect.OffsetByCopy(-x, -y); // the place were we are now visible
ConvertToParent(&oldScreenRect); BRect newVisibleBounds = Bounds();
// we can use the frame of the old
// local clipping to see which parts need invalidation
BRect oldVisibleBounds(Bounds());
oldVisibleBounds.OffsetBy(-x, -y);
ConvertToTop(&oldVisibleBounds);
BRect screenRect(Bounds()); ConvertToVisibleInTopView(&newVisibleBounds);
ConvertToParent(&screenRect);
// TODO: see AddChild dirtyRegion->Include(oldVisibleBounds);
// TODO: shouldn't we use regions? // newVisibleBounds already is in screen coords
BRect dirty = oldScreenRect | screenRect; dirtyRegion->Include(newVisibleBounds);
dirty = dirty & fParent->Bounds(); #else
fParent->ConvertToTop(&dirty); // blitting version, invalidates
// old contents
dirtyRegion->Include(dirty); BRect oldVisibleBounds(Bounds());
oldVisibleBounds.OffsetBy(-x, -y);
ConvertToTop(&oldVisibleBounds);
BRect newVisibleBounds(Bounds());
// NOTE: using ConvertToVisibleInTopView()
// instead of ConvertToTop()! see below
ConvertToVisibleInTopView(&newVisibleBounds);
newVisibleBounds.OffsetBy(-x, -y);
// clipping oldVisibleBounds to newVisibleBounds
// makes sure we don't copy parts hidden under
// parent views
BRegion copyRegion(oldVisibleBounds & newVisibleBounds);
fWindow->CopyContents(&copyRegion, x, y);
BRegion dirty(oldVisibleBounds);
newVisibleBounds.OffsetBy(x, y);
dirty.Exclude(newVisibleBounds);
dirtyRegion->Include(&dirty);
#endif
}
if (!fParent) {
// the top view's screen clipping does not change,
// because no parts are clipped away from parent
// views
_MoveScreenClipping(x, y, true);
} else {
// parts might have been revealed from underneath
// the parent, or might now be hidden underneath
// the parent, this is taken care of when building
// the screen clipping
InvalidateScreenClipping(true);
} }
} }
#endif // 0
// ResizeBy // ResizeBy
void void
@@ -472,19 +483,17 @@ ViewLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
ConvertToTop(&dirty); ConvertToTop(&dirty);
dirtyRegion->Include(&dirty); dirtyRegion->Include(&dirty);
} }
// layout the children
for (ViewLayer* child = FirstChild(); child; child = NextChild())
child->ParentResized(x, y, dirtyRegion);
// at this point, children are at their new locations,
// so we can rebuild the clipping
RebuildClipping(false);
} else {
// just layout the children
for (ViewLayer* child = FirstChild(); child; child = NextChild())
child->ParentResized(x, y, NULL);
} }
// layout the children
for (ViewLayer* child = FirstChild(); child; child = NextChild())
child->ParentResized(x, y, dirtyRegion);
// at this point, children are at their new locations,
// so we can rebuild the clipping
// TODO: when the implementation of Hide() and Show() is
// complete, see if this should be avoided
RebuildClipping(false);
} }
// ParentResized // ParentResized
@@ -542,6 +551,8 @@ ViewLayer::ScrollBy(int32 x, int32 y, BRegion* dirtyRegion)
InvalidateScreenClipping(true); InvalidateScreenClipping(true);
} }
#pragma mark -
// Draw // Draw
void void
ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping, ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
@@ -606,20 +617,17 @@ ViewLayer::ClientDraw(DrawingEngine* drawingEngine, BRegion* effectiveClipping)
} }
} }
#pragma mark -
// IsHidden // IsHidden
bool bool
ViewLayer::IsHidden() const ViewLayer::IsHidden() const
{ {
// if we're explicitely hidden... // if we're explicitely hidden, then we're hidden...
if (fHidden) if (fHidden)
return true; return true;
// if we don't have a window, or our window is hidden, // ...but if we're not hidden, we might still be hidden if our parent is
// then yes, we're hidden too
if (fWindow == NULL || (fWindow && fWindow->IsHidden()))
return true;
// if we're not hidden yet, we might still be hidden if our parent is
if (fParent) if (fParent)
return fParent->IsHidden(); return fParent->IsHidden();
@@ -631,18 +639,30 @@ ViewLayer::IsHidden() const
void void
ViewLayer::Hide() ViewLayer::Hide()
{ {
fHidden = true; if (!fHidden) {
fHidden = true;
// TODO: track regions if (fParent && !fParent->IsHidden()) {
// TODO: track regions
// RebuildClipping()
// ...
}
}
} }
// Show // Show
void void
ViewLayer::Show() ViewLayer::Show()
{ {
fHidden = false; if (fHidden) {
fHidden = false;
// TODO: track regions if (fParent && !fParent->IsHidden()) {
// TODO: track regions
// RebuildClipping()
// ...
}
}
} }
// PrintToStream // PrintToStream
@@ -655,9 +675,6 @@ ViewLayer::PrintToStream() const
void void
ViewLayer::RebuildClipping(bool deep) ViewLayer::RebuildClipping(bool deep)
{ {
// remember current local clipping in dirty region
BRegion oldLocalClipping(fLocalClipping);
// the clipping spans over the bounds area // the clipping spans over the bounds area
fLocalClipping.Set(Bounds()); fLocalClipping.Set(Bounds());
@@ -678,13 +695,18 @@ ViewLayer::ScreenClipping(BRegion* windowContentClipping, bool force) const
{ {
if (!fScreenClippingValid || force) { if (!fScreenClippingValid || force) {
fScreenClipping = fLocalClipping; fScreenClipping = fLocalClipping;
if (fParent) {
BRect parentWindow = fParent->Bounds();
ConvertFromParent(&parentWindow);
BRegion visibleInParent(parentWindow);
fScreenClipping.IntersectWith(&visibleInParent);
}
ConvertToTop(&fScreenClipping); ConvertToTop(&fScreenClipping);
// see if we parts of our bounds are hidden underneath
// the parent, the local clipping does not account for this
BRect clippedBounds = Bounds();
ConvertToVisibleInTopView(&clippedBounds);
if (clippedBounds.Width() < fScreenClipping.Frame().Width() ||
clippedBounds.Height() < fScreenClipping.Frame().Height()) {
BRegion temp(clippedBounds);
fScreenClipping.IntersectWith(&temp);
}
fScreenClipping.IntersectWith(windowContentClipping); fScreenClipping.IntersectWith(windowContentClipping);
fScreenClippingValid = true; fScreenClippingValid = true;
} }
@@ -23,12 +23,14 @@ class ViewLayer {
inline BRect Frame() const inline BRect Frame() const
{ return fFrame; } { return fFrame; }
BRect Bounds() const; BRect Bounds() const;
// converts the given frame up the view hirarchy and
// clips to each views bounds
void ConvertToVisibleInTopView(BRect* bounds) const;
inline rgb_color ViewColor() const inline rgb_color ViewColor() const
{ return fViewColor; } { return fViewColor; }
void AttachedToWindow(WindowLayer* window, void AttachedToWindow(WindowLayer* window);
bool topLayer = false);
void DetachedFromWindow(); void DetachedFromWindow();
// tree stuff // tree stuff
@@ -61,6 +63,10 @@ class ViewLayer {
void ConvertToTop(BRect* rect) const; void ConvertToTop(BRect* rect) const;
void ConvertToTop(BRegion* region) const; void ConvertToTop(BRegion* region) const;
void ConvertFromTop(BPoint* point) const;
void ConvertFromTop(BRect* rect) const;
void ConvertFromTop(BRegion* region) const;
// settings // settings
void SetName(const char* string); void SetName(const char* string);
inline const char* Name() const inline const char* Name() const
@@ -120,7 +126,6 @@ private:
WindowLayer* fWindow; WindowLayer* fWindow;
ViewLayer* fParent; ViewLayer* fParent;
bool fIsTopLayer;
ViewLayer* fFirstChild; ViewLayer* fFirstChild;
ViewLayer* fPreviousSibling; ViewLayer* fPreviousSibling;
@@ -56,7 +56,7 @@ WindowLayer::WindowLayer(BRect frame, const char* name,
// fFrame as if it had // fFrame as if it had
fTopLayer = new(nothrow) ViewLayer(fFrame, "top view", B_FOLLOW_ALL, 0, fTopLayer = new(nothrow) ViewLayer(fFrame, "top view", B_FOLLOW_ALL, 0,
(rgb_color){ 255, 255, 255, 255 }); (rgb_color){ 255, 255, 255, 255 });
fTopLayer->AttachedToWindow(this, true); fTopLayer->AttachedToWindow(this);
fClient->Run(); fClient->Run();
} }
@@ -82,7 +82,7 @@ WindowLayer::MessageReceived(BMessage* message)
} }
} }
_DrawBorder(); _DrawBorder();
_DrawContents(fTopLayer); _TriggerContentRedraw();
fDesktop->ReadUnlockClipping(); fDesktop->ReadUnlockClipping();
} else { } else {
@@ -307,6 +307,7 @@ WindowLayer::Show()
void void
WindowLayer::MarkDirty(BRegion* regionOnScreen) WindowLayer::MarkDirty(BRegion* regionOnScreen)
{ {
// for triggering MSG_REDRAW
if (fDesktop) if (fDesktop)
fDesktop->MarkDirty(regionOnScreen); fDesktop->MarkDirty(regionOnScreen);
} }
@@ -315,6 +316,7 @@ WindowLayer::MarkDirty(BRegion* regionOnScreen)
void void
WindowLayer::MarkContentDirty(BRegion* regionOnScreen) WindowLayer::MarkContentDirty(BRegion* regionOnScreen)
{ {
// for triggering MSG_REDRAW
if (fDesktop && fDesktop->LockClipping()) { if (fDesktop && fDesktop->LockClipping()) {
regionOnScreen->IntersectWith(&fVisibleContentRegion); regionOnScreen->IntersectWith(&fVisibleContentRegion);
@@ -323,29 +325,65 @@ WindowLayer::MarkContentDirty(BRegion* regionOnScreen)
fDesktop->UnlockClipping(); fDesktop->UnlockClipping();
} }
} }
/*
// DirtyRegion
BRegion
WindowLayer::DirtyRegion()
{
BRegion dirty;
if (fDesktop->ReadLockClipping()) {
dirty = *fDesktop->DirtyRegion();
fDesktop->ReadUnlockClipping();
}
return dirty;
}
*/
# pragma mark - # pragma mark -
// _DrawContents // CopyContents
void void
WindowLayer::_DrawContents(ViewLayer* layer) WindowLayer::CopyContents(BRegion* region, int32 xOffset, int32 yOffset)
{
// this function takes care of invalidating parts that could not be copied
if (fDesktop->LockClipping()) {
BRegion newDirty(*region);
region->IntersectWith(&fVisibleContentRegion);
region->OffsetBy(xOffset, yOffset);
region->IntersectWith(&fVisibleContentRegion);
region->OffsetBy(-xOffset, -yOffset);
newDirty.Exclude(region);
_ShiftPartOfRegion(fDesktop->DirtyRegion(), region, xOffset, yOffset);
if (fDrawingEngine->Lock()) {
fDrawingEngine->CopyRegion(region, xOffset, yOffset);
fDrawingEngine->Unlock();
}
if (fCurrentUpdateSession)
_ShiftPartOfRegion(&fCurrentUpdateSession->DirtyRegion(), region, xOffset, yOffset);
if (fPendingUpdateSession)
_ShiftPartOfRegion(&fPendingUpdateSession->DirtyRegion(), region, xOffset, yOffset);
newDirty.OffsetBy(xOffset, yOffset);
newDirty.IntersectWith(&fVisibleContentRegion);
fDesktop->MarkDirty(&newDirty);
fDesktop->UnlockClipping();
}
}
# pragma mark -
// _ShiftPartOfRegion
void
WindowLayer::_ShiftPartOfRegion(BRegion* region, BRegion* regionToShift,
int32 xOffset, int32 yOffset)
{
BRegion common(*region);
common.IntersectWith(regionToShift);
region->Exclude(&common);
common.OffsetBy(xOffset, yOffset);
region->Include(&common);
}
// _TriggerContentRedraw
void
WindowLayer::_TriggerContentRedraw()
{ {
//printf("%s - DrawContents()\n", Name()); //printf("%s - DrawContents()\n", Name());
if (!layer)
layer = fTopLayer;
if (fDesktop->ReadLockClipping()) { if (fDesktop->ReadLockClipping()) {
BRegion dirtyContentRegion(fVisibleContentRegion); BRegion dirtyContentRegion(fVisibleContentRegion);
@@ -367,8 +405,8 @@ if (fDrawingEngine->Lock()) {
fDesktop->MarkClean(&dirtyContentRegion); fDesktop->MarkClean(&dirtyContentRegion);
layer->Draw(fDrawingEngine, &dirtyContentRegion, fTopLayer->Draw(fDrawingEngine, &dirtyContentRegion,
&fVisibleContentRegion, true); &fVisibleContentRegion, false);
} }
fDesktop->ReadUnlockClipping(); fDesktop->ReadUnlockClipping();
@@ -398,8 +436,14 @@ WindowLayer::_DrawClient(int32 token)
BRegion effectiveClipping(fEffectiveDrawingRegion); BRegion effectiveClipping(fEffectiveDrawingRegion);
effectiveClipping.IntersectWith(&layer->ScreenClipping(&fVisibleContentRegion)); effectiveClipping.IntersectWith(&layer->ScreenClipping(&fVisibleContentRegion));
if (effectiveClipping.CountRects() > 0) { if (effectiveClipping.CountRects() > 0) {
// clear the back ground
// TODO: only if this is the first drawing command for
// this layer of course!
layer->Draw(fDrawingEngine, &effectiveClipping,
&fVisibleContentRegion, false);
layer->ClientDraw(fDrawingEngine, &effectiveClipping); layer->ClientDraw(fDrawingEngine, &effectiveClipping);
} }
@@ -456,6 +500,8 @@ WindowLayer::_DrawBorder()
void void
WindowLayer::_MarkContentDirty(BRegion* contentDirtyRegion) WindowLayer::_MarkContentDirty(BRegion* contentDirtyRegion)
{ {
if (fDesktop->ReadLockClipping()) {
if (contentDirtyRegion->CountRects() <= 0) if (contentDirtyRegion->CountRects() <= 0)
return; return;
@@ -480,12 +526,17 @@ WindowLayer::_MarkContentDirty(BRegion* contentDirtyRegion)
fClient->PostMessage(MSG_UPDATE); fClient->PostMessage(MSG_UPDATE);
fUpdateRequested = true; fUpdateRequested = true;
} }
fDesktop->ReadUnlockClipping();
}
} }
// _BeginUpdate // _BeginUpdate
void void
WindowLayer::_BeginUpdate() WindowLayer::_BeginUpdate()
{ {
if (fDesktop->ReadLockClipping()) {
if (fUpdateRequested && !fCurrentUpdateSession) { if (fUpdateRequested && !fCurrentUpdateSession) {
fCurrentUpdateSession = fPendingUpdateSession; fCurrentUpdateSession = fPendingUpdateSession;
fPendingUpdateSession = NULL; fPendingUpdateSession = NULL;
@@ -498,12 +549,17 @@ WindowLayer::_BeginUpdate()
} }
fEffectiveDrawingRegionValid = false; fEffectiveDrawingRegionValid = false;
} }
fDesktop->ReadUnlockClipping();
}
} }
// _EndUpdate // _EndUpdate
void void
WindowLayer::_EndUpdate() WindowLayer::_EndUpdate()
{ {
if (fDesktop->ReadLockClipping()) {
if (fInUpdate) { if (fInUpdate) {
delete fCurrentUpdateSession; delete fCurrentUpdateSession;
fCurrentUpdateSession = NULL; fCurrentUpdateSession = NULL;
@@ -518,6 +574,9 @@ WindowLayer::_EndUpdate()
} else { } else {
fUpdateRequested = false; fUpdateRequested = false;
} }
fDesktop->ReadUnlockClipping();
}
} }
#pragma mark - #pragma mark -
@@ -74,13 +74,19 @@ class WindowLayer : public BLooper {
DrawingEngine* GetDrawingEngine() const DrawingEngine* GetDrawingEngine() const
{ return fDrawingEngine; } { return fDrawingEngine; }
// BRegion DirtyRegion(); void CopyContents(BRegion* region,
int32 xOffset, int32 yOffset);
private: private:
void _DrawContents(ViewLayer* layer = NULL); void _ShiftPartOfRegion(BRegion* region, BRegion* regionToShift,
int32 xOffset, int32 yOffset);
// different types of drawing
void _TriggerContentRedraw();
void _DrawClient(int32 token); void _DrawClient(int32 token);
void _DrawBorder(); void _DrawBorder();
// handling update sessions
void _MarkContentDirty(BRegion* contentDirtyRegion); void _MarkContentDirty(BRegion* contentDirtyRegion);
void _BeginUpdate(); void _BeginUpdate();
void _EndUpdate(); void _EndUpdate();
@@ -110,11 +116,26 @@ class WindowLayer : public BLooper {
DrawingEngine* fDrawingEngine; DrawingEngine* fDrawingEngine;
Desktop* fDesktop; Desktop* fDesktop;
// for mapping drawing requests from the client
// to the local view pointers
BList fTokenViewMap; BList fTokenViewMap;
// the client looper, which will do asynchronous
// drawing (the window will clear the content
// and the client is supposed to draw onto
// the cleared regions)
ClientLooper* fClient; ClientLooper* fClient;
// The synchronization, which client drawing commands
// belong to the redraw of which region is handled
// through an UpdateSession. When the client has
// been informed that it should redraw stuff, then
// this is the current update session. All new
// redraw requests from the root layer will go
// into the pending update session.
UpdateSession* fCurrentUpdateSession; UpdateSession* fCurrentUpdateSession;
UpdateSession* fPendingUpdateSession; UpdateSession* fPendingUpdateSession;
// these two flags are supposed to ensure a sane
// and consistent update session
bool fUpdateRequested; bool fUpdateRequested;
bool fInUpdate; bool fInUpdate;
}; };
+4 -2
View File
@@ -144,13 +144,15 @@ Window::AddWindow(BRect frame, const char* name)
f.OffsetBy(f.Width() + 6, 0); f.OffsetBy(f.Width() + 6, 0);
layer = new ViewLayer(f, "View", B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM, // layer = new ViewLayer(f, "View", B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM,
layer = new ViewLayer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 }); B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddChild(layer); layer1->AddChild(layer);
f.OffsetBy(f.Width() + 6, 0); f.OffsetBy(f.Width() + 6, 0);
layer = new ViewLayer(f, "View", B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM, // layer = new ViewLayer(f, "View", B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM,
layer = new ViewLayer(f, "View", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 }); B_FULL_UPDATE_ON_RESIZE, (rgb_color){ 120, 120, 120, 255 });
layer1->AddChild(layer); layer1->AddChild(layer);
} }