зеркало из https://github.com/mozilla/gecko-dev.git
Bug 806256 - Improve WrapPreserve3DList's behaviour by walking through nsDisplayWrapList without flushing the temp list. r=roc
This commit is contained in:
Родитель
1509c7378c
Коммит
608df10dff
|
@ -1764,69 +1764,63 @@ DisplayDebugBorders(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
|||
#endif
|
||||
|
||||
static nsresult
|
||||
WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder, nsDisplayList *aList, uint32_t& aIndex)
|
||||
WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder, nsDisplayList *aList, nsDisplayList *aOutput, uint32_t& aIndex, nsDisplayList* aTemp)
|
||||
{
|
||||
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();
|
||||
|
||||
// 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
|
||||
// and then flush this list into aOutput by wrapping the whole lot with a single
|
||||
// nsDisplayTransform.
|
||||
|
||||
if (childFrame && (childFrame->GetParent()->Preserves3DChildren() || childFrame == aFrame)) {
|
||||
switch (item->GetType()) {
|
||||
case nsDisplayItem::TYPE_TRANSFORM: {
|
||||
if (!temp.IsEmpty()) {
|
||||
newList.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, &temp, aIndex++));
|
||||
if (!aTemp->IsEmpty()) {
|
||||
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
|
||||
}
|
||||
newList.AppendToTop(item);
|
||||
aOutput->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 = WrapPreserve3DListInternal(aFrame, aBuilder, list->GetList(), aIndex);
|
||||
newList.AppendToTop(list->GetList());
|
||||
rv = WrapPreserve3DListInternal(aFrame, aBuilder, list->GetList(), aOutput, aIndex, aTemp);
|
||||
list->~nsDisplayWrapList();
|
||||
break;
|
||||
}
|
||||
case nsDisplayItem::TYPE_OPACITY: {
|
||||
if (!temp.IsEmpty()) {
|
||||
newList.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, &temp, aIndex++));
|
||||
if (!aTemp->IsEmpty()) {
|
||||
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
|
||||
}
|
||||
nsDisplayOpacity *opacity = static_cast<nsDisplayOpacity*>(item);
|
||||
rv = WrapPreserve3DListInternal(aFrame, aBuilder, opacity->GetList(), aIndex);
|
||||
nsDisplayList output;
|
||||
rv = WrapPreserve3DListInternal(aFrame, aBuilder, opacity->GetList(), &output, aIndex, aTemp);
|
||||
if (!aTemp->IsEmpty()) {
|
||||
output.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
|
||||
}
|
||||
opacity->GetList()->AppendToTop(&output);
|
||||
opacity->UpdateBounds(aBuilder);
|
||||
newList.AppendToTop(item);
|
||||
aOutput->AppendToTop(item);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
temp.AppendToTop(item);
|
||||
aTemp->AppendToTop(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
temp.AppendToTop(item);
|
||||
aTemp->AppendToTop(item);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv) || !item || aIndex > nsDisplayTransform::INDEX_MAX)
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!temp.IsEmpty()) {
|
||||
newList.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, &temp, aIndex++));
|
||||
}
|
||||
|
||||
aList->AppendToTop(&newList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1834,7 +1828,16 @@ static nsresult
|
|||
WrapPreserve3DList(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder, nsDisplayList *aList)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
return WrapPreserve3DListInternal(aFrame, aBuilder, aList, index);
|
||||
nsDisplayList temp;
|
||||
nsDisplayList output;
|
||||
nsresult rv = WrapPreserve3DListInternal(aFrame, aBuilder, aList, &output, index, &temp);
|
||||
|
||||
if (!temp.IsEmpty()) {
|
||||
output.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, &temp, index++));
|
||||
}
|
||||
|
||||
aList->AppendToTop(&output);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
Загрузка…
Ссылка в новой задаче