From 868c2e128c45c15a55c82ffe8a6efdf22d1c2e5f Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Thu, 19 Jun 2014 14:22:17 -0400 Subject: [PATCH] Bug 1027380 - Paint flashing from an inactive layer manager saturates the transparent layers. r=mattwoodrow --HG-- extra : rebase_source : 7444cf86fc14bd811d836d4c788958bf3790f572 --- gfx/layers/Layers.h | 1 + gfx/layers/basic/BasicLayerManager.cpp | 21 +++++++++++++-------- gfx/layers/basic/BasicLayers.h | 9 ++++++++- layout/base/FrameLayerBuilder.cpp | 5 +++-- layout/base/nsDisplayList.cpp | 2 +- 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 1f9932d10095..4944f236798b 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -213,6 +213,7 @@ public: * and is used for drawing into the widget. */ virtual bool IsWidgetLayerManager() { return true; } + virtual bool IsInactiveLayerManager() { return false; } /** * Start a new transaction. Nested transactions are not allowed so diff --git a/gfx/layers/basic/BasicLayerManager.cpp b/gfx/layers/basic/BasicLayerManager.cpp index d7cdd0be9321..8d8012c1b7d5 100644 --- a/gfx/layers/basic/BasicLayerManager.cpp +++ b/gfx/layers/basic/BasicLayerManager.cpp @@ -210,10 +210,12 @@ public: bool mPushedOpaqueRect; }; -BasicLayerManager::BasicLayerManager(nsIWidget* aWidget) : - mPhase(PHASE_NONE), - mWidget(aWidget) - , mDoubleBuffering(BufferMode::BUFFER_NONE), mUsingDefaultTarget(false) +BasicLayerManager::BasicLayerManager(nsIWidget* aWidget) + : mPhase(PHASE_NONE) + , mWidget(aWidget) + , mDoubleBuffering(BufferMode::BUFFER_NONE) + , mType(BLM_WIDGET) + , mUsingDefaultTarget(false) , mTransactionIncomplete(false) , mCompositorMightResample(false) { @@ -221,13 +223,16 @@ BasicLayerManager::BasicLayerManager(nsIWidget* aWidget) : NS_ASSERTION(aWidget, "Must provide a widget"); } -BasicLayerManager::BasicLayerManager() : - mPhase(PHASE_NONE), - mWidget(nullptr) - , mDoubleBuffering(BufferMode::BUFFER_NONE), mUsingDefaultTarget(false) +BasicLayerManager::BasicLayerManager(BasicLayerManagerType aType) + : mPhase(PHASE_NONE) + , mWidget(nullptr) + , mDoubleBuffering(BufferMode::BUFFER_NONE) + , mType(aType) + , mUsingDefaultTarget(false) , mTransactionIncomplete(false) { MOZ_COUNT_CTOR(BasicLayerManager); + MOZ_ASSERT(mType != BLM_WIDGET); } BasicLayerManager::~BasicLayerManager() diff --git a/gfx/layers/basic/BasicLayers.h b/gfx/layers/basic/BasicLayers.h index 293a4e46edc3..2ddd15bcbb6b 100644 --- a/gfx/layers/basic/BasicLayers.h +++ b/gfx/layers/basic/BasicLayers.h @@ -45,13 +45,18 @@ class BasicLayerManager : public LayerManager { public: + enum BasicLayerManagerType { + BLM_WIDGET, + BLM_OFFSCREEN, + BLM_INACTIVE + }; /** * Construct a BasicLayerManager which will have no default * target context. SetDefaultTarget or BeginTransactionWithTarget * must be called for any rendering to happen. ThebesLayers will not * be retained. */ - BasicLayerManager(); + BasicLayerManager(BasicLayerManagerType aType); /** * Construct a BasicLayerManager which will have no default * target context. SetDefaultTarget or BeginTransactionWithTarget @@ -89,6 +94,7 @@ public: void ClearRetainerWidget() { mWidget = nullptr; } virtual bool IsWidgetLayerManager() { return mWidget != nullptr; } + virtual bool IsInactiveLayerManager() { return mType == BLM_INACTIVE; } virtual void BeginTransaction(); virtual void BeginTransactionWithTarget(gfxContext* aTarget); @@ -183,6 +189,7 @@ protected: nsRefPtr mFactory; BufferMode mDoubleBuffering; + BasicLayerManagerType mType; bool mUsingDefaultTarget; bool mTransactionIncomplete; bool mCompositorMightResample; diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 01835432ed8d..94d9c455aa52 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -2826,7 +2826,7 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayerData* aLayerData, tempManager = data->mInactiveManager; } if (!tempManager) { - tempManager = new BasicLayerManager(); + tempManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE); } // We need to grab these before calling AddLayerDisplayItem because it will overwrite them. @@ -3891,7 +3891,8 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer, entry->mCommonClipCount); } - if (presContext->GetPaintFlashing()) { + if (presContext->GetPaintFlashing() && + !aLayer->Manager()->IsInactiveLayerManager()) { gfxContextAutoSaveRestore save(aContext); if (shouldDrawRectsSeparately) { if (aClip == DrawRegionClip::DRAW_SNAPPED) { diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 1bef6e307b0d..b82f17b66d47 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -1280,7 +1280,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder, NS_WARNING("Nowhere to paint into"); return; } - layerManager = new BasicLayerManager(); + layerManager = new BasicLayerManager(BasicLayerManager::BLM_OFFSCREEN); } // Store the existing layer builder to reinstate it on return.