Bug 1410777 - Force a full transaction for WR when the window overlay changes. r=mstange
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 26 Oct 2017 14:17:19 -0400
changeset 439484 7b501bcc9d3f2a9d7ff3cee0a9019cb3fd2bea3f
parent 439483 15b3f352292e8ec1f0e8c66dd83a3b535e35c582
child 439485 cd78beac7f6f52c46d438ecd6c7e397f19f77c79
push id8114
push userjlorenzo@mozilla.com
push dateThu, 02 Nov 2017 16:33:21 +0000
treeherdermozilla-beta@73e0d89a540f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1410777
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1410777 - Force a full transaction for WR when the window overlay changes. r=mstange The window buttons are drawn as part of the AddWindowOverlayWebRenderCommands function which is invoked in the full-transaction codepath. It should be possible to have the empty transaction codepath simply update the image (without building a full WR display list) and do a recomposite. That would be more performant but it requires some plumbing to build and ship across a IpcResourceUpdateQueue on empty transactions. MozReview-Commit-ID: 2Mrb0wELD6E
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderLayerManager.h
widget/cocoa/nsChildView.mm
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -23,16 +23,17 @@ namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
 WebRenderLayerManager::WebRenderLayerManager(nsIWidget* aWidget)
   : mWidget(aWidget)
   , mLatestTransactionId(0)
+  , mWindowOverlayChanged(false)
   , mNeedsComposite(false)
   , mIsFirstPaint(false)
   , mTarget(nullptr)
   , mPaintSequenceNumber(0)
   , mWebRenderCommandBuilder(this)
   , mLastDisplayListSize(0)
 {
   MOZ_COUNT_CTOR(WebRenderLayerManager);
@@ -169,16 +170,26 @@ WebRenderLayerManager::BeginTransaction(
     mApzTestData.StartNewPaint(mPaintSequenceNumber);
   }
   return true;
 }
 
 bool
 WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
 {
+  if (mWindowOverlayChanged) {
+    // If the window overlay changed then we can't do an empty transaction
+    // because we need to repaint the window overlay which we only currently
+    // support in a full transaction.
+    // XXX If we end up hitting this branch a lot we can probably optimize it
+    // by just sending an updated window overlay image instead of rebuilding
+    // the entire WR display list.
+    return false;
+  }
+
   // With the WebRenderLayerManager we reject attempts to set most kind of
   // "pending data" for empty transactions. Any place that attempts to update
   // transforms or scroll offset, for example, will get failure return values
   // back, and will fall back to a full transaction. Therefore the only piece
   // of "pending" information we need to send in an empty transaction are the
   // APZ focus state and canvases's CompositableOperations.
 
   if (aFlags & EndTransactionFlags::END_NO_COMPOSITE && 
@@ -270,16 +281,18 @@ WebRenderLayerManager::EndTransactionWit
   mWebRenderCommandBuilder.BuildWebRenderCommands(builder,
                                                   resourceUpdates,
                                                   aDisplayList,
                                                   aDisplayListBuilder,
                                                   mScrollData,
                                                   contentSize);
 
   mWidget->AddWindowOverlayWebRenderCommands(WrBridge(), builder, resourceUpdates);
+  mWindowOverlayChanged = false;
+
   WrBridge()->ClearReadLocks();
 
   if (AsyncPanZoomEnabled()) {
     mScrollData.SetFocusTarget(mFocusTarget);
     mFocusTarget = FocusTarget();
 
     if (mIsFirstPaint) {
       mScrollData.SetIsFirstPaint();
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -149,16 +149,17 @@ public:
   bool SetPendingScrollUpdateForNextTransaction(FrameMetrics::ViewID aScrollId,
                                                 const ScrollUpdateInfo& aUpdateInfo) override;
 
   WebRenderCommandBuilder& CommandBuilder() { return mWebRenderCommandBuilder; }
   WebRenderUserDataRefTable* GetWebRenderUserDataTable() { return mWebRenderCommandBuilder.GetWebRenderUserDataTable(); }
   WebRenderScrollData& GetScrollData() { return mScrollData; }
 
   void WrUpdated();
+  void WindowOverlayChanged() { mWindowOverlayChanged = true; }
 
 private:
   /**
    * Take a snapshot of the parent context, and copy
    * it into mTarget.
    */
   void MakeSnapshotIfRequired(LayoutDeviceIntSize aSize);
 
@@ -186,16 +187,17 @@ private:
   uint64_t mLatestTransactionId;
 
   nsTArray<DidCompositeObserver*> mDidCompositeObservers;
 
   // This holds the scroll data that we need to send to the compositor for
   // APZ to do it's job
   WebRenderScrollData mScrollData;
 
+  bool mWindowOverlayChanged;
   bool mNeedsComposite;
   bool mIsFirstPaint;
   FocusTarget mFocusTarget;
 
   // When we're doing a transaction in order to draw to a non-default
   // target, the layers transaction is only performed in order to send
   // a PLayers:Update.  We save the original non-default target to
   // mTarget, and then perform the transaction. After the transaction ends,
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -66,16 +66,17 @@
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/GLManager.h"
 #include "mozilla/layers/CompositorOGL.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/BasicCompositor.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/layers/IpcResourceUpdateQueue.h"
 #include "mozilla/layers/WebRenderBridgeChild.h"
+#include "mozilla/layers/WebRenderLayerManager.h"
 #include "mozilla/webrender/WebRenderAPI.h"
 #include "mozilla/widget/CompositorWidget.h"
 #include "gfxUtils.h"
 #include "gfxPrefs.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/BorrowedContext.h"
 #include "mozilla/gfx/MacIOSurface.h"
 #ifdef ACCESSIBILITY
@@ -4016,16 +4017,18 @@ NSEvent* gLastDragMouseDownEvent = nil;
       nsCOMPtr<nsIRunnable> releaserRunnable =
         new WidgetsReleaserRunnable(Move(widgetArray));
       NS_DispatchToMainThread(releaserRunnable);
     }
 
     if ([self isUsingOpenGL]) {
       if (ShadowLayerForwarder* slf = mGeckoChild->GetLayerManager()->AsShadowForwarder()) {
         slf->WindowOverlayChanged();
+      } else if (WebRenderLayerManager* wrlm = mGeckoChild->GetLayerManager()->AsWebRenderLayerManager()) {
+        wrlm->WindowOverlayChanged();
       }
     }
 
     mGeckoChild->WillPaintWindow();
   }
   [super viewWillDraw];
 }