Cleaned up the dirty region handling in Window::CopyContents()
(the backend of scrolling and BView::CopyBits()). Seems to fix the dirty entries when opening Tracker windows, and another problem I've seen when scrolling too fast in Beam. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29495 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+40
-28
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2008, Haiku, Inc.
|
* Copyright (c) 2001-2009, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -449,41 +449,53 @@ Window::CopyContents(BRegion* region, int32 xOffset, int32 yOffset)
|
|||||||
// the part which we can copy is not dirty
|
// the part which we can copy is not dirty
|
||||||
newDirty->Exclude(region);
|
newDirty->Exclude(region);
|
||||||
|
|
||||||
|
BRegion* allDirtyRegions = fRegionPool.GetRegion(fDirtyRegion);
|
||||||
|
if (allDirtyRegions != NULL) {
|
||||||
|
if (fPendingUpdateSession->IsUsed()) {
|
||||||
|
allDirtyRegions->Include(
|
||||||
|
&fPendingUpdateSession->DirtyRegion());
|
||||||
|
}
|
||||||
|
if (fCurrentUpdateSession->IsUsed()) {
|
||||||
|
allDirtyRegions->Include(
|
||||||
|
&fCurrentUpdateSession->DirtyRegion());
|
||||||
|
}
|
||||||
|
// Get just the part of the dirty regions which is semantically
|
||||||
|
// copied along
|
||||||
|
allDirtyRegions->IntersectWith(region);
|
||||||
|
}
|
||||||
|
|
||||||
BRegion* copyRegion = fRegionPool.GetRegion(*region);
|
BRegion* copyRegion = fRegionPool.GetRegion(*region);
|
||||||
if (copyRegion != NULL) {
|
if (copyRegion != NULL) {
|
||||||
copyRegion->Exclude(&fPendingUpdateSession->DirtyRegion());
|
// never copy what's already dirty
|
||||||
copyRegion->Exclude(&fCurrentUpdateSession->DirtyRegion());
|
if (allDirtyRegions != NULL)
|
||||||
copyRegion->Exclude(&fDirtyRegion);
|
copyRegion->Exclude(allDirtyRegions);
|
||||||
|
|
||||||
fDrawingEngine->CopyRegion(copyRegion, xOffset, yOffset);
|
fDrawingEngine->CopyRegion(copyRegion, xOffset, yOffset);
|
||||||
fRegionPool.Recycle(copyRegion);
|
fRegionPool.Recycle(copyRegion);
|
||||||
} else {
|
} else {
|
||||||
|
// Fallback, should never be here.
|
||||||
fDrawingEngine->CopyRegion(region, xOffset, yOffset);
|
fDrawingEngine->CopyRegion(region, xOffset, yOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// move along the already dirty regions that are common
|
if (allDirtyRegions != NULL) {
|
||||||
// with the region that we could copy
|
// Move along the dirty regions and include it in the newDirty
|
||||||
_ShiftPartOfRegion(&fDirtyRegion, region, xOffset, yOffset);
|
// region. TODO: This is disabled for the moment, since it
|
||||||
if (fPendingUpdateSession->IsUsed()) {
|
// works fine without excluding the pending region. But there
|
||||||
_ShiftPartOfRegion(&(fPendingUpdateSession->DirtyRegion()), region,
|
// is one occasion where I observed flickering that could be
|
||||||
xOffset, yOffset);
|
// explained by disabling this.
|
||||||
}
|
//allDirtyRegions->OffsetBy(xOffset, yOffset);
|
||||||
|
//// no need to include what's already pending anyways
|
||||||
if (fCurrentUpdateSession->IsUsed()) {
|
//// NOTE: The left overs of the current update session which
|
||||||
// if there are parts in the current update session
|
//// have been moved are still included!
|
||||||
// that intersect with the copied region, we cannot
|
//if (fPendingUpdateSession->IsUsed()) {
|
||||||
// simply shift them as with the other dirty regions
|
//allDirtyRegions->Exclude(
|
||||||
// - we cannot change the update rect already told to the
|
//&fPendingUpdateSession->DirtyRegion());
|
||||||
// client, that's why we transfer those parts to the
|
//}
|
||||||
// new dirty region instead
|
//allDirtyRegions->OffsetBy(-xOffset, -yOffset);
|
||||||
BRegion* common = fRegionPool.GetRegion(*region);
|
// include the left over of the moved dirty regions in the
|
||||||
// see if there is a common part at all
|
// new dirty region
|
||||||
common->IntersectWith(&fCurrentUpdateSession->DirtyRegion());
|
newDirty->Include(allDirtyRegions);
|
||||||
if (common->CountRects() > 0) {
|
fRegionPool.Recycle(allDirtyRegions);
|
||||||
// cut the common part from the region
|
|
||||||
fCurrentUpdateSession->DirtyRegion().Exclude(common);
|
|
||||||
newDirty->Include(common);
|
|
||||||
}
|
|
||||||
fRegionPool.Recycle(common);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user