mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
merge mozilla-central to autoland
This commit is contained in:
commit
e6123cd888
@ -28,6 +28,7 @@ skip-if = !e10s # Pref and test only relevant for e10s.
|
||||
[browser_positional_attributes.js]
|
||||
[browser_preloadedBrowser_zoom.js]
|
||||
[browser_reload_deleted_file.js]
|
||||
skip-if = (debug && os == 'mac') || (debug && os == 'linux' && bits == 64) #Bug 1421183, disabled on Linux/OSX for leaked windows
|
||||
[browser_tabswitch_updatecommands.js]
|
||||
[browser_viewsource_of_data_URI_in_file_process.js]
|
||||
[browser_visibleTabs_bookmarkAllTabs.js]
|
||||
|
@ -162,6 +162,7 @@ skip-if = !e10s
|
||||
[browser_ext_tabs_hide.js]
|
||||
[browser_ext_tabs_insertCSS.js]
|
||||
[browser_ext_tabs_lastAccessed.js]
|
||||
skip-if = os == 'win' # Bug 1434590
|
||||
[browser_ext_tabs_lazy.js]
|
||||
[browser_ext_tabs_removeCSS.js]
|
||||
[browser_ext_tabs_move_array.js]
|
||||
|
@ -339,14 +339,6 @@ public:
|
||||
virtual void StorePluginWidgetConfigurations(const nsTArray<nsIWidget::Configuration>& aConfigurations) {}
|
||||
bool IsSnappingEffectiveTransforms() { return mSnapEffectiveTransforms; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the layer manager can't render component alpha
|
||||
* layers, and layer building should do it's best to avoid
|
||||
* creating them.
|
||||
*/
|
||||
virtual bool ShouldAvoidComponentAlphaLayers() { return false; }
|
||||
|
||||
/**
|
||||
* Returns true if this LayerManager can properly support layers with
|
||||
* SurfaceMode::SURFACE_COMPONENT_ALPHA. LayerManagers that can't will use
|
||||
|
@ -106,8 +106,6 @@ public:
|
||||
virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags = END_DEFAULT) override;
|
||||
virtual bool ShouldAvoidComponentAlphaLayers() override { return IsWidgetLayerManager(); }
|
||||
|
||||
void AbortTransaction();
|
||||
|
||||
virtual void SetRoot(Layer* aLayer) override;
|
||||
|
@ -176,9 +176,6 @@ public:
|
||||
|
||||
virtual CompositorBridgeChild* GetCompositorBridgeChild() override;
|
||||
|
||||
// Disable component alpha layers with the software compositor.
|
||||
virtual bool ShouldAvoidComponentAlphaLayers() override { return !IsCompositingCheap(); }
|
||||
|
||||
bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; }
|
||||
#ifdef DEBUG
|
||||
bool InDrawing() { return mPhase == PHASE_DRAWING; }
|
||||
|
@ -1788,28 +1788,6 @@ PresShell::Initialize(nscoord aWidth, nscoord aHeight)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsIFrame* invalidateFrame = nullptr;
|
||||
for (nsIFrame* f = rootFrame; f; f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
|
||||
if (f->GetStateBits() & NS_FRAME_NO_COMPONENT_ALPHA) {
|
||||
invalidateFrame = f;
|
||||
f->RemoveStateBits(NS_FRAME_NO_COMPONENT_ALPHA);
|
||||
}
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
if (f->IsSubDocumentFrame() &&
|
||||
(shell = static_cast<nsSubDocumentFrame*>(f)
|
||||
->GetSubdocumentPresShellForPainting(0)) &&
|
||||
shell->GetPresContext()->IsRootContentDocument()) {
|
||||
// Root content documents build a 'force active' layer, and component alpha flattening
|
||||
// can't be propagated across that so no need to invalidate above this frame.
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (invalidateFrame) {
|
||||
invalidateFrame->InvalidateFrameSubtree();
|
||||
}
|
||||
|
||||
Element *root = mDocument->GetRootElement();
|
||||
|
||||
if (root) {
|
||||
|
@ -3634,7 +3634,6 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
||||
PaintFrameFlags aFlags)
|
||||
{
|
||||
AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame", GRAPHICS);
|
||||
typedef RetainedDisplayListBuilder::PartialUpdateResult PartialUpdateResult;
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (!gPaintCountStack) {
|
||||
@ -3792,7 +3791,6 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
||||
}
|
||||
|
||||
nsRect visibleRect = visibleRegion.GetBounds();
|
||||
PartialUpdateResult updateState = PartialUpdateResult::Failed;
|
||||
|
||||
{
|
||||
AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame:BuildDisplayList",
|
||||
@ -3842,20 +3840,22 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
||||
// Attempt to do a partial build and merge into the existing list.
|
||||
// This calls BuildDisplayListForStacking context on a subset of the
|
||||
// viewport.
|
||||
bool merged = false;
|
||||
|
||||
if (useRetainedBuilder) {
|
||||
if (gfxPrefs::LayoutVerifyRetainDisplayList()) {
|
||||
beforeMergeChecker.Set(&list, "BM");
|
||||
}
|
||||
updateState = retainedBuilder->AttemptPartialUpdate(
|
||||
merged = retainedBuilder->AttemptPartialUpdate(
|
||||
aBackstop, beforeMergeChecker ? &toBeMergedChecker : nullptr);
|
||||
if ((updateState != PartialUpdateResult::Failed) && beforeMergeChecker) {
|
||||
if (merged && beforeMergeChecker) {
|
||||
afterMergeChecker.Set(&list, "AM");
|
||||
}
|
||||
}
|
||||
|
||||
if ((updateState != PartialUpdateResult::Failed) &&
|
||||
if (merged &&
|
||||
(gfxPrefs::LayoutDisplayListBuildTwice() || afterMergeChecker)) {
|
||||
updateState = PartialUpdateResult::Failed;
|
||||
merged = false;
|
||||
if (gfxPrefs::LayersDrawFPS()) {
|
||||
if (RefPtr<LayerManager> lm = builder.GetWidgetLayerManager()) {
|
||||
if (PaintTiming* pt = ClientLayerManager::MaybeGetPaintTiming(lm)) {
|
||||
@ -3866,7 +3866,7 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
||||
dlStart = TimeStamp::Now();
|
||||
}
|
||||
|
||||
if (updateState == PartialUpdateResult::Failed) {
|
||||
if (!merged) {
|
||||
list.DeleteAll(&builder);
|
||||
builder.EnterPresShell(aFrame);
|
||||
builder.SetDirtyRect(visibleRect);
|
||||
@ -3875,7 +3875,6 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
||||
AddExtraBackgroundItems(builder, list, aFrame, canvasArea, visibleRegion, aBackstop);
|
||||
|
||||
builder.LeavePresShell(aFrame, &list);
|
||||
updateState = PartialUpdateResult::Updated;
|
||||
|
||||
if (afterMergeChecker) {
|
||||
DisplayListChecker nonRetainedChecker(&list, "NR");
|
||||
@ -3913,7 +3912,6 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(updateState != PartialUpdateResult::Failed);
|
||||
builder.Check();
|
||||
|
||||
Telemetry::AccumulateTimeDelta(Telemetry::PAINT_BUILD_DISPLAYLIST_TIME,
|
||||
@ -3988,9 +3986,6 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
||||
if (aFlags & PaintFrameFlags::PAINT_COMPRESSED) {
|
||||
flags |= nsDisplayList::PAINT_COMPRESSED;
|
||||
}
|
||||
if (updateState == PartialUpdateResult::NoChange) {
|
||||
flags |= nsDisplayList::PAINT_IDENTICAL_DISPLAY_LIST;
|
||||
}
|
||||
|
||||
TimeStamp paintStart = TimeStamp::Now();
|
||||
RefPtr<LayerManager> layerManager
|
||||
|
@ -194,7 +194,7 @@ nsPresContext::MakeColorPref(const nsString& aColor)
|
||||
bool
|
||||
nsPresContext::IsDOMPaintEventPending()
|
||||
{
|
||||
if (!mTransactions.IsEmpty()) {
|
||||
if (mFireAfterPaintEvents) {
|
||||
return true;
|
||||
}
|
||||
nsRootPresContext* drpc = GetRootPresContext();
|
||||
@ -203,6 +203,7 @@ nsPresContext::IsDOMPaintEventPending()
|
||||
// fired, we record an empty invalidation in case display list
|
||||
// invalidation doesn't invalidate anything further.
|
||||
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 false;
|
||||
@ -314,6 +315,7 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
|
||||
mFontFeatureValuesDirty(true),
|
||||
mSuppressResizeReflow(false),
|
||||
mIsVisual(false),
|
||||
mFireAfterPaintEvents(false),
|
||||
mIsChrome(false),
|
||||
mIsChromeOriginImage(false),
|
||||
mPaintFlashing(false),
|
||||
@ -2581,17 +2583,6 @@ nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsIntRect& aRec
|
||||
NotifyInvalidation(aTransactionId, rect);
|
||||
}
|
||||
|
||||
nsPresContext::TransactionInvalidations*
|
||||
nsPresContext::GetInvalidations(uint64_t aTransactionId)
|
||||
{
|
||||
for (TransactionInvalidations& t : mTransactions) {
|
||||
if (t.mTransactionId == aTransactionId) {
|
||||
return &t;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect)
|
||||
{
|
||||
@ -2605,13 +2596,9 @@ nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect)
|
||||
|
||||
nsPresContext* pc;
|
||||
for (pc = this; pc; pc = pc->GetParentPresContext()) {
|
||||
TransactionInvalidations* transaction = pc->GetInvalidations(aTransactionId);
|
||||
if (transaction) {
|
||||
if (pc->mFireAfterPaintEvents)
|
||||
break;
|
||||
} else {
|
||||
transaction = pc->mTransactions.AppendElement();
|
||||
transaction->mTransactionId = aTransactionId;
|
||||
}
|
||||
pc->mFireAfterPaintEvents = true;
|
||||
}
|
||||
if (!pc) {
|
||||
nsRootPresContext* rpc = GetRootPresContext();
|
||||
@ -2620,8 +2607,18 @@ nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect)
|
||||
}
|
||||
}
|
||||
|
||||
TransactionInvalidations* transaction = GetInvalidations(aTransactionId);
|
||||
MOZ_ASSERT(transaction);
|
||||
TransactionInvalidations* transaction = nullptr;
|
||||
for (TransactionInvalidations& t : mTransactions) {
|
||||
if (t.mTransactionId == aTransactionId) {
|
||||
transaction = &t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!transaction) {
|
||||
transaction = mTransactions.AppendElement();
|
||||
transaction->mTransactionId = aTransactionId;
|
||||
}
|
||||
|
||||
transaction->mInvalidations.AppendElement(aRect);
|
||||
}
|
||||
|
||||
@ -2673,6 +2670,7 @@ nsPresContext::ClearNotifySubDocInvalidationData(ContainerLayer* aContainer)
|
||||
struct NotifyDidPaintSubdocumentCallbackClosure {
|
||||
uint64_t mTransactionId;
|
||||
const mozilla::TimeStamp& mTimeStamp;
|
||||
bool mNeedsAnotherDidPaintNotification;
|
||||
};
|
||||
/* static */ bool
|
||||
nsPresContext::NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData)
|
||||
@ -2685,6 +2683,9 @@ nsPresContext::NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* a
|
||||
if (pc) {
|
||||
pc->NotifyDidPaintForSubtree(closure->mTransactionId,
|
||||
closure->mTimeStamp);
|
||||
if (pc->mFireAfterPaintEvents) {
|
||||
closure->mNeedsAnotherDidPaintNotification = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -2729,12 +2730,12 @@ nsPresContext::NotifyDidPaintForSubtree(uint64_t aTransactionId,
|
||||
if (IsRoot()) {
|
||||
static_cast<nsRootPresContext*>(this)->CancelDidPaintTimers(aTransactionId);
|
||||
|
||||
if (mTransactions.IsEmpty()) {
|
||||
if (!mFireAfterPaintEvents) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PresShell()->IsVisible() && mTransactions.IsEmpty()) {
|
||||
if (!PresShell()->IsVisible() && !mFireAfterPaintEvents) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2748,13 +2749,11 @@ nsPresContext::NotifyDidPaintForSubtree(uint64_t aTransactionId,
|
||||
uint32_t i = 0;
|
||||
while (i < mTransactions.Length()) {
|
||||
if (mTransactions[i].mTransactionId <= aTransactionId) {
|
||||
if (!mTransactions[i].mInvalidations.IsEmpty()) {
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new DelayedFireDOMPaintEvent(this, &mTransactions[i].mInvalidations,
|
||||
mTransactions[i].mTransactionId, aTimeStamp);
|
||||
nsContentUtils::AddScriptRunner(ev);
|
||||
sent = true;
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new DelayedFireDOMPaintEvent(this, &mTransactions[i].mInvalidations,
|
||||
mTransactions[i].mTransactionId, aTimeStamp);
|
||||
nsContentUtils::AddScriptRunner(ev);
|
||||
sent = true;
|
||||
mTransactions.RemoveElementAt(i);
|
||||
} else {
|
||||
i++;
|
||||
@ -2769,8 +2768,14 @@ nsPresContext::NotifyDidPaintForSubtree(uint64_t aTransactionId,
|
||||
nsContentUtils::AddScriptRunner(ev);
|
||||
}
|
||||
|
||||
NotifyDidPaintSubdocumentCallbackClosure closure = { aTransactionId, aTimeStamp };
|
||||
NotifyDidPaintSubdocumentCallbackClosure closure = { aTransactionId, aTimeStamp, false };
|
||||
mDocument->EnumerateSubDocuments(nsPresContext::NotifyDidPaintSubdocumentCallback, &closure);
|
||||
|
||||
if (!closure.mNeedsAnotherDidPaintNotification &&
|
||||
mTransactions.IsEmpty()) {
|
||||
// Nothing more to do for the moment.
|
||||
mFireAfterPaintEvents = false;
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsITimer>
|
||||
|
@ -1288,12 +1288,6 @@ protected:
|
||||
const char* aName,
|
||||
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
|
||||
// has been explicitly checked. If you add any members to this class,
|
||||
// please make the ownership explicit (pinkerton, scc).
|
||||
@ -1362,6 +1356,10 @@ protected:
|
||||
|
||||
mozilla::UniquePtr<nsBidi> mBidiEngine;
|
||||
|
||||
struct TransactionInvalidations {
|
||||
uint64_t mTransactionId;
|
||||
nsTArray<nsRect> mInvalidations;
|
||||
};
|
||||
AutoTArray<TransactionInvalidations, 4> mTransactions;
|
||||
|
||||
// text performance metrics
|
||||
@ -1488,6 +1486,8 @@ protected:
|
||||
|
||||
unsigned mIsVisual : 1;
|
||||
|
||||
unsigned mFireAfterPaintEvents : 1;
|
||||
|
||||
unsigned mIsChrome : 1;
|
||||
unsigned mIsChromeOriginImage : 1;
|
||||
|
||||
|
@ -351,16 +351,6 @@ nsDisplayCanvasBackgroundColor::WriteDebugInfo(std::stringstream& aStream)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
static void BlitSurface(DrawTarget* aDest, const gfxRect& aRect, DrawTarget* aSource)
|
||||
{
|
||||
RefPtr<SourceSurface> source = aSource->Snapshot();
|
||||
aDest->DrawSurface(source,
|
||||
Rect(aRect.x, aRect.y, aRect.width, aRect.height),
|
||||
Rect(0, 0, aRect.width, aRect.height));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
|
||||
gfxContext* aCtx)
|
||||
@ -369,39 +359,6 @@ nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsPoint offset = ToReferenceFrame();
|
||||
nsRect bgClipRect = frame->CanvasArea() + offset;
|
||||
|
||||
#ifndef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
RefPtr<gfxContext> dest = aCtx;
|
||||
gfxRect destRect;
|
||||
if (IsSingleFixedPositionImage(aBuilder, bgClipRect, &destRect) &&
|
||||
aBuilder->IsPaintingToWindow() && !aBuilder->IsCompositingCheap() &&
|
||||
!dest->CurrentMatrix().HasNonIntegerTranslation()) {
|
||||
// Snap image rectangle to nearest pixel boundaries. This is the right way
|
||||
// to snap for this context, because we checked HasNonIntegerTranslation
|
||||
// above.
|
||||
destRect.Round();
|
||||
RefPtr<DrawTarget> dt =
|
||||
Frame()->GetProperty(nsIFrame::CachedBackgroundImageDT());
|
||||
DrawTarget* destDT = dest->GetDrawTarget();
|
||||
if (dt) {
|
||||
BlitSurface(destDT, destRect, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
dt = destDT->CreateSimilarRasterTarget(IntSize::Ceil(destRect.width,
|
||||
destRect.height),
|
||||
SurfaceFormat::B8G8R8A8);
|
||||
if (dt && dt->IsValid()) {
|
||||
RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(dt);
|
||||
MOZ_ASSERT(ctx); // already checked draw target above
|
||||
ctx->SetMatrix(ctx->CurrentMatrix().PreTranslate(-destRect.x, -destRect.y));
|
||||
PaintInternal(aBuilder, ctx, bgClipRect, &bgClipRect);
|
||||
BlitSurface(dest->GetDrawTarget(), destRect, dt);
|
||||
frame->SetProperty(nsIFrame::CachedBackgroundImageDT(),
|
||||
dt.forget().take());
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
PaintInternal(aBuilder, aCtx, mVisibleRect, &bgClipRect);
|
||||
}
|
||||
|
||||
@ -546,8 +503,7 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const ActiveScrolledRoot* thisItemASR = asr;
|
||||
nsDisplayList thisItemList;
|
||||
nsDisplayBackgroundImage::InitData bgData =
|
||||
nsDisplayBackgroundImage::GetInitData(aBuilder, this, i, bgRect, bg,
|
||||
nsDisplayBackgroundImage::LayerizeFixed::ALWAYS_LAYERIZE_FIXED_BACKGROUND);
|
||||
nsDisplayBackgroundImage::GetInitData(aBuilder, this, i, bgRect, bg);
|
||||
|
||||
if (bgData.shouldFixToViewport) {
|
||||
|
||||
|
@ -197,11 +197,6 @@ public:
|
||||
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
|
||||
|
||||
virtual void NotifyRenderingChanged() const override
|
||||
{
|
||||
mFrame->DeleteProperty(nsIFrame::CachedBackgroundImageDT());
|
||||
}
|
||||
|
||||
// We still need to paint a background color as well as an image for this item,
|
||||
// so we can't support this yet.
|
||||
virtual bool SupportsOptimizingToImage() const override { return false; }
|
||||
|
@ -227,10 +227,7 @@ FRAME_STATE_BIT(Generic, 43, NS_FRAME_SVG_LAYOUT)
|
||||
// Is this frame allowed to have generated (::before/::after) content?
|
||||
FRAME_STATE_BIT(Generic, 44, NS_FRAME_MAY_HAVE_GENERATED_CONTENT)
|
||||
|
||||
// This bit is set on frames that create ContainerLayers with component
|
||||
// alpha children. With BasicLayers we avoid creating these, so we mark
|
||||
// the frames for future reference.
|
||||
FRAME_STATE_BIT(Generic, 45, NS_FRAME_NO_COMPONENT_ALPHA)
|
||||
// Bit 45 is currently unused.
|
||||
|
||||
// This bit indicates that we're tracking visibility for this frame, and that
|
||||
// the frame has a VisibilityStateProperty property.
|
||||
@ -290,6 +287,8 @@ FRAME_STATE_BIT(Generic, 59, NS_FRAME_IS_IN_SINGLE_CHAR_MI)
|
||||
// NOTE: Bits 20-31 and 60-63 of the frame state are reserved for specific
|
||||
// frame classes.
|
||||
|
||||
// NOTE: Bit 45 is currently unused and available.
|
||||
|
||||
|
||||
// == Frame state bits that apply to box frames ===============================
|
||||
|
||||
|
@ -1250,8 +1250,6 @@ public:
|
||||
// or height), imposed by its flex container.
|
||||
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(FlexItemMainSizeOverride, nscoord)
|
||||
|
||||
NS_DECLARE_FRAME_PROPERTY_RELEASABLE(CachedBackgroundImageDT, DrawTarget)
|
||||
|
||||
NS_DECLARE_FRAME_PROPERTY_DELETABLE(InvalidationRect, nsRect)
|
||||
|
||||
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(RefusedAsyncAnimationProperty, bool)
|
||||
|
@ -124,8 +124,6 @@ FrameLayerBuilder::FrameLayerBuilder()
|
||||
, mInvalidateAllLayers(false)
|
||||
, mInLayerTreeCompressionMode(false)
|
||||
, mIsInactiveLayerManager(false)
|
||||
, mContainerLayerGeneration(0)
|
||||
, mMaxContainerLayerGeneration(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(FrameLayerBuilder);
|
||||
}
|
||||
@ -146,6 +144,7 @@ DisplayItemData::DisplayItemData(LayerManagerData* aParent, uint32_t aKey,
|
||||
, mItem(nullptr)
|
||||
, mUsed(true)
|
||||
, mIsInvalid(false)
|
||||
, mReusedItem(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(DisplayItemData);
|
||||
|
||||
@ -187,9 +186,10 @@ void
|
||||
DisplayItemData::EndUpdate()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mLayer);
|
||||
MOZ_ASSERT(!mItem);
|
||||
mItem = nullptr;
|
||||
mIsInvalid = false;
|
||||
mUsed = false;
|
||||
mReusedItem = false;
|
||||
}
|
||||
|
||||
void
|
||||
@ -211,7 +211,6 @@ DisplayItemData::EndUpdate(nsAutoPtr<nsDisplayItemGeometry> aGeometry)
|
||||
|
||||
void
|
||||
DisplayItemData::BeginUpdate(Layer* aLayer, LayerState aState,
|
||||
uint32_t aContainerLayerGeneration,
|
||||
nsDisplayItem* aItem /* = nullptr */)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mLayer);
|
||||
@ -220,11 +219,11 @@ DisplayItemData::BeginUpdate(Layer* aLayer, LayerState aState,
|
||||
mOptLayer = nullptr;
|
||||
mInactiveManager = nullptr;
|
||||
mLayerState = aState;
|
||||
mContainerLayerGeneration = aContainerLayerGeneration;
|
||||
mUsed = true;
|
||||
|
||||
if (aLayer->AsPaintedLayer()) {
|
||||
mItem = aItem;
|
||||
mReusedItem = aItem->IsReused();
|
||||
}
|
||||
|
||||
if (!aItem) {
|
||||
@ -1064,7 +1063,6 @@ public:
|
||||
const nsRect& aContainerBounds,
|
||||
ContainerLayer* aContainerLayer,
|
||||
const ContainerLayerParameters& aParameters,
|
||||
bool aFlattenToSingleLayer,
|
||||
nscolor aBackgroundColor,
|
||||
const ActiveScrolledRoot* aContainerASR,
|
||||
const ActiveScrolledRoot* aContainerScrollMetadataASR,
|
||||
@ -1079,7 +1077,6 @@ public:
|
||||
mContainerCompositorASR(aContainerCompositorASR),
|
||||
mParameters(aParameters),
|
||||
mPaintedLayerDataTree(*this, aBackgroundColor),
|
||||
mFlattenToSingleLayer(aFlattenToSingleLayer),
|
||||
mLastDisplayPortAGR(nullptr)
|
||||
{
|
||||
nsPresContext* presContext = aContainerFrame->PresContext();
|
||||
@ -1118,7 +1115,7 @@ public:
|
||||
*/
|
||||
void Finish(uint32_t *aTextContentFlags,
|
||||
const nsIntRect& aContainerPixelBounds,
|
||||
nsDisplayList* aChildItems, bool* aHasComponentAlphaChildren);
|
||||
nsDisplayList* aChildItems);
|
||||
|
||||
nscoord GetAppUnitsPerDevPixel() { return mAppUnitsPerDevPixel; }
|
||||
|
||||
@ -1406,10 +1403,6 @@ protected:
|
||||
const Maybe<size_t>& aForAncestorMaskLayer,
|
||||
uint32_t aRoundedRectClipCount = UINT32_MAX);
|
||||
|
||||
bool ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
|
||||
AnimatedGeometryRoot** aAnimatedGeometryRoot,
|
||||
const ActiveScrolledRoot** aASR);
|
||||
|
||||
/**
|
||||
* Get the display port for an AGR.
|
||||
* The result would be cached for later reusing.
|
||||
@ -1461,7 +1454,6 @@ protected:
|
||||
nsTHashtable<nsRefPtrHashKey<PaintedLayer>> mPaintedLayersAvailableForRecycling;
|
||||
nscoord mAppUnitsPerDevPixel;
|
||||
bool mSnappingEnabled;
|
||||
bool mFlattenToSingleLayer;
|
||||
|
||||
struct MaskLayerKey {
|
||||
MaskLayerKey() : mLayer(nullptr) {}
|
||||
@ -3825,32 +3817,6 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Chooses a single active scrolled root for the entire display list, used
|
||||
* when we are flattening layers.
|
||||
*/
|
||||
bool
|
||||
ContainerState::ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
|
||||
AnimatedGeometryRoot** aAnimatedGeometryRoot,
|
||||
const ActiveScrolledRoot** aASR)
|
||||
{
|
||||
for (nsDisplayItem* item = aList.GetBottom(); item; item = item->GetAbove()) {
|
||||
LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
|
||||
// Don't use an item that won't be part of any PaintedLayers to pick the
|
||||
// active scrolled root.
|
||||
if (layerState == LAYER_ACTIVE_FORCE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try using the actual active scrolled root of the backmost item, as that
|
||||
// should result in the least invalidation when scrolling.
|
||||
*aAnimatedGeometryRoot = item->GetAnimatedGeometryRoot();
|
||||
*aASR = item->GetActiveScrolledRoot();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRect
|
||||
ContainerState::GetDisplayPortForAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot)
|
||||
{
|
||||
@ -4068,20 +4034,8 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
{
|
||||
AUTO_PROFILER_LABEL("ContainerState::ProcessDisplayItems", GRAPHICS);
|
||||
|
||||
AnimatedGeometryRoot* lastAnimatedGeometryRoot = mContainerAnimatedGeometryRoot;
|
||||
const ActiveScrolledRoot* lastASR = mContainerASR;
|
||||
nsPoint lastAGRTopLeft;
|
||||
nsPoint topLeft(0,0);
|
||||
|
||||
// When NO_COMPONENT_ALPHA is set, items will be flattened into a single
|
||||
// layer, so we need to choose which active scrolled root to use for all
|
||||
// items.
|
||||
if (mFlattenToSingleLayer) {
|
||||
if (ChooseAnimatedGeometryRoot(*aList, &lastAnimatedGeometryRoot, &lastASR)) {
|
||||
lastAGRTopLeft = (*lastAnimatedGeometryRoot)->GetOffsetToCrossDoc(mContainerReferenceFrame);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t maxLayers = gfxPrefs::MaxActiveLayers();
|
||||
int layerCount = 0;
|
||||
|
||||
@ -4090,6 +4044,8 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
bool hadCompositorHitTestInfo = false;
|
||||
#endif
|
||||
|
||||
AnimatedGeometryRoot* lastAnimatedGeometryRoot = nullptr;
|
||||
nsPoint lastTopLeft;
|
||||
FlattenedDisplayItemIterator iter(mBuilder, aList);
|
||||
while (nsDisplayItem* i = iter.GetNext()) {
|
||||
nsDisplayItem* item = i;
|
||||
@ -4171,37 +4127,34 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
layerState = LAYER_ACTIVE;
|
||||
}
|
||||
|
||||
bool forceInactive;
|
||||
bool forceInactive = false;
|
||||
AnimatedGeometryRoot* animatedGeometryRoot;
|
||||
const ActiveScrolledRoot* itemASR = nullptr;
|
||||
const DisplayItemClipChain* layerClipChain = nullptr;
|
||||
if (mFlattenToSingleLayer && layerState != LAYER_ACTIVE_FORCE) {
|
||||
forceInactive = true;
|
||||
animatedGeometryRoot = lastAnimatedGeometryRoot;
|
||||
itemASR = lastASR;
|
||||
topLeft = lastAGRTopLeft;
|
||||
item->FuseClipChainUpTo(mBuilder, mContainerASR);
|
||||
} else {
|
||||
forceInactive = false;
|
||||
if (mManager->IsWidgetLayerManager()) {
|
||||
animatedGeometryRoot = item->GetAnimatedGeometryRoot();
|
||||
itemASR = item->GetActiveScrolledRoot();
|
||||
const DisplayItemClipChain* itemClipChain = item->GetClipChain();
|
||||
if (itemClipChain && itemClipChain->mASR == itemASR &&
|
||||
itemType != DisplayItemType::TYPE_STICKY_POSITION) {
|
||||
layerClipChain = itemClipChain->mParent;
|
||||
} else {
|
||||
layerClipChain = itemClipChain;
|
||||
}
|
||||
|
||||
if (mManager->IsWidgetLayerManager()) {
|
||||
animatedGeometryRoot = item->GetAnimatedGeometryRoot();
|
||||
itemASR = item->GetActiveScrolledRoot();
|
||||
const DisplayItemClipChain* itemClipChain = item->GetClipChain();
|
||||
if (itemClipChain && itemClipChain->mASR == itemASR &&
|
||||
itemType != DisplayItemType::TYPE_STICKY_POSITION) {
|
||||
layerClipChain = itemClipChain->mParent;
|
||||
} else {
|
||||
// For inactive layer subtrees, splitting content into PaintedLayers
|
||||
// based on animated geometry roots is pointless. It's more efficient
|
||||
// to build the minimum number of layers.
|
||||
animatedGeometryRoot = mContainerAnimatedGeometryRoot;
|
||||
itemASR = mContainerASR;
|
||||
item->FuseClipChainUpTo(mBuilder, mContainerASR);
|
||||
layerClipChain = itemClipChain;
|
||||
}
|
||||
topLeft = (*animatedGeometryRoot)->GetOffsetToCrossDoc(mContainerReferenceFrame);
|
||||
} else {
|
||||
// For inactive layer subtrees, splitting content into PaintedLayers
|
||||
// based on animated geometry roots is pointless. It's more efficient
|
||||
// to build the minimum number of layers.
|
||||
animatedGeometryRoot = mContainerAnimatedGeometryRoot;
|
||||
itemASR = mContainerASR;
|
||||
item->FuseClipChainUpTo(mBuilder, mContainerASR);
|
||||
}
|
||||
if (animatedGeometryRoot == lastAnimatedGeometryRoot) {
|
||||
topLeft = lastTopLeft;
|
||||
} else {
|
||||
lastTopLeft = topLeft = (*animatedGeometryRoot)->GetOffsetToCrossDoc(mContainerReferenceFrame);
|
||||
lastAnimatedGeometryRoot = animatedGeometryRoot;
|
||||
}
|
||||
|
||||
const ActiveScrolledRoot* scrollMetadataASR =
|
||||
@ -4662,7 +4615,6 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
|
||||
// Clear the old geometry so that invalidation thinks the item has been
|
||||
// added this paint.
|
||||
aData->mGeometry = nullptr;
|
||||
aItem->NotifyRenderingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4683,8 +4635,8 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
|
||||
// for this item (if it was an active layer), then we can't skip this
|
||||
// yet.
|
||||
nsAutoPtr<nsDisplayItemGeometry> geometry;
|
||||
if (item->IsReused() && aData->mGeometry) {
|
||||
aData->EndUpdate(geometry);
|
||||
if (aData->mReusedItem && aData->mGeometry) {
|
||||
aData->EndUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4699,7 +4651,6 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
|
||||
// If we do get an invalid rect, then we want to add this on top of the change areas.
|
||||
nsRect invalid;
|
||||
nsRegion combined;
|
||||
bool notifyRenderingChanged = true;
|
||||
if (!aData->mGeometry) {
|
||||
// This item is being added for the first time, invalidate its entire area.
|
||||
geometry = item->AllocateGeometry(mDisplayListBuilder);
|
||||
@ -4728,24 +4679,12 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
|
||||
aData->mGeometry->MoveBy(shift);
|
||||
item->ComputeInvalidationRegion(mDisplayListBuilder, aData->mGeometry, &combined);
|
||||
|
||||
// We have an optimization to cache the drawing of background-attachment: fixed canvas
|
||||
// background images so we can scroll and just blit them when they are flattened into
|
||||
// the same layer as scrolling content. NotifyRenderingChanged is only used to tell
|
||||
// the canvas bg image item to purge this cache. We want to be careful not to accidentally
|
||||
// purge the cache if we are just invalidating due to scrolling (ie the background image
|
||||
// moves on the scrolling layer but it's rendering stays the same) so if
|
||||
// AddOffsetAndComputeDifference is the only thing that will invalidate we skip the
|
||||
// NotifyRenderingChanged call (ComputeInvalidationRegion for background images also calls
|
||||
// NotifyRenderingChanged if anything changes).
|
||||
// Only allocate a new geometry object if something actually changed, otherwise the existing
|
||||
// one should be fine. We always reallocate for inactive layers, since these types don't
|
||||
// implement ComputeInvalidateRegion (and rely on the ComputeDifferences call in
|
||||
// AddPaintedDisplayItem instead).
|
||||
if (!combined.IsEmpty() || aData->mLayerState == LAYER_INACTIVE) {
|
||||
geometry = item->AllocateGeometry(mDisplayListBuilder);
|
||||
} else if (aData->mClip == clip && invalid.IsEmpty() &&
|
||||
changedFrameInvalidations.IsEmpty() == 0) {
|
||||
notifyRenderingChanged = false;
|
||||
}
|
||||
PaintedLayerItemsEntry* entry = mPaintedLayerItems.GetEntry(paintedLayer);
|
||||
aData->mClip.AddOffsetAndComputeDifference(entry->mCommonClipCount,
|
||||
@ -4773,9 +4712,6 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
|
||||
#endif
|
||||
}
|
||||
if (!combined.IsEmpty()) {
|
||||
if (notifyRenderingChanged) {
|
||||
item->NotifyRenderingChanged();
|
||||
}
|
||||
InvalidatePostTransformRegion(paintedLayer,
|
||||
combined.ScaleToOutsidePixels(layerData->mXScale, layerData->mYScale, layerData->mAppUnitsPerDevPixel),
|
||||
layerData->mTranslation);
|
||||
@ -4829,9 +4765,6 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
||||
PaintedLayerItemsEntry* entry = mPaintedLayerItems.PutEntry(layer);
|
||||
if (entry) {
|
||||
entry->mContainerLayerFrame = aContainerState.GetContainerFrame();
|
||||
if (entry->mContainerLayerGeneration == 0) {
|
||||
entry->mContainerLayerGeneration = mContainerLayerGeneration;
|
||||
}
|
||||
if (tempManager) {
|
||||
FLB_LOG_PAINTED_LAYER_DECISION(aLayerData, "Creating nested FLB for item %p\n", aItem);
|
||||
FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
|
||||
@ -4925,8 +4858,7 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
||||
}
|
||||
}
|
||||
ClippedDisplayItem* cdi =
|
||||
entry->mItems.AppendElement(ClippedDisplayItem(aItem,
|
||||
mContainerLayerGeneration));
|
||||
entry->mItems.AppendElement(ClippedDisplayItem(aItem));
|
||||
cdi->mInactiveLayerManager = tempManager;
|
||||
}
|
||||
}
|
||||
@ -4937,7 +4869,7 @@ FrameLayerBuilder::StoreDataForFrame(nsDisplayItem* aItem, Layer* aLayer,
|
||||
{
|
||||
if (aData) {
|
||||
if (!aData->mUsed) {
|
||||
aData->BeginUpdate(aLayer, aState, mContainerLayerGeneration, aItem);
|
||||
aData->BeginUpdate(aLayer, aState, aItem);
|
||||
}
|
||||
return aData;
|
||||
}
|
||||
@ -4948,7 +4880,7 @@ FrameLayerBuilder::StoreDataForFrame(nsDisplayItem* aItem, Layer* aLayer,
|
||||
RefPtr<DisplayItemData> data =
|
||||
new (aItem->Frame()->PresContext()) DisplayItemData(lmd, aItem->GetPerFrameKey(), aLayer);
|
||||
|
||||
data->BeginUpdate(aLayer, aState, mContainerLayerGeneration, aItem);
|
||||
data->BeginUpdate(aLayer, aState, aItem);
|
||||
|
||||
lmd->mDisplayItems.PutEntry(data);
|
||||
return data;
|
||||
@ -4962,7 +4894,7 @@ FrameLayerBuilder::StoreDataForFrame(nsIFrame* aFrame,
|
||||
{
|
||||
DisplayItemData* oldData = GetDisplayItemData(aFrame, aDisplayItemKey);
|
||||
if (oldData && oldData->mFrameList.Length() == 1) {
|
||||
oldData->BeginUpdate(aLayer, aState, mContainerLayerGeneration);
|
||||
oldData->BeginUpdate(aLayer, aState);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4972,15 +4904,13 @@ FrameLayerBuilder::StoreDataForFrame(nsIFrame* aFrame,
|
||||
RefPtr<DisplayItemData> data =
|
||||
new (aFrame->PresContext()) DisplayItemData(lmd, aDisplayItemKey, aLayer, aFrame);
|
||||
|
||||
data->BeginUpdate(aLayer, aState, mContainerLayerGeneration);
|
||||
data->BeginUpdate(aLayer, aState);
|
||||
|
||||
lmd->mDisplayItems.PutEntry(data);
|
||||
}
|
||||
|
||||
FrameLayerBuilder::ClippedDisplayItem::ClippedDisplayItem(nsDisplayItem* aItem,
|
||||
uint32_t aGeneration)
|
||||
FrameLayerBuilder::ClippedDisplayItem::ClippedDisplayItem(nsDisplayItem* aItem)
|
||||
: mItem(aItem)
|
||||
, mContainerLayerGeneration(aGeneration)
|
||||
{
|
||||
}
|
||||
|
||||
@ -4995,7 +4925,6 @@ FrameLayerBuilder::PaintedLayerItemsEntry::PaintedLayerItemsEntry(const PaintedL
|
||||
: nsPtrHashKey<PaintedLayer>(aKey)
|
||||
, mContainerLayerFrame(nullptr)
|
||||
, mLastCommonClipCount(0)
|
||||
, mContainerLayerGeneration(0)
|
||||
, mHasExplicitLastPaintOffset(false)
|
||||
, mCommonClipCount(0)
|
||||
{
|
||||
@ -5031,9 +4960,6 @@ FrameLayerBuilder::GetLastPaintOffset(PaintedLayer* aLayer)
|
||||
{
|
||||
PaintedLayerItemsEntry* entry = mPaintedLayerItems.PutEntry(aLayer);
|
||||
if (entry) {
|
||||
if (entry->mContainerLayerGeneration == 0) {
|
||||
entry->mContainerLayerGeneration = mContainerLayerGeneration;
|
||||
}
|
||||
if (entry->mHasExplicitLastPaintOffset)
|
||||
return entry->mLastPaintOffset;
|
||||
}
|
||||
@ -5045,9 +4971,6 @@ FrameLayerBuilder::SavePreviousDataForLayer(PaintedLayer* aLayer, uint32_t aClip
|
||||
{
|
||||
PaintedLayerItemsEntry* entry = mPaintedLayerItems.PutEntry(aLayer);
|
||||
if (entry) {
|
||||
if (entry->mContainerLayerGeneration == 0) {
|
||||
entry->mContainerLayerGeneration = mContainerLayerGeneration;
|
||||
}
|
||||
entry->mLastPaintOffset = GetTranslationForPaintedLayer(aLayer);
|
||||
entry->mHasExplicitLastPaintOffset = true;
|
||||
entry->mLastCommonClipCount = aClipCount;
|
||||
@ -5195,12 +5118,6 @@ FixUpFixedPositionLayer(Layer* aLayer,
|
||||
void
|
||||
ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
|
||||
{
|
||||
if (mFlattenToSingleLayer) {
|
||||
// animated geometry roots are forced to all match, so we can't
|
||||
// use them and we don't get async scrolling.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mBuilder->IsPaintingToWindow()) {
|
||||
// async scrolling not possible, and async scrolling info not computed
|
||||
// for this paint.
|
||||
@ -5408,7 +5325,7 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer
|
||||
void
|
||||
ContainerState::Finish(uint32_t* aTextContentFlags,
|
||||
const nsIntRect& aContainerPixelBounds,
|
||||
nsDisplayList* aChildItems, bool* aHasComponentAlphaChildren)
|
||||
nsDisplayList* aChildItems)
|
||||
{
|
||||
mPaintedLayerDataTree.Finish();
|
||||
|
||||
@ -5445,24 +5362,6 @@ ContainerState::Finish(uint32_t* aTextContentFlags,
|
||||
layer->GetContentFlags() & (Layer::CONTENT_COMPONENT_ALPHA |
|
||||
Layer::CONTENT_COMPONENT_ALPHA_DESCENDANT |
|
||||
Layer::CONTENT_DISABLE_FLATTENING);
|
||||
|
||||
// Notify the parent of component alpha children unless it's coming from
|
||||
// within a child that has asked not to contribute to layer flattening.
|
||||
if (aHasComponentAlphaChildren &&
|
||||
mNewChildLayers[i].mPropagateComponentAlphaFlattening &&
|
||||
(layer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA)) {
|
||||
|
||||
for (int32_t j = i - 1; j >= 0; j--) {
|
||||
if (mNewChildLayers[j].mVisibleRegion.Intersects(mNewChildLayers[i].mVisibleRegion.GetBounds())) {
|
||||
if (mNewChildLayers[j].mLayerState != LAYER_ACTIVE_FORCE) {
|
||||
*aHasComponentAlphaChildren = true;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!layer->GetParent()) {
|
||||
@ -5745,13 +5644,13 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LayerState state = aContainerItem ? aContainerItem->GetLayerState(aBuilder, aManager, aParameters) : LAYER_ACTIVE;
|
||||
if (state == LAYER_INACTIVE &&
|
||||
LayerState layerState = aContainerItem ? aContainerItem->GetLayerState(aBuilder, aManager, aParameters) : LAYER_ACTIVE;
|
||||
if (layerState == LAYER_INACTIVE &&
|
||||
nsDisplayItem::ForceActiveLayers()) {
|
||||
state = LAYER_ACTIVE;
|
||||
layerState = LAYER_ACTIVE;
|
||||
}
|
||||
|
||||
if (aContainerItem && state == LAYER_ACTIVE_EMPTY) {
|
||||
if (aContainerItem && layerState == LAYER_ACTIVE_EMPTY) {
|
||||
// Empty layers only have metadata and should never have display items. We
|
||||
// early exit because later, invalidation will walk up the frame tree to
|
||||
// determine which painted layer gets invalidated. Since an empty layer
|
||||
@ -5779,13 +5678,10 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
|
||||
aContainerItem,
|
||||
bounds.Intersect(childrenVisible),
|
||||
aTransform, aParameters,
|
||||
containerLayer, state, scaleParameters)) {
|
||||
containerLayer, layerState, scaleParameters)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t oldGeneration = mContainerLayerGeneration;
|
||||
mContainerLayerGeneration = ++mMaxContainerLayerGeneration;
|
||||
|
||||
if (mRetainingManager) {
|
||||
if (aContainerItem) {
|
||||
DisplayItemData* data = GetDisplayItemDataForManager(aContainerItem, mRetainingManager);
|
||||
@ -5795,19 +5691,8 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
}
|
||||
|
||||
LayerManagerData* data = static_cast<LayerManagerData*>
|
||||
(aManager->GetUserData(&gLayerManagerUserData));
|
||||
|
||||
nsIntRect pixBounds;
|
||||
nscoord appUnitsPerDevPixel;
|
||||
bool flattenToSingleLayer = false;
|
||||
if ((aContainerFrame->GetStateBits() & NS_FRAME_NO_COMPONENT_ALPHA) &&
|
||||
mRetainingManager &&
|
||||
mRetainingManager->ShouldAvoidComponentAlphaLayers() &&
|
||||
!nsLayoutUtils::AsyncPanZoomEnabled(aContainerFrame))
|
||||
{
|
||||
flattenToSingleLayer = true;
|
||||
}
|
||||
|
||||
nscolor backgroundColor = NS_RGBA(0,0,0,0);
|
||||
if (aFlags & CONTAINER_ALLOW_PULL_BACKGROUND_COLOR) {
|
||||
@ -5815,71 +5700,20 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
|
||||
uint32_t flags;
|
||||
while (true) {
|
||||
ContainerState state(aBuilder, aManager, aManager->GetLayerBuilder(),
|
||||
aContainerFrame, aContainerItem, bounds,
|
||||
containerLayer, scaleParameters, flattenToSingleLayer,
|
||||
backgroundColor, containerASR, containerScrollMetadataASR,
|
||||
containerCompositorASR);
|
||||
ContainerState state(aBuilder, aManager, aManager->GetLayerBuilder(),
|
||||
aContainerFrame, aContainerItem, bounds,
|
||||
containerLayer, scaleParameters,
|
||||
backgroundColor, containerASR, containerScrollMetadataASR,
|
||||
containerCompositorASR);
|
||||
|
||||
state.ProcessDisplayItems(aChildren);
|
||||
state.ProcessDisplayItems(aChildren);
|
||||
|
||||
// Set CONTENT_COMPONENT_ALPHA if any of our children have it.
|
||||
// This is suboptimal ... a child could have text that's over transparent
|
||||
// pixels in its own layer, but over opaque parts of previous siblings.
|
||||
bool hasComponentAlphaChildren = false;
|
||||
bool mayFlatten =
|
||||
mRetainingManager &&
|
||||
mRetainingManager->ShouldAvoidComponentAlphaLayers() &&
|
||||
!flattenToSingleLayer &&
|
||||
!nsLayoutUtils::AsyncPanZoomEnabled(aContainerFrame);
|
||||
|
||||
pixBounds = state.ScaleToOutsidePixels(bounds, false);
|
||||
appUnitsPerDevPixel = state.GetAppUnitsPerDevPixel();
|
||||
state.Finish(&flags, pixBounds, aChildren, mayFlatten ? &hasComponentAlphaChildren : nullptr);
|
||||
|
||||
if (hasComponentAlphaChildren &&
|
||||
!(flags & Layer::CONTENT_DISABLE_FLATTENING) &&
|
||||
containerLayer->HasMultipleChildren())
|
||||
{
|
||||
// Since we don't want any component alpha layers on BasicLayers, we repeat
|
||||
// the layer building process with this explicitely forced off.
|
||||
// We restore the previous FrameLayerBuilder state since the first set
|
||||
// of layer building will have changed it.
|
||||
flattenToSingleLayer = true;
|
||||
|
||||
// Restore DisplayItemData
|
||||
for (auto iter = data->mDisplayItems.Iter(); !iter.Done(); iter.Next()) {
|
||||
DisplayItemData* data = iter.Get()->GetKey();
|
||||
if (data->mUsed && data->mContainerLayerGeneration >= mContainerLayerGeneration) {
|
||||
iter.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Restore PaintedLayerItemEntries
|
||||
for (auto iter = mPaintedLayerItems.Iter(); !iter.Done(); iter.Next()) {
|
||||
PaintedLayerItemsEntry* entry = iter.Get();
|
||||
if (entry->mContainerLayerGeneration >= mContainerLayerGeneration) {
|
||||
// We can just remove these items rather than attempting to revert them
|
||||
// because we're going to want to invalidate everything when transitioning
|
||||
// to component alpha flattening.
|
||||
iter.Remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < entry->mItems.Length(); i++) {
|
||||
if (entry->mItems[i].mContainerLayerGeneration >= mContainerLayerGeneration) {
|
||||
entry->mItems.TruncateLength(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aContainerFrame->AddStateBits(NS_FRAME_NO_COMPONENT_ALPHA);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Set CONTENT_COMPONENT_ALPHA if any of our children have it.
|
||||
// This is suboptimal ... a child could have text that's over transparent
|
||||
// pixels in its own layer, but over opaque parts of previous siblings.
|
||||
pixBounds = state.ScaleToOutsidePixels(bounds, false);
|
||||
appUnitsPerDevPixel = state.GetAppUnitsPerDevPixel();
|
||||
state.Finish(&flags, pixBounds, aChildren);
|
||||
|
||||
// CONTENT_COMPONENT_ALPHA is propogated up to the nearest CONTENT_OPAQUE
|
||||
// ancestor so that BasicLayerManager knows when to copy the background into
|
||||
@ -5910,7 +5744,6 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
|
||||
*aParameters.mLayerContentsVisibleRect = pixBounds + scaleParameters.mOffset;
|
||||
}
|
||||
|
||||
mContainerLayerGeneration = oldGeneration;
|
||||
nsPresContext::ClearNotifySubDocInvalidationData(containerLayer);
|
||||
|
||||
return containerLayer.forget();
|
||||
|
@ -147,7 +147,7 @@ private:
|
||||
* EndUpdate must be called before the end of the transaction to complete the update.
|
||||
*/
|
||||
void BeginUpdate(layers::Layer* aLayer, LayerState aState,
|
||||
uint32_t aContainerLayerGeneration, nsDisplayItem* aItem = nullptr);
|
||||
nsDisplayItem* aItem = nullptr);
|
||||
|
||||
/**
|
||||
* Completes the update of this, and removes any references to data that won't live
|
||||
@ -170,7 +170,6 @@ private:
|
||||
nsAutoPtr<nsDisplayItemGeometry> mGeometry;
|
||||
DisplayItemClip mClip;
|
||||
uint32_t mDisplayItemKey;
|
||||
uint32_t mContainerLayerGeneration;
|
||||
LayerState mLayerState;
|
||||
|
||||
/**
|
||||
@ -186,6 +185,7 @@ private:
|
||||
*/
|
||||
bool mUsed;
|
||||
bool mIsInvalid;
|
||||
bool mReusedItem;
|
||||
};
|
||||
|
||||
class RefCountedRegion {
|
||||
@ -649,7 +649,7 @@ protected:
|
||||
* PaintedLayer.
|
||||
*/
|
||||
struct ClippedDisplayItem {
|
||||
ClippedDisplayItem(nsDisplayItem* aItem, uint32_t aGeneration);
|
||||
explicit ClippedDisplayItem(nsDisplayItem* aItem);
|
||||
~ClippedDisplayItem();
|
||||
|
||||
nsDisplayItem* mItem;
|
||||
@ -660,9 +660,6 @@ protected:
|
||||
* used for the inactive transaction.
|
||||
*/
|
||||
RefPtr<LayerManager> mInactiveLayerManager;
|
||||
|
||||
uint32_t mContainerLayerGeneration;
|
||||
|
||||
};
|
||||
|
||||
static void RecomputeVisibilityForItems(nsTArray<ClippedDisplayItem>& aItems,
|
||||
@ -700,7 +697,6 @@ public:
|
||||
nsIntPoint mLastPaintOffset;
|
||||
uint32_t mLastCommonClipCount;
|
||||
|
||||
uint32_t mContainerLayerGeneration;
|
||||
bool mHasExplicitLastPaintOffset;
|
||||
/**
|
||||
* The first mCommonClipCount rounded rectangle clips are identical for
|
||||
@ -787,8 +783,6 @@ protected:
|
||||
|
||||
bool mIsInactiveLayerManager;
|
||||
|
||||
uint32_t mContainerLayerGeneration;
|
||||
uint32_t mMaxContainerLayerGeneration;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -104,25 +104,21 @@ SelectAGRForFrame(nsIFrame* aFrame, AnimatedGeometryRoot* aParentAGR)
|
||||
// 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
|
||||
// jump into those immediately rather than walking the entire thing.
|
||||
bool
|
||||
void
|
||||
RetainedDisplayListBuilder::PreProcessDisplayList(nsDisplayList* aList,
|
||||
AnimatedGeometryRoot* aAGR)
|
||||
{
|
||||
bool modified = false;
|
||||
nsDisplayList saved;
|
||||
while (nsDisplayItem* i = aList->RemoveBottom()) {
|
||||
if (i->HasDeletedFrame() || !i->CanBeReused()) {
|
||||
i->Destroy(&mBuilder);
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
nsIFrame* f = i->Frame();
|
||||
|
||||
if (i->GetChildren()) {
|
||||
if (PreProcessDisplayList(i->GetChildren(), SelectAGRForFrame(f, aAGR))) {
|
||||
modified = true;
|
||||
}
|
||||
PreProcessDisplayList(i->GetChildren(), SelectAGRForFrame(f, aAGR));
|
||||
}
|
||||
|
||||
// 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.
|
||||
if (aAGR && i->GetAnimatedGeometryRoot()->GetAsyncAGR() != aAGR) {
|
||||
mBuilder.MarkFrameForDisplayIfVisible(f, mBuilder.RootReferenceFrame());
|
||||
modified = true;
|
||||
}
|
||||
|
||||
// TODO: This is here because we sometimes reuse the previous display list
|
||||
@ -142,7 +137,6 @@ RetainedDisplayListBuilder::PreProcessDisplayList(nsDisplayList* aList,
|
||||
}
|
||||
aList->AppendToTop(&saved);
|
||||
aList->RestoreState();
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool IsSameItem(nsDisplayItem* aFirst, nsDisplayItem* aSecond)
|
||||
@ -205,13 +199,12 @@ void SwapAndRemove(nsTArray<T>& aArray, uint32_t aIndex)
|
||||
aArray.RemoveElementAt(aArray.Length() - 1);
|
||||
}
|
||||
|
||||
static bool
|
||||
static void
|
||||
MergeFrameRects(nsDisplayLayerEventRegions* aOldItem,
|
||||
nsDisplayLayerEventRegions* aNewItem,
|
||||
nsDisplayLayerEventRegions::FrameRects nsDisplayLayerEventRegions::*aRectList,
|
||||
nsTArray<nsIFrame*>& aAddedFrames)
|
||||
{
|
||||
bool modified = false;
|
||||
// Go through the old item's rect list and remove any rectangles
|
||||
// belonging to invalidated frames (deleted frames should
|
||||
// already be gone at this point)
|
||||
@ -226,13 +219,12 @@ MergeFrameRects(nsDisplayLayerEventRegions* aOldItem,
|
||||
f->RemoveDisplayItem(aOldItem);
|
||||
SwapAndRemove(oldRects.mFrames, i);
|
||||
SwapAndRemove(oldRects.mBoxes, i);
|
||||
modified = true;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (!aNewItem) {
|
||||
return modified;
|
||||
return;
|
||||
}
|
||||
|
||||
// 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.
|
||||
aAddedFrames.AppendElement(f);
|
||||
MOZ_ASSERT(f != aOldItem->Frame());
|
||||
|
||||
modified = true;
|
||||
}
|
||||
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool MergeLayerEventRegions(nsDisplayItem* aOldItem,
|
||||
void MergeLayerEventRegions(nsDisplayItem* aOldItem,
|
||||
nsDisplayItem* aNewItem)
|
||||
{
|
||||
nsDisplayLayerEventRegions* oldItem =
|
||||
@ -271,13 +260,12 @@ bool MergeLayerEventRegions(nsDisplayItem* aOldItem,
|
||||
|
||||
nsTArray<nsIFrame*> addedFrames;
|
||||
|
||||
bool modified = false;
|
||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mHitRegion, addedFrames);
|
||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mMaybeHitRegion, addedFrames);
|
||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mDispatchToContentHitRegion, addedFrames);
|
||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mNoActionRegion, addedFrames);
|
||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mHorizontalPanRegion, addedFrames);
|
||||
modified |= MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mVerticalPanRegion, addedFrames);
|
||||
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mHitRegion, addedFrames);
|
||||
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mMaybeHitRegion, addedFrames);
|
||||
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mDispatchToContentHitRegion, addedFrames);
|
||||
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mNoActionRegion, addedFrames);
|
||||
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mHorizontalPanRegion, addedFrames);
|
||||
MergeFrameRects(oldItem, newItem, &nsDisplayLayerEventRegions::mVerticalPanRegion, addedFrames);
|
||||
|
||||
// MergeFrameRects deferred updating the display item data list during
|
||||
// processing so that earlier calls didn't change the result of later
|
||||
@ -287,7 +275,6 @@ bool MergeLayerEventRegions(nsDisplayItem* aOldItem,
|
||||
f->AddDisplayItem(aOldItem);
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
void
|
||||
@ -401,14 +388,12 @@ void UpdateASR(nsDisplayItem* aItem,
|
||||
*
|
||||
* Merged List: C, A, B
|
||||
*/
|
||||
bool
|
||||
void
|
||||
RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
||||
nsDisplayList* aOldList,
|
||||
nsDisplayList* aOutList,
|
||||
Maybe<const ActiveScrolledRoot*>& aOutContainerASR)
|
||||
{
|
||||
bool modified = false;
|
||||
|
||||
nsDisplayList merged;
|
||||
const auto UseItem = [&](nsDisplayItem* aItem) {
|
||||
const ActiveScrolledRoot* itemClipASR =
|
||||
@ -472,11 +457,9 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
||||
oldListLookup.Remove({ old->Frame(), old->GetPerFrameKey() });
|
||||
aOldList->RemoveBottom();
|
||||
old->Destroy(&mBuilder);
|
||||
modified = true;
|
||||
} 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.
|
||||
// Stop now, and we'll deal with it when we get to the new entry.
|
||||
modified = true;
|
||||
break;
|
||||
} else {
|
||||
// Recurse into the child list (without a matching new list) to
|
||||
@ -484,10 +467,8 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
||||
if (old->GetChildren()) {
|
||||
nsDisplayList empty;
|
||||
Maybe<const ActiveScrolledRoot*> containerASRForChildren;
|
||||
if (MergeDisplayLists(&empty, old->GetChildren(),
|
||||
old->GetChildren(), containerASRForChildren)) {
|
||||
modified = true;
|
||||
}
|
||||
MergeDisplayLists(&empty, old->GetChildren(),
|
||||
old->GetChildren(), containerASRForChildren);
|
||||
UpdateASR(old, containerASRForChildren);
|
||||
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
|
||||
// newer item. Always use the old item instead since we assume it's
|
||||
// likely to have the bigger lists and merging will be quicker.
|
||||
if (MergeLayerEventRegions(oldItem, newItem)) {
|
||||
modified = true;
|
||||
}
|
||||
MergeLayerEventRegions(oldItem, newItem);
|
||||
ReuseItem(oldItem);
|
||||
newItem->Destroy(&mBuilder);
|
||||
} else {
|
||||
if (IsAnyAncestorModified(oldItem->FrameForInvalidation())) {
|
||||
modified = true;
|
||||
} else if (oldItem->GetChildren()) {
|
||||
if (!IsAnyAncestorModified(oldItem->FrameForInvalidation()) &&
|
||||
oldItem->GetChildren()) {
|
||||
MOZ_ASSERT(newItem->GetChildren());
|
||||
Maybe<const ActiveScrolledRoot*> containerASRForChildren;
|
||||
if (MergeDisplayLists(newItem->GetChildren(), oldItem->GetChildren(),
|
||||
newItem->GetChildren(), containerASRForChildren)) {
|
||||
modified = true;
|
||||
}
|
||||
MergeDisplayLists(newItem->GetChildren(), oldItem->GetChildren(),
|
||||
newItem->GetChildren(), containerASRForChildren);
|
||||
UpdateASR(newItem, containerASRForChildren);
|
||||
newItem->UpdateBounds(&mBuilder);
|
||||
}
|
||||
@ -544,7 +520,6 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
||||
} else {
|
||||
// If there was no matching item in the old list, then we only need to
|
||||
// add the new item to the merged list.
|
||||
modified = true;
|
||||
UseItem(newItem);
|
||||
}
|
||||
}
|
||||
@ -562,27 +537,21 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList,
|
||||
nsDisplayList empty;
|
||||
Maybe<const ActiveScrolledRoot*> containerASRForChildren;
|
||||
|
||||
if (MergeDisplayLists(&empty, old->GetChildren(),
|
||||
old->GetChildren(), containerASRForChildren)) {
|
||||
modified = true;
|
||||
}
|
||||
MergeDisplayLists(&empty, old->GetChildren(),
|
||||
old->GetChildren(), containerASRForChildren);
|
||||
UpdateASR(old, containerASRForChildren);
|
||||
old->UpdateBounds(&mBuilder);
|
||||
}
|
||||
if (old->GetType() == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
|
||||
if (MergeLayerEventRegions(old, nullptr)) {
|
||||
modified = true;
|
||||
}
|
||||
MergeLayerEventRegions(old, nullptr);
|
||||
}
|
||||
ReuseItem(old);
|
||||
} else {
|
||||
old->Destroy(&mBuilder);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
aOutList->AppendToTop(&merged);
|
||||
return modified;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -720,6 +689,22 @@ GetModifiedAndFramesWithProps(nsDisplayListBuilder* aBuilder,
|
||||
# define CRR_LOG(...)
|
||||
#endif
|
||||
|
||||
static nsDisplayItem*
|
||||
GetFirstDisplayItemWithChildren(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame::DisplayItemArray* items = aFrame->GetProperty(nsIFrame::DisplayItems());
|
||||
if (!items) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (nsDisplayItem* i : *items) {
|
||||
if (i->GetChildren()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static nsIFrame*
|
||||
HandlePreserve3D(nsIFrame* aFrame, nsRect& aOverflow)
|
||||
{
|
||||
@ -750,8 +735,6 @@ ProcessFrame(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
||||
{
|
||||
nsIFrame* currentFrame = aFrame;
|
||||
|
||||
aBuilder.MarkFrameForDisplayIfVisible(aFrame, aBuilder.RootReferenceFrame());
|
||||
|
||||
while (currentFrame != aStopAtFrame) {
|
||||
CRR_LOG("currentFrame: %p (placeholder=%d), aOverflow: %d %d %d %d\n",
|
||||
currentFrame, !aStopAtStackingContext,
|
||||
@ -802,10 +785,6 @@ ProcessFrame(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
||||
/* aStopAtStackingContextAndDisplayPortAndOOFFrame = */ true,
|
||||
¤tFrame);
|
||||
MOZ_ASSERT(currentFrame);
|
||||
aOverflow.IntersectRect(aOverflow, currentFrame->GetVisualOverflowRectRelativeToSelf());
|
||||
if (aOverflow.IsEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (nsLayoutUtils::FrameHasDisplayPort(currentFrame)) {
|
||||
CRR_LOG("Frame belongs to displayport frame %p\n", currentFrame);
|
||||
@ -843,19 +822,17 @@ ProcessFrame(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
||||
}
|
||||
}
|
||||
|
||||
if (currentFrame->IsStackingContext()) {
|
||||
if (currentFrame != aBuilder.RootReferenceFrame() &&
|
||||
currentFrame->IsStackingContext()) {
|
||||
CRR_LOG("Frame belongs to stacking context frame %p\n", currentFrame);
|
||||
// If we found an intermediate stacking context with an existing display item
|
||||
// then we can store the dirty rect there and stop. If we couldn't find one then
|
||||
// we need to keep bubbling up to the next stacking context.
|
||||
if (currentFrame == aBuilder.RootReferenceFrame() ||
|
||||
!currentFrame->HasDisplayItems()) {
|
||||
nsDisplayItem* wrapperItem = GetFirstDisplayItemWithChildren(currentFrame);
|
||||
if (!wrapperItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
aBuilder.MarkFrameForDisplayIfVisible(currentFrame,
|
||||
aBuilder.RootReferenceFrame());
|
||||
|
||||
// Store the stacking context relative dirty area such
|
||||
// that display list building will pick it up when it
|
||||
// gets to it.
|
||||
@ -876,6 +853,24 @@ ProcessFrame(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
||||
continue;
|
||||
}
|
||||
|
||||
// Grab the visible (display list building) rect for children of this wrapper
|
||||
// item and convert into into coordinate relative to the current frame.
|
||||
nsRect previousVisible = wrapperItem->GetVisibleRectForChildren();
|
||||
if (wrapperItem->ReferenceFrameForChildren() == wrapperItem->ReferenceFrame()) {
|
||||
previousVisible -= wrapperItem->ToReferenceFrame();
|
||||
} else {
|
||||
MOZ_ASSERT(wrapperItem->ReferenceFrameForChildren() == wrapperItem->Frame());
|
||||
}
|
||||
|
||||
if (!previousVisible.Contains(aOverflow)) {
|
||||
// If the overflow area of the changed frame isn't contained within the old
|
||||
// item, then we might change the size of the item and need to update its
|
||||
// sorting accordingly. Keep propagating the overflow area up so that we
|
||||
// build intersecting items for sorting.
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!data->mModifiedAGR) {
|
||||
data->mModifiedAGR = *aAGR;
|
||||
} else if (data->mModifiedAGR != *aAGR) {
|
||||
@ -962,20 +957,18 @@ RetainedDisplayListBuilder::ComputeRebuildRegion(nsTArray<nsIFrame*>& aModifiedF
|
||||
ProcessFrame(f, mBuilder, &agr, overflow, mBuilder.RootReferenceFrame(),
|
||||
aOutFramesWithProps, true);
|
||||
|
||||
if (!overflow.IsEmpty()) {
|
||||
aOutDirty->UnionRect(*aOutDirty, overflow);
|
||||
CRR_LOG("Adding area to root draw area: %d %d %d %d\n",
|
||||
overflow.x, overflow.y, overflow.width, overflow.height);
|
||||
aOutDirty->UnionRect(*aOutDirty, overflow);
|
||||
CRR_LOG("Adding area to root draw area: %d %d %d %d\n",
|
||||
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
|
||||
// track which items would need to be marked in MarkFramesForDifferentAGR.
|
||||
if (!*aOutModifiedAGR) {
|
||||
CRR_LOG("Setting %p as root stacking context AGR\n", agr);
|
||||
*aOutModifiedAGR = agr;
|
||||
} else if (agr && *aOutModifiedAGR != agr) {
|
||||
CRR_LOG("Found multiple AGRs in root stacking context, giving up\n");
|
||||
return false;
|
||||
}
|
||||
// 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.
|
||||
if (!*aOutModifiedAGR) {
|
||||
CRR_LOG("Setting %p as root stacking context AGR\n", agr);
|
||||
*aOutModifiedAGR = agr;
|
||||
} else if (agr && *aOutModifiedAGR != agr) {
|
||||
CRR_LOG("Found multiple AGRs in root stacking context, giving up\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1028,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
|
||||
RetainedDisplayListBuilder::ClearFramesWithProps()
|
||||
{
|
||||
AutoClearFramePropsArray modifiedFrames;
|
||||
AutoClearFramePropsArray framesWithProps;
|
||||
GetModifiedAndFramesWithProps(&mBuilder, &modifiedFrames.Frames(), &framesWithProps.Frames());
|
||||
nsTArray<nsIFrame*> modifiedFrames;
|
||||
nsTArray<nsIFrame*> framesWithProps;
|
||||
GetModifiedAndFramesWithProps(&mBuilder, &modifiedFrames, &framesWithProps);
|
||||
|
||||
ClearFrameProps(modifiedFrames);
|
||||
ClearFrameProps(framesWithProps);
|
||||
}
|
||||
|
||||
auto
|
||||
bool
|
||||
RetainedDisplayListBuilder::AttemptPartialUpdate(
|
||||
nscolor aBackstop,
|
||||
mozilla::DisplayListChecker* aChecker) -> PartialUpdateResult
|
||||
mozilla::DisplayListChecker* aChecker)
|
||||
{
|
||||
mBuilder.RemoveModifiedWindowRegions();
|
||||
mBuilder.ClearWindowOpaqueRegion();
|
||||
@ -1068,27 +1046,24 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(
|
||||
|
||||
mBuilder.EnterPresShell(mBuilder.RootReferenceFrame());
|
||||
|
||||
// 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.
|
||||
AutoClearFramePropsArray modifiedFrames;
|
||||
AutoClearFramePropsArray framesWithProps;
|
||||
GetModifiedAndFramesWithProps(&mBuilder, &modifiedFrames.Frames(), &framesWithProps.Frames());
|
||||
nsTArray<nsIFrame*> modifiedFrames;
|
||||
nsTArray<nsIFrame*> framesWithProps;
|
||||
GetModifiedAndFramesWithProps(&mBuilder, &modifiedFrames, &framesWithProps);
|
||||
|
||||
// Do not allow partial builds if the retained display list is empty, or if
|
||||
// ShouldBuildPartial heuristic fails.
|
||||
const bool shouldBuildPartial = !mList.IsEmpty() && ShouldBuildPartial(modifiedFrames.Frames());
|
||||
const bool shouldBuildPartial = !mList.IsEmpty() && ShouldBuildPartial(modifiedFrames);
|
||||
|
||||
if (mPreviousCaret != mBuilder.GetCaretFrame()) {
|
||||
if (mPreviousCaret) {
|
||||
if (mBuilder.MarkFrameModifiedDuringBuilding(mPreviousCaret)) {
|
||||
modifiedFrames.Frames().AppendElement(mPreviousCaret);
|
||||
modifiedFrames.AppendElement(mPreviousCaret);
|
||||
}
|
||||
}
|
||||
|
||||
if (mBuilder.GetCaretFrame()) {
|
||||
if (mBuilder.MarkFrameModifiedDuringBuilding(mBuilder.GetCaretFrame())) {
|
||||
modifiedFrames.Frames().AppendElement(mBuilder.GetCaretFrame());
|
||||
modifiedFrames.AppendElement(mBuilder.GetCaretFrame());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1097,60 +1072,61 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(
|
||||
|
||||
nsRect modifiedDirty;
|
||||
AnimatedGeometryRoot* modifiedAGR = nullptr;
|
||||
if (!shouldBuildPartial ||
|
||||
!ComputeRebuildRegion(modifiedFrames.Frames(), &modifiedDirty,
|
||||
&modifiedAGR, framesWithProps.Frames())) {
|
||||
mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), &mList);
|
||||
return PartialUpdateResult::Failed;
|
||||
bool merged = false;
|
||||
if (shouldBuildPartial &&
|
||||
ComputeRebuildRegion(modifiedFrames, &modifiedDirty,
|
||||
&modifiedAGR, framesWithProps)) {
|
||||
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);
|
||||
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; }
|
||||
|
||||
enum class PartialUpdateResult {
|
||||
Failed,
|
||||
NoChange,
|
||||
Updated
|
||||
};
|
||||
|
||||
PartialUpdateResult AttemptPartialUpdate(nscolor aBackstop,
|
||||
mozilla::DisplayListChecker* aChecker);
|
||||
bool AttemptPartialUpdate(nscolor aBackstop,
|
||||
mozilla::DisplayListChecker* aChecker);
|
||||
|
||||
/**
|
||||
* Iterates through the display list builder reference frame document and
|
||||
@ -49,9 +43,9 @@ struct RetainedDisplayListBuilder {
|
||||
NS_DECLARE_FRAME_PROPERTY_DELETABLE(Cached, RetainedDisplayListBuilder)
|
||||
|
||||
private:
|
||||
bool PreProcessDisplayList(nsDisplayList* aList, AnimatedGeometryRoot* aAGR);
|
||||
void PreProcessDisplayList(nsDisplayList* aList, AnimatedGeometryRoot* aAGR);
|
||||
|
||||
bool MergeDisplayLists(nsDisplayList* aNewList,
|
||||
void MergeDisplayLists(nsDisplayList* aNewList,
|
||||
nsDisplayList* aOldList,
|
||||
nsDisplayList* aOutList,
|
||||
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_REGION, 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(SVG_OUTER_SVG, TYPE_RENDERS_NO_IMAGES)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(SVG_GEOMETRY, 0)
|
||||
|
@ -2504,100 +2504,6 @@ nsDisplayListBuilder::GetWidgetLayerManager(nsView** aView)
|
||||
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
|
||||
* 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;
|
||||
|
||||
UniquePtr<LayerProperties> props;
|
||||
RefPtr<ContainerLayer> root;
|
||||
|
||||
bool computeInvalidRect = (computeInvalidFunc ||
|
||||
(!layerManager->IsCompositingCheap() && layerManager->NeedsWidgetInvalidation())) &&
|
||||
widgetTransaction;
|
||||
// Store the existing layer builder to reinstate it on return.
|
||||
FrameLayerBuilder *oldBuilder = layerManager->GetLayerBuilder();
|
||||
|
||||
if (computeInvalidRect) {
|
||||
props = Move(LayerProperties::CloneFrom(layerManager->GetRoot()));
|
||||
FrameLayerBuilder *layerBuilder = new FrameLayerBuilder();
|
||||
layerBuilder->Init(aBuilder, layerManager);
|
||||
|
||||
if (aFlags & PAINT_COMPRESSED) {
|
||||
layerBuilder->SetLayerTreeCompressionMode();
|
||||
}
|
||||
|
||||
if (doBeginTransaction) {
|
||||
if (aCtx) {
|
||||
if (!layerManager->BeginTransactionWithTarget(aCtx)) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
if (!layerManager->BeginTransaction()) {
|
||||
return nullptr;
|
||||
{
|
||||
AUTO_PROFILER_TRACING("Paint", "LayerBuilding");
|
||||
|
||||
if (doBeginTransaction) {
|
||||
if (aCtx) {
|
||||
if (!layerManager->BeginTransactionWithTarget(aCtx)) {
|
||||
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());
|
||||
@ -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);
|
||||
|
||||
// Store the existing layer builder to reinstate it on return.
|
||||
FrameLayerBuilder *oldBuilder = layerManager->GetLayerBuilder();
|
||||
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();
|
||||
}
|
||||
|
||||
layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer,
|
||||
aBuilder, flags);
|
||||
aBuilder->SetIsCompositingCheap(temp);
|
||||
layerBuilder->DidEndTransaction();
|
||||
|
||||
if (document && widgetTransaction) {
|
||||
TriggerPendingAnimations(document, layerManager->GetAnimationReadyTime());
|
||||
@ -2780,11 +2752,11 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
|
||||
nsIntRegion invalid;
|
||||
bool areaOverflowed = false;
|
||||
if (props) {
|
||||
if (!props->ComputeDifferences(layerManager->GetRoot(), invalid, computeInvalidFunc)) {
|
||||
if (!props->ComputeDifferences(root, invalid, computeInvalidFunc)) {
|
||||
areaOverflowed = true;
|
||||
}
|
||||
} else if (widgetTransaction) {
|
||||
LayerProperties::ClearInvalidations(layerManager->GetRoot());
|
||||
LayerProperties::ClearInvalidations(root);
|
||||
}
|
||||
|
||||
bool shouldInvalidate = layerManager->NeedsWidgetInvalidation();
|
||||
@ -3494,8 +3466,7 @@ nsDisplayBackgroundImage::GetInitData(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame,
|
||||
uint32_t aLayer,
|
||||
const nsRect& aBackgroundRect,
|
||||
const nsStyleBackground* aBackgroundStyle,
|
||||
LayerizeFixed aLayerizeFixed)
|
||||
const nsStyleBackground* aBackgroundStyle)
|
||||
{
|
||||
nsPresContext* presContext = aFrame->PresContext();
|
||||
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
|
||||
@ -3514,15 +3485,6 @@ nsDisplayBackgroundImage::GetInitData(nsDisplayListBuilder* aBuilder,
|
||||
layer.mAttachment == NS_STYLE_IMAGELAYER_ATTACHMENT_FIXED && !isTransformedFixed;
|
||||
|
||||
bool shouldFixToViewport = shouldTreatAsFixed && !layer.mImage.IsEmpty();
|
||||
if (shouldFixToViewport &&
|
||||
aLayerizeFixed == LayerizeFixed::DO_NOT_LAYERIZE_FIXED_BACKGROUND_IF_AVOIDING_COMPONENT_ALPHA_LAYERS &&
|
||||
!nsLayoutUtils::UsesAsyncScrolling(aFrame)) {
|
||||
RefPtr<LayerManager> layerManager = aBuilder->GetWidgetLayerManager();
|
||||
if (layerManager && layerManager->ShouldAvoidComponentAlphaLayers()) {
|
||||
shouldFixToViewport = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isRasterImage = state.mImageRenderer.IsRasterImage();
|
||||
nsCOMPtr<imgIContainer> image;
|
||||
if (isRasterImage) {
|
||||
@ -3819,8 +3781,7 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
|
||||
|
||||
nsDisplayList thisItemList;
|
||||
nsDisplayBackgroundImage::InitData bgData =
|
||||
nsDisplayBackgroundImage::GetInitData(aBuilder, aFrame, i, bgOriginRect, bg,
|
||||
LayerizeFixed::DO_NOT_LAYERIZE_FIXED_BACKGROUND_IF_AVOIDING_COMPONENT_ALPHA_LAYERS);
|
||||
nsDisplayBackgroundImage::GetInitData(aBuilder, aFrame, i, bgOriginRect, bg);
|
||||
|
||||
if (bgData.shouldFixToViewport) {
|
||||
|
||||
@ -4349,17 +4310,12 @@ nsDisplayBackgroundImage::ComputeInvalidationRegion(nsDisplayListBuilder* aBuild
|
||||
// Positioning area changed in a way that could cause everything to change,
|
||||
// so invalidate everything (both old and new painting areas).
|
||||
aInvalidRegion->Or(bounds, geometry->mBounds);
|
||||
|
||||
if (positioningArea.Size() != geometry->mPositioningArea.Size()) {
|
||||
NotifyRenderingChanged();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!mDestRect.IsEqualInterior(geometry->mDestRect)) {
|
||||
// Dest area changed in a way that could cause everything to change,
|
||||
// so invalidate everything (both old and new painting areas).
|
||||
aInvalidRegion->Or(bounds, geometry->mBounds);
|
||||
NotifyRenderingChanged();
|
||||
return;
|
||||
}
|
||||
if (aBuilder->ShouldSyncDecodeImages()) {
|
||||
@ -4367,16 +4323,12 @@ nsDisplayBackgroundImage::ComputeInvalidationRegion(nsDisplayListBuilder* aBuild
|
||||
if (image.GetType() == eStyleImageType_Image &&
|
||||
geometry->ShouldInvalidateToSyncDecodeImages()) {
|
||||
aInvalidRegion->Or(*aInvalidRegion, bounds);
|
||||
|
||||
NotifyRenderingChanged();
|
||||
}
|
||||
}
|
||||
if (!bounds.IsEqualInterior(geometry->mBounds)) {
|
||||
// Positioning area is unchanged, so invalidate just the change in the
|
||||
// painting area.
|
||||
aInvalidRegion->Xor(bounds, geometry->mBounds);
|
||||
|
||||
NotifyRenderingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -10188,37 +10140,33 @@ PaintTelemetry::AutoRecordPaint::~AutoRecordPaint()
|
||||
// Record the total time.
|
||||
Telemetry::Accumulate(Telemetry::CONTENT_PAINT_TIME, static_cast<uint32_t>(totalMs));
|
||||
|
||||
// If the total time was >= 16ms, then it's likely we missed a frame due to
|
||||
// painting. In this case we'll gather some detailed metrics below.
|
||||
if (totalMs <= 16.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto record = [=](const char* aKey, double aDurationMs) -> void {
|
||||
// Helpers for recording large/small paints.
|
||||
auto recordLarge = [=](const nsCString& aKey, double aDurationMs) -> void {
|
||||
MOZ_ASSERT(aDurationMs <= totalMs);
|
||||
|
||||
uint32_t amount = static_cast<int32_t>((aDurationMs / totalMs) * 100.0);
|
||||
|
||||
nsDependentCString key(aKey);
|
||||
Telemetry::Accumulate(Telemetry::CONTENT_LARGE_PAINT_PHASE_WEIGHT, key, amount);
|
||||
Telemetry::Accumulate(Telemetry::CONTENT_LARGE_PAINT_PHASE_WEIGHT, aKey, amount);
|
||||
};
|
||||
auto recordSmall = [=](const nsString& aKey, double aDurationMs) -> void {
|
||||
MOZ_ASSERT(aDurationMs <= totalMs);
|
||||
uint32_t amount = static_cast<int32_t>((aDurationMs / totalMs) * 100.0);
|
||||
Telemetry::ScalarAdd(Telemetry::ScalarID::GFX_SMALL_PAINT_PHASE_WEIGHT, aKey, amount);
|
||||
};
|
||||
|
||||
double dlMs = sMetrics[Metric::DisplayList];
|
||||
double flbMs = sMetrics[Metric::Layerization];
|
||||
double rMs = sMetrics[Metric::Rasterization];
|
||||
|
||||
// Record all permutations since aggregation makes it difficult to
|
||||
// correlate. For example we can't derive "flb+r" from "dl" because we
|
||||
// don't know the total time associated with a bucket entry. So we just
|
||||
// play it safe and include everything. We can however derive "other" time
|
||||
// from the final permutation.
|
||||
record("dl", dlMs);
|
||||
record("flb", flbMs);
|
||||
record("r", rMs);
|
||||
record("dl,flb", dlMs + flbMs);
|
||||
record("dl,r", dlMs + rMs);
|
||||
record("flb,r", flbMs + rMs);
|
||||
record("dl,flb,r", dlMs + flbMs + rMs);
|
||||
// If the total time was >= 16ms, then it's likely we missed a frame due to
|
||||
// painting. We bucket these metrics separately.
|
||||
if (totalMs >= 16.0) {
|
||||
recordLarge(NS_LITERAL_CSTRING("dl"), dlMs);
|
||||
recordLarge(NS_LITERAL_CSTRING("flb"), flbMs);
|
||||
recordLarge(NS_LITERAL_CSTRING("r"), rMs);
|
||||
} else {
|
||||
recordSmall(NS_LITERAL_STRING("dl"), dlMs);
|
||||
recordSmall(NS_LITERAL_STRING("flb"), flbMs);
|
||||
recordSmall(NS_LITERAL_STRING("r"), rMs);
|
||||
}
|
||||
}
|
||||
|
||||
PaintTelemetry::AutoRecord::AutoRecord(Metric aMetric)
|
||||
|
@ -2364,16 +2364,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the area rendered by this display item has changed (been
|
||||
* invalidated or changed geometry) since the last paint. This includes
|
||||
* when the display item was not rendered at all in the last paint.
|
||||
* It does NOT get called when a display item was being rendered and no
|
||||
* longer is, because generally that means there is no display item to
|
||||
* call this method on.
|
||||
*/
|
||||
virtual void NotifyRenderingChanged() const {}
|
||||
|
||||
/**
|
||||
* @param aSnap set to true if the edges of the rectangles of the opaque
|
||||
* region would be snapped to device pixels when drawing
|
||||
@ -3100,17 +3090,11 @@ public:
|
||||
PAINT_USE_WIDGET_LAYERS = 0x01,
|
||||
PAINT_EXISTING_TRANSACTION = 0x04,
|
||||
PAINT_NO_COMPOSITE = 0x08,
|
||||
PAINT_COMPRESSED = 0x10,
|
||||
PAINT_IDENTICAL_DISPLAY_LIST = 0x20
|
||||
PAINT_COMPRESSED = 0x10
|
||||
};
|
||||
already_AddRefed<LayerManager> PaintRoot(nsDisplayListBuilder* aBuilder,
|
||||
gfxContext* aCtx,
|
||||
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.
|
||||
* The result is not cached.
|
||||
@ -3837,16 +3821,11 @@ public:
|
||||
* nsCSSRendering::FindBackground, or null if FindBackground returned false.
|
||||
* aBackgroundRect is relative to aFrame.
|
||||
*/
|
||||
enum class LayerizeFixed : uint8_t {
|
||||
ALWAYS_LAYERIZE_FIXED_BACKGROUND,
|
||||
DO_NOT_LAYERIZE_FIXED_BACKGROUND_IF_AVOIDING_COMPONENT_ALPHA_LAYERS
|
||||
};
|
||||
static InitData GetInitData(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame,
|
||||
uint32_t aLayer,
|
||||
const nsRect& aBackgroundRect,
|
||||
const nsStyleBackground* aBackgroundStyle,
|
||||
LayerizeFixed aLayerizeFixed);
|
||||
const nsStyleBackground* aBackgroundStyle);
|
||||
|
||||
explicit nsDisplayBackgroundImage(const InitData& aInitData,
|
||||
nsIFrame* aFrameForBounds = nullptr);
|
||||
@ -4802,7 +4781,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
friend bool MergeLayerEventRegions(nsDisplayItem*, nsDisplayItem*);
|
||||
friend void MergeLayerEventRegions(nsDisplayItem*, nsDisplayItem*);
|
||||
|
||||
// Relative to aFrame's reference frame.
|
||||
// These are the points that are definitely in the hit region.
|
||||
|
26
layout/reftests/display-list/1420480-1-ref.html
Normal file
26
layout/reftests/display-list/1420480-1-ref.html
Normal file
@ -0,0 +1,26 @@
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
div {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-color: blue;
|
||||
opacity: 0.95;
|
||||
position: absolute;
|
||||
}
|
||||
#second {
|
||||
width: 600px;
|
||||
height: 800px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="first">
|
||||
<div id="second"></div>
|
||||
</div>
|
||||
<div style="z-index:-2; top: 220px;"></div>
|
||||
<div style="top: 440px;"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
43
layout/reftests/display-list/1420480-1.html
Normal file
43
layout/reftests/display-list/1420480-1.html
Normal file
@ -0,0 +1,43 @@
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<style>
|
||||
div {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-color: blue;
|
||||
opacity: 0.95;
|
||||
position: absolute;
|
||||
}
|
||||
#first {
|
||||
display: none;
|
||||
}
|
||||
#second {
|
||||
width: 600px;
|
||||
height: 800px;
|
||||
display: none;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="first">
|
||||
<div id="second"></div>
|
||||
</div>
|
||||
<div style="z-index:-2; top: 220px;"></div>
|
||||
<div style="top: 440px;"></div>
|
||||
|
||||
<script>
|
||||
function doTest2() {
|
||||
document.getElementById("second").style.display = "block";
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
document.getElementById("first").style.display = "block";
|
||||
setTimeout(doTest2, 500);
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -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,4 +19,5 @@ skip-if(Android) == 1428993-1.html 1428993-1-ref.html
|
||||
needs-focus == 1429027-1.html 1429027-1-ref.html
|
||||
== 1432553-1.html 1432553-1-ref.html
|
||||
== 1432553-2.html 1432553-2-ref.html
|
||||
== 1436189-1.html 1436189-1-ref.html
|
||||
== 1420480-1.html 1420480-1-ref.html
|
||||
|
||||
|
@ -230,6 +230,8 @@ const char*
|
||||
PrefTypeToString(PrefType aType)
|
||||
{
|
||||
switch (aType) {
|
||||
case PrefType::None:
|
||||
return "none";
|
||||
case PrefType::String:
|
||||
return "string";
|
||||
case PrefType::Int:
|
||||
@ -299,11 +301,15 @@ class Pref : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
explicit Pref(const char* aName)
|
||||
: mType(static_cast<uint32_t>(PrefType::None))
|
||||
, mIsSticky(false)
|
||||
, mIsLocked(false)
|
||||
, mHasDefaultValue(false)
|
||||
, mHasUserValue(false)
|
||||
, mName(ArenaStrdup(aName, gPrefNameArena))
|
||||
, mDefaultValue()
|
||||
, mUserValue()
|
||||
{
|
||||
mName = ArenaStrdup(aName, gPrefNameArena);
|
||||
|
||||
// We don't set the other fields because PLDHashTable always zeroes new
|
||||
// entries.
|
||||
}
|
||||
|
||||
~Pref()
|
||||
@ -323,6 +329,7 @@ public:
|
||||
void SetType(PrefType aType) { mType = static_cast<uint32_t>(aType); }
|
||||
|
||||
bool IsType(PrefType aType) const { return Type() == aType; }
|
||||
bool IsTypeNone() const { return IsType(PrefType::None); }
|
||||
bool IsTypeString() const { return IsType(PrefType::String); }
|
||||
bool IsTypeInt() const { return IsType(PrefType::Int); }
|
||||
bool IsTypeBool() const { return IsType(PrefType::Bool); }
|
||||
@ -353,6 +360,13 @@ public:
|
||||
return strcmp(pref->mName, key) == 0;
|
||||
}
|
||||
|
||||
static void InitEntry(PLDHashEntryHdr* aEntry, const void* aKey)
|
||||
{
|
||||
auto pref = static_cast<Pref*>(aEntry);
|
||||
auto prefName = static_cast<const char*>(aKey);
|
||||
new (pref) Pref(prefName);
|
||||
}
|
||||
|
||||
static void ClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
|
||||
{
|
||||
auto pref = static_cast<Pref*>(aEntry);
|
||||
@ -648,8 +662,8 @@ private:
|
||||
uint32_t mType : 2;
|
||||
uint32_t mIsSticky : 1;
|
||||
uint32_t mIsLocked : 1;
|
||||
uint32_t mHasUserValue : 1;
|
||||
uint32_t mHasDefaultValue : 1;
|
||||
uint32_t mHasUserValue : 1;
|
||||
|
||||
const char* mName; // allocated in gPrefNameArena
|
||||
|
||||
@ -700,7 +714,7 @@ static PLDHashTableOps pref_HashTableOps = {
|
||||
Pref::MatchEntry,
|
||||
PLDHashTable::MoveEntryStub,
|
||||
Pref::ClearEntry,
|
||||
nullptr,
|
||||
Pref::InitEntry,
|
||||
};
|
||||
|
||||
static Pref*
|
||||
@ -823,9 +837,8 @@ pref_SetPref(const char* aPrefName,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (!pref->Name()) {
|
||||
// New (zeroed) entry. Partially initialize it.
|
||||
new (pref) Pref(aPrefName);
|
||||
if (pref->IsTypeNone()) {
|
||||
// New entry. Set the type.
|
||||
pref->SetType(aType);
|
||||
}
|
||||
|
||||
@ -3165,11 +3178,6 @@ Preferences::SetPreference(const dom::Pref& aDomPref)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pref->Name()) {
|
||||
// New (zeroed) entry. Partially initialize it.
|
||||
new (pref) Pref(prefName);
|
||||
}
|
||||
|
||||
bool valueChanged = false;
|
||||
pref->FromDomPref(aDomPref, &valueChanged);
|
||||
|
||||
|
@ -2292,8 +2292,8 @@ HttpChannelParent::UpdateAndSerializeSecurityInfo(nsACString& aSerializedSecurit
|
||||
bool
|
||||
HttpChannelParent::DoSendDeleteSelf()
|
||||
{
|
||||
mIPCClosed = true;
|
||||
bool rv = SendDeleteSelf();
|
||||
mIPCClosed = true;
|
||||
|
||||
CleanupBackgroundChannel();
|
||||
|
||||
|
@ -2169,9 +2169,21 @@ class Repackage(MachCommandBase):
|
||||
help='Optional package .zip for building a full installer')
|
||||
@CommandArgument('--output', '-o', type=str, required=True,
|
||||
help='Output filename')
|
||||
def repackage_installer(self, tag, setupexe, package, output):
|
||||
@CommandArgument('--package-name', type=str, required=False,
|
||||
help='Name of the package being rebuilt')
|
||||
@CommandArgument('--sfx-stub', type=str, required=True,
|
||||
help='Path to the self-extraction stub.')
|
||||
def repackage_installer(self, tag, setupexe, package, output, package_name, sfx_stub):
|
||||
from mozbuild.repackaging.installer import repackage_installer
|
||||
repackage_installer(self.topsrcdir, tag, setupexe, package, output)
|
||||
repackage_installer(
|
||||
topsrcdir=self.topsrcdir,
|
||||
tag=tag,
|
||||
setupexe=setupexe,
|
||||
package=package,
|
||||
output=output,
|
||||
package_name=package_name,
|
||||
sfx_stub=sfx_stub,
|
||||
)
|
||||
|
||||
@SubCommand('repackage', 'mar',
|
||||
description='Repackage into complete MAR file')
|
||||
|
@ -10,9 +10,14 @@ import mozpack.path as mozpath
|
||||
from mozbuild.action.exe_7z_archive import archive_exe
|
||||
from mozbuild.util import ensureParentDir
|
||||
|
||||
def repackage_installer(topsrcdir, tag, setupexe, package, output):
|
||||
|
||||
def repackage_installer(topsrcdir, tag, setupexe, package, output, package_name, sfx_stub):
|
||||
if package and not zipfile.is_zipfile(package):
|
||||
raise Exception("Package file %s is not a valid .zip file." % package)
|
||||
if package is not None and package_name is None:
|
||||
raise Exception("Package name must be provided, if a package is provided.")
|
||||
if package is None and package_name is not None:
|
||||
raise Exception("Package name must not be provided, if a package is not provided.")
|
||||
|
||||
# We need the full path for the tag and output, since we chdir later.
|
||||
tag = mozpath.realpath(tag)
|
||||
@ -35,9 +40,8 @@ def repackage_installer(topsrcdir, tag, setupexe, package, output):
|
||||
# unpacked (the tmpdir)
|
||||
os.chdir(tmpdir)
|
||||
|
||||
sfx_package = mozpath.join(topsrcdir, 'other-licenses/7zstub/firefox/7zSD.sfx')
|
||||
sfx_package = mozpath.join(topsrcdir, sfx_stub)
|
||||
|
||||
package_name = 'firefox' if package else None
|
||||
archive_exe(package_name, tag, sfx_package, output)
|
||||
|
||||
finally:
|
||||
|
@ -12,20 +12,23 @@ download_config = {
|
||||
|
||||
repackage_config = [[
|
||||
"installer",
|
||||
"--package-name", "firefox",
|
||||
"--package", "{abs_work_dir}\\inputs\\target.zip",
|
||||
"--tag", "{abs_mozilla_dir}\\browser\\installer\\windows\\app.tag",
|
||||
"--setupexe", "{abs_work_dir}\\inputs\\setup.exe",
|
||||
"-o", "{output_home}\\target.installer.exe"
|
||||
"-o", "{output_home}\\target.installer.exe",
|
||||
"--sfx-stub", "other-licenses/7zstub/firefox/7zSD.sfx",
|
||||
], [
|
||||
"mar",
|
||||
"-i", "{abs_work_dir}\\inputs\\target.zip",
|
||||
"--mar", "{abs_work_dir}\\inputs\\mar.exe",
|
||||
"-o", "{output_home}\\target.complete.mar"
|
||||
"-o", "{output_home}\\target.complete.mar",
|
||||
], [
|
||||
"installer",
|
||||
"--tag", "{abs_mozilla_dir}\\browser\\installer\\windows\\stub.tag",
|
||||
"--setupexe", "{abs_work_dir}\\inputs\\setup-stub.exe",
|
||||
"-o", "{output_home}\\target.stub-installer.exe"
|
||||
"-o", "{output_home}\\target.stub-installer.exe",
|
||||
"--sfx-stub", "other-licenses/7zstub/firefox/7zSD.sfx",
|
||||
]]
|
||||
|
||||
config = {
|
||||
|
@ -10,15 +10,17 @@ download_config = {
|
||||
|
||||
repackage_config = [[
|
||||
"installer",
|
||||
"--package-name", "firefox",
|
||||
"--package", "{abs_work_dir}\\inputs\\target.zip",
|
||||
"--tag", "{abs_mozilla_dir}\\browser\\installer\\windows\\app.tag",
|
||||
"--setupexe", "{abs_work_dir}\\inputs\\setup.exe",
|
||||
"-o", "{output_home}\\target.installer.exe"
|
||||
"-o", "{output_home}\\target.installer.exe",
|
||||
"--sfx-stub", "other-licenses/7zstub/firefox/7zSD.sfx",
|
||||
], [
|
||||
"mar",
|
||||
"-i", "{abs_work_dir}\\inputs\\target.zip",
|
||||
"--mar", "{abs_work_dir}\\inputs\\mar.exe",
|
||||
"-o", "{output_home}\\target.complete.mar"
|
||||
"-o", "{output_home}\\target.complete.mar",
|
||||
]]
|
||||
|
||||
config = {
|
||||
|
@ -16,10 +16,8 @@ config = {
|
||||
"hg_l10n_tag": "default",
|
||||
|
||||
# MAR
|
||||
"update_mar_dir": "dist/update", # sure?
|
||||
"application_ini": "application.ini",
|
||||
"local_mar_tool_dir": "dist/host/bin",
|
||||
"mar": "mar",
|
||||
"mbsdiff": "mbsdiff",
|
||||
"localized_mar": "firefox-%(version)s.%(locale)s.linux-i686.complete.mar",
|
||||
}
|
||||
|
@ -16,10 +16,8 @@ config = {
|
||||
"hg_l10n_tag": "default",
|
||||
|
||||
# MAR
|
||||
"update_mar_dir": "dist/update", # sure?
|
||||
"application_ini": "application.ini",
|
||||
"local_mar_tool_dir": "dist/host/bin",
|
||||
"mar": "mar",
|
||||
"mbsdiff": "mbsdiff",
|
||||
"localized_mar": "firefox-%(version)s.%(locale)s.linux-x86_64.complete.mar",
|
||||
}
|
||||
|
@ -16,12 +16,10 @@ config = {
|
||||
"hg_l10n_tag": "default",
|
||||
|
||||
# MAR
|
||||
"update_mar_dir": "dist/update", # sure?
|
||||
"application_ini": "application.ini",
|
||||
"local_mar_tool_dir": "dist/host/bin",
|
||||
"mar": "mar",
|
||||
"mbsdiff": "mbsdiff",
|
||||
"localized_mar": "firefox-%(version)s.%(locale)s.linux-x86_64.complete.mar",
|
||||
|
||||
"update_channel": "aurora",
|
||||
}
|
||||
|
@ -16,12 +16,10 @@ config = {
|
||||
"hg_l10n_tag": "default",
|
||||
|
||||
# MAR
|
||||
"update_mar_dir": "dist/update", # sure?
|
||||
"application_ini": "application.ini",
|
||||
"local_mar_tool_dir": "dist/host/bin",
|
||||
"mar": "mar",
|
||||
"mbsdiff": "mbsdiff",
|
||||
"localized_mar": "firefox-%(version)s.%(locale)s.linux-i686.complete.mar",
|
||||
|
||||
"update_channel": "aurora",
|
||||
}
|
||||
|
@ -21,10 +21,8 @@ config = {
|
||||
"hg_l10n_tag": "default",
|
||||
|
||||
# MAR
|
||||
"update_mar_dir": "dist/update", # sure?
|
||||
"application_ini": "Contents/Resources/application.ini",
|
||||
"local_mar_tool_dir": "dist/host/bin",
|
||||
"mar": "mar",
|
||||
"mbsdiff": "mbsdiff",
|
||||
"localized_mar": "firefox-%(version)s.%(locale)s.mac.complete.mar",
|
||||
}
|
||||
|
@ -22,12 +22,10 @@ config = {
|
||||
"hg_l10n_tag": "default",
|
||||
|
||||
# MAR
|
||||
"update_mar_dir": "dist/update", # sure?
|
||||
"application_ini": "Contents/Resources/application.ini",
|
||||
"local_mar_tool_dir": "dist/host/bin",
|
||||
"mar": "mar",
|
||||
"mbsdiff": "mbsdiff",
|
||||
"localized_mar": "firefox-%(version)s.%(locale)s.mac.complete.mar",
|
||||
|
||||
"update_channel": "aurora",
|
||||
}
|
||||
|
@ -21,12 +21,10 @@ config = {
|
||||
"hg_l10n_tag": "default",
|
||||
|
||||
# MAR
|
||||
"update_mar_dir": "dist\\update", # sure?
|
||||
"application_ini": "application.ini",
|
||||
"local_mar_tool_dir": "dist\\host\\bin",
|
||||
"mar": "mar.exe",
|
||||
"mbsdiff": "mbsdiff.exe",
|
||||
"localized_mar": "firefox-%(version)s.%(locale)s.win32.complete.mar",
|
||||
|
||||
# use mozmake?
|
||||
"enable_mozmake": True,
|
||||
|
@ -20,12 +20,10 @@ config = {
|
||||
"hg_l10n_tag": "default",
|
||||
|
||||
# MAR
|
||||
"update_mar_dir": "dist\\update", # sure?
|
||||
"application_ini": "application.ini",
|
||||
"local_mar_tool_dir": "dist\\host\\bin",
|
||||
"mar": "mar.exe",
|
||||
"mbsdiff": "mbsdiff.exe",
|
||||
"localized_mar": "firefox-%(version)s.%(locale)s.win32.complete.mar",
|
||||
|
||||
# use mozmake?
|
||||
"enable_mozmake": True,
|
||||
|
@ -20,12 +20,10 @@ config = {
|
||||
"hg_l10n_tag": "default",
|
||||
|
||||
# MAR
|
||||
"update_mar_dir": "dist\\update", # sure?
|
||||
"application_ini": "application.ini",
|
||||
"local_mar_tool_dir": "dist\\host\\bin",
|
||||
"mar": "mar.exe",
|
||||
"mbsdiff": "mbsdiff.exe",
|
||||
"localized_mar": "firefox-%(version)s.%(locale)s.win64.complete.mar",
|
||||
|
||||
# use mozmake?
|
||||
"enable_mozmake": True,
|
||||
|
@ -20,12 +20,10 @@ config = {
|
||||
"hg_l10n_tag": "default",
|
||||
|
||||
# MAR
|
||||
"update_mar_dir": "dist\\update", # sure?
|
||||
"application_ini": "application.ini",
|
||||
"local_mar_tool_dir": "dist\\host\\bin",
|
||||
"mar": "mar.exe",
|
||||
"mbsdiff": "mbsdiff.exe",
|
||||
"localized_mar": "firefox-%(version)s.%(locale)s.win64.complete.mar",
|
||||
|
||||
# use mozmake?
|
||||
"enable_mozmake": True,
|
||||
|
@ -31,7 +31,6 @@ from mozharness.mozilla.building.buildbase import (
|
||||
)
|
||||
from mozharness.mozilla.l10n.locales import LocalesMixin
|
||||
from mozharness.mozilla.mar import MarMixin
|
||||
from mozharness.mozilla.mock import MockMixin
|
||||
from mozharness.mozilla.release import ReleaseMixin
|
||||
from mozharness.mozilla.signing import SigningMixin
|
||||
from mozharness.mozilla.updates.balrog import BalrogMixin
|
||||
@ -73,7 +72,7 @@ runtime_config_tokens = ('buildid', 'version', 'locale', 'from_buildid',
|
||||
|
||||
|
||||
# DesktopSingleLocale {{{1
|
||||
class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
|
||||
class DesktopSingleLocale(LocalesMixin, ReleaseMixin, BuildbotMixin,
|
||||
VCSMixin, SigningMixin, PurgeMixin, BaseScript,
|
||||
BalrogMixin, MarMixin, VirtualenvMixin, TransferMixin):
|
||||
"""Manages desktop repacks"""
|
||||
@ -161,7 +160,7 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
|
||||
["--disable-mock"], {
|
||||
"dest": "disable_mock",
|
||||
"action": "store_true",
|
||||
"help": "do not run under mock despite what gecko-config says"}
|
||||
"help": "(deprecated) no-op for CLI compatability with mobile_l10n.py"}
|
||||
], [
|
||||
['--scm-level'], { # Ignored on desktop for now: see Bug 1414678.
|
||||
"action": "store",
|
||||
@ -192,7 +191,6 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
|
||||
"buildbot_json_path": "buildprops.json",
|
||||
"ignore_locales": ["en-US"],
|
||||
"locales_dir": "browser/locales",
|
||||
"update_mar_dir": "dist/update",
|
||||
"buildid_section": "App",
|
||||
"buildid_option": "BuildID",
|
||||
"application_ini": "application.ini",
|
||||
@ -228,14 +226,10 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
|
||||
self.version = None
|
||||
self.upload_urls = {}
|
||||
self.locales_property = {}
|
||||
self.package_urls = {}
|
||||
self.pushdate = None
|
||||
# upload_files is a dictionary of files to upload, keyed by locale.
|
||||
self.upload_files = {}
|
||||
|
||||
if 'mock_target' in self.config:
|
||||
self.enable_mock()
|
||||
|
||||
def _pre_config_lock(self, rw_config):
|
||||
"""replaces 'configuration_tokens' with their values, before the
|
||||
configuration gets locked. If some of the configuration_tokens
|
||||
@ -715,12 +709,7 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
|
||||
return self._mach(target=target, env=env)
|
||||
|
||||
def _get_mach_executable(self):
|
||||
python = sys.executable
|
||||
# A mock environment is a special case, the system python isn't
|
||||
# available there
|
||||
if 'mock_target' in self.config:
|
||||
python = 'python2.7'
|
||||
return [python, 'mach']
|
||||
return [sys.executable, 'mach']
|
||||
|
||||
def _get_make_executable(self):
|
||||
config = self.config
|
||||
@ -793,9 +782,6 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
|
||||
log_obj=self.log_obj)
|
||||
retval = self._make(target=target, cwd=cwd, env=env,
|
||||
halt_on_failure=False, output_parser=parser)
|
||||
if locale not in self.package_urls:
|
||||
self.package_urls[locale] = {}
|
||||
self.package_urls[locale].update(parser.matches)
|
||||
if retval == SUCCESS:
|
||||
self.info('Upload successful (%s)' % locale)
|
||||
ret = SUCCESS
|
||||
@ -955,80 +941,7 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
|
||||
self.generate_balrog_props(props_path)
|
||||
return SUCCESS
|
||||
|
||||
if self.config.get('taskcluster_nightly'):
|
||||
self._map(balrog_props_wrapper, self.query_locales())
|
||||
else:
|
||||
if not self.config.get("balrog_servers"):
|
||||
self.info("balrog_servers not set; skipping balrog submission.")
|
||||
return
|
||||
# submit complete mar to balrog
|
||||
# clean up buildbot_properties
|
||||
self._map(self.submit_repack_to_balrog, self.query_locales())
|
||||
|
||||
def submit_repack_to_balrog(self, locale):
|
||||
"""submit a single locale to balrog"""
|
||||
# check if locale has been uploaded, if not just return a FAILURE
|
||||
if locale not in self.package_urls:
|
||||
self.error("%s is not present in package_urls. Did you run make upload?" % locale)
|
||||
return FAILURE
|
||||
|
||||
if not self.query_is_nightly():
|
||||
# remove this check when we extend this script to non-nightly builds
|
||||
self.fatal("Not a nightly build")
|
||||
return FAILURE
|
||||
|
||||
# complete mar file
|
||||
c_marfile = self._query_complete_mar_filename(locale)
|
||||
c_mar_url = self._query_complete_mar_url(locale)
|
||||
|
||||
# Set other necessary properties for Balrog submission. None need to
|
||||
# be passed back to buildbot, so we won't write them to the properties
|
||||
# files
|
||||
# Locale is hardcoded to en-US, for silly reasons
|
||||
# The Balrog submitter translates this platform into a build target
|
||||
# via
|
||||
# https://github.com/mozilla/build-tools/blob/master/lib/python/release/platforms.py#L23
|
||||
self.set_buildbot_property("completeMarSize", self.query_filesize(c_marfile))
|
||||
self.set_buildbot_property("completeMarHash", self.query_sha512sum(c_marfile))
|
||||
self.set_buildbot_property("completeMarUrl", c_mar_url)
|
||||
self.set_buildbot_property("locale", locale)
|
||||
if "partialInfo" in self.package_urls[locale]:
|
||||
self.set_buildbot_property("partialInfo",
|
||||
self.package_urls[locale]["partialInfo"])
|
||||
ret = FAILURE
|
||||
try:
|
||||
result = self.submit_balrog_updates()
|
||||
self.info("balrog return code: %s" % (result))
|
||||
if result == 0:
|
||||
ret = SUCCESS
|
||||
except Exception as error:
|
||||
self.error("submit repack to balrog failed: %s" % (str(error)))
|
||||
return ret
|
||||
|
||||
def _query_complete_mar_filename(self, locale):
|
||||
"""returns the full path to a localized complete mar file"""
|
||||
config = self.config
|
||||
version = self.query_version()
|
||||
complete_mar_name = config['localized_mar'] % {'version': version,
|
||||
'locale': locale}
|
||||
return os.path.join(self._update_mar_dir(), complete_mar_name)
|
||||
|
||||
def _query_complete_mar_url(self, locale):
|
||||
"""returns the complete mar url taken from self.package_urls[locale]
|
||||
this value is available only after make_upload"""
|
||||
if "complete_mar_url" in self.config:
|
||||
return self.config["complete_mar_url"]
|
||||
if "completeMarUrl" in self.package_urls[locale]:
|
||||
return self.package_urls[locale]["completeMarUrl"]
|
||||
# url = self.config.get("update", {}).get("mar_base_url")
|
||||
# if url:
|
||||
# url += os.path.basename(self.query_marfile_path())
|
||||
# return url.format(branch=self.query_branch())
|
||||
self.fatal("Couldn't find complete mar url in config or package_urls")
|
||||
|
||||
def _update_mar_dir(self):
|
||||
"""returns the full path of the update/ directory"""
|
||||
return self._mar_dir('update_mar_dir')
|
||||
self._map(balrog_props_wrapper, self.query_locales())
|
||||
|
||||
def _mar_binaries(self):
|
||||
"""returns a tuple with mar and mbsdiff paths"""
|
||||
@ -1070,10 +983,6 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
|
||||
if not manifest_src and not toolchains:
|
||||
return
|
||||
python = sys.executable
|
||||
# A mock environment is a special case, the system python isn't
|
||||
# available there
|
||||
if 'mock_target' in self.config:
|
||||
python = 'python2.7'
|
||||
|
||||
cmd = [
|
||||
python, '-u',
|
||||
@ -1104,22 +1013,6 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
|
||||
self.run_command(cmd, cwd=dirs['abs_mozilla_dir'], halt_on_failure=True,
|
||||
env=env)
|
||||
|
||||
def funsize_props(self):
|
||||
"""Set buildbot properties required to trigger funsize tasks
|
||||
responsible to generate partial updates for successfully generated locales"""
|
||||
locales = self.query_locales()
|
||||
funsize_info = {
|
||||
'locales': locales,
|
||||
'branch': self.config['branch'],
|
||||
'appName': self.config['appName'],
|
||||
'platform': self.config['platform'],
|
||||
'completeMarUrls': {locale: self._query_complete_mar_url(locale)
|
||||
for locale in locales},
|
||||
}
|
||||
self.info('funsize info: %s' % funsize_info)
|
||||
self.set_buildbot_property('funsize_info', json.dumps(funsize_info),
|
||||
write_to_file=True)
|
||||
|
||||
def taskcluster_upload(self):
|
||||
auth = os.path.join(os.getcwd(), self.config['taskcluster_credentials_file'])
|
||||
credentials = {}
|
||||
@ -1135,9 +1028,7 @@ class DesktopSingleLocale(LocalesMixin, ReleaseMixin, MockMixin, BuildbotMixin,
|
||||
# could create the virtualenv as an action, but due to some odd
|
||||
# dependencies with query_build_env() being called from build(), which
|
||||
# is necessary before the virtualenv can be created.
|
||||
self.disable_mock()
|
||||
self.create_virtualenv()
|
||||
self.enable_mock()
|
||||
self.activate_virtualenv()
|
||||
|
||||
branch = self.config['branch']
|
||||
|
@ -12242,7 +12242,8 @@
|
||||
"record_in_processes": ["main", "content"],
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"alert_emails": ["push@mozilla.com"],
|
||||
"expires_in_version": "60",
|
||||
"bug_numbers": [1429286],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Number of push messages that were successfully decrypted and delivered to a ServiceWorker."
|
||||
},
|
||||
@ -12292,8 +12293,8 @@
|
||||
"record_in_processes": ["main", "content"],
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"alert_emails": ["firefox-dev@mozilla.org", "push@mozilla.com"],
|
||||
"bug_numbers": [1225336],
|
||||
"expires_in_version": "60",
|
||||
"bug_numbers": [1225336, 1429286],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Count of times a web notification was clicked"
|
||||
},
|
||||
@ -12310,8 +12311,8 @@
|
||||
"record_in_processes": ["main", "content"],
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"alert_emails": ["firefox-dev@mozilla.org", "push@mozilla.com"],
|
||||
"bug_numbers": [1225336],
|
||||
"expires_in_version": "60",
|
||||
"bug_numbers": [1225336, 1429286],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"description": "Count of times a Notification was rendered (accounting for XUL DND). A system backend may put the notification directly into the tray if its own DND is on."
|
||||
},
|
||||
@ -12426,8 +12427,8 @@
|
||||
"record_in_processes": ["main", "content"],
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"alert_emails": ["firefox-dev@mozilla.org", "push@mozilla.com"],
|
||||
"bug_numbers": [1219030],
|
||||
"expires_in_version": "60",
|
||||
"bug_numbers": [1219030, 1429286],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 10,
|
||||
"description": "Number of origins with the web notifications permission (0 = denied, 1 = allowed)."
|
||||
|
@ -1098,6 +1098,24 @@ gfx.omtp:
|
||||
record_in_processes:
|
||||
- 'content'
|
||||
|
||||
gfx:
|
||||
small_paint_phase_weight:
|
||||
bug_numbers:
|
||||
- 1430897
|
||||
description: >
|
||||
Time that is spent in each phase of painting, as a percentage of
|
||||
paint time. See also CONTENT_LARGE_PAINT_PHASE_WEIGHT in Histograms.json.
|
||||
Keys are r (rasterization), dl (display list construction), and flb
|
||||
(FrameLayerBuilder).
|
||||
keyed: true
|
||||
kind: uint
|
||||
expires: "66"
|
||||
notification_emails:
|
||||
- gfx-telemetry-alerts@mozilla.com
|
||||
- mwoodrow@mozilla.com
|
||||
record_in_processes:
|
||||
- 'content'
|
||||
|
||||
# The following section contains the form autofill related scalars.
|
||||
formautofill:
|
||||
availability:
|
||||
|
@ -1154,7 +1154,6 @@
|
||||
"PREDICTOR_WAIT_TIME",
|
||||
"PROCESS_CRASH_SUBMIT_ATTEMPT",
|
||||
"PROCESS_CRASH_SUBMIT_SUCCESS",
|
||||
"PUSH_API_NOTIFY",
|
||||
"PWMGR_BLOCKLIST_NUM_SITES",
|
||||
"PWMGR_LOGIN_LAST_USED_DAYS",
|
||||
"PWMGR_MANAGE_COPIED_PASSWORD",
|
||||
|
Loading…
x
Reference in New Issue
Block a user