Bug 590468. Part 6: Fix setting of nsDisplayList::mOpaque, and return it from nsDisplayWrapList::IsOpaque. r=tnikkel

This commit is contained in:
Robert O'Callahan 2010-08-27 18:15:08 -05:00
Родитель aa665b135f
Коммит f54339d471
8 изменённых файлов: 62 добавлений и 22 удалений

Просмотреть файл

@ -287,9 +287,24 @@ nsDisplayList::GetBounds(nsDisplayListBuilder* aBuilder) const {
} }
PRBool PRBool
nsDisplayList::ComputeVisibility(nsDisplayListBuilder* aBuilder, nsDisplayList::ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) { nsRegion* aVisibleRegion) {
mVisibleRect = aVisibleRegion->GetBounds(); nsRegion r;
r.And(*aVisibleRegion, GetBounds(aBuilder));
return ComputeVisibilityForSublist(aBuilder, aVisibleRegion, r.GetBounds());
}
PRBool
nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aListVisibleBounds) {
#ifdef DEBUG
nsRegion r;
r.And(*aVisibleRegion, GetBounds(aBuilder));
NS_ASSERTION(r.GetBounds() == aListVisibleBounds,
"bad aListVisibleBounds");
#endif
mVisibleRect = aListVisibleBounds;
PRBool anyVisible = PR_FALSE; PRBool anyVisible = PR_FALSE;
nsAutoTArray<nsDisplayItem*, 512> elements; nsAutoTArray<nsDisplayItem*, 512> elements;
@ -322,7 +337,7 @@ nsDisplayList::ComputeVisibility(nsDisplayListBuilder* aBuilder,
AppendToBottom(item); AppendToBottom(item);
} }
mIsOpaque = aVisibleRegion->IsEmpty(); mIsOpaque = !aVisibleRegion->Intersects(mVisibleRect);
#ifdef DEBUG #ifdef DEBUG
mDidComputeVisibility = PR_TRUE; mDidComputeVisibility = PR_TRUE;
#endif #endif
@ -1055,14 +1070,13 @@ nsDisplayWrapList::GetBounds(nsDisplayListBuilder* aBuilder) {
PRBool PRBool
nsDisplayWrapList::ComputeVisibility(nsDisplayListBuilder* aBuilder, nsDisplayWrapList::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) { nsRegion* aVisibleRegion) {
return mList.ComputeVisibility(aBuilder, aVisibleRegion); return mList.ComputeVisibilityForSublist(aBuilder, aVisibleRegion,
mVisibleRect);
} }
PRBool PRBool
nsDisplayWrapList::IsOpaque(nsDisplayListBuilder* aBuilder) { nsDisplayWrapList::IsOpaque(nsDisplayListBuilder* aBuilder) {
// We could try to do something but let's conservatively just return PR_FALSE. return mList.IsOpaque();
// We reimplement ComputeVisibility and that's what really matters
return PR_FALSE;
} }
PRBool nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { PRBool nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) {
@ -1384,8 +1398,11 @@ PRBool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder,
aVisibleRegion->ConvertAppUnitsRoundOut(mParentAPD, mAPD); aVisibleRegion->ConvertAppUnitsRoundOut(mParentAPD, mAPD);
nsRegion originalVisibleRegion = visibleRegion; nsRegion originalVisibleRegion = visibleRegion;
nsRect transformedVisibleRect =
mVisibleRect.ConvertAppUnitsRoundOut(mParentAPD, mAPD);
PRBool retval = PRBool retval =
nsDisplayWrapList::ComputeVisibility(aBuilder, &visibleRegion); mList.ComputeVisibilityForSublist(aBuilder, &visibleRegion,
transformedVisibleRect);
nsRegion removed; nsRegion removed;
// removed = originalVisibleRegion - visibleRegion // removed = originalVisibleRegion - visibleRegion
@ -1584,8 +1601,10 @@ PRBool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
* think that it's painting in its original rectangular coordinate space. */ * think that it's painting in its original rectangular coordinate space. */
nsRegion untransformedVisible = nsRegion untransformedVisible =
UntransformRect(mVisibleRect, mFrame, ToReferenceFrame()); UntransformRect(mVisibleRect, mFrame, ToReferenceFrame());
// Call RecomputeVisiblity instead of ComputeVisibilty since
mStoredList.ComputeVisibility(aBuilder, &untransformedVisible); // nsDisplayItem::ComputeVisibility should only be called from
// nsDisplayList::ComputeVisibility (which sets mVisibleRect on the item)
mStoredList.RecomputeVisibility(aBuilder, &untransformedVisible);
return PR_TRUE; return PR_TRUE;
} }
@ -1843,7 +1862,9 @@ PRBool nsDisplaySVGEffects::ComputeVisibility(nsDisplayListBuilder* aBuilder,
// Our children may be made translucent or arbitrarily deformed so we should // Our children may be made translucent or arbitrarily deformed so we should
// not allow them to subtract area from aVisibleRegion. // not allow them to subtract area from aVisibleRegion.
nsRegion childrenVisible(dirtyRect); nsRegion childrenVisible(dirtyRect);
nsDisplayWrapList::ComputeVisibility(aBuilder, &childrenVisible); nsRect r;
r.IntersectRect(dirtyRect, mList.GetBounds(aBuilder));
mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r);
return PR_TRUE; return PR_TRUE;
} }

