Bug 339548. Part 5: Support an accurate mode for display lists computing visible regions. r=dbaron

This commit is contained in:
Robert O'Callahan 2009-07-22 12:44:56 +12:00
parent 6200540a04
commit f18d65c6a2
2 changed files with 20 additions and 5 deletions

View File

@ -69,7 +69,8 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mBuildCaret(aBuildCaret),
mEventDelivery(aIsForEvents),
mIsAtRootOfPseudoStackingContext(PR_FALSE),
mPaintAllFrames(PR_FALSE) {
mPaintAllFrames(PR_FALSE),
mAccurateVisibleRegions(PR_FALSE) {
PL_InitArenaPool(&mPool, "displayListArena", 1024, sizeof(void*)-1);
nsPresContext* pc = aReferenceFrame->PresContext();
@ -246,18 +247,21 @@ nsDisplayItem::OptimizeVisibility(nsDisplayListBuilder* aBuilder,
nsIFrame* f = GetUnderlyingFrame();
NS_ASSERTION(f, "GetUnderlyingFrame() must return non-null for leaf items");
PRBool isMoving = aBuilder->IsMovingFrame(f);
if (IsOpaque(aBuilder)) {
nsRect opaqueArea = bounds;
if (isMoving) {
if (aBuilder->IsMovingFrame(f)) {
// The display list should include items for both the before and after
// states (see nsLayoutUtils::ComputeRepaintRegionForCopy. So the
// only area we want to cover is the area that was opaque in the
// before state and in the after state.
opaqueArea.IntersectRect(bounds - aBuilder->GetMoveDelta(), bounds);
}
aVisibleRegion->SimpleSubtract(opaqueArea);
if (aBuilder->GetAccurateVisibleRegions()) {
aVisibleRegion->Sub(*aVisibleRegion, opaqueArea);
} else {
aVisibleRegion->SimpleSubtract(opaqueArea);
}
}
return PR_TRUE;
@ -1015,7 +1019,11 @@ PRBool nsDisplayClip::OptimizeVisibility(nsDisplayListBuilder* aBuilder,
PRBool anyVisible = nsDisplayWrapList::OptimizeVisibility(aBuilder, &rNew);
nsRegion subtracted;
subtracted.Sub(clipped, rNew);
aVisibleRegion->SimpleSubtract(subtracted);
if (aBuilder->GetAccurateVisibleRegions()) {
aVisibleRegion->Sub(*aVisibleRegion, subtracted);
} else {
aVisibleRegion->SimpleSubtract(subtracted);
}
return anyVisible;
}

View File

@ -224,6 +224,12 @@ public:
*/
void SetPaintAllFrames() { mPaintAllFrames = PR_TRUE; }
PRBool GetPaintAllFrames() { return mPaintAllFrames; }
/**
* Calling this setter makes us compute accurate visible regions at the cost
* of performance if regions get very complex.
*/
void SetAccurateVisibleRegions() { mAccurateVisibleRegions = PR_TRUE; }
PRBool GetAccurateVisibleRegions() { return mAccurateVisibleRegions; }
/**
* Allows callers to selectively override the regular paint suppression checks,
* so that methods like GetFrameForPoint work when painting is suppressed.
@ -334,6 +340,7 @@ private:
PRPackedBool mIsBackgroundOnly;
PRPackedBool mIsAtRootOfPseudoStackingContext;
PRPackedBool mPaintAllFrames;
PRPackedBool mAccurateVisibleRegions;
};
class nsDisplayItem;