mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
fad4d039ef
@ -3631,7 +3631,6 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||||||
PaintFrameFlags aFlags)
|
PaintFrameFlags aFlags)
|
||||||
{
|
{
|
||||||
AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame", GRAPHICS);
|
AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame", GRAPHICS);
|
||||||
typedef RetainedDisplayListBuilder::PartialUpdateResult PartialUpdateResult;
|
|
||||||
|
|
||||||
#ifdef MOZ_DUMP_PAINTING
|
#ifdef MOZ_DUMP_PAINTING
|
||||||
if (!gPaintCountStack) {
|
if (!gPaintCountStack) {
|
||||||
@ -3789,7 +3788,6 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsRect visibleRect = visibleRegion.GetBounds();
|
nsRect visibleRect = visibleRegion.GetBounds();
|
||||||
PartialUpdateResult updateState = PartialUpdateResult::Failed;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame:BuildDisplayList",
|
AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame:BuildDisplayList",
|
||||||
@ -3839,20 +3837,22 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||||||
// Attempt to do a partial build and merge into the existing list.
|
// Attempt to do a partial build and merge into the existing list.
|
||||||
// This calls BuildDisplayListForStacking context on a subset of the
|
// This calls BuildDisplayListForStacking context on a subset of the
|
||||||
// viewport.
|
// viewport.
|
||||||
|
bool merged = false;
|
||||||
|
|
||||||
if (useRetainedBuilder) {
|
if (useRetainedBuilder) {
|
||||||
if (gfxPrefs::LayoutVerifyRetainDisplayList()) {
|
if (gfxPrefs::LayoutVerifyRetainDisplayList()) {
|
||||||
beforeMergeChecker.Set(&list, "BM");
|
beforeMergeChecker.Set(&list, "BM");
|
||||||
}
|
}
|
||||||
updateState = retainedBuilder->AttemptPartialUpdate(
|
merged = retainedBuilder->AttemptPartialUpdate(
|
||||||
aBackstop, beforeMergeChecker ? &toBeMergedChecker : nullptr);
|
aBackstop, beforeMergeChecker ? &toBeMergedChecker : nullptr);
|
||||||
if ((updateState != PartialUpdateResult::Failed) && beforeMergeChecker) {
|
if (merged && beforeMergeChecker) {
|
||||||
afterMergeChecker.Set(&list, "AM");
|
afterMergeChecker.Set(&list, "AM");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((updateState != PartialUpdateResult::Failed) &&
|
if (merged &&
|
||||||
(gfxPrefs::LayoutDisplayListBuildTwice() || afterMergeChecker)) {
|
(gfxPrefs::LayoutDisplayListBuildTwice() || afterMergeChecker)) {
|
||||||
updateState = PartialUpdateResult::Failed;
|
merged = false;
|
||||||
if (gfxPrefs::LayersDrawFPS()) {
|
if (gfxPrefs::LayersDrawFPS()) {
|
||||||
if (RefPtr<LayerManager> lm = builder.GetWidgetLayerManager()) {
|
if (RefPtr<LayerManager> lm = builder.GetWidgetLayerManager()) {
|
||||||
if (PaintTiming* pt = ClientLayerManager::MaybeGetPaintTiming(lm)) {
|
if (PaintTiming* pt = ClientLayerManager::MaybeGetPaintTiming(lm)) {
|
||||||
@ -3863,7 +3863,7 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||||||
dlStart = TimeStamp::Now();
|
dlStart = TimeStamp::Now();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateState == PartialUpdateResult::Failed) {
|
if (!merged) {
|
||||||
list.DeleteAll(&builder);
|
list.DeleteAll(&builder);
|
||||||
builder.EnterPresShell(aFrame);
|
builder.EnterPresShell(aFrame);
|
||||||
builder.SetDirtyRect(visibleRect);
|
builder.SetDirtyRect(visibleRect);
|
||||||
@ -3872,7 +3872,6 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||||||
AddExtraBackgroundItems(builder, list, aFrame, canvasArea, visibleRegion, aBackstop);
|
AddExtraBackgroundItems(builder, list, aFrame, canvasArea, visibleRegion, aBackstop);
|
||||||
|
|
||||||
builder.LeavePresShell(aFrame, &list);
|
builder.LeavePresShell(aFrame, &list);
|
||||||
updateState = PartialUpdateResult::Updated;
|
|
||||||
|
|
||||||
if (afterMergeChecker) {
|
if (afterMergeChecker) {
|
||||||
DisplayListChecker nonRetainedChecker(&list, "NR");
|
DisplayListChecker nonRetainedChecker(&list, "NR");
|
||||||
@ -3910,7 +3909,6 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(updateState != PartialUpdateResult::Failed);
|
|
||||||
builder.Check();
|
builder.Check();
|
||||||
|
|
||||||
Telemetry::AccumulateTimeDelta(Telemetry::PAINT_BUILD_DISPLAYLIST_TIME,
|
Telemetry::AccumulateTimeDelta(Telemetry::PAINT_BUILD_DISPLAYLIST_TIME,
|
||||||
@ -3985,9 +3983,6 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||||||
if (aFlags & PaintFrameFlags::PAINT_COMPRESSED) {
|
if (aFlags & PaintFrameFlags::PAINT_COMPRESSED) {
|
||||||
flags |= nsDisplayList::PAINT_COMPRESSED;
|
flags |= nsDisplayList::PAINT_COMPRESSED;
|
||||||
}
|
}
|
||||||
if (updateState == PartialUpdateResult::NoChange) {
|
|
||||||
flags |= nsDisplayList::PAINT_IDENTICAL_DISPLAY_LIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeStamp paintStart = TimeStamp::Now();
|
TimeStamp paintStart = TimeStamp::Now();
|
||||||
RefPtr<LayerManager> layerManager
|
RefPtr<LayerManager> layerManager
|
||||||
|
@ -194,7 +194,7 @@ nsPresContext::MakeColorPref(const nsString& aColor)
|
|||||||
bool
|
bool
|
||||||
nsPresContext::IsDOMPaintEventPending()
|
nsPresContext::IsDOMPaintEventPending()
|
||||||
{
|
{
|
||||||
if (!mTransactions.IsEmpty()) {
|
if (mFireAfterPaintEvents) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
nsRootPresContext* drpc = GetRootPresContext();
|
nsRootPresContext* drpc = GetRootPresContext();
|
||||||
@ -203,6 +203,7 @@ nsPresContext::IsDOMPaintEventPending()
|
|||||||
// fired, we record an empty invalidation in case display list
|
// fired, we record an empty invalidation in case display list
|
||||||
// invalidation doesn't invalidate anything further.
|
// invalidation doesn't invalidate anything further.
|
||||||
NotifyInvalidation(drpc->mRefreshDriver->LastTransactionId() + 1, nsRect(0, 0, 0, 0));
|
NotifyInvalidation(drpc->mRefreshDriver->LastTransactionId() + 1, nsRect(0, 0, 0, 0));
|
||||||
|
NS_ASSERTION(mFireAfterPaintEvents, "Why aren't we planning to fire the event?");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -314,6 +315,7 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
|
|||||||
mFontFeatureValuesDirty(true),
|
mFontFeatureValuesDirty(true),
|
||||||
mSuppressResizeReflow(false),
|
mSuppressResizeReflow(false),
|
||||||
mIsVisual(false),
|
mIsVisual(false),
|
||||||
|
mFireAfterPaintEvents(false),
|
||||||
mIsChrome(false),
|
mIsChrome(false),
|
||||||
mIsChromeOriginImage(false),
|
mIsChromeOriginImage(false),
|
||||||
mPaintFlashing(false),
|
mPaintFlashing(false),
|
||||||
@ -2594,17 +2596,6 @@ nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsIntRect& aRec
|
|||||||
NotifyInvalidation(aTransactionId, rect);
|
NotifyInvalidation(aTransactionId, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPresContext::TransactionInvalidations*
|
|
||||||
nsPresContext::GetInvalidations(uint64_t aTransactionId)
|
|
||||||
{
|
|
||||||
for (TransactionInvalidations& t : mTransactions) {
|
|
||||||
if (t.mTransactionId == aTransactionId) {
|
|
||||||
return &t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect)
|
nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect)
|
||||||
{
|
{
|
||||||
@ -2618,13 +2609,9 @@ nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect)
|
|||||||
|
|
||||||
nsPresContext* pc;
|
nsPresContext* pc;
|
||||||
for (pc = this; pc; pc = pc->GetParentPresContext()) {
|
for (pc = this; pc; pc = pc->GetParentPresContext()) {
|
||||||
TransactionInvalidations* transaction = pc->GetInvalidations(aTransactionId);
|
if (pc->mFireAfterPaintEvents)
|
||||||
if (transaction) {
|
|
||||||
break;
|
break;
|
||||||
} else {
|
pc->mFireAfterPaintEvents = true;
|
||||||
transaction = pc->mTransactions.AppendElement();
|
|
||||||
transaction->mTransactionId = aTransactionId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!pc) {
|
if (!pc) {
|
||||||
nsRootPresContext* rpc = GetRootPresContext();
|
nsRootPresContext* rpc = GetRootPresContext();
|
||||||
@ -2633,8 +2620,18 @@ nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionInvalidations* transaction = GetInvalidations(aTransactionId);
|
TransactionInvalidations* transaction = nullptr;
|
||||||
MOZ_ASSERT(transaction);
|
for (TransactionInvalidations& t : mTransactions) {
|
||||||
|
if (t.mTransactionId == aTransactionId) {
|
||||||
|
transaction = &t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!transaction) {
|
||||||
|
transaction = mTransactions.AppendElement();
|
||||||
|
transaction->mTransactionId = aTransactionId;
|
||||||
|
}
|
||||||
|
|
||||||
transaction->mInvalidations.AppendElement(aRect);
|
transaction->mInvalidations.AppendElement(aRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2686,6 +2683,7 @@ nsPresContext::ClearNotifySubDocInvalidationData(ContainerLayer* aContainer)
|
|||||||
struct NotifyDidPaintSubdocumentCallbackClosure {
|
struct NotifyDidPaintSubdocumentCallbackClosure {
|
||||||
uint64_t mTransactionId;
|
uint64_t mTransactionId;
|
||||||
const mozilla::TimeStamp& mTimeStamp;
|
const mozilla::TimeStamp& mTimeStamp;
|
||||||
|
bool mNeedsAnotherDidPaintNotification;
|
||||||
};
|
};
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
nsPresContext::NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData)
|
nsPresContext::NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData)
|
||||||
@ -2698,6 +2696,9 @@ nsPresContext::NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* a
|
|||||||
if (pc) {
|
if (pc) {
|
||||||
pc->NotifyDidPaintForSubtree(closure->mTransactionId,
|
pc->NotifyDidPaintForSubtree(closure->mTransactionId,
|
||||||
closure->mTimeStamp);
|
closure->mTimeStamp);
|
||||||
|
if (pc->mFireAfterPaintEvents) {
|
||||||
|
closure->mNeedsAnotherDidPaintNotification = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -2742,12 +2743,12 @@ nsPresContext::NotifyDidPaintForSubtree(uint64_t aTransactionId,
|
|||||||
if (IsRoot()) {
|
if (IsRoot()) {
|
||||||
static_cast<nsRootPresContext*>(this)->CancelDidPaintTimers(aTransactionId);
|
static_cast<nsRootPresContext*>(this)->CancelDidPaintTimers(aTransactionId);
|
||||||
|
|
||||||
if (mTransactions.IsEmpty()) {
|
if (!mFireAfterPaintEvents) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PresShell()->IsVisible() && mTransactions.IsEmpty()) {
|
if (!PresShell()->IsVisible() && !mFireAfterPaintEvents) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2761,13 +2762,11 @@ nsPresContext::NotifyDidPaintForSubtree(uint64_t aTransactionId,
|
|||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
while (i < mTransactions.Length()) {
|
while (i < mTransactions.Length()) {
|
||||||
if (mTransactions[i].mTransactionId <= aTransactionId) {
|
if (mTransactions[i].mTransactionId <= aTransactionId) {
|
||||||
if (!mTransactions[i].mInvalidations.IsEmpty()) {
|
nsCOMPtr<nsIRunnable> ev =
|
||||||
nsCOMPtr<nsIRunnable> ev =
|
new DelayedFireDOMPaintEvent(this, &mTransactions[i].mInvalidations,
|
||||||
new DelayedFireDOMPaintEvent(this, &mTransactions[i].mInvalidations,
|
mTransactions[i].mTransactionId, aTimeStamp);
|
||||||
mTransactions[i].mTransactionId, aTimeStamp);
|
nsContentUtils::AddScriptRunner(ev);
|
||||||
nsContentUtils::AddScriptRunner(ev);
|
sent = true;
|
||||||
sent = true;
|
|
||||||
}
|
|
||||||
mTransactions.RemoveElementAt(i);
|
mTransactions.RemoveElementAt(i);
|
||||||
} else {
|
} else {
|
||||||
i++;
|
i++;
|
||||||
@ -2782,8 +2781,14 @@ nsPresContext::NotifyDidPaintForSubtree(uint64_t aTransactionId,
|
|||||||
nsContentUtils::AddScriptRunner(ev);
|
nsContentUtils::AddScriptRunner(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
NotifyDidPaintSubdocumentCallbackClosure closure = { aTransactionId, aTimeStamp };
|
NotifyDidPaintSubdocumentCallbackClosure closure = { aTransactionId, aTimeStamp, false };
|
||||||
mDocument->EnumerateSubDocuments(nsPresContext::NotifyDidPaintSubdocumentCallback, &closure);
|
mDocument->EnumerateSubDocuments(nsPresContext::NotifyDidPaintSubdocumentCallback, &closure);
|
||||||
|
|
||||||
|
if (!closure.mNeedsAnotherDidPaintNotification &&
|
||||||
|
mTransactions.IsEmpty()) {
|
||||||
|
// Nothing more to do for the moment.
|
||||||
|
mFireAfterPaintEvents = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1291,12 +1291,6 @@ protected:
|
|||||||
const char* aName,
|
const char* aName,
|
||||||
uint32_t aDelay);
|
uint32_t aDelay);
|
||||||
|
|
||||||
struct TransactionInvalidations {
|
|
||||||
uint64_t mTransactionId;
|
|
||||||
nsTArray<nsRect> mInvalidations;
|
|
||||||
};
|
|
||||||
TransactionInvalidations* GetInvalidations(uint64_t aTransactionId);
|
|
||||||
|
|
||||||
// IMPORTANT: The ownership implicit in the following member variables
|
// IMPORTANT: The ownership implicit in the following member variables
|
||||||
// has been explicitly checked. If you add any members to this class,
|
// has been explicitly checked. If you add any members to this class,
|
||||||
// please make the ownership explicit (pinkerton, scc).
|
// please make the ownership explicit (pinkerton, scc).
|
||||||
@ -1365,6 +1359,10 @@ protected:
|
|||||||
|
|
||||||
mozilla::UniquePtr<nsBidi> mBidiEngine;
|
mozilla::UniquePtr<nsBidi> mBidiEngine;
|
||||||
|
|
||||||
|
struct TransactionInvalidations {
|
||||||
|
uint64_t mTransactionId;
|
||||||
|
nsTArray<nsRect> mInvalidations;
|
||||||
|
};
|
||||||
AutoTArray<TransactionInvalidations, 4> mTransactions;
|
AutoTArray<TransactionInvalidations, 4> mTransactions;
|
||||||
|
|
||||||
// text performance metrics
|
// text performance metrics
|
||||||
@ -1491,6 +1489,8 @@ protected:
|
|||||||
|
|
||||||
unsigned mIsVisual : 1;
|
unsigned mIsVisual : 1;
|
||||||
|
|
||||||
|
unsigned mFireAfterPaintEvents : 1;
|
||||||
|
|
||||||
unsigned mIsChrome : 1;
|
unsigned mIsChrome : 1;
|
||||||
unsigned mIsChromeOriginImage : 1;
|
unsigned mIsChromeOriginImage : 1;
|
||||||
|
|
||||||
|
@ -104,25 +104,21 @@ SelectAGRForFrame(nsIFrame* aFrame, AnimatedGeometryRoot* aParentAGR)
|
|||||||
// TODO: We currently descend into all children even if we don't have an AGR
|
// TODO: We currently descend into all children even if we don't have an AGR
|
||||||
// to mark, as child stacking contexts might. It would be nice if we could
|
// to mark, as child stacking contexts might. It would be nice if we could
|
||||||
// jump into those immediately rather than walking the entire thing.
|
// jump into those immediately rather than walking the entire thing.
|
||||||
bool
|
void
|
||||||
RetainedDisplayListBuilder::PreProcessDisplayList(nsDisplayList* aList,
|
RetainedDisplayListBuilder::PreProcessDisplayList(nsDisplayList* aList,
|
||||||
AnimatedGeometryRoot* aAGR)
|
AnimatedGeometryRoot* aAGR)
|
||||||
{
|
{
|
||||||
bool modified = false;
|
|
||||||
nsDisplayList saved;
|
nsDisplayList saved;
|
||||||
while (nsDisplayItem* i = aList->RemoveBottom()) {
|
while (nsDisplayItem* i = aList->RemoveBottom()) {
|
||||||
if (i->HasDeletedFrame() || !i->CanBeReused()) {
|
if (i->HasDeletedFrame() || !i->CanBeReused()) {
|
||||||
i->Destroy(&mBuilder);
|
i->Destroy(&mBuilder);
|
||||||
modified = true;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame* f = i->Frame();
|
nsIFrame* f = i->Frame();
|
||||||
|
|
||||||
if (i->GetChildren()) {
|
if (i->GetChildren()) {
|
||||||
if (PreProcessDisplayList(i->GetChildren(), SelectAGRForFrame(f, aAGR))) {
|
PreProcessDisplayList(i->GetChildren(), SelectAGRForFrame(f, aAGR));
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: We should be able to check the clipped bounds relative
|
// TODO: We should be able to check the clipped bounds relative
|
||||||
@ -130,7 +126,6 @@ RetainedDisplayListBuilder::PreProcessDisplayList(nsDisplayList* aList,
|
|||||||
// frame) and determine if they can ever intersect.
|
// frame) and determine if they can ever intersect.
|
||||||
if (aAGR && i->GetAnimatedGeometryRoot()->GetAsyncAGR() != aAGR) {
|
if (aAGR && i->GetAnimatedGeometryRoot()->GetAsyncAGR() != aAGR) {
|
||||||
mBuilder.MarkFrameForDisplayIfVisible(f, mBuilder.RootReferenceFrame());
|
mBuilder.MarkFrameForDisplayIfVisible(f, mBuilder.RootReferenceFrame());
|
||||||
modified = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This is here because we sometimes reuse the previous display list
|
// TODO: This is here because we sometimes reuse the previous display list
|
||||||
@ -142,7 +137,6 @@ RetainedDisplayListBuilder::PreProcessDisplayList(nsDisplayList* aList,
|
|||||||
}
|
}
|
||||||
aList->AppendToTop(&saved);
|
aList->AppendToTop(&saved);
|
||||||
aList->RestoreState();
|
aList->RestoreState();
|
||||||
return modified;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSameItem(nsDisplayItem* aFirst, nsDisplayItem* aSecond)
|
bool IsSameItem(nsDisplayItem* aFirst, nsDisplayItem* aSecond)
|
||||||
@ -205,13 +199,12 @@ void SwapAndRemove(nsTArray<T>& aArray, uint32_t aIndex)
|
|||||||
aArray.RemoveElementAt(aArray.Length() - 1);
|
aArray.RemoveElementAt(aArray.Length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
MergeFrameRects(nsDisplayLayerEventRegions* aOldItem,
|
MergeFrameRects(nsDisplayLayerEventRegions* aOldItem,
|
||||||
nsDisplayLayerEventRegions* aNewItem,
|
nsDisplayLayerEventRegions* aNewItem,
|
||||||
nsDisplayLayerEventRegions::FrameRects nsDisplayLayerEventRegions::*aRectList,
|
nsDisplayLayerEventRegions::FrameRects nsDisplayLayerEventRegions::*aRectList,
|
||||||
nsTArray<nsIFrame*>& aAddedFrames)
|
nsTArray<nsIFrame*>& aAddedFrames)
|
||||||
{
|
{
|
||||||
bool modified = false;
|
|
||||||
// Go through the old item's rect list and remove any rectangles
|
// Go through the old item's rect list and remove any rectangles
|
||||||
// belonging to invalidated frames (deleted frames should
|
// belonging to invalidated frames (deleted frames should
|
||||||
// already be gone at this point)
|
// already be gone at this point)
|
||||||
@ -226,13 +219,12 @@ MergeFrameRects(nsDisplayLayerEventRegions* aOldItem,
|
|||||||
f->RemoveDisplayItem(aOldItem);
|
f->RemoveDisplayItem(aOldItem);
|
||||||
SwapAndRemove(oldRects.mFrames, i);
|
SwapAndRemove(oldRects.mFrames, i);
|
||||||
SwapAndRemove(oldRects.mBoxes, i);
|
SwapAndRemove(oldRects.mBoxes, i);
|
||||||
modified = true;
|
|
||||||
} else {
|
} else {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!aNewItem) {
|
if (!aNewItem) {
|
||||||
return modified;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy items from the source list to the dest list, but
|
// Copy items from the source list to the dest list, but
|
||||||
@ -253,15 +245,12 @@ MergeFrameRects(nsDisplayLayerEventRegions* aOldItem,
|
|||||||
// FrameRects lists, so defer that until the end.
|
// FrameRects lists, so defer that until the end.
|
||||||
aAddedFrames.AppendElement(f);
|
aAddedFrames.AppendElement(f);
|
||||||
MOZ_ASSERT(f != aOldItem->Frame());
|
MOZ_ASSERT(f != aOldItem->Frame());
|
||||||
|
|
||||||
modified = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return modified;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MergeLayerEventRegions(nsDisplayItem* aOldItem,
|
void MergeLayerEventRegions(nsDisplayItem* aOldItem,
|
||||||
nsDisplayItem* aNewItem)
|
nsDisplayItem* aNewItem)
|
||||||
{
|
{
|
||||||
nsDisplayLayerEventRegions* oldItem =
|
nsDisplayLayerEventRegions* oldItem =
|
||||||
@ -271,13 +260,12 @@ bool MergeLayerEventRegions(nsDisplayItem* aOldItem,
|
|||||||
|
|
||||||
nsTArray<nsIFrame*> addedFrames;
|
nsTArray<nsIFrame*> addedFrames;
|
||||||
|
|
||||||
bool modified = false;
|
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mHitRegion, addedFrames);
|
||||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mHitRegion, addedFrames);
|
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mMaybeHitRegion, addedFrames);
|
||||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mMaybeHitRegion, addedFrames);
|
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mDispatchToContentHitRegion, addedFrames);
|
||||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mDispatchToContentHitRegion, addedFrames);
|
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mNoActionRegion, addedFrames);
|
||||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mNoActionRegion, addedFrames);
|
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mHorizontalPanRegion, addedFrames);
|
||||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mHorizontalPanRegion, addedFrames);
|
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mVerticalPanRegion, addedFrames);
|
||||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mVerticalPanRegion, addedFrames);
|
|
||||||
|
|
||||||
// MergeFrameRects deferred updating the display item data list during
|
// MergeFrameRects deferred updating the display item data list during
|
||||||
// processing so that earlier calls didn't change the result of later
|
// processing so that earlier calls didn't change the result of later
|
||||||
@ -287,7 +275,6 @@ bool MergeLayerEventRegions(nsDisplayItem* aOldItem,
|
|||||||
f->AddDisplayItem(aOldItem);
|
f->AddDisplayItem(aOldItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return modified;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -401,14 +388,12 @@ void UpdateASR(nsDisplayItem* aItem,
|
|||||||
*
|
*
|
||||||
* Merged List: C, A, B
|
* Merged List: C, A, B
|
||||||
*/
|
*/
|
||||||
bool
|
void
|
||||||
RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
||||||
nsDisplayList* aOldList,
|
nsDisplayList* aOldList,
|
||||||
nsDisplayList* aOutList,
|
nsDisplayList* aOutList,
|
||||||
Maybe<const ActiveScrolledRoot*>& aOutContainerASR)
|
Maybe<const ActiveScrolledRoot*>& aOutContainerASR)
|
||||||
{
|
{
|
||||||
bool modified = false;
|
|
||||||
|
|
||||||
nsDisplayList merged;
|
nsDisplayList merged;
|
||||||
const auto UseItem = [&](nsDisplayItem* aItem) {
|
const auto UseItem = [&](nsDisplayItem* aItem) {
|
||||||
const ActiveScrolledRoot* itemClipASR =
|
const ActiveScrolledRoot* itemClipASR =
|
||||||
@ -472,11 +457,9 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
|||||||
oldListLookup.Remove({ old->Frame(), old->GetPerFrameKey() });
|
oldListLookup.Remove({ old->Frame(), old->GetPerFrameKey() });
|
||||||
aOldList->RemoveBottom();
|
aOldList->RemoveBottom();
|
||||||
old->Destroy(&mBuilder);
|
old->Destroy(&mBuilder);
|
||||||
modified = true;
|
|
||||||
} else if (newListLookup.Get({ old->Frame(), old->GetPerFrameKey() })) {
|
} else if (newListLookup.Get({ old->Frame(), old->GetPerFrameKey() })) {
|
||||||
// This old item is also in the new list, but we haven't got to it yet.
|
// This old item is also in the new list, but we haven't got to it yet.
|
||||||
// Stop now, and we'll deal with it when we get to the new entry.
|
// Stop now, and we'll deal with it when we get to the new entry.
|
||||||
modified = true;
|
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// Recurse into the child list (without a matching new list) to
|
// Recurse into the child list (without a matching new list) to
|
||||||
@ -484,10 +467,8 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
|||||||
if (old->GetChildren()) {
|
if (old->GetChildren()) {
|
||||||
nsDisplayList empty;
|
nsDisplayList empty;
|
||||||
Maybe<const ActiveScrolledRoot*> containerASRForChildren;
|
Maybe<const ActiveScrolledRoot*> containerASRForChildren;
|
||||||
if (MergeDisplayLists(&empty, old->GetChildren(),
|
MergeDisplayLists(&empty, old->GetChildren(),
|
||||||
old->GetChildren(), containerASRForChildren)) {
|
old->GetChildren(), containerASRForChildren);
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
UpdateASR(old, containerASRForChildren);
|
UpdateASR(old, containerASRForChildren);
|
||||||
old->UpdateBounds(&mBuilder);
|
old->UpdateBounds(&mBuilder);
|
||||||
}
|
}
|
||||||
@ -517,21 +498,16 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
|||||||
// the lists of regions and frames, so we have no need to use the
|
// the lists of regions and frames, so we have no need to use the
|
||||||
// newer item. Always use the old item instead since we assume it's
|
// newer item. Always use the old item instead since we assume it's
|
||||||
// likely to have the bigger lists and merging will be quicker.
|
// likely to have the bigger lists and merging will be quicker.
|
||||||
if (MergeLayerEventRegions(oldItem, newItem)) {
|
MergeLayerEventRegions(oldItem, newItem);
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
ReuseItem(oldItem);
|
ReuseItem(oldItem);
|
||||||
newItem->Destroy(&mBuilder);
|
newItem->Destroy(&mBuilder);
|
||||||
} else {
|
} else {
|
||||||
if (IsAnyAncestorModified(oldItem->FrameForInvalidation())) {
|
if (!IsAnyAncestorModified(oldItem->FrameForInvalidation()) &&
|
||||||
modified = true;
|
oldItem->GetChildren()) {
|
||||||
} else if (oldItem->GetChildren()) {
|
|
||||||
MOZ_ASSERT(newItem->GetChildren());
|
MOZ_ASSERT(newItem->GetChildren());
|
||||||
Maybe<const ActiveScrolledRoot*> containerASRForChildren;
|
Maybe<const ActiveScrolledRoot*> containerASRForChildren;
|
||||||
if (MergeDisplayLists(newItem->GetChildren(), oldItem->GetChildren(),
|
MergeDisplayLists(newItem->GetChildren(), oldItem->GetChildren(),
|
||||||
newItem->GetChildren(), containerASRForChildren)) {
|
newItem->GetChildren(), containerASRForChildren);
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
UpdateASR(newItem, containerASRForChildren);
|
UpdateASR(newItem, containerASRForChildren);
|
||||||
newItem->UpdateBounds(&mBuilder);
|
newItem->UpdateBounds(&mBuilder);
|
||||||
}
|
}
|
||||||
@ -544,7 +520,6 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
|||||||
} else {
|
} else {
|
||||||
// If there was no matching item in the old list, then we only need to
|
// If there was no matching item in the old list, then we only need to
|
||||||
// add the new item to the merged list.
|
// add the new item to the merged list.
|
||||||
modified = true;
|
|
||||||
UseItem(newItem);
|
UseItem(newItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -562,27 +537,21 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
|||||||
nsDisplayList empty;
|
nsDisplayList empty;
|
||||||
Maybe<const ActiveScrolledRoot*> containerASRForChildren;
|
Maybe<const ActiveScrolledRoot*> containerASRForChildren;
|
||||||
|
|
||||||
if (MergeDisplayLists(&empty, old->GetChildren(),
|
MergeDisplayLists(&empty, old->GetChildren(),
|
||||||
old->GetChildren(), containerASRForChildren)) {
|
old->GetChildren(), containerASRForChildren);
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
UpdateASR(old, containerASRForChildren);
|
UpdateASR(old, containerASRForChildren);
|
||||||
old->UpdateBounds(&mBuilder);
|
old->UpdateBounds(&mBuilder);
|
||||||
}
|
}
|
||||||
if (old->GetType() == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
|
if (old->GetType() == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
|
||||||
if (MergeLayerEventRegions(old, nullptr)) {
|
MergeLayerEventRegions(old, nullptr);
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ReuseItem(old);
|
ReuseItem(old);
|
||||||
} else {
|
} else {
|
||||||
old->Destroy(&mBuilder);
|
old->Destroy(&mBuilder);
|
||||||
modified = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aOutList->AppendToTop(&merged);
|
aOutList->AppendToTop(&merged);
|
||||||
return modified;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -766,8 +735,6 @@ ProcessFrame(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
|||||||
{
|
{
|
||||||
nsIFrame* currentFrame = aFrame;
|
nsIFrame* currentFrame = aFrame;
|
||||||
|
|
||||||
aBuilder.MarkFrameForDisplayIfVisible(aFrame, aBuilder.RootReferenceFrame());
|
|
||||||
|
|
||||||
while (currentFrame != aStopAtFrame) {
|
while (currentFrame != aStopAtFrame) {
|
||||||
CRR_LOG("currentFrame: %p (placeholder=%d), aOverflow: %d %d %d %d\n",
|
CRR_LOG("currentFrame: %p (placeholder=%d), aOverflow: %d %d %d %d\n",
|
||||||
currentFrame, !aStopAtStackingContext,
|
currentFrame, !aStopAtStackingContext,
|
||||||
@ -818,10 +785,6 @@ ProcessFrame(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
|||||||
/* aStopAtStackingContextAndDisplayPortAndOOFFrame = */ true,
|
/* aStopAtStackingContextAndDisplayPortAndOOFFrame = */ true,
|
||||||
¤tFrame);
|
¤tFrame);
|
||||||
MOZ_ASSERT(currentFrame);
|
MOZ_ASSERT(currentFrame);
|
||||||
aOverflow.IntersectRect(aOverflow, currentFrame->GetVisualOverflowRectRelativeToSelf());
|
|
||||||
if (aOverflow.IsEmpty()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nsLayoutUtils::FrameHasDisplayPort(currentFrame)) {
|
if (nsLayoutUtils::FrameHasDisplayPort(currentFrame)) {
|
||||||
CRR_LOG("Frame belongs to displayport frame %p\n", currentFrame);
|
CRR_LOG("Frame belongs to displayport frame %p\n", currentFrame);
|
||||||
@ -994,20 +957,18 @@ RetainedDisplayListBuilder::ComputeRebuildRegion(nsTArray<nsIFrame*>& aModifiedF
|
|||||||
ProcessFrame(f, mBuilder, &agr, overflow, mBuilder.RootReferenceFrame(),
|
ProcessFrame(f, mBuilder, &agr, overflow, mBuilder.RootReferenceFrame(),
|
||||||
aOutFramesWithProps, true);
|
aOutFramesWithProps, true);
|
||||||
|
|
||||||
if (!overflow.IsEmpty()) {
|
aOutDirty->UnionRect(*aOutDirty, overflow);
|
||||||
aOutDirty->UnionRect(*aOutDirty, overflow);
|
CRR_LOG("Adding area to root draw area: %d %d %d %d\n",
|
||||||
CRR_LOG("Adding area to root draw area: %d %d %d %d\n",
|
overflow.x, overflow.y, overflow.width, overflow.height);
|
||||||
overflow.x, overflow.y, overflow.width, overflow.height);
|
|
||||||
|
|
||||||
// If we get changed frames from multiple AGRS, then just give up as it gets really complex to
|
// If we get changed frames from multiple AGRS, then just give up as it gets really complex to
|
||||||
// track which items would need to be marked in MarkFramesForDifferentAGR.
|
// track which items would need to be marked in MarkFramesForDifferentAGR.
|
||||||
if (!*aOutModifiedAGR) {
|
if (!*aOutModifiedAGR) {
|
||||||
CRR_LOG("Setting %p as root stacking context AGR\n", agr);
|
CRR_LOG("Setting %p as root stacking context AGR\n", agr);
|
||||||
*aOutModifiedAGR = agr;
|
*aOutModifiedAGR = agr;
|
||||||
} else if (agr && *aOutModifiedAGR != agr) {
|
} else if (agr && *aOutModifiedAGR != agr) {
|
||||||
CRR_LOG("Found multiple AGRs in root stacking context, giving up\n");
|
CRR_LOG("Found multiple AGRs in root stacking context, giving up\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,36 +1021,21 @@ ClearFrameProps(nsTArray<nsIFrame*>& aFrames)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AutoClearFramePropsArray
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AutoClearFramePropsArray() = default;
|
|
||||||
|
|
||||||
~AutoClearFramePropsArray()
|
|
||||||
{
|
|
||||||
ClearFrameProps(mFrames);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsTArray<nsIFrame*>& Frames() { return mFrames; }
|
|
||||||
|
|
||||||
bool IsEmpty() const { return mFrames.IsEmpty(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsTArray<nsIFrame*> mFrames;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RetainedDisplayListBuilder::ClearFramesWithProps()
|
RetainedDisplayListBuilder::ClearFramesWithProps()
|
||||||
{
|
{
|
||||||
AutoClearFramePropsArray modifiedFrames;
|
nsTArray<nsIFrame*> modifiedFrames;
|
||||||
AutoClearFramePropsArray framesWithProps;
|
nsTArray<nsIFrame*> framesWithProps;
|
||||||
GetModifiedAndFramesWithProps(&mBuilder, &modifiedFrames.Frames(), &framesWithProps.Frames());
|
GetModifiedAndFramesWithProps(&mBuilder, &modifiedFrames, &framesWithProps);
|
||||||
|
|
||||||
|
ClearFrameProps(modifiedFrames);
|
||||||
|
ClearFrameProps(framesWithProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto
|
bool
|
||||||
RetainedDisplayListBuilder::AttemptPartialUpdate(
|
RetainedDisplayListBuilder::AttemptPartialUpdate(
|
||||||
nscolor aBackstop,
|
nscolor aBackstop,
|
||||||
mozilla::DisplayListChecker* aChecker) -> PartialUpdateResult
|
mozilla::DisplayListChecker* aChecker)
|
||||||
{
|
{
|
||||||
mBuilder.RemoveModifiedWindowRegions();
|
mBuilder.RemoveModifiedWindowRegions();
|
||||||
mBuilder.ClearWindowOpaqueRegion();
|
mBuilder.ClearWindowOpaqueRegion();
|
||||||
@ -1100,27 +1046,24 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(
|
|||||||
|
|
||||||
mBuilder.EnterPresShell(mBuilder.RootReferenceFrame());
|
mBuilder.EnterPresShell(mBuilder.RootReferenceFrame());
|
||||||
|
|
||||||
// We set the override dirty regions during ComputeRebuildRegion or in
|
nsTArray<nsIFrame*> modifiedFrames;
|
||||||
// nsLayoutUtils::InvalidateForDisplayPortChange. The display port change also
|
nsTArray<nsIFrame*> framesWithProps;
|
||||||
// marks the frame modified, so those regions are cleared here as well.
|
GetModifiedAndFramesWithProps(&mBuilder, &modifiedFrames, &framesWithProps);
|
||||||
AutoClearFramePropsArray modifiedFrames;
|
|
||||||
AutoClearFramePropsArray framesWithProps;
|
|
||||||
GetModifiedAndFramesWithProps(&mBuilder, &modifiedFrames.Frames(), &framesWithProps.Frames());
|
|
||||||
|
|
||||||
// Do not allow partial builds if the retained display list is empty, or if
|
// Do not allow partial builds if the retained display list is empty, or if
|
||||||
// ShouldBuildPartial heuristic fails.
|
// ShouldBuildPartial heuristic fails.
|
||||||
const bool shouldBuildPartial = !mList.IsEmpty() && ShouldBuildPartial(modifiedFrames.Frames());
|
const bool shouldBuildPartial = !mList.IsEmpty() && ShouldBuildPartial(modifiedFrames);
|
||||||
|
|
||||||
if (mPreviousCaret != mBuilder.GetCaretFrame()) {
|
if (mPreviousCaret != mBuilder.GetCaretFrame()) {
|
||||||
if (mPreviousCaret) {
|
if (mPreviousCaret) {
|
||||||
if (mBuilder.MarkFrameModifiedDuringBuilding(mPreviousCaret)) {
|
if (mBuilder.MarkFrameModifiedDuringBuilding(mPreviousCaret)) {
|
||||||
modifiedFrames.Frames().AppendElement(mPreviousCaret);
|
modifiedFrames.AppendElement(mPreviousCaret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mBuilder.GetCaretFrame()) {
|
if (mBuilder.GetCaretFrame()) {
|
||||||
if (mBuilder.MarkFrameModifiedDuringBuilding(mBuilder.GetCaretFrame())) {
|
if (mBuilder.MarkFrameModifiedDuringBuilding(mBuilder.GetCaretFrame())) {
|
||||||
modifiedFrames.Frames().AppendElement(mBuilder.GetCaretFrame());
|
modifiedFrames.AppendElement(mBuilder.GetCaretFrame());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1129,60 +1072,61 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(
|
|||||||
|
|
||||||
nsRect modifiedDirty;
|
nsRect modifiedDirty;
|
||||||
AnimatedGeometryRoot* modifiedAGR = nullptr;
|
AnimatedGeometryRoot* modifiedAGR = nullptr;
|
||||||
if (!shouldBuildPartial ||
|
bool merged = false;
|
||||||
!ComputeRebuildRegion(modifiedFrames.Frames(), &modifiedDirty,
|
if (shouldBuildPartial &&
|
||||||
&modifiedAGR, framesWithProps.Frames())) {
|
ComputeRebuildRegion(modifiedFrames, &modifiedDirty,
|
||||||
mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), &mList);
|
&modifiedAGR, framesWithProps)) {
|
||||||
return PartialUpdateResult::Failed;
|
modifiedDirty.IntersectRect(modifiedDirty, mBuilder.RootReferenceFrame()->GetVisualOverflowRectRelativeToSelf());
|
||||||
|
|
||||||
|
PreProcessDisplayList(&mList, modifiedAGR);
|
||||||
|
|
||||||
|
nsDisplayList modifiedDL;
|
||||||
|
if (!modifiedDirty.IsEmpty() || !framesWithProps.IsEmpty()) {
|
||||||
|
mBuilder.SetDirtyRect(modifiedDirty);
|
||||||
|
mBuilder.SetPartialUpdate(true);
|
||||||
|
mBuilder.RootReferenceFrame()->BuildDisplayListForStackingContext(&mBuilder, &modifiedDL);
|
||||||
|
nsLayoutUtils::AddExtraBackgroundItems(mBuilder, modifiedDL, mBuilder.RootReferenceFrame(),
|
||||||
|
nsRect(nsPoint(0, 0), mBuilder.RootReferenceFrame()->GetSize()),
|
||||||
|
mBuilder.RootReferenceFrame()->GetVisualOverflowRectRelativeToSelf(),
|
||||||
|
aBackstop);
|
||||||
|
mBuilder.SetPartialUpdate(false);
|
||||||
|
|
||||||
|
//printf_stderr("Painting --- Modified list (dirty %d,%d,%d,%d):\n",
|
||||||
|
// modifiedDirty.x, modifiedDirty.y, modifiedDirty.width, modifiedDirty.height);
|
||||||
|
//nsFrame::PrintDisplayList(&mBuilder, modifiedDL);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// TODO: We can also skip layer building and painting if
|
||||||
|
// PreProcessDisplayList didn't end up changing anything
|
||||||
|
// Invariant: display items should have their original state here.
|
||||||
|
// printf_stderr("Skipping display list building since nothing needed to be done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aChecker) {
|
||||||
|
aChecker->Set(&modifiedDL, "TM");
|
||||||
|
}
|
||||||
|
|
||||||
|
// |modifiedDL| can sometimes be empty here. We still perform the
|
||||||
|
// display list merging to prune unused items (for example, items that
|
||||||
|
// are not visible anymore) from the old list.
|
||||||
|
// TODO: Optimization opportunity. In this case, MergeDisplayLists()
|
||||||
|
// unnecessarily creates a hashtable of the old items.
|
||||||
|
Maybe<const ActiveScrolledRoot*> dummy;
|
||||||
|
MergeDisplayLists(&modifiedDL, &mList, &mList, dummy);
|
||||||
|
|
||||||
|
//printf_stderr("Painting --- Merged list:\n");
|
||||||
|
//nsFrame::PrintDisplayList(&mBuilder, mList);
|
||||||
|
|
||||||
|
merged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifiedDirty.IntersectRect(modifiedDirty, mBuilder.RootReferenceFrame()->GetVisualOverflowRectRelativeToSelf());
|
|
||||||
|
|
||||||
PartialUpdateResult result = PartialUpdateResult::NoChange;
|
|
||||||
if (PreProcessDisplayList(&mList, modifiedAGR) ||
|
|
||||||
!modifiedDirty.IsEmpty() ||
|
|
||||||
!framesWithProps.IsEmpty()) {
|
|
||||||
result = PartialUpdateResult::Updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
mBuilder.SetDirtyRect(modifiedDirty);
|
|
||||||
mBuilder.SetPartialUpdate(true);
|
|
||||||
|
|
||||||
nsDisplayList modifiedDL;
|
|
||||||
mBuilder.RootReferenceFrame()->BuildDisplayListForStackingContext(&mBuilder, &modifiedDL);
|
|
||||||
if (!modifiedDL.IsEmpty()) {
|
|
||||||
nsLayoutUtils::AddExtraBackgroundItems(mBuilder, modifiedDL, mBuilder.RootReferenceFrame(),
|
|
||||||
nsRect(nsPoint(0, 0), mBuilder.RootReferenceFrame()->GetSize()),
|
|
||||||
mBuilder.RootReferenceFrame()->GetVisualOverflowRectRelativeToSelf(),
|
|
||||||
aBackstop);
|
|
||||||
}
|
|
||||||
mBuilder.SetPartialUpdate(false);
|
|
||||||
|
|
||||||
if (aChecker) {
|
|
||||||
aChecker->Set(&modifiedDL, "TM");
|
|
||||||
}
|
|
||||||
|
|
||||||
//printf_stderr("Painting --- Modified list (dirty %d,%d,%d,%d):\n",
|
|
||||||
// modifiedDirty.x, modifiedDirty.y, modifiedDirty.width, modifiedDirty.height);
|
|
||||||
//nsFrame::PrintDisplayList(&mBuilder, modifiedDL);
|
|
||||||
|
|
||||||
// |modifiedDL| can sometimes be empty here. We still perform the
|
|
||||||
// display list merging to prune unused items (for example, items that
|
|
||||||
// are not visible anymore) from the old list.
|
|
||||||
// TODO: Optimization opportunity. In this case, MergeDisplayLists()
|
|
||||||
// unnecessarily creates a hashtable of the old items.
|
|
||||||
// TODO: Ideally we could skip this if result is NoChange, but currently when
|
|
||||||
// we call RestoreState on nsDisplayWrapList it resets the clip to the base
|
|
||||||
// clip, and we need the UpdateBounds call (within MergeDisplayLists) to
|
|
||||||
// move it to the correct inner clip.
|
|
||||||
Maybe<const ActiveScrolledRoot*> dummy;
|
|
||||||
if (MergeDisplayLists(&modifiedDL, &mList, &mList, dummy)) {
|
|
||||||
result = PartialUpdateResult::Updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
//printf_stderr("Painting --- Merged list:\n");
|
|
||||||
//nsFrame::PrintDisplayList(&mBuilder, mList);
|
|
||||||
|
|
||||||
mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), &mList);
|
mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), &mList);
|
||||||
return result;
|
|
||||||
|
// We set the override dirty regions during ComputeRebuildRegion or in
|
||||||
|
// nsLayoutUtils::InvalidateForDisplayPortChange. The display port change also
|
||||||
|
// marks the frame modified, so those regions are cleared here as well.
|
||||||
|
ClearFrameProps(modifiedFrames);
|
||||||
|
ClearFrameProps(framesWithProps);
|
||||||
|
|
||||||
|
return merged;
|
||||||
}
|
}
|
||||||
|
@ -29,14 +29,8 @@ struct RetainedDisplayListBuilder {
|
|||||||
|
|
||||||
nsDisplayList* List() { return &mList; }
|
nsDisplayList* List() { return &mList; }
|
||||||
|
|
||||||
enum class PartialUpdateResult {
|
bool AttemptPartialUpdate(nscolor aBackstop,
|
||||||
Failed,
|
mozilla::DisplayListChecker* aChecker);
|
||||||
NoChange,
|
|
||||||
Updated
|
|
||||||
};
|
|
||||||
|
|
||||||
PartialUpdateResult AttemptPartialUpdate(nscolor aBackstop,
|
|
||||||
mozilla::DisplayListChecker* aChecker);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterates through the display list builder reference frame document and
|
* Iterates through the display list builder reference frame document and
|
||||||
@ -49,9 +43,9 @@ struct RetainedDisplayListBuilder {
|
|||||||
NS_DECLARE_FRAME_PROPERTY_DELETABLE(Cached, RetainedDisplayListBuilder)
|
NS_DECLARE_FRAME_PROPERTY_DELETABLE(Cached, RetainedDisplayListBuilder)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool PreProcessDisplayList(nsDisplayList* aList, AnimatedGeometryRoot* aAGR);
|
void PreProcessDisplayList(nsDisplayList* aList, AnimatedGeometryRoot* aAGR);
|
||||||
|
|
||||||
bool MergeDisplayLists(nsDisplayList* aNewList,
|
void MergeDisplayLists(nsDisplayList* aNewList,
|
||||||
nsDisplayList* aOldList,
|
nsDisplayList* aOldList,
|
||||||
nsDisplayList* aOutList,
|
nsDisplayList* aOutList,
|
||||||
mozilla::Maybe<const mozilla::ActiveScrolledRoot*>& aOutContainerASR);
|
mozilla::Maybe<const mozilla::ActiveScrolledRoot*>& aOutContainerASR);
|
||||||
|
@ -54,7 +54,7 @@ DECLARE_DISPLAY_ITEM_TYPE(SELECTION_OVERLAY, TYPE_RENDERS_NO_IMAGES)
|
|||||||
DECLARE_DISPLAY_ITEM_TYPE(SOLID_COLOR, TYPE_RENDERS_NO_IMAGES)
|
DECLARE_DISPLAY_ITEM_TYPE(SOLID_COLOR, TYPE_RENDERS_NO_IMAGES)
|
||||||
DECLARE_DISPLAY_ITEM_TYPE(SOLID_COLOR_REGION, TYPE_RENDERS_NO_IMAGES)
|
DECLARE_DISPLAY_ITEM_TYPE(SOLID_COLOR_REGION, TYPE_RENDERS_NO_IMAGES)
|
||||||
DECLARE_DISPLAY_ITEM_TYPE(SUBDOCUMENT, TYPE_RENDERS_NO_IMAGES)
|
DECLARE_DISPLAY_ITEM_TYPE(SUBDOCUMENT, TYPE_RENDERS_NO_IMAGES)
|
||||||
DECLARE_DISPLAY_ITEM_TYPE(MASK, 0)
|
DECLARE_DISPLAY_ITEM_TYPE(MASK, TYPE_RENDERS_NO_IMAGES)
|
||||||
DECLARE_DISPLAY_ITEM_TYPE(FILTER, TYPE_RENDERS_NO_IMAGES)
|
DECLARE_DISPLAY_ITEM_TYPE(FILTER, TYPE_RENDERS_NO_IMAGES)
|
||||||
DECLARE_DISPLAY_ITEM_TYPE(SVG_OUTER_SVG, TYPE_RENDERS_NO_IMAGES)
|
DECLARE_DISPLAY_ITEM_TYPE(SVG_OUTER_SVG, TYPE_RENDERS_NO_IMAGES)
|
||||||
DECLARE_DISPLAY_ITEM_TYPE(SVG_GEOMETRY, 0)
|
DECLARE_DISPLAY_ITEM_TYPE(SVG_GEOMETRY, 0)
|
||||||
|
@ -2504,100 +2504,6 @@ nsDisplayListBuilder::GetWidgetLayerManager(nsView** aView)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameLayerBuilder*
|
|
||||||
nsDisplayList::BuildLayers(nsDisplayListBuilder* aBuilder,
|
|
||||||
LayerManager* aLayerManager,
|
|
||||||
uint32_t aFlags,
|
|
||||||
bool aIsWidgetTransaction)
|
|
||||||
{
|
|
||||||
nsIFrame* frame = aBuilder->RootReferenceFrame();
|
|
||||||
nsPresContext* presContext = frame->PresContext();
|
|
||||||
nsIPresShell* presShell = presContext->PresShell();
|
|
||||||
|
|
||||||
FrameLayerBuilder *layerBuilder = new FrameLayerBuilder();
|
|
||||||
layerBuilder->Init(aBuilder, aLayerManager);
|
|
||||||
|
|
||||||
if (aFlags & PAINT_COMPRESSED) {
|
|
||||||
layerBuilder->SetLayerTreeCompressionMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
RefPtr<ContainerLayer> root;
|
|
||||||
{
|
|
||||||
AUTO_PROFILER_TRACING("Paint", "LayerBuilding");
|
|
||||||
|
|
||||||
if (XRE_IsContentProcess() && gfxPrefs::AlwaysPaint()) {
|
|
||||||
FrameLayerBuilder::InvalidateAllLayers(aLayerManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aIsWidgetTransaction) {
|
|
||||||
layerBuilder->DidBeginRetainedLayerTransaction(aLayerManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear any ScrollMetadata that may have been set on the root layer on a
|
|
||||||
// previous paint. This paint will set new metrics if necessary, and if we
|
|
||||||
// don't clear the old one here, we may be left with extra metrics.
|
|
||||||
if (Layer* rootLayer = aLayerManager->GetRoot()) {
|
|
||||||
rootLayer->SetScrollMetadata(nsTArray<ScrollMetadata>());
|
|
||||||
}
|
|
||||||
|
|
||||||
ContainerLayerParameters containerParameters
|
|
||||||
(presShell->GetResolution(), presShell->GetResolution());
|
|
||||||
|
|
||||||
{
|
|
||||||
PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::Layerization);
|
|
||||||
|
|
||||||
root = layerBuilder->
|
|
||||||
BuildContainerLayerFor(aBuilder, aLayerManager, frame, nullptr, this,
|
|
||||||
containerParameters, nullptr);
|
|
||||||
|
|
||||||
if (!record.GetStart().IsNull() && gfxPrefs::LayersDrawFPS()) {
|
|
||||||
if (PaintTiming* pt = ClientLayerManager::MaybeGetPaintTiming(aLayerManager)) {
|
|
||||||
pt->flbMs() = (TimeStamp::Now() - record.GetStart()).ToMilliseconds();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!root) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
// Root is being scaled up by the X/Y resolution. Scale it back down.
|
|
||||||
root->SetPostScale(1.0f/containerParameters.mXScale,
|
|
||||||
1.0f/containerParameters.mYScale);
|
|
||||||
root->SetScaleToResolution(presShell->ScaleToResolution(),
|
|
||||||
containerParameters.mXScale);
|
|
||||||
|
|
||||||
auto callback = [root](FrameMetrics::ViewID aScrollId) -> bool {
|
|
||||||
return nsLayoutUtils::ContainsMetricsWithId(root, aScrollId);
|
|
||||||
};
|
|
||||||
if (Maybe<ScrollMetadata> rootMetadata = nsLayoutUtils::GetRootMetadata(
|
|
||||||
aBuilder, root->Manager(), containerParameters, callback)) {
|
|
||||||
root->SetScrollMetadata(rootMetadata.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
// NS_WARNING is debug-only, so don't even bother checking the conditions in
|
|
||||||
// a release build.
|
|
||||||
#ifdef DEBUG
|
|
||||||
bool usingDisplayport = false;
|
|
||||||
if (nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame()) {
|
|
||||||
nsIContent* content = rootScrollFrame->GetContent();
|
|
||||||
if (content) {
|
|
||||||
usingDisplayport = nsLayoutUtils::HasDisplayPort(content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (usingDisplayport &&
|
|
||||||
!(root->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
|
|
||||||
SpammyLayoutWarningsEnabled()) {
|
|
||||||
// See bug 693938, attachment 567017
|
|
||||||
NS_WARNING("Transparent content with displayports can be expensive.");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
aLayerManager->SetRoot(root);
|
|
||||||
layerBuilder->WillEndTransaction();
|
|
||||||
}
|
|
||||||
return layerBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We paint by executing a layer manager transaction, constructing a
|
* We paint by executing a layer manager transaction, constructing a
|
||||||
* single layer representing the display list, and then making it the
|
* single layer representing the display list, and then making it the
|
||||||
@ -2690,25 +2596,119 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
|
|||||||
presContext->MayHavePaintEventListenerInSubDocument() ? nsPresContext::NotifySubDocInvalidation : 0;
|
presContext->MayHavePaintEventListenerInSubDocument() ? nsPresContext::NotifySubDocInvalidation : 0;
|
||||||
|
|
||||||
UniquePtr<LayerProperties> props;
|
UniquePtr<LayerProperties> props;
|
||||||
|
RefPtr<ContainerLayer> root;
|
||||||
|
|
||||||
bool computeInvalidRect = (computeInvalidFunc ||
|
// Store the existing layer builder to reinstate it on return.
|
||||||
(!layerManager->IsCompositingCheap() && layerManager->NeedsWidgetInvalidation())) &&
|
FrameLayerBuilder *oldBuilder = layerManager->GetLayerBuilder();
|
||||||
widgetTransaction;
|
|
||||||
|
|
||||||
if (computeInvalidRect) {
|
FrameLayerBuilder *layerBuilder = new FrameLayerBuilder();
|
||||||
props = Move(LayerProperties::CloneFrom(layerManager->GetRoot()));
|
layerBuilder->Init(aBuilder, layerManager);
|
||||||
|
|
||||||
|
if (aFlags & PAINT_COMPRESSED) {
|
||||||
|
layerBuilder->SetLayerTreeCompressionMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doBeginTransaction) {
|
{
|
||||||
if (aCtx) {
|
AUTO_PROFILER_TRACING("Paint", "LayerBuilding");
|
||||||
if (!layerManager->BeginTransactionWithTarget(aCtx)) {
|
|
||||||
return nullptr;
|
if (doBeginTransaction) {
|
||||||
}
|
if (aCtx) {
|
||||||
} else {
|
if (!layerManager->BeginTransactionWithTarget(aCtx)) {
|
||||||
if (!layerManager->BeginTransaction()) {
|
return nullptr;
|
||||||
return nullptr;
|
}
|
||||||
|
} else {
|
||||||
|
if (!layerManager->BeginTransaction()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (XRE_IsContentProcess() && gfxPrefs::AlwaysPaint()) {
|
||||||
|
FrameLayerBuilder::InvalidateAllLayers(layerManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widgetTransaction) {
|
||||||
|
layerBuilder->DidBeginRetainedLayerTransaction(layerManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool computeInvalidRect = (computeInvalidFunc ||
|
||||||
|
(!layerManager->IsCompositingCheap() && layerManager->NeedsWidgetInvalidation())) &&
|
||||||
|
widgetTransaction;
|
||||||
|
|
||||||
|
if (computeInvalidRect) {
|
||||||
|
props = Move(LayerProperties::CloneFrom(layerManager->GetRoot()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear any ScrollMetadata that may have been set on the root layer on a
|
||||||
|
// previous paint. This paint will set new metrics if necessary, and if we
|
||||||
|
// don't clear the old one here, we may be left with extra metrics.
|
||||||
|
if (Layer* rootLayer = layerManager->GetRoot()) {
|
||||||
|
rootLayer->SetScrollMetadata(nsTArray<ScrollMetadata>());
|
||||||
|
}
|
||||||
|
|
||||||
|
ContainerLayerParameters containerParameters
|
||||||
|
(presShell->GetResolution(), presShell->GetResolution());
|
||||||
|
|
||||||
|
{
|
||||||
|
PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::Layerization);
|
||||||
|
|
||||||
|
root = layerBuilder->
|
||||||
|
BuildContainerLayerFor(aBuilder, layerManager, frame, nullptr, this,
|
||||||
|
containerParameters, nullptr);
|
||||||
|
|
||||||
|
if (!record.GetStart().IsNull() && gfxPrefs::LayersDrawFPS()) {
|
||||||
|
if (PaintTiming* pt = ClientLayerManager::MaybeGetPaintTiming(layerManager)) {
|
||||||
|
pt->flbMs() = (TimeStamp::Now() - record.GetStart()).ToMilliseconds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!root) {
|
||||||
|
layerManager->SetUserData(&gLayerManagerLayerBuilder, oldBuilder);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
// Root is being scaled up by the X/Y resolution. Scale it back down.
|
||||||
|
root->SetPostScale(1.0f/containerParameters.mXScale,
|
||||||
|
1.0f/containerParameters.mYScale);
|
||||||
|
root->SetScaleToResolution(presShell->ScaleToResolution(),
|
||||||
|
containerParameters.mXScale);
|
||||||
|
|
||||||
|
auto callback = [root](FrameMetrics::ViewID aScrollId) -> bool {
|
||||||
|
return nsLayoutUtils::ContainsMetricsWithId(root, aScrollId);
|
||||||
|
};
|
||||||
|
if (Maybe<ScrollMetadata> rootMetadata = nsLayoutUtils::GetRootMetadata(
|
||||||
|
aBuilder, root->Manager(), containerParameters, callback)) {
|
||||||
|
root->SetScrollMetadata(rootMetadata.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// NS_WARNING is debug-only, so don't even bother checking the conditions in
|
||||||
|
// a release build.
|
||||||
|
#ifdef DEBUG
|
||||||
|
bool usingDisplayport = false;
|
||||||
|
if (nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame()) {
|
||||||
|
nsIContent* content = rootScrollFrame->GetContent();
|
||||||
|
if (content) {
|
||||||
|
usingDisplayport = nsLayoutUtils::HasDisplayPort(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (usingDisplayport &&
|
||||||
|
!(root->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
|
||||||
|
SpammyLayoutWarningsEnabled()) {
|
||||||
|
// See bug 693938, attachment 567017
|
||||||
|
NS_WARNING("Transparent content with displayports can be expensive.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
layerManager->SetRoot(root);
|
||||||
|
layerBuilder->WillEndTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widgetTransaction ||
|
||||||
|
// SVG-as-an-image docs don't paint as part of the retained layer tree,
|
||||||
|
// but they still need the invalidation state bits cleared in order for
|
||||||
|
// invalidation for CSS/SMIL animation to work properly.
|
||||||
|
(document && document->IsBeingUsedAsImage())) {
|
||||||
|
frame->ClearInvalidationStateBits();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool temp = aBuilder->SetIsCompositingCheap(layerManager->IsCompositingCheap());
|
bool temp = aBuilder->SetIsCompositingCheap(layerManager->IsCompositingCheap());
|
||||||
@ -2725,53 +2725,25 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is the content process, we ship plugin geometry updates over with layer
|
||||||
|
// updates, so calculate that now before we call EndTransaction.
|
||||||
|
nsRootPresContext* rootPresContext = presContext->GetRootPresContext();
|
||||||
|
if (rootPresContext && XRE_IsContentProcess()) {
|
||||||
|
if (aBuilder->WillComputePluginGeometry()) {
|
||||||
|
rootPresContext->ComputePluginGeometryUpdates(aBuilder->RootReferenceFrame(), aBuilder, this);
|
||||||
|
}
|
||||||
|
// The layer system caches plugin configuration information for forwarding
|
||||||
|
// with layer updates which needs to get set during reflow. This must be
|
||||||
|
// called even if there are no windowed plugins in the page.
|
||||||
|
rootPresContext->CollectPluginGeometryUpdates(layerManager);
|
||||||
|
}
|
||||||
|
|
||||||
MaybeSetupTransactionIdAllocator(layerManager, presContext);
|
MaybeSetupTransactionIdAllocator(layerManager, presContext);
|
||||||
|
|
||||||
// Store the existing layer builder to reinstate it on return.
|
layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer,
|
||||||
FrameLayerBuilder *oldBuilder = layerManager->GetLayerBuilder();
|
aBuilder, flags);
|
||||||
FrameLayerBuilder *layerBuilder = nullptr;
|
|
||||||
|
|
||||||
bool sent = false;
|
|
||||||
if (aFlags & PAINT_IDENTICAL_DISPLAY_LIST) {
|
|
||||||
sent = layerManager->EndEmptyTransaction(flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sent) {
|
|
||||||
layerBuilder = BuildLayers(aBuilder, layerManager,
|
|
||||||
aFlags, widgetTransaction);
|
|
||||||
|
|
||||||
if (!layerBuilder) {
|
|
||||||
layerManager->SetUserData(&gLayerManagerLayerBuilder, oldBuilder);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is the content process, we ship plugin geometry updates over with layer
|
|
||||||
// updates, so calculate that now before we call EndTransaction.
|
|
||||||
nsRootPresContext* rootPresContext = presContext->GetRootPresContext();
|
|
||||||
if (rootPresContext && XRE_IsContentProcess()) {
|
|
||||||
if (aBuilder->WillComputePluginGeometry()) {
|
|
||||||
rootPresContext->ComputePluginGeometryUpdates(aBuilder->RootReferenceFrame(), aBuilder, this);
|
|
||||||
}
|
|
||||||
// The layer system caches plugin configuration information for forwarding
|
|
||||||
// with layer updates which needs to get set during reflow. This must be
|
|
||||||
// called even if there are no windowed plugins in the page.
|
|
||||||
rootPresContext->CollectPluginGeometryUpdates(layerManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer,
|
|
||||||
aBuilder, flags);
|
|
||||||
layerBuilder->DidEndTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (widgetTransaction ||
|
|
||||||
// SVG-as-an-image docs don't paint as part of the retained layer tree,
|
|
||||||
// but they still need the invalidation state bits cleared in order for
|
|
||||||
// invalidation for CSS/SMIL animation to work properly.
|
|
||||||
(document && document->IsBeingUsedAsImage())) {
|
|
||||||
frame->ClearInvalidationStateBits();
|
|
||||||
}
|
|
||||||
|
|
||||||
aBuilder->SetIsCompositingCheap(temp);
|
aBuilder->SetIsCompositingCheap(temp);
|
||||||
|
layerBuilder->DidEndTransaction();
|
||||||
|
|
||||||
if (document && widgetTransaction) {
|
if (document && widgetTransaction) {
|
||||||
TriggerPendingAnimations(document, layerManager->GetAnimationReadyTime());
|
TriggerPendingAnimations(document, layerManager->GetAnimationReadyTime());
|
||||||
@ -2780,11 +2752,11 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
|
|||||||
nsIntRegion invalid;
|
nsIntRegion invalid;
|
||||||
bool areaOverflowed = false;
|
bool areaOverflowed = false;
|
||||||
if (props) {
|
if (props) {
|
||||||
if (!props->ComputeDifferences(layerManager->GetRoot(), invalid, computeInvalidFunc)) {
|
if (!props->ComputeDifferences(root, invalid, computeInvalidFunc)) {
|
||||||
areaOverflowed = true;
|
areaOverflowed = true;
|
||||||
}
|
}
|
||||||
} else if (widgetTransaction) {
|
} else if (widgetTransaction) {
|
||||||
LayerProperties::ClearInvalidations(layerManager->GetRoot());
|
LayerProperties::ClearInvalidations(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldInvalidate = layerManager->NeedsWidgetInvalidation();
|
bool shouldInvalidate = layerManager->NeedsWidgetInvalidation();
|
||||||
|
@ -3090,17 +3090,11 @@ public:
|
|||||||
PAINT_USE_WIDGET_LAYERS = 0x01,
|
PAINT_USE_WIDGET_LAYERS = 0x01,
|
||||||
PAINT_EXISTING_TRANSACTION = 0x04,
|
PAINT_EXISTING_TRANSACTION = 0x04,
|
||||||
PAINT_NO_COMPOSITE = 0x08,
|
PAINT_NO_COMPOSITE = 0x08,
|
||||||
PAINT_COMPRESSED = 0x10,
|
PAINT_COMPRESSED = 0x10
|
||||||
PAINT_IDENTICAL_DISPLAY_LIST = 0x20
|
|
||||||
};
|
};
|
||||||
already_AddRefed<LayerManager> PaintRoot(nsDisplayListBuilder* aBuilder,
|
already_AddRefed<LayerManager> PaintRoot(nsDisplayListBuilder* aBuilder,
|
||||||
gfxContext* aCtx,
|
gfxContext* aCtx,
|
||||||
uint32_t aFlags);
|
uint32_t aFlags);
|
||||||
|
|
||||||
mozilla::FrameLayerBuilder* BuildLayers(nsDisplayListBuilder* aBuilder,
|
|
||||||
LayerManager* aLayerManager,
|
|
||||||
uint32_t aFlags,
|
|
||||||
bool aIsWidgetTransaction);
|
|
||||||
/**
|
/**
|
||||||
* Get the bounds. Takes the union of the bounds of all children.
|
* Get the bounds. Takes the union of the bounds of all children.
|
||||||
* The result is not cached.
|
* The result is not cached.
|
||||||
@ -4787,7 +4781,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool MergeLayerEventRegions(nsDisplayItem*, nsDisplayItem*);
|
friend void MergeLayerEventRegions(nsDisplayItem*, nsDisplayItem*);
|
||||||
|
|
||||||
// Relative to aFrame's reference frame.
|
// Relative to aFrame's reference frame.
|
||||||
// These are the points that are definitely in the hit region.
|
// These are the points that are definitely in the hit region.
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<body>
|
|
||||||
<div style="opacity:0.5" id="hi">
|
|
||||||
<div style="position:fixed; width:200px; height:200px; background-color:blue"></div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,20 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" class="reftest-wait">
|
|
||||||
<body>
|
|
||||||
<div style="opacity:0.5" id="hi">
|
|
||||||
<div style="position:fixed; width:200px; height:200px; background-color:blue"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
function doTest()
|
|
||||||
{
|
|
||||||
var opacityElement = document.getElementById("hi");
|
|
||||||
opacityElement.style.left = '100px';
|
|
||||||
document.documentElement.removeAttribute("class");
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("MozReftestInvalidate", doTest);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -19,5 +19,5 @@ skip-if(Android) == 1428993-1.html 1428993-1-ref.html
|
|||||||
needs-focus == 1429027-1.html 1429027-1-ref.html
|
needs-focus == 1429027-1.html 1429027-1-ref.html
|
||||||
== 1432553-1.html 1432553-1-ref.html
|
== 1432553-1.html 1432553-1-ref.html
|
||||||
== 1432553-2.html 1432553-2-ref.html
|
== 1432553-2.html 1432553-2-ref.html
|
||||||
== 1436189-1.html 1436189-1-ref.html
|
|
||||||
== 1420480-1.html 1420480-1-ref.html
|
== 1420480-1.html 1420480-1-ref.html
|
||||||
|
|
||||||
|
@ -2292,8 +2292,8 @@ HttpChannelParent::UpdateAndSerializeSecurityInfo(nsACString& aSerializedSecurit
|
|||||||
bool
|
bool
|
||||||
HttpChannelParent::DoSendDeleteSelf()
|
HttpChannelParent::DoSendDeleteSelf()
|
||||||
{
|
{
|
||||||
mIPCClosed = true;
|
|
||||||
bool rv = SendDeleteSelf();
|
bool rv = SendDeleteSelf();
|
||||||
|
mIPCClosed = true;
|
||||||
|
|
||||||
CleanupBackgroundChannel();
|
CleanupBackgroundChannel();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user