Bug 1022612. Part 15: Add nsDisplayItem::GetVisibleRectForChildren(). r=mattwoodrow

--HG--
extra : rebase_source : cf958f41493ab25762f0c3bcc0361b0810e88549
This commit is contained in:
Robert O'Callahan 2014-07-15 23:47:46 +12:00
parent a57376f075
commit 0475b87298
6 changed files with 78 additions and 29 deletions

View File

@ -1044,6 +1044,15 @@ nsDisplayList::GetBounds(nsDisplayListBuilder* aBuilder) const {
return bounds;
}
nsRect
nsDisplayList::GetVisibleRect() const {
nsRect result;
for (nsDisplayItem* i = GetBottom(); i != nullptr; i = i->GetAbove()) {
result.UnionRect(result, i->GetVisibleRect());
}
return result;
}
bool
nsDisplayList::ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
@ -4315,12 +4324,15 @@ nsDisplayTransform::GetFrameBoundsForTransform(const nsIFrame* aFrame)
#endif
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayList *aList, ComputeTransformFunction aTransformGetter,
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
nsIFrame *aFrame, nsDisplayList *aList,
const nsRect& aChildrenVisibleRect,
ComputeTransformFunction aTransformGetter,
uint32_t aIndex)
: nsDisplayItem(aBuilder, aFrame)
, mStoredList(aBuilder, aFrame, aList)
, mTransformGetter(aTransformGetter)
, mChildrenVisibleRect(aChildrenVisibleRect)
, mIndex(aIndex)
{
MOZ_COUNT_CTOR(nsDisplayTransform);
@ -4338,11 +4350,14 @@ nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder)
mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;
}
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayList *aList, uint32_t aIndex)
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
nsIFrame *aFrame, nsDisplayList *aList,
const nsRect& aChildrenVisibleRect,
uint32_t aIndex)
: nsDisplayItem(aBuilder, aFrame)
, mStoredList(aBuilder, aFrame, aList)
, mTransformGetter(nullptr)
, mChildrenVisibleRect(aChildrenVisibleRect)
, mIndex(aIndex)
{
MOZ_COUNT_CTOR(nsDisplayTransform);
@ -4351,11 +4366,14 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame
mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip());
}
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayItem *aItem, uint32_t aIndex)
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
nsIFrame *aFrame, nsDisplayItem *aItem,
const nsRect& aChildrenVisibleRect,
uint32_t aIndex)
: nsDisplayItem(aBuilder, aFrame)
, mStoredList(aBuilder, aFrame, aItem)
, mTransformGetter(nullptr)
, mChildrenVisibleRect(aChildrenVisibleRect)
, mIndex(aIndex)
{
MOZ_COUNT_CTOR(nsDisplayTransform);

View File

@ -1083,7 +1083,7 @@ public:
* @param aSnap set to true if the edges of the rectangles of the opaque
* region would be snapped to device pixels when drawing
* @return a region of the item that is opaque --- that is, every pixel
* that is visible (according to ComputeVisibility) is painted with an opaque
* that is visible is painted with an opaque
* color. This is useful for determining when one piece
* of content completely obscures another so that we can do occlusion
* culling.
@ -1270,10 +1270,17 @@ public:
virtual nsDisplayList* GetChildren() { return nullptr; }
/**
* Returns the visible rect. Should only be called after ComputeVisibility
* has happened.
* Returns the visible rect.
*/
const nsRect& GetVisibleRect() { return mVisibleRect; }
const nsRect& GetVisibleRect() const { return mVisibleRect; }
/**
* Returns the visible rect for the children, relative to their
* reference frame. Can be different from mVisibleRect for nsDisplayTransform,
* since the reference frame for the children is different from the reference
* frame for the item itself.
*/
virtual const nsRect& GetVisibleRectForChildren() const { return mVisibleRect; }
/**
* Stores the given opacity value to be applied when drawing. Returns
@ -1685,6 +1692,11 @@ public:
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
nsDisplayItem::HitTestState* aState,
nsTArray<nsIFrame*> *aOutFrames) const;
/**
* Compute the union of the visible rects of the items in the list. The
* result is not cached.
*/
nsRect GetVisibleRect() const;
#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING)
bool DidComputeVisibility() const { return mDidComputeVisibility; }
@ -1705,8 +1717,6 @@ public:
mForceTransparentSurface = true;
}
nsRect GetVisibleRect() const { return mVisibleRect; }
private:
// This class is only used on stack, so we don't have to worry about leaking
// it. Don't let us be heap-allocated!
@ -2985,7 +2995,7 @@ public:
/**
* This potentially creates a layer for the given list of items, whose
* visibility is determined by the displayport for the given frame instead of
* what is passed in to ComputeVisibility.
* normal visibility computation.
*
* Here in content, we can use this to render more content than is actually
* visible. Then, the compositing process can manipulate the generated layer
@ -3245,11 +3255,14 @@ public:
* ferries the underlying frame to the nsDisplayItem constructor.
*/
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayList *aList, uint32_t aIndex = 0);
nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
uint32_t aIndex = 0);
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayItem *aItem, uint32_t aIndex = 0);
nsDisplayItem *aItem, const nsRect& aChildrenVisibleRect,
uint32_t aIndex = 0);
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayList *aList, ComputeTransformFunction aTransformGetter, uint32_t aIndex = 0);
nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
ComputeTransformFunction aTransformGetter, uint32_t aIndex = 0);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayTransform()
@ -3307,6 +3320,11 @@ public:
return nsDisplayItem::ReferenceFrameForChildren();
}
virtual const nsRect& GetVisibleRectForChildren() const MOZ_OVERRIDE
{
return mChildrenVisibleRect;
}
enum {
INDEX_MAX = UINT32_MAX >> nsDisplayItem::TYPE_BITS
};
@ -3454,6 +3472,7 @@ private:
nsDisplayWrapList mStoredList;
gfx3DMatrix mTransform;
ComputeTransformFunction mTransformGetter;
nsRect mChildrenVisibleRect;
uint32_t mIndex;
};

