Bug 1444449 - Implement CompositorD3D11::GetWindowRenderTarget API r=mstange,bas
authorBarret Rennie <barret@brennie.ca>
Tue, 19 Feb 2019 14:54:12 +0000
changeset 519122 6d6bbd91a4ee61702a6141101e9cae7177fac06b
parent 519121 b70102d25a47d2edca9f28c31db8a0103ff009a4
child 519123 82aa021d894dd25b43a74e619fdeb01395b6c712
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange, bas
bugs1444449
milestone67.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 1444449 - Implement CompositorD3D11::GetWindowRenderTarget API r=mstange,bas Differential Revision: https://phabricator.services.mozilla.com/D18145
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/d3d11/CompositorD3D11.h
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -45,16 +45,17 @@ namespace layers {
 
 bool CanUsePartialPresents(ID3D11Device* aDevice);
 
 const FLOAT sBlendFactor[] = {0, 0, 0, 0};
 
 CompositorD3D11::CompositorD3D11(CompositorBridgeParent* aParent,
                                  widget::CompositorWidget* aWidget)
     : Compositor(aWidget, aParent),
+      mWindowRTCopy(nullptr),
       mAttachments(nullptr),
       mHwnd(nullptr),
       mDisableSequenceForNextFrame(false),
       mAllowPartialPresents(false),
       mIsDoubleBuffered(false),
       mVerifyBuffersFailed(false),
       mUseMutexOnPresent(false) {
   mUseMutexOnPresent = gfxPrefs::UseMutexOnPresent();
@@ -392,16 +393,65 @@ CompositorD3D11::CreateRenderTargetFromS
 
   RefPtr<CompositingRenderTargetD3D11> rt =
       new CompositingRenderTargetD3D11(texture, aRect.TopLeft());
   rt->SetSize(aRect.Size());
 
   return rt.forget();
 }
 
+already_AddRefed<CompositingRenderTarget>
+CompositorD3D11::GetWindowRenderTarget() const {
+#ifndef MOZ_GECKO_PROFILER
+  return nullptr;
+#else
+  if (!profiler_feature_active(ProfilerFeature::Screenshots)) {
+    return nullptr;
+  }
+
+  if (!mDefaultRT) {
+    return nullptr;
+  }
+
+  const IntSize size = mDefaultRT->GetSize();
+
+  RefPtr<ID3D11Texture2D> rtTexture;
+
+  if (!mWindowRTCopy || mWindowRTCopy->GetSize() != size) {
+    /*
+     * The compositor screenshots infrastructure is going to scale down the
+     * render target returned by this method. However, mDefaultRT does not
+     * contain a texture created wth the D3D11_BIND_SHADER_RESOURCE flag, so if
+     * we were to simply return mDefaultRT then scaling would fail.
+     */
+    CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, size.width,
+                               size.height, 1, 1, D3D11_BIND_SHADER_RESOURCE);
+
+    HRESULT hr =
+        mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(rtTexture));
+    if (FAILED(hr)) {
+      return nullptr;
+    }
+
+    mWindowRTCopy = MakeRefPtr<CompositingRenderTargetD3D11>(
+        rtTexture, IntPoint(0, 0), DXGI_FORMAT_B8G8R8A8_UNORM);
+    mWindowRTCopy->SetSize(size);
+  } else {
+    rtTexture = mWindowRTCopy->GetD3D11Texture();
+  }
+
+  const RefPtr<ID3D11Texture2D> sourceTexture = mDefaultRT->GetD3D11Texture();
+  mContext->CopyResource(rtTexture, sourceTexture);
+
+  return RefPtr<CompositingRenderTarget>(
+             static_cast<CompositingRenderTarget*>(mWindowRTCopy))
+      .forget();
+#endif
+}
+
 bool CompositorD3D11::CopyBackdrop(const gfx::IntRect& aRect,
                                    RefPtr<ID3D11Texture2D>* aOutTexture,
                                    RefPtr<ID3D11ShaderResourceView>* aOutView) {
   RefPtr<ID3D11Texture2D> texture =
       CreateTexture(aRect, mCurrentRT, aRect.TopLeft());
   if (!texture) {
     return false;
   }
@@ -1045,16 +1095,20 @@ void CompositorD3D11::BeginFrame(const n
 
     mDiagnostics->Start(pixelsPerFrame);
   }
 }
 
 void CompositorD3D11::NormalDrawingDone() { mDiagnostics->End(); }
 
 void CompositorD3D11::EndFrame() {
+  if (!profiler_feature_active(ProfilerFeature::Screenshots) && mWindowRTCopy) {
+    mWindowRTCopy = nullptr;
+  }
+
   if (!mDefaultRT) {
     Compositor::EndFrame();
     return;
   }
 
   if (XRE_IsParentProcess() && mDevice->GetDeviceRemovedReason() != S_OK) {
     gfxCriticalNote << "GFX: D3D11 skip EndFrame with device-removed.";
     Compositor::EndFrame();
@@ -1276,16 +1330,17 @@ bool CompositorD3D11::VerifyBufferSize()
     RefPtr<ID3D11RenderTargetView> rtView = mDefaultRT->mRTView;
     RefPtr<ID3D11ShaderResourceView> srView = mDefaultRT->mSRV;
 
     // Make sure the texture, which belongs to the swapchain, is destroyed
     // before resizing the swapchain.
     if (mCurrentRT == mDefaultRT) {
       mCurrentRT = nullptr;
     }
+
     MOZ_ASSERT(mDefaultRT->hasOneRef());
     mDefaultRT = nullptr;
 
     RefPtr<ID3D11Resource> resource;
     rtView->GetResource(getter_AddRefs(resource));
 
     ULONG newRefCnt = rtView.forget().take()->Release();
 
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -53,16 +53,18 @@ class CompositorD3D11 : public Composito
                                const CompositingRenderTarget* aSource,
                                const gfx::IntPoint& aSourcePoint) override;
 
   virtual void SetRenderTarget(CompositingRenderTarget* aSurface) override;
   virtual already_AddRefed<CompositingRenderTarget> GetCurrentRenderTarget()
       const override {
     return do_AddRef(mCurrentRT);
   }
+  virtual already_AddRefed<CompositingRenderTarget> GetWindowRenderTarget()
+      const override;
 
   virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) override {}
 
   /**
    * Declare an offset to use when rendering layers. This will be ignored when
    * rendering to a target instead of the screen.
    */
   virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) override {
@@ -201,16 +203,17 @@ class CompositorD3D11 : public Composito
   template <typename VertexType>
   void SetVertexBuffer(ID3D11Buffer* aBuffer);
 
   RefPtr<ID3D11DeviceContext> mContext;
   RefPtr<ID3D11Device> mDevice;
   RefPtr<IDXGISwapChain> mSwapChain;
   RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
   RefPtr<CompositingRenderTargetD3D11> mCurrentRT;
+  mutable RefPtr<CompositingRenderTargetD3D11> mWindowRTCopy;
 
   RefPtr<ID3D11Query> mQuery;
 
   RefPtr<DeviceAttachmentsD3D11> mAttachments;
   UniquePtr<DiagnosticsD3D11> mDiagnostics;
 
   LayoutDeviceIntSize mSize;