Просмотреть файл

@ -587,6 +587,8 @@ public:
* nsDisplayList::ComputeVisibility will already have set mVisibleRect on * nsDisplayList::ComputeVisibility will already have set mVisibleRect on
* this item to the intersection of *aVisibleRegion (unioned with * this item to the intersection of *aVisibleRegion (unioned with
* *aVisibleRegionBeforeMove, if that's non-null) and this item's bounds. * *aVisibleRegionBeforeMove, if that's non-null) and this item's bounds.
* We rely on that, so this should only be called by
* nsDisplayList::ComputeVisibility or nsDisplayItem::RecomputeVisibility.
* *
* @return PR_TRUE if the item is visible, PR_FALSE if no part of the item * @return PR_TRUE if the item is visible, PR_FALSE if no part of the item
* is visible * is visible
@ -842,17 +844,32 @@ public:
* This is also a good place to put ComputeVisibility-related logic * This is also a good place to put ComputeVisibility-related logic
* that must be applied to every display item. In particular, this * that must be applied to every display item. In particular, this
* sets mVisibleRect on each display item. * sets mVisibleRect on each display item.
* This also sets mIsOpaque to whether aVisibleRegion is empty on return. * This sets mIsOpaque if the entire visible area of this list has
* been removed from aVisibleRegion when we return.
* This does not remove any items from the list, so we can recompute * This does not remove any items from the list, so we can recompute
* visiblity with different regions later (see * visiblity with different regions later (see
* FrameLayerBuilder::DrawThebesLayer). * FrameLayerBuilder::DrawThebesLayer).
* *
* @param aVisibleRegion the area that is visible, relative to the * @param aVisibleRegion the area that is visible, relative to the
* reference frame; on return, this contains the area visible under the list * reference frame; on return, this contains the area visible under the list.
* I.e., opaque contents of this list are subtracted from aVisibleRegion.
* @param aListVisibleBounds must be equal to the bounds of the intersection
* of aVisibleRegion and GetBounds() for this list.
* @return true if any item in the list is visible * @return true if any item in the list is visible
*/ */
PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder, PRBool ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aListVisibleBounds);
/**
* As ComputeVisibilityForSublist, but computes visibility for a root
* list (a list that does not belong to an nsDisplayItem).
*
* @param aVisibleRegion the area that is visible
*/
PRBool ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion); nsRegion* aVisibleRegion);
/** /**
* Returns true if the visible region output from ComputeVisiblity was * Returns true if the visible region output from ComputeVisiblity was
* empty, i.e. everything visible in this list is opaque. * empty, i.e. everything visible in this list is opaque.

Просмотреть файл

@ -176,13 +176,13 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
} }
nscolor color; nscolor color;
nsRect vis = i->GetVisibleRect(); nsRect vis = i->GetVisibleRect();
nsDisplayList* list = i->GetList();
fprintf(aOutput, "%s %p(%s) (%d,%d,%d,%d)(%d,%d,%d,%d)%s%s\n", fprintf(aOutput, "%s %p(%s) (%d,%d,%d,%d)(%d,%d,%d,%d)%s%s\n",
i->Name(), (void*)f, NS_ConvertUTF16toUTF8(fName).get(), i->Name(), (void*)f, NS_ConvertUTF16toUTF8(fName).get(),
rect.x, rect.y, rect.width, rect.height, rect.x, rect.y, rect.width, rect.height,
vis.x, vis.y, vis.width, vis.height, vis.x, vis.y, vis.width, vis.height,
i->IsOpaque(aBuilder) ? " opaque" : "", ((!list || list->DidComputeVisibility()) && i->IsOpaque(aBuilder)) ? " opaque" : "",
i->IsUniform(aBuilder, &color) ? " uniform" : ""); i->IsUniform(aBuilder, &color) ? " uniform" : "");
nsDisplayList* list = i->GetList();
if (list) { if (list) {
PrintDisplayListTo(aBuilder, *list, aIndent + 4, aOutput); PrintDisplayListTo(aBuilder, *list, aIndent + 4, aOutput);
} }

Просмотреть файл

@ -1377,7 +1377,7 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
} }
#endif #endif
list.ComputeVisibility(&builder, &visibleRegion); list.ComputeVisibilityForRoot(&builder, &visibleRegion);
#ifdef DEBUG #ifdef DEBUG
if (gDumpPaintList) { if (gDumpPaintList) {

Просмотреть файл

@ -2536,7 +2536,7 @@ nsRootPresContext::GetPluginGeometryUpdates(nsIFrame* aChangedSubtree,
#endif #endif
nsRegion visibleRegion(bounds); nsRegion visibleRegion(bounds);
list.ComputeVisibility(&builder, &visibleRegion); list.ComputeVisibilityForRoot(&builder, &visibleRegion);
#ifdef DEBUG #ifdef DEBUG
if (gDumpPluginList) { if (gDumpPluginList) {

Просмотреть файл

@ -5618,7 +5618,7 @@ PresShell::PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems,
aArea.MoveBy(-rangeInfo->mRootOffset.x, -rangeInfo->mRootOffset.y); aArea.MoveBy(-rangeInfo->mRootOffset.x, -rangeInfo->mRootOffset.y);
nsRegion visible(aArea); nsRegion visible(aArea);
rangeInfo->mList.ComputeVisibility(&rangeInfo->mBuilder, &visible); rangeInfo->mList.ComputeVisibilityForRoot(&rangeInfo->mBuilder, &visible);
rangeInfo->mList.PaintRoot(&rangeInfo->mBuilder, rc, nsDisplayList::PAINT_DEFAULT); rangeInfo->mList.PaintRoot(&rangeInfo->mBuilder, rc, nsDisplayList::PAINT_DEFAULT);
aArea.MoveBy(rangeInfo->mRootOffset.x, rangeInfo->mRootOffset.y); aArea.MoveBy(rangeInfo->mRootOffset.x, rangeInfo->mRootOffset.y);
} }

Просмотреть файл

@ -1568,7 +1568,7 @@ InvalidateFixedBackgroundFrames(nsIFrame* aRootFrame,
return; return;
nsRegion visibleRegion(aUpdateRect); nsRegion visibleRegion(aUpdateRect);
list.ComputeVisibility(&builder, &visibleRegion); list.ComputeVisibilityForRoot(&builder, &visibleRegion);
InvalidateFixedBackgroundFramesFromList(&builder, aMovingFrame, list); InvalidateFixedBackgroundFramesFromList(&builder, aMovingFrame, list);
list.DeleteAll(); list.DeleteAll();

Просмотреть файл

@ -149,6 +149,8 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext,
aDesiredSize.height = aReflowState.availableHeight; aDesiredSize.height = aReflowState.availableHeight;
} }
FinishAndStoreOverflow(&aDesiredSize);
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
return NS_OK; return NS_OK;
} }