diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index 7d45638cefca..9e7f1ff27d9e 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -43,6 +43,7 @@ ClientLayerManager::ClientLayerManager(nsIWidget* aWidget) , mIsRepeatTransaction(false) , mTransactionIncomplete(false) , mCompositorMightResample(false) + , mNeedsComposite(false) { MOZ_COUNT_CTOR(ClientLayerManager); } @@ -299,8 +300,9 @@ ClientLayerManager::ForwardTransaction() mPhase = PHASE_FORWARD; // forward this transaction's changeset to our LayerManagerComposite + bool sent; AutoInfallibleTArray replies; - if (HasShadowManager() && ShadowLayerForwarder::EndTransaction(&replies)) { + if (HasShadowManager() && ShadowLayerForwarder::EndTransaction(&replies, &sent)) { for (nsTArray::size_type i = 0; i < replies.Length(); ++i) { const EditReply& reply = replies[i]; @@ -349,6 +351,10 @@ ClientLayerManager::ForwardTransaction() NS_RUNTIMEABORT("not reached"); } } + + if (sent) { + mNeedsComposite = false; + } } else if (HasShadowManager()) { NS_WARNING("failed to forward Layers transaction"); } diff --git a/gfx/layers/client/ClientLayerManager.h b/gfx/layers/client/ClientLayerManager.h index 1b3b61c8d2d0..1b3985a9107e 100644 --- a/gfx/layers/client/ClientLayerManager.h +++ b/gfx/layers/client/ClientLayerManager.h @@ -142,6 +142,12 @@ public: #endif bool InTransaction() { return mPhase != PHASE_NONE; } + void SetNeedsComposite(bool aNeedsComposite) + { + mNeedsComposite = aNeedsComposite; + } + bool NeedsComposite() const { return mNeedsComposite; } + protected: enum TransactionPhase { PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD @@ -200,6 +206,7 @@ private: bool mIsRepeatTransaction; bool mTransactionIncomplete; bool mCompositorMightResample; + bool mNeedsComposite; }; class ClientLayer : public ShadowableLayer diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 4a36695c79a0..81b1b66f4244 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -467,8 +467,10 @@ ShadowLayerForwarder::UseTexture(CompositableClient* aCompositable, } bool -ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies) +ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies, bool* aSent) { + *aSent = false; + PROFILER_LABEL("ShadowLayerForwarder", "EndTranscation"); RenderTraceScope rendertrace("Foward Transaction", "000091"); NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to"); @@ -582,6 +584,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies) } } + *aSent = true; mIsFirstPaint = false; MOZ_LAYERS_LOG(("[LayersForwarder] ... done")); return true; diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index db17030119c6..f088d0d4bdae 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -334,7 +334,7 @@ public: * |aReplies| are directions from the LayerManagerComposite to the * caller of EndTransaction(). */ - bool EndTransaction(InfallibleTArray* aReplies); + bool EndTransaction(InfallibleTArray* aReplies, bool* aSent); /** * Set an actor through which layer updates will be pushed. diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 5df0943cc1df..f5b03068b54c 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -1980,10 +1980,17 @@ nsWindow::OnExposeEvent(cairo_t *cr) if (!listener) return FALSE; - // Do an early async composite so that we at least have something on screen - // in the right place, even if the content is out of date. - if (GetLayerManager()->GetBackendType() == LAYERS_CLIENT && mCompositorParent) { - mCompositorParent->ScheduleRenderOnCompositorThread(); + ClientLayerManager *clientLayers = + (GetLayerManager()->GetBackendType() == LAYERS_CLIENT) + ? static_cast(GetLayerManager()) + : nullptr; + + if (clientLayers && mCompositorParent && + !gdk_screen_is_composited(gdk_window_get_screen(mGdkWindow))) + { + // We need to paint to the screen even if nothing changed, since if we + // don't have a compositing window manager, our pixels could be stale. + clientLayers->SetNeedsComposite(true); } // Dispatch WillPaintWindow notification to allow scripts etc. to run @@ -2004,6 +2011,11 @@ nsWindow::OnExposeEvent(cairo_t *cr) return FALSE; } + if (clientLayers && mCompositorParent && clientLayers->NeedsComposite()) { + mCompositorParent->ScheduleRenderOnCompositorThread(); + clientLayers->SetNeedsComposite(false); + } + #if (MOZ_WIDGET_GTK == 2) GdkRectangle *rects; gint nrects;