still buggy but less buggy than before, more caching and less overhead
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15160 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -38,7 +38,7 @@ ClientLooper::MessageReceived(BMessage* message)
|
|||||||
|
|
||||||
for (int32 i = 0; i < fViewCount; i++) {
|
for (int32 i = 0; i < fViewCount; i++) {
|
||||||
// the client is slow
|
// the client is slow
|
||||||
snooze(1000L);
|
// snooze(20000L);
|
||||||
// send the command to redraw a view
|
// send the command to redraw a view
|
||||||
BMessage command(MSG_DRAWING_COMMAND);
|
BMessage command(MSG_DRAWING_COMMAND);
|
||||||
command.AddInt32("token", i);
|
command.AddInt32("token", i);
|
||||||
|
|||||||
@@ -116,7 +116,19 @@ ViewLayer::AddChild(ViewLayer* layer)
|
|||||||
|
|
||||||
if (fWindow) {
|
if (fWindow) {
|
||||||
layer->AttachedToWindow(fWindow);
|
layer->AttachedToWindow(fWindow);
|
||||||
fWindow->MarkDirty(&layer->ScreenClipping());
|
|
||||||
|
// TODO: not correct... need something like
|
||||||
|
// ViewLayer::ClipToParent(BRect frame)
|
||||||
|
// {
|
||||||
|
// frame = frame & Bounds();
|
||||||
|
// ConvertToParent(&frame);
|
||||||
|
// fParent->ClipToParent(&frame);
|
||||||
|
// }
|
||||||
|
BRect dirty(layer->Frame());
|
||||||
|
dirty = dirty & Bounds();
|
||||||
|
ConvertToTop(&dirty);
|
||||||
|
BRegion dirtyRegion(dirty);
|
||||||
|
fWindow->MarkContentDirty(&dirtyRegion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +167,7 @@ ViewLayer::RemoveChild(ViewLayer* layer)
|
|||||||
}
|
}
|
||||||
if (fWindow) {
|
if (fWindow) {
|
||||||
layer->DetachedFromWindow();
|
layer->DetachedFromWindow();
|
||||||
|
// TODO: handle exposed area
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -290,16 +303,14 @@ ViewLayer::SetName(const char* string)
|
|||||||
fName.SetTo(string);
|
fName.SetTo(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HW_MOVE 0
|
#if 0
|
||||||
|
|
||||||
// MoveBy
|
// MoveBy
|
||||||
void
|
void
|
||||||
ViewLayer::MoveBy(int32 x, int32 y)
|
ViewLayer::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
|
||||||
{
|
{
|
||||||
if (x == 0 && y == 0)
|
if (x == 0 && y == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if HW_MOVE
|
|
||||||
if (!fIsTopLayer && fWindow) {
|
if (!fIsTopLayer && fWindow) {
|
||||||
// blit to new location (children as well)
|
// blit to new location (children as well)
|
||||||
BRect screenRect;
|
BRect screenRect;
|
||||||
@@ -355,21 +366,46 @@ if (fParent) {
|
|||||||
fFrame.OffsetBy(x, y);
|
fFrame.OffsetBy(x, y);
|
||||||
_MoveScreenClipping(x, y, true);
|
_MoveScreenClipping(x, y, true);
|
||||||
}
|
}
|
||||||
#else // HW_MOVE
|
|
||||||
fFrame.OffsetBy(x, y);
|
fFrame.OffsetBy(x, y);
|
||||||
|
|
||||||
_MoveScreenClipping(x, y, true);
|
|
||||||
|
|
||||||
if (!fIsTopLayer && fWindow) {
|
|
||||||
BRect screenRect(Bounds());
|
|
||||||
ConvertToTop(&screenRect);
|
|
||||||
screenRect = screenRect | screenRect.OffsetByCopy(-x, -y);
|
|
||||||
BRegion dirty(screenRect);
|
|
||||||
|
|
||||||
fWindow->MarkDirty(&dirty);
|
|
||||||
}
|
|
||||||
#endif // !HW_MOVE
|
|
||||||
}
|
}
|
||||||
|
#else // 0
|
||||||
|
|
||||||
|
// MoveBy
|
||||||
|
void
|
||||||
|
ViewLayer::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
|
||||||
|
{
|
||||||
|
if (x == 0 && y == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fFrame.OffsetBy(x, y);
|
||||||
|
InvalidateScreenClipping(true);
|
||||||
|
|
||||||
|
if (!fIsTopLayer && dirtyRegion) {
|
||||||
|
if (fParent) {
|
||||||
|
// clip to parent
|
||||||
|
BRect oldScreenRect(Bounds());
|
||||||
|
oldScreenRect.OffsetByCopy(-x, -y);
|
||||||
|
ConvertToParent(&oldScreenRect);
|
||||||
|
|
||||||
|
BRect screenRect(Bounds());
|
||||||
|
ConvertToParent(&screenRect);
|
||||||
|
|
||||||
|
// TODO: see AddLayer
|
||||||
|
BRect dirty = oldScreenRect | screenRect;
|
||||||
|
dirty = dirty & fParent->Bounds();
|
||||||
|
fParent->ConvertToTop(&dirty);
|
||||||
|
|
||||||
|
dirtyRegion->Include(dirty);
|
||||||
|
} else {
|
||||||
|
BRect screenRect(Bounds());
|
||||||
|
screenRect = screenRect | screenRect.OffsetByCopy(-x, -y);
|
||||||
|
ConvertToTop(&screenRect);
|
||||||
|
|
||||||
|
dirtyRegion->Include(screenRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
// ResizeBy
|
// ResizeBy
|
||||||
void
|
void
|
||||||
@@ -391,7 +427,7 @@ ViewLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
|
|||||||
dirty.Exclude(oldBounds & Bounds());
|
dirty.Exclude(oldBounds & Bounds());
|
||||||
}
|
}
|
||||||
|
|
||||||
_InvalidateScreenClipping(true);
|
InvalidateScreenClipping(true);
|
||||||
|
|
||||||
if (dirty.CountRects() > 0) {
|
if (dirty.CountRects() > 0) {
|
||||||
// exclude children, they are expected to
|
// exclude children, they are expected to
|
||||||
@@ -418,14 +454,14 @@ ViewLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
|
|||||||
|
|
||||||
// ScrollBy
|
// ScrollBy
|
||||||
void
|
void
|
||||||
ViewLayer::ScrollBy(int32 x, int32 y)
|
ViewLayer::ScrollBy(int32 x, int32 y, BRegion* dirtyRegion)
|
||||||
{
|
{
|
||||||
fScrollingOffset.x += x;
|
fScrollingOffset.x += x;
|
||||||
fScrollingOffset.y += y;
|
fScrollingOffset.y += y;
|
||||||
// TODO: CopyRegion...
|
// TODO: CopyRegion...
|
||||||
// TODO: ...
|
// TODO: ...
|
||||||
|
|
||||||
_InvalidateScreenClipping(true);
|
InvalidateScreenClipping(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParentResized
|
// ParentResized
|
||||||
@@ -463,7 +499,7 @@ ViewLayer::ParentResized(int32 x, int32 y, BRegion* dirtyRegion)
|
|||||||
// MoveBy will change fFrame, so cache it
|
// MoveBy will change fFrame, so cache it
|
||||||
BRect oldFrame = fFrame;
|
BRect oldFrame = fFrame;
|
||||||
MoveBy(newFrame.left - oldFrame.left,
|
MoveBy(newFrame.left - oldFrame.left,
|
||||||
newFrame.top - oldFrame.top);
|
newFrame.top - oldFrame.top, dirtyRegion);
|
||||||
|
|
||||||
ResizeBy(newFrame.Width() - oldFrame.Width(),
|
ResizeBy(newFrame.Width() - oldFrame.Width(),
|
||||||
newFrame.Height() - oldFrame.Height(), dirtyRegion);
|
newFrame.Height() - oldFrame.Height(), dirtyRegion);
|
||||||
@@ -472,10 +508,11 @@ ViewLayer::ParentResized(int32 x, int32 y, BRegion* dirtyRegion)
|
|||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
void
|
void
|
||||||
ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping, bool deep)
|
ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
|
||||||
|
BRegion* windowContentClipping,bool deep)
|
||||||
{
|
{
|
||||||
// we can only draw within our own area
|
// we can only draw within our own area
|
||||||
BRegion redraw(ScreenClipping());
|
BRegion redraw(ScreenClipping(windowContentClipping));
|
||||||
// add the current clipping
|
// add the current clipping
|
||||||
redraw.IntersectWith(effectiveClipping);
|
redraw.IntersectWith(effectiveClipping);
|
||||||
|
|
||||||
@@ -494,10 +531,11 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping, bool d
|
|||||||
if (deep) {
|
if (deep) {
|
||||||
// before passing the clipping on to children, exclude our
|
// before passing the clipping on to children, exclude our
|
||||||
// own region from the available clipping
|
// own region from the available clipping
|
||||||
effectiveClipping->Exclude(&ScreenClipping());
|
effectiveClipping->Exclude(&ScreenClipping(windowContentClipping));
|
||||||
|
|
||||||
for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
|
for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
|
||||||
child->Draw(drawingEngine, effectiveClipping, deep);
|
child->Draw(drawingEngine, effectiveClipping,
|
||||||
|
windowContentClipping, deep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -587,25 +625,26 @@ ViewLayer::RebuildClipping(bool deep)
|
|||||||
|
|
||||||
// ScreenClipping
|
// ScreenClipping
|
||||||
BRegion&
|
BRegion&
|
||||||
ViewLayer::ScreenClipping() const
|
ViewLayer::ScreenClipping(BRegion* windowContentClipping, bool force) const
|
||||||
{
|
{
|
||||||
if (!fScreenClippingValid) {
|
if (!fScreenClippingValid || force) {
|
||||||
fScreenClipping = fLocalClipping;
|
fScreenClipping = fLocalClipping;
|
||||||
ConvertToTop(&fScreenClipping);
|
ConvertToTop(&fScreenClipping);
|
||||||
|
fScreenClipping.IntersectWith(windowContentClipping);
|
||||||
fScreenClippingValid = true;
|
fScreenClippingValid = true;
|
||||||
}
|
}
|
||||||
return fScreenClipping;
|
return fScreenClipping;
|
||||||
}
|
}
|
||||||
|
|
||||||
// _InvalidateScreenClipping
|
// InvalidateScreenClipping
|
||||||
void
|
void
|
||||||
ViewLayer::_InvalidateScreenClipping(bool deep)
|
ViewLayer::InvalidateScreenClipping(bool deep)
|
||||||
{
|
{
|
||||||
fScreenClippingValid = false;
|
fScreenClippingValid = false;
|
||||||
if (deep) {
|
if (deep) {
|
||||||
// invalidate the childrens screen clipping as well
|
// invalidate the childrens screen clipping as well
|
||||||
for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
|
for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
|
||||||
child->_InvalidateScreenClipping(deep);
|
child->InvalidateScreenClipping(deep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -618,7 +657,7 @@ ViewLayer::_MoveScreenClipping(int32 x, int32 y, bool deep)
|
|||||||
fScreenClipping.OffsetBy(x, y);
|
fScreenClipping.OffsetBy(x, y);
|
||||||
|
|
||||||
if (deep) {
|
if (deep) {
|
||||||
// invalidate the childrens screen clipping as well
|
// move the childrens screen clipping as well
|
||||||
for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
|
for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
|
||||||
child->_MoveScreenClipping(x, y, deep);
|
child->_MoveScreenClipping(x, y, deep);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,21 +62,27 @@ class ViewLayer {
|
|||||||
inline const char* Name() const
|
inline const char* Name() const
|
||||||
{ return fName.String(); }
|
{ return fName.String(); }
|
||||||
|
|
||||||
void MoveBy(int32 dx, int32 dy);
|
void MoveBy( int32 dx, int32 dy,
|
||||||
void ResizeBy(int32 dx, int32 dy, BRegion* dirtyRegion);
|
BRegion* dirtyRegion);
|
||||||
void ScrollBy(int32 dx, int32 dy);
|
|
||||||
|
|
||||||
void ParentResized(int32 dx, int32 dy,
|
void ResizeBy( int32 dx, int32 dy,
|
||||||
BRegion* dirtyRegion);
|
BRegion* dirtyRegion);
|
||||||
|
|
||||||
|
void ScrollBy( int32 dx, int32 dy,
|
||||||
|
BRegion* dirtyRegion);
|
||||||
|
|
||||||
|
void ParentResized( int32 dx, int32 dy,
|
||||||
|
BRegion* dirtyRegion);
|
||||||
|
|
||||||
// for background clearing
|
// for background clearing
|
||||||
void Draw(DrawingEngine* drawingEngine,
|
void Draw( DrawingEngine* drawingEngine,
|
||||||
BRegion* effectiveClipping,
|
BRegion* effectiveClipping,
|
||||||
bool deep = false);
|
BRegion* windowContentClipping,
|
||||||
|
bool deep = false);
|
||||||
|
|
||||||
// to simulate drawing done from client side
|
// to simulate drawing triggered from client side
|
||||||
void ClientDraw(DrawingEngine* drawingEngine,
|
void ClientDraw( DrawingEngine* drawingEngine,
|
||||||
BRegion* effectiveClipping);
|
BRegion* effectiveClipping);
|
||||||
|
|
||||||
bool IsHidden() const;
|
bool IsHidden() const;
|
||||||
void Hide();
|
void Hide();
|
||||||
@@ -84,13 +90,15 @@ class ViewLayer {
|
|||||||
|
|
||||||
// clipping
|
// clipping
|
||||||
void RebuildClipping(bool deep);
|
void RebuildClipping(bool deep);
|
||||||
BRegion& ScreenClipping() const;
|
BRegion& ScreenClipping(BRegion* windowContentClipping,
|
||||||
|
bool force = false) const;
|
||||||
|
|
||||||
// debugging
|
// debugging
|
||||||
void PrintToStream() const;
|
void PrintToStream() const;
|
||||||
|
|
||||||
|
void InvalidateScreenClipping(bool deep);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _InvalidateScreenClipping(bool deep);
|
|
||||||
void _MoveScreenClipping(int32 x, int32 y,
|
void _MoveScreenClipping(int32 x, int32 y,
|
||||||
bool deep);
|
bool deep);
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,16 @@ WindowLayer::WindowLayer(BRect frame, const char* name,
|
|||||||
DrawingEngine* drawingEngine, Desktop* desktop)
|
DrawingEngine* drawingEngine, Desktop* desktop)
|
||||||
: BLooper(name),
|
: BLooper(name),
|
||||||
fFrame(frame),
|
fFrame(frame),
|
||||||
|
|
||||||
fVisibleRegion(),
|
fVisibleRegion(),
|
||||||
|
fVisibleContentRegion(),
|
||||||
|
|
||||||
fBorderRegion(),
|
fBorderRegion(),
|
||||||
fBorderRegionValid(false),
|
fBorderRegionValid(false),
|
||||||
fContentRegion(),
|
fContentRegion(),
|
||||||
fContentRegionValid(false),
|
fContentRegionValid(false),
|
||||||
|
fEffectiveDrawingRegion(),
|
||||||
|
fEffectiveDrawingRegionValid(false),
|
||||||
|
|
||||||
fFocus(false),
|
fFocus(false),
|
||||||
|
|
||||||
@@ -103,10 +107,18 @@ WindowLayer::MessageReceived(BMessage* message)
|
|||||||
void
|
void
|
||||||
WindowLayer::SetClipping(BRegion* stillAvailableOnScreen)
|
WindowLayer::SetClipping(BRegion* stillAvailableOnScreen)
|
||||||
{
|
{
|
||||||
|
// this function is only called from the Desktop thread
|
||||||
|
|
||||||
// start from full region (as if the window was fully visible)
|
// start from full region (as if the window was fully visible)
|
||||||
GetFullRegion(&fVisibleRegion);
|
GetFullRegion(&fVisibleRegion);
|
||||||
// clip to region still available on screen
|
// clip to region still available on screen
|
||||||
fVisibleRegion.IntersectWith(stillAvailableOnScreen);
|
fVisibleRegion.IntersectWith(stillAvailableOnScreen);
|
||||||
|
|
||||||
|
GetContentRegion(&fVisibleContentRegion);
|
||||||
|
fVisibleContentRegion.IntersectWith(&fVisibleRegion);
|
||||||
|
|
||||||
|
fEffectiveDrawingRegionValid = false;
|
||||||
|
fTopLayer->InvalidateScreenClipping(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFullRegion
|
// GetFullRegion
|
||||||
@@ -123,45 +135,48 @@ WindowLayer::GetFullRegion(BRegion* region) const
|
|||||||
|
|
||||||
// GetBorderRegion
|
// GetBorderRegion
|
||||||
void
|
void
|
||||||
WindowLayer::GetBorderRegion(BRegion* region) const
|
WindowLayer::GetBorderRegion(BRegion* region)
|
||||||
{
|
{
|
||||||
if (fBorderRegionValid) {
|
if (!fBorderRegionValid) {
|
||||||
*region = fBorderRegion;
|
// TODO: speed up by avoiding "Exclude()"
|
||||||
|
// start from the frame, extend to include decorator border
|
||||||
|
fBorderRegion.Set(BRect(fFrame.left - 4, fFrame.top - 4,
|
||||||
|
fFrame.right + 4, fFrame.bottom + 4));
|
||||||
|
|
||||||
|
fBorderRegion.Exclude(fFrame);
|
||||||
|
|
||||||
|
// add the title tab
|
||||||
|
fBorderRegion.Include(BRect(fFrame.left - 4, fFrame.top - 20,
|
||||||
|
(fFrame.left + fFrame.right) / 2, fFrame.top - 5));
|
||||||
|
|
||||||
|
// resize handle
|
||||||
|
// if (B_DOCUMENT_WINDOW_LOOK)
|
||||||
|
fBorderRegion.Include(BRect(fFrame.right - 10, fFrame.bottom - 10,
|
||||||
|
fFrame.right, fFrame.bottom));
|
||||||
|
fBorderRegionValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: speed up by avoiding "Exclude()"
|
*region = fBorderRegion;
|
||||||
// start from the frame, extend to include decorator border
|
|
||||||
region->Set(BRect(fFrame.left - 4, fFrame.top - 4,
|
|
||||||
fFrame.right + 4, fFrame.bottom + 4));
|
|
||||||
|
|
||||||
region->Exclude(fFrame);
|
|
||||||
|
|
||||||
// add the title tab
|
|
||||||
region->Include(BRect(fFrame.left - 4, fFrame.top - 20,
|
|
||||||
(fFrame.left + fFrame.right) / 2, fFrame.top - 5));
|
|
||||||
|
|
||||||
// resize handle
|
|
||||||
// if (B_DOCUMENT_WINDOW_LOOK)
|
|
||||||
region->Include(BRect(fFrame.right - 10, fFrame.bottom - 10,
|
|
||||||
fFrame.right, fFrame.bottom));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContentRegion
|
// GetContentRegion
|
||||||
void
|
void
|
||||||
WindowLayer::GetContentRegion(BRegion* region) const
|
WindowLayer::GetContentRegion(BRegion* region)
|
||||||
{
|
{
|
||||||
if (fContentRegionValid) {
|
if (!fContentRegionValid) {
|
||||||
*region = fContentRegion;
|
// TODO: speed up by avoiding "Exclude()"
|
||||||
|
// start from the frame, extend to include decorator border
|
||||||
|
fContentRegion.Set(fFrame);
|
||||||
|
|
||||||
|
// resize handle
|
||||||
|
// if (B_DOCUMENT_WINDOW_LOOK)
|
||||||
|
fContentRegion.Exclude(BRect(fFrame.right - 10, fFrame.bottom - 10,
|
||||||
|
fFrame.right, fFrame.bottom));
|
||||||
|
|
||||||
|
fContentRegionValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: speed up by avoiding "Exclude()"
|
*region = fContentRegion;
|
||||||
// start from the frame, extend to include decorator border
|
|
||||||
region->Set(fFrame);
|
|
||||||
|
|
||||||
// resize handle
|
|
||||||
// if (B_DOCUMENT_WINDOW_LOOK)
|
|
||||||
region->Exclude(BRect(fFrame.right - 10, fFrame.bottom - 10,
|
|
||||||
fFrame.right, fFrame.bottom));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFocus
|
// SetFocus
|
||||||
@@ -189,6 +204,8 @@ WindowLayer::SetFocus(bool focus)
|
|||||||
void
|
void
|
||||||
WindowLayer::MoveBy(int32 x, int32 y)
|
WindowLayer::MoveBy(int32 x, int32 y)
|
||||||
{
|
{
|
||||||
|
// this function is only called from the desktop thread
|
||||||
|
|
||||||
if (x == 0 && y == 0)
|
if (x == 0 && y == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -204,9 +221,11 @@ WindowLayer::MoveBy(int32 x, int32 y)
|
|||||||
if (fPendingUpdateSession)
|
if (fPendingUpdateSession)
|
||||||
fPendingUpdateSession->MoveBy(x, y);
|
fPendingUpdateSession->MoveBy(x, y);
|
||||||
|
|
||||||
fTopLayer->MoveBy(x, y);
|
fEffectiveDrawingRegionValid = false;
|
||||||
|
|
||||||
// TODO: move a local dirty region!
|
fTopLayer->MoveBy(x, y, NULL);
|
||||||
|
|
||||||
|
// the desktop will take care of dirty regions
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResizeBy
|
// ResizeBy
|
||||||
@@ -219,18 +238,21 @@ WindowLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
|
|||||||
fFrame.right += x;
|
fFrame.right += x;
|
||||||
fFrame.bottom += y;
|
fFrame.bottom += y;
|
||||||
|
|
||||||
|
// put the previous border region into the dirty region as well
|
||||||
|
// to handle the part that was overlapping a layer
|
||||||
|
dirtyRegion->Include(&fBorderRegion);
|
||||||
|
|
||||||
fBorderRegionValid = false;
|
fBorderRegionValid = false;
|
||||||
fContentRegionValid = false;
|
fContentRegionValid = false;
|
||||||
|
fEffectiveDrawingRegionValid = false;
|
||||||
|
|
||||||
// the border is dirty, put it into
|
// the border is dirty, put it into
|
||||||
// dirtyRegion for a start
|
// dirtyRegion for a start
|
||||||
GetBorderRegion(dirtyRegion);
|
BRegion newBorderRegion;
|
||||||
|
GetBorderRegion(&newBorderRegion);
|
||||||
// put the previous border region into the dirty region as well
|
dirtyRegion->Include(&newBorderRegion);
|
||||||
// to handle the part that was overlapping a layer
|
|
||||||
// if B_DOCUMENT_WINDOW_LOOK
|
|
||||||
dirtyRegion->Include(&fBorderRegion);
|
|
||||||
|
|
||||||
|
// TODO: should this be clipped to the content region?
|
||||||
fTopLayer->ResizeBy(x, y, dirtyRegion);
|
fTopLayer->ResizeBy(x, y, dirtyRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,6 +281,19 @@ WindowLayer::MarkDirty(BRegion* regionOnScreen)
|
|||||||
fDesktop->MarkDirty(regionOnScreen);
|
fDesktop->MarkDirty(regionOnScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarkDirty
|
||||||
|
void
|
||||||
|
WindowLayer::MarkContentDirty(BRegion* regionOnScreen)
|
||||||
|
{
|
||||||
|
if (fDesktop && fDesktop->LockClipping()) {
|
||||||
|
|
||||||
|
regionOnScreen->IntersectWith(&fVisibleContentRegion);
|
||||||
|
fDesktop->MarkDirty(regionOnScreen);
|
||||||
|
|
||||||
|
fDesktop->UnlockClipping();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
// DirtyRegion
|
// DirtyRegion
|
||||||
BRegion
|
BRegion
|
||||||
WindowLayer::DirtyRegion()
|
WindowLayer::DirtyRegion()
|
||||||
@@ -270,7 +305,7 @@ WindowLayer::DirtyRegion()
|
|||||||
}
|
}
|
||||||
return dirty;
|
return dirty;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
# pragma mark -
|
# pragma mark -
|
||||||
|
|
||||||
// _DrawContents
|
// _DrawContents
|
||||||
@@ -285,30 +320,23 @@ WindowLayer::_DrawContents(ViewLayer* layer)
|
|||||||
if (!layer)
|
if (!layer)
|
||||||
layer = fTopLayer;
|
layer = fTopLayer;
|
||||||
|
|
||||||
if (!fContentRegionValid) {
|
if (fDesktop->ReadLockClipping()) {
|
||||||
GetContentRegion(&fContentRegion);
|
|
||||||
fContentRegionValid = true;
|
BRegion effectiveWindowClipping(fVisibleContentRegion);
|
||||||
|
effectiveWindowClipping.IntersectWith(fDesktop->DirtyRegion());
|
||||||
|
|
||||||
|
if (effectiveWindowClipping.Frame().IsValid()) {
|
||||||
|
// send UPDATE message to the client
|
||||||
|
_MarkContentDirty(&effectiveWindowClipping);
|
||||||
|
|
||||||
|
layer->Draw(fDrawingEngine, &effectiveWindowClipping,
|
||||||
|
&fVisibleContentRegion, true);
|
||||||
|
|
||||||
|
fDesktop->MarkClean(&fContentRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
fDesktop->ReadUnlockClipping();
|
||||||
}
|
}
|
||||||
|
|
||||||
BRegion effectiveWindowClipping(fContentRegion);
|
|
||||||
// TODO: simplify
|
|
||||||
// ideally, there would only be a local fDirtyRegion,
|
|
||||||
// that we need to intersect with. fDirtyRegion would
|
|
||||||
// already only include fVisibleRegion
|
|
||||||
effectiveWindowClipping.IntersectWith(&fVisibleRegion);
|
|
||||||
effectiveWindowClipping.IntersectWith(fDesktop->DirtyRegion());
|
|
||||||
if (effectiveWindowClipping.Frame().IsValid()) {
|
|
||||||
// send UPDATE message to the client here
|
|
||||||
_MarkContentDirty(&effectiveWindowClipping);
|
|
||||||
|
|
||||||
layer->Draw(fDrawingEngine, &effectiveWindowClipping, true);
|
|
||||||
|
|
||||||
fDesktop->MarkClean(&fContentRegion);
|
|
||||||
}
|
|
||||||
//else {
|
|
||||||
//printf(" nothing to do\n");
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// _DrawClient
|
// _DrawClient
|
||||||
@@ -319,22 +347,25 @@ WindowLayer::_DrawClient(int32 token)
|
|||||||
if (!layer)
|
if (!layer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BRegion effectiveClipping(layer->ScreenClipping());
|
if (fDesktop->ReadLockClipping()) {
|
||||||
if (fInUpdate) {
|
|
||||||
// enforce the dirty region of the update session
|
|
||||||
effectiveClipping.IntersectWith(&fCurrentUpdateSession->DirtyRegion());
|
|
||||||
} else {
|
|
||||||
printf("%s - _DrawClient(token: %ld) - not in update\n", Name(), token);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (effectiveClipping.CountRects() > 0 && fDesktop->ReadLockClipping()) {
|
if (!fEffectiveDrawingRegionValid) {
|
||||||
effectiveClipping.IntersectWith(&fVisibleRegion);
|
fEffectiveDrawingRegion = fVisibleContentRegion;
|
||||||
// TODO: This step seems too much
|
if (fInUpdate) {
|
||||||
BRegion contentRegion;
|
// enforce the dirty region of the update session
|
||||||
GetContentRegion(&contentRegion);
|
fEffectiveDrawingRegion.IntersectWith(&fCurrentUpdateSession->DirtyRegion());
|
||||||
effectiveClipping.IntersectWith(&contentRegion);
|
} else {
|
||||||
|
printf("%s - _DrawClient(token: %ld) - not in update\n", Name(), token);
|
||||||
|
}
|
||||||
|
fEffectiveDrawingRegionValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
layer->ClientDraw(fDrawingEngine, &effectiveClipping);
|
BRegion effectiveClipping(fEffectiveDrawingRegion);
|
||||||
|
effectiveClipping.IntersectWith(&layer->ScreenClipping(&fVisibleContentRegion));
|
||||||
|
|
||||||
|
if (effectiveClipping.CountRects() > 0) {
|
||||||
|
layer->ClientDraw(fDrawingEngine, &effectiveClipping);
|
||||||
|
}
|
||||||
|
|
||||||
fDesktop->ReadUnlockClipping();
|
fDesktop->ReadUnlockClipping();
|
||||||
}
|
}
|
||||||
@@ -348,34 +379,31 @@ WindowLayer::_DrawBorder()
|
|||||||
#if SLOW_DRAWING
|
#if SLOW_DRAWING
|
||||||
snooze(10000);
|
snooze(10000);
|
||||||
#endif
|
#endif
|
||||||
|
if (fDesktop->ReadLockClipping()) {
|
||||||
|
|
||||||
if (!fBorderRegionValid) {
|
// construct the region of the border that needs redrawing
|
||||||
GetBorderRegion(&fBorderRegion);
|
BRegion dirtyBorderRegion;
|
||||||
fBorderRegionValid = true;
|
GetBorderRegion(&dirtyBorderRegion);
|
||||||
}
|
// intersect with our visible region
|
||||||
|
dirtyBorderRegion.IntersectWith(&fVisibleRegion);
|
||||||
|
// intersect with the Desktop's dirty region
|
||||||
|
dirtyBorderRegion.IntersectWith(fDesktop->DirtyRegion());
|
||||||
|
|
||||||
// construct the region of the border that needs redrawing
|
if (dirtyBorderRegion.Frame().IsValid()) {
|
||||||
BRegion dirtyBorderRegion(fBorderRegion);
|
if (fDrawingEngine->Lock()) {
|
||||||
// intersect with our visible region
|
if (fFocus)
|
||||||
dirtyBorderRegion.IntersectWith(&fVisibleRegion);
|
fDrawingEngine->SetHighColor(255, 203, 0, 255);
|
||||||
// intersect with the Desktop's dirty region
|
else
|
||||||
dirtyBorderRegion.IntersectWith(fDesktop->DirtyRegion());
|
fDrawingEngine->SetHighColor(216, 216, 216, 0);
|
||||||
|
fDrawingEngine->FillRegion(&dirtyBorderRegion);
|
||||||
if (dirtyBorderRegion.Frame().IsValid()) {
|
fDrawingEngine->MarkDirty(&dirtyBorderRegion);
|
||||||
if (fDrawingEngine->Lock()) {
|
fDrawingEngine->Unlock();
|
||||||
if (fFocus)
|
}
|
||||||
fDrawingEngine->SetHighColor(255, 203, 0, 255);
|
fDesktop->MarkClean(&dirtyBorderRegion);
|
||||||
else
|
|
||||||
fDrawingEngine->SetHighColor(216, 216, 216, 0);
|
|
||||||
fDrawingEngine->FillRegion(&dirtyBorderRegion);
|
|
||||||
fDrawingEngine->MarkDirty(&dirtyBorderRegion);
|
|
||||||
fDrawingEngine->Unlock();
|
|
||||||
}
|
}
|
||||||
fDesktop->MarkClean(&dirtyBorderRegion);
|
|
||||||
|
fDesktop->ReadUnlockClipping();
|
||||||
}
|
}
|
||||||
//else {
|
|
||||||
//printf(" nothing to do\n");
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// _MarkContentDirty
|
// _MarkContentDirty
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ class WindowLayer : public BLooper {
|
|||||||
inline BRegion& VisibleRegion()
|
inline BRegion& VisibleRegion()
|
||||||
{ return fVisibleRegion; }
|
{ return fVisibleRegion; }
|
||||||
void GetFullRegion(BRegion* region) const;
|
void GetFullRegion(BRegion* region) const;
|
||||||
void GetBorderRegion(BRegion* region) const;
|
void GetBorderRegion(BRegion* region);
|
||||||
void GetContentRegion(BRegion* region) const;
|
void GetContentRegion(BRegion* region);
|
||||||
|
|
||||||
void SetFocus(bool focus);
|
void SetFocus(bool focus);
|
||||||
|
|
||||||
@@ -63,11 +63,12 @@ class WindowLayer : public BLooper {
|
|||||||
void AddChild(ViewLayer* layer);
|
void AddChild(ViewLayer* layer);
|
||||||
|
|
||||||
void MarkDirty(BRegion* regionOnScreen);
|
void MarkDirty(BRegion* regionOnScreen);
|
||||||
|
void MarkContentDirty(BRegion* regionOnScreen);
|
||||||
|
|
||||||
DrawingEngine* GetDrawingEngine() const
|
DrawingEngine* GetDrawingEngine() const
|
||||||
{ return fDrawingEngine; }
|
{ return fDrawingEngine; }
|
||||||
|
|
||||||
BRegion DirtyRegion();
|
// BRegion DirtyRegion();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _DrawContents(ViewLayer* layer = NULL);
|
void _DrawContents(ViewLayer* layer = NULL);
|
||||||
@@ -84,12 +85,15 @@ class WindowLayer : public BLooper {
|
|||||||
// Desktop thread, when using it, Desktop::LockClipping()
|
// Desktop thread, when using it, Desktop::LockClipping()
|
||||||
// has to be called
|
// has to be called
|
||||||
BRegion fVisibleRegion;
|
BRegion fVisibleRegion;
|
||||||
|
BRegion fVisibleContentRegion;
|
||||||
|
|
||||||
// caching local regions
|
// caching local regions
|
||||||
BRegion fBorderRegion;
|
BRegion fBorderRegion;
|
||||||
bool fBorderRegionValid;
|
bool fBorderRegionValid;
|
||||||
BRegion fContentRegion;
|
BRegion fContentRegion;
|
||||||
bool fContentRegionValid;
|
bool fContentRegionValid;
|
||||||
|
BRegion fEffectiveDrawingRegion;
|
||||||
|
bool fEffectiveDrawingRegionValid;
|
||||||
|
|
||||||
bool fFocus;
|
bool fFocus;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user