mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 691106 - Merge sequential nsDisplayTransforms and give them unique frame keys. r=roc
This commit is contained in:
parent
a20a2599bb
commit
ae2391fce2
@ -2451,13 +2451,6 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
||||
*aOutAncestor = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
|
||||
}
|
||||
|
||||
/* Preserve-3d can cause frames without a transform to get an nsDisplayTransform created, we should
|
||||
* use our parent's transform here.
|
||||
*/
|
||||
if (!aFrame->GetStyleDisplay()->HasTransform()) {
|
||||
return GetResultingTransformMatrix(aFrame->GetParent(), aOrigin - aFrame->GetPosition(), aFactor, nsnull, aOutAncestor);
|
||||
}
|
||||
|
||||
/* Account for the -moz-transform-origin property by translating the
|
||||
* coordinate space to the new origin.
|
||||
*/
|
||||
|
@ -2079,16 +2079,16 @@ public:
|
||||
* ferries the underlying frame to the nsDisplayItem constructor.
|
||||
*/
|
||||
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
|
||||
nsDisplayList *aList) :
|
||||
nsDisplayItem(aBuilder, aFrame), mStoredList(aBuilder, aFrame, aList)
|
||||
nsDisplayList *aList, PRUint32 aIndex = 0) :
|
||||
nsDisplayItem(aBuilder, aFrame), mStoredList(aBuilder, aFrame, aList), mIndex(aIndex)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayTransform);
|
||||
NS_ABORT_IF_FALSE(aFrame, "Must have a frame!");
|
||||
}
|
||||
|
||||
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
|
||||
nsDisplayItem *aItem) :
|
||||
nsDisplayItem(aBuilder, aFrame), mStoredList(aBuilder, aFrame, aItem)
|
||||
nsDisplayItem *aItem, PRUint32 aIndex = 0) :
|
||||
nsDisplayItem(aBuilder, aFrame), mStoredList(aBuilder, aFrame, aItem), mIndex(aIndex)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayTransform);
|
||||
NS_ABORT_IF_FALSE(aFrame, "Must have a frame!");
|
||||
@ -2127,6 +2127,12 @@ public:
|
||||
nsRegion *aVisibleRegion,
|
||||
const nsRect& aAllowVisibleRegionExpansion);
|
||||
virtual bool TryMerge(nsDisplayListBuilder *aBuilder, nsDisplayItem *aItem);
|
||||
|
||||
virtual PRUint32 GetPerFrameKey() { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); }
|
||||
|
||||
enum {
|
||||
INDEX_MAX = PR_UINT32_MAX >> nsDisplayItem::TYPE_BITS
|
||||
};
|
||||
|
||||
const gfx3DMatrix& GetTransform(float aFactor);
|
||||
|
||||
@ -2205,6 +2211,7 @@ private:
|
||||
nsDisplayWrapList mStoredList;
|
||||
gfx3DMatrix mTransform;
|
||||
float mCachedFactor;
|
||||
PRUint32 mIndex;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1518,47 +1518,78 @@ DisplayDebugBorders(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
#endif
|
||||
|
||||
static nsresult
|
||||
WrapPreserve3DList(nsIFrame *aFrame, nsDisplayListBuilder *aBuilder, nsDisplayList *aList)
|
||||
WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder, nsDisplayList *aList, PRUint32& aIndex)
|
||||
{
|
||||
if (aIndex > nsDisplayTransform::INDEX_MAX) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsDisplayList newList;
|
||||
nsDisplayList temp;
|
||||
while (nsDisplayItem *item = aList->RemoveBottom()) {
|
||||
nsIFrame *childFrame = item->GetUnderlyingFrame();
|
||||
NS_ASSERTION(childFrame, "All display items to be wrapped must have a frame!");
|
||||
|
||||
// We accumulate sequential items that aren't transforms into the 'temp' list
|
||||
// and then flush this list into newList by wrapping the whole lot with a single
|
||||
// nsDisplayTransform.
|
||||
|
||||
if (childFrame->GetParent()->Preserves3DChildren()) {
|
||||
switch (item->GetType()) {
|
||||
case nsDisplayItem::TYPE_TRANSFORM: {
|
||||
if (!temp.IsEmpty()) {
|
||||
newList.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, &temp, aIndex++));
|
||||
}
|
||||
newList.AppendToTop(item);
|
||||
break;
|
||||
}
|
||||
case nsDisplayItem::TYPE_WRAP_LIST: {
|
||||
if (!temp.IsEmpty()) {
|
||||
newList.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, &temp, aIndex++));
|
||||
}
|
||||
nsDisplayWrapList *list = static_cast<nsDisplayWrapList*>(item);
|
||||
rv = WrapPreserve3DList(aFrame, aBuilder, list->GetList());
|
||||
rv = WrapPreserve3DListInternal(aFrame, aBuilder, list->GetList(), aIndex);
|
||||
newList.AppendToTop(item);
|
||||
break;
|
||||
}
|
||||
case nsDisplayItem::TYPE_OPACITY: {
|
||||
if (!temp.IsEmpty()) {
|
||||
newList.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, &temp, aIndex++));
|
||||
}
|
||||
nsDisplayOpacity *opacity = static_cast<nsDisplayOpacity*>(item);
|
||||
rv = WrapPreserve3DList(aFrame, aBuilder, opacity->GetList());
|
||||
rv = WrapPreserve3DListInternal(aFrame, aBuilder, opacity->GetList(), aIndex);
|
||||
newList.AppendToTop(item);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
item = new (aBuilder) nsDisplayTransform(aBuilder, childFrame, item);
|
||||
temp.AppendToTop(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
item = new (aBuilder) nsDisplayTransform(aBuilder, childFrame, item);
|
||||
temp.AppendToTop(item);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv) || !item)
|
||||
if (NS_FAILED(rv) || !item || aIndex > nsDisplayTransform::INDEX_MAX)
|
||||
return rv;
|
||||
|
||||
newList.AppendToTop(item);
|
||||
}
|
||||
|
||||
if (!temp.IsEmpty()) {
|
||||
newList.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, &temp, aIndex++));
|
||||
}
|
||||
|
||||
aList->AppendToTop(&newList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
WrapPreserve3DList(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder, nsDisplayList *aList)
|
||||
{
|
||||
PRUint32 index = 0;
|
||||
return WrapPreserve3DListInternal(aFrame, aBuilder, aList, index);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
|
Loading…
Reference in New Issue
Block a user