View File

@ -2323,7 +2323,7 @@ nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
false/*don't build caret*/);
nsDisplayList list;
nsDisplayTransform* item =
new (&builder) nsDisplayTransform(&builder, aFrame, &list);
new (&builder) nsDisplayTransform(&builder, aFrame, &list, nsRect());
*aTransform =
item->GetTransform();

View File

@ -1737,7 +1737,9 @@ DisplayDebugBorders(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
#endif
static nsresult
WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder, nsDisplayList *aList, nsDisplayList *aOutput, uint32_t& aIndex, nsDisplayList* aTemp)
WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder,
nsDisplayList *aList, nsDisplayList *aOutput,
uint32_t& aIndex, nsDisplayList* aTemp)
{
if (aIndex > nsDisplayTransform::INDEX_MAX) {
return NS_OK;
@ -1756,7 +1758,8 @@ WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder, nsD
switch (item->GetType()) {
case nsDisplayItem::TYPE_TRANSFORM: {
if (!aTemp->IsEmpty()) {
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder,
aFrame, aTemp, aTemp->GetVisibleRect(), aIndex++));
}
// Override item's clipping with our current clip state (if any). Since we're
// bubbling up a preserve-3d transformed child to a preserve-3d parent,
@ -1778,7 +1781,8 @@ WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder, nsD
}
case nsDisplayItem::TYPE_OPACITY: {
if (!aTemp->IsEmpty()) {
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder,
aFrame, aTemp, aTemp->GetVisibleRect(), aIndex++));
}
nsDisplayOpacity *opacity = static_cast<nsDisplayOpacity*>(item);
nsDisplayList output;
@ -1788,7 +1792,8 @@ WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder, nsD
rv = WrapPreserve3DListInternal(aFrame, aBuilder,
opacity->GetChildren(), &output, aIndex, aTemp);
if (!aTemp->IsEmpty()) {
output.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
output.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder,
aFrame, aTemp, aTemp->GetVisibleRect(), aIndex++));
}
opacity->GetChildren()->AppendToTop(&output);
opacity->UpdateBounds(aBuilder);
@ -1798,10 +1803,12 @@ WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder, nsD
default: {
if (childFrame->StyleDisplay()->BackfaceIsHidden()) {
if (!aTemp->IsEmpty()) {
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder,
aFrame, aTemp, aTemp->GetVisibleRect(), aIndex++));
}
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, childFrame, item, aIndex++));
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder,
childFrame, item, item->GetVisibleRect(), aIndex++));
} else {
aTemp->AppendToTop(item);
}
@ -1826,15 +1833,18 @@ IsScrollFrameActive(nsIScrollableFrame* aScrollableFrame)
}
static nsresult
WrapPreserve3DList(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder, nsDisplayList *aList)
WrapPreserve3DList(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder,
nsDisplayList *aList)
{
uint32_t index = 0;
nsDisplayList temp;
nsDisplayList output;
nsresult rv = WrapPreserve3DListInternal(aFrame, aBuilder, aList, &output, index, &temp);
nsresult rv = WrapPreserve3DListInternal(aFrame, aBuilder, aList, &output,
index, &temp);
if (!temp.IsEmpty()) {
output.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, &temp, index++));
output.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame,
&temp, temp.GetVisibleRect(), index++));
}
aList->AppendToTop(&output);
@ -2096,7 +2106,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
WrapPreserve3DList(this, aBuilder, &resultList);
} else {
resultList.AppendNewToTop(
new (aBuilder) nsDisplayTransform(aBuilder, this, &resultList));
new (aBuilder) nsDisplayTransform(aBuilder, this, &resultList, dirtyRect));
}
}

View File

@ -531,7 +531,8 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
*aBuilder, content, child, backgroundRect, NS_RGBA(0,0,0,0));
}
content.AppendNewToTop(new (aBuilder) nsDisplayTransform(aBuilder, child, &content, ::ComputePageTransform));
content.AppendNewToTop(new (aBuilder) nsDisplayTransform(aBuilder, child,
&content, content.GetVisibleRect(), ::ComputePageTransform));
set.Content()->AppendToTop(&content);

View File

@ -797,7 +797,8 @@ nsSimplePageSequenceFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
content.AppendNewToTop(new (aBuilder)
nsDisplayTransform(aBuilder, this, &content, ::ComputePageSequenceTransform));
nsDisplayTransform(aBuilder, this, &content, content.GetVisibleRect(),
::ComputePageSequenceTransform));
aLists.Content()->AppendToTop(&content);
}