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:
Stephan Aßmus
2009-03-13 20:09:31 +00:00
parent a41b1bcb3a
commit 5ea31e66f7
+40 -28
View File
@@ -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);
} }
} }
} }