Bug 1547369 - Support composition recording on CompositorD3D11 r=mstange
authorBarret Rennie <barret@brennie.ca>
Thu, 02 May 2019 17:33:38 +0000
changeset 472325 98a5645c05669d1ad56bf3d6f5f602869e477876
parent 472324 68e1511514dfeabaa403e29a8bfa950f7e4b0c8d
child 472326 6de795fcf1fa66ba4275014bebd7eda321583d44
push id84599
push userbrennie@mozilla.com
push dateThu, 02 May 2019 17:34:47 +0000
treeherderautoland@98a5645c0566 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1547369
milestone68.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 1547369 - Support composition recording on CompositorD3D11 r=mstange CompositorD3D11's implementation of `GetWindowRenderTarget` would return a `nullptr` if we were not presently recording a profile with screenshots. Now, CompositorD3D11 correctly will return a window render target when it has been asked to by the `LayerManagerComposite` via `Compositor::RequestRecordFrames`. Differential Revision: https://phabricator.services.mozilla.com/D29369
gfx/layers/Compositor.h
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/d3d11/CompositorD3D11.h
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -520,17 +520,17 @@ class Compositor : public TextureSourceP
   // frames and should not be used.
   void SetInvalid();
   bool IsValid() const override;
   CompositorBridgeParent* GetCompositorBridgeParent() const { return mParent; }
 
   /**
    * Request the compositor to allow recording its frames.
    *
-   * For all compositors except |BasicCompositor|, this is a noop.
+   * This is a noop on |CompositorOGL|.
    */
   virtual void RequestAllowFrameRecording(bool aWillRecord) {}
 
   /**
    * Record the current frame for readback by the |CompositionRecorder|.
    *
    * If this compositor does not support this feature, a null pointer is
    * returned instead.
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -444,22 +444,27 @@ CompositorD3D11::CreateRenderTargetFromS
 
   RefPtr<CompositingRenderTargetD3D11> rt =
       new CompositingRenderTargetD3D11(texture, aRect.TopLeft());
   rt->SetSize(aRect.Size());
 
   return rt.forget();
 }
 
+bool CompositorD3D11::ShouldAllowFrameRecording() const {
+#ifdef MOZ_GECKO_PROFILER
+  return mAllowFrameRecording || profiler_feature_active(ProfilerFeature::Screenshots);
+#else
+  return mAllowFrameRecording;
+#endif
+}
+
 already_AddRefed<CompositingRenderTarget>
 CompositorD3D11::GetWindowRenderTarget() const {
-#ifndef MOZ_GECKO_PROFILER
-  return nullptr;
-#else
-  if (!profiler_feature_active(ProfilerFeature::Screenshots)) {
+  if (!ShouldAllowFrameRecording()) {
     return nullptr;
   }
 
   if (!mDefaultRT) {
     return nullptr;
   }
 
   const IntSize size = mDefaultRT->GetSize();
@@ -490,17 +495,16 @@ CompositorD3D11::GetWindowRenderTarget()
   }
 
   const RefPtr<ID3D11Texture2D> sourceTexture = mDefaultRT->GetD3D11Texture();
   mContext->CopyResource(rtTexture, sourceTexture);
 
   return RefPtr<CompositingRenderTarget>(
              static_cast<CompositingRenderTarget*>(mWindowRTCopy))
       .forget();
-#endif
 }
 
 bool CompositorD3D11::ReadbackRenderTarget(CompositingRenderTarget* aSource,
                                            AsyncReadbackBuffer* aDest) {
   RefPtr<CompositingRenderTargetD3D11> srcTexture =
       static_cast<CompositingRenderTargetD3D11*>(aSource);
   RefPtr<AsyncReadbackBufferD3D11> destBuffer =
       static_cast<AsyncReadbackBufferD3D11*>(aDest);
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -134,16 +134,20 @@ class CompositorD3D11 : public Composito
 
   // For TextureSourceProvider.
   ID3D11Device* GetD3D11Device() const override { return mDevice; }
 
   ID3D11Device* GetDevice() { return mDevice; }
 
   ID3D11DeviceContext* GetDC() { return mContext; }
 
+  virtual void RequestAllowFrameRecording(bool aWillRecord) override {
+    mAllowFrameRecording = aWillRecord;
+  }
+
  private:
   enum Severity {
     Recoverable,
     DebugAssert,
     Critical,
   };
 
   void HandleError(HRESULT hr, Severity aSeverity = DebugAssert);
@@ -204,16 +208,29 @@ class CompositorD3D11 : public Composito
 
   ID3D11VertexShader* GetVSForGeometry(const gfx::Rect& aRect,
                                        const bool aUseBlendShader,
                                        const MaskType aMaskType);
 
   template <typename VertexType>
   void SetVertexBuffer(ID3D11Buffer* aBuffer);
 
+  /**
+   * Whether or not the recorder should be recording frames.
+   *
+   * When this returns true, the CompositorD3D11 will allocate and return window
+   * render targets from |GetWindowRenderTarget|, which otherwise returns
+   * nullptr.
+   *
+   * This will be true when either we are recording a profile with screenshots
+   * enabled or the |LayerManagerComposite| has requested us to record frames
+   * for the |CompositionRecorder|.
+   */
+  bool ShouldAllowFrameRecording() const;
+
   RefPtr<ID3D11DeviceContext> mContext;
   RefPtr<ID3D11Device> mDevice;
   RefPtr<IDXGISwapChain> mSwapChain;
   RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
   RefPtr<CompositingRenderTargetD3D11> mCurrentRT;
   mutable RefPtr<CompositingRenderTargetD3D11> mWindowRTCopy;
 
   RefPtr<ID3D11Query> mQuery;
@@ -235,16 +252,17 @@ class CompositorD3D11 : public Composito
 
   gfx::IntRegion mFrontBufferInvalid;
   gfx::IntRegion mBackBufferInvalid;
   // This is the clip rect applied to the default DrawTarget (i.e. the window)
   gfx::IntRect mCurrentClip;
 
   bool mVerifyBuffersFailed;
   bool mUseMutexOnPresent;
+  bool mAllowFrameRecording;
 };
 
 namespace TexSlot {
 static const int RGB = 0;
 static const int Y = 1;
 static const int Cb = 2;
 static const int Cr = 3;
 static const int RGBWhite = 4;