Bug 1331944 - Part 3. Refactor mozilla::wr::LockExternalImage to make it easier to add new types. r=jrmuizel
authorAndrew Osmond <aosmond@mozilla.com>
Mon, 30 Oct 2017 09:10:44 -0400
changeset 439859 40ec5550739449f1cb8ad7d030a40cc10f9653bc
parent 439858 83cc1f67e9f78482484d8945e6caed4517810dcf
child 439860 5bdfda0b0b3aeba50ed171ef0227ab6cc9fbede7
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)
reviewersjrmuizel
bugs1331944
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 1331944 - Part 3. Refactor mozilla::wr::LockExternalImage to make it easier to add new types. r=jrmuizel
gfx/webrender_bindings/RenderBufferTextureHost.cpp
gfx/webrender_bindings/RenderBufferTextureHost.h
gfx/webrender_bindings/RenderD3D11TextureHostOGL.cpp
gfx/webrender_bindings/RenderD3D11TextureHostOGL.h
gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.cpp
gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.h
gfx/webrender_bindings/RenderTextureHost.h
gfx/webrender_bindings/RenderTextureHostOGL.h
gfx/webrender_bindings/RendererOGL.cpp
--- a/gfx/webrender_bindings/RenderBufferTextureHost.cpp
+++ b/gfx/webrender_bindings/RenderBufferTextureHost.cpp
@@ -38,35 +38,35 @@ RenderBufferTextureHost::RenderBufferTex
   }
 }
 
 RenderBufferTextureHost::~RenderBufferTextureHost()
 {
   MOZ_COUNT_DTOR_INHERITED(RenderBufferTextureHost, RenderTextureHost);
 }
 
-bool
-RenderBufferTextureHost::Lock()
+wr::WrExternalImage
+RenderBufferTextureHost::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
 {
   if (!mLocked) {
     if (!GetBuffer()) {
       // We hit some problems to get the shmem.
-      return false;
+      return RawDataToWrExternalImage(nullptr, 0);
     }
     if (mFormat != gfx::SurfaceFormat::YUV) {
       mSurface = gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(),
                                                                layers::ImageDataSerializer::GetRGBStride(mDescriptor.get_RGBDescriptor()),
                                                                mSize,
                                                                mFormat);
       if (NS_WARN_IF(!mSurface)) {
-        return false;
+        return RawDataToWrExternalImage(nullptr, 0);
       }
       if (NS_WARN_IF(!mSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mMap))) {
         mSurface = nullptr;
-        return false;
+        return RawDataToWrExternalImage(nullptr, 0);
       }
     } else {
       const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
 
       mYSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetYChannel(GetBuffer(), desc),
                                                                 desc.yStride(),
                                                                 desc.ySize(),
                                                                 gfx::SurfaceFormat::A8);
@@ -75,29 +75,30 @@ RenderBufferTextureHost::Lock()
                                                                  desc.cbCrSize(),
                                                                  gfx::SurfaceFormat::A8);
       mCrSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetCrChannel(GetBuffer(), desc),
                                                                  desc.cbCrStride(),
                                                                  desc.cbCrSize(),
                                                                  gfx::SurfaceFormat::A8);
       if (NS_WARN_IF(!mYSurface || !mCbSurface || !mCrSurface)) {
         mYSurface = mCbSurface = mCrSurface = nullptr;
-        return false;
+        return RawDataToWrExternalImage(nullptr, 0);
       }
       if (NS_WARN_IF(!mYSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mYMap) ||
                      !mCbSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mCbMap) ||
                      !mCrSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mCrMap))) {
         mYSurface = mCbSurface = mCrSurface = nullptr;
-        return false;
+        return RawDataToWrExternalImage(nullptr, 0);
       }
     }
     mLocked = true;
   }
 
-  return true;
+  RenderBufferData data = GetBufferDataForRender(aChannelIndex);
+  return RawDataToWrExternalImage(data.mData, data.mBufferSize);
 }
 
 void
 RenderBufferTextureHost::Unlock()
 {
   if (mLocked) {
     if (mSurface) {
       mSurface->Unmap();
--- a/gfx/webrender_bindings/RenderBufferTextureHost.h
+++ b/gfx/webrender_bindings/RenderBufferTextureHost.h
@@ -12,23 +12,18 @@ namespace mozilla {
 namespace wr {
 
 class RenderBufferTextureHost final : public RenderTextureHost
 {
 public:
   RenderBufferTextureHost(uint8_t* aBuffer,
                           const layers::BufferDescriptor& aDescriptor);
 
-  virtual bool Lock() override;
-  virtual void Unlock() override;
-
-  virtual RenderBufferTextureHost* AsBufferTextureHost() override
-  {
-    return this;
-  }
+  wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override;
+  void Unlock() override;
 
   class RenderBufferData
   {
   public:
     RenderBufferData(uint8_t* aData, size_t aBufferSize)
       : mData(aData)
       , mBufferSize(aBufferSize)
     {
--- a/gfx/webrender_bindings/RenderD3D11TextureHostOGL.cpp
+++ b/gfx/webrender_bindings/RenderD3D11TextureHostOGL.cpp
@@ -54,27 +54,16 @@ RenderDXGITextureHostOGL::RenderDXGIText
 }
 
 RenderDXGITextureHostOGL::~RenderDXGITextureHostOGL()
 {
   MOZ_COUNT_DTOR_INHERITED(RenderDXGITextureHostOGL, RenderTextureHostOGL);
   DeleteTextureHandle();
 }
 
-void
-RenderDXGITextureHostOGL::SetGLContext(gl::GLContext* aContext)
-{
-  if (mGL.get() != aContext) {
-    // Release the texture handle in the previous gl context.
-    DeleteTextureHandle();
-    mGL = aContext;
-    mGL->MakeCurrent();
-  }
-}
-
 bool
 RenderDXGITextureHostOGL::EnsureLockable()
 {
   if (mTextureHandle[0]) {
     return true;
   }
 
   const auto& egl = &gl::sEGLLibrary;
@@ -177,37 +166,44 @@ RenderDXGITextureHostOGL::EnsureLockable
     // Now, we could get the NV12 gl handle from the stream.
     egl->fStreamConsumerAcquireKHR(egl->Display(), mStream);
     MOZ_ASSERT(egl->fGetError() == LOCAL_EGL_SUCCESS);
   }
 
   return true;
 }
 
-bool
-RenderDXGITextureHostOGL::Lock()
+wr::WrExternalImage
+RenderDXGITextureHostOGL::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
 {
-  if (!EnsureLockable()) {
-    return false;
+  if (mGL.get() != aGL) {
+    // Release the texture handle in the previous gl context.
+    DeleteTextureHandle();
+    mGL = aGL;
+    mGL->MakeCurrent();
   }
 
-  if (mLocked) {
-    return true;
+  if (!EnsureLockable()) {
+    return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
   }
 
-  if (mKeyedMutex) {
-    HRESULT hr = mKeyedMutex->AcquireSync(0, 100);
-    if (hr != S_OK) {
-      gfxCriticalError() << "RenderDXGITextureHostOGL AcquireSync timeout, hr=" << gfx::hexa(hr);
-      return false;
+  if (!mLocked) {
+    if (mKeyedMutex) {
+      HRESULT hr = mKeyedMutex->AcquireSync(0, 100);
+      if (hr != S_OK) {
+        gfxCriticalError() << "RenderDXGITextureHostOGL AcquireSync timeout, hr=" << gfx::hexa(hr);
+        return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
+      }
     }
+    mLocked = true;
   }
-  mLocked = true;
 
-  return true;
+  gfx::IntSize size = GetSize(aChannelIndex);
+  return NativeTextureToWrExternalImage(GetGLHandle(aChannelIndex), 0, 0,
+                                        size.width, size.height);
 }
 
 void
 RenderDXGITextureHostOGL::Unlock()
 {
   if (mLocked) {
     if (mKeyedMutex) {
       mKeyedMutex->ReleaseSync(0);
@@ -284,27 +280,16 @@ RenderDXGIYCbCrTextureHostOGL::RenderDXG
 }
 
 RenderDXGIYCbCrTextureHostOGL::~RenderDXGIYCbCrTextureHostOGL()
 {
   MOZ_COUNT_CTOR_INHERITED(RenderDXGIYCbCrTextureHostOGL, RenderTextureHostOGL);
   DeleteTextureHandle();
 }
 
-void
-RenderDXGIYCbCrTextureHostOGL::SetGLContext(gl::GLContext* aContext)
-{
-  if (mGL.get() != aContext) {
-    // Release the texture handle in the previous gl context.
-    DeleteTextureHandle();
-    mGL = aContext;
-    mGL->MakeCurrent();
-  }
-}
-
 bool
 RenderDXGIYCbCrTextureHostOGL::EnsureLockable()
 {
   if (mTextureHandles[0]) {
     return true;
   }
 
   const auto& egl = &gl::sEGLLibrary;
@@ -362,39 +347,46 @@ RenderDXGIYCbCrTextureHostOGL::EnsureLoc
     // Now, we could get the R8 gl handle from the stream.
     egl->fStreamConsumerAcquireKHR(egl->Display(), mStreams[i]);
     MOZ_ASSERT(egl->fGetError() == LOCAL_EGL_SUCCESS);
   }
 
   return true;
 }
 
-bool
-RenderDXGIYCbCrTextureHostOGL::Lock()
+wr::WrExternalImage
+RenderDXGIYCbCrTextureHostOGL::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
 {
-  if (!EnsureLockable()) {
-    return false;
+  if (mGL.get() != aGL) {
+    // Release the texture handle in the previous gl context.
+    DeleteTextureHandle();
+    mGL = aGL;
+    mGL->MakeCurrent();
   }
 
-  if (mLocked) {
-    return true;
+  if (!EnsureLockable()) {
+    return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
   }
 
-  if (mKeyedMutexs[0]) {
-    for (const auto& mutex : mKeyedMutexs) {
-      HRESULT hr = mutex->AcquireSync(0, 100);
-      if (hr != S_OK) {
-        gfxCriticalError() << "RenderDXGIYCbCrTextureHostOGL AcquireSync timeout, hr=" << gfx::hexa(hr);
-        return false;
+  if (!mLocked) {
+    if (mKeyedMutexs[0]) {
+      for (const auto& mutex : mKeyedMutexs) {
+        HRESULT hr = mutex->AcquireSync(0, 100);
+        if (hr != S_OK) {
+          gfxCriticalError() << "RenderDXGIYCbCrTextureHostOGL AcquireSync timeout, hr=" << gfx::hexa(hr);
+          return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
+        }
       }
     }
+    mLocked = true;
   }
-  mLocked = true;
 
-  return true;
+  gfx::IntSize size = GetSize(aChannelIndex);
+  return NativeTextureToWrExternalImage(GetGLHandle(aChannelIndex), 0, 0,
+                                        size.width, size.height);
 }
 
 void
 RenderDXGIYCbCrTextureHostOGL::Unlock()
 {
   if (mLocked) {
     if (mKeyedMutexs[0]) {
       for (const auto& mutex : mKeyedMutexs) {
--- a/gfx/webrender_bindings/RenderD3D11TextureHostOGL.h
+++ b/gfx/webrender_bindings/RenderD3D11TextureHostOGL.h
@@ -18,20 +18,18 @@ namespace wr {
 
 class RenderDXGITextureHostOGL final : public RenderTextureHostOGL
 {
 public:
   explicit RenderDXGITextureHostOGL(WindowsHandle aHandle,
                                     gfx::SurfaceFormat aFormat,
                                     gfx::IntSize aSize);
 
-  virtual void SetGLContext(gl::GLContext* aContext) override;
-
-  virtual bool Lock() override;
-  virtual void Unlock() override;
+  wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override;
+  void Unlock() override;
 
   virtual gfx::IntSize GetSize(uint8_t aChannelIndex) const;
   virtual GLuint GetGLHandle(uint8_t aChannelIndex) const;
 
 private:
   virtual ~RenderDXGITextureHostOGL();
 
   bool EnsureLockable();
@@ -58,19 +56,17 @@ private:
 };
 
 class RenderDXGIYCbCrTextureHostOGL final : public RenderTextureHostOGL
 {
 public:
   explicit RenderDXGIYCbCrTextureHostOGL(WindowsHandle (&aHandles)[3],
                                          gfx::IntSize aSize);
 
-  virtual void SetGLContext(gl::GLContext* aContext) override;
-
-  virtual bool Lock() override;
+  wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override;
   virtual void Unlock() override;
 
   virtual gfx::IntSize GetSize(uint8_t aChannelIndex) const;
   virtual GLuint GetGLHandle(uint8_t aChannelIndex) const;
 
 private:
   virtual ~RenderDXGIYCbCrTextureHostOGL();
 
--- a/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.cpp
@@ -66,55 +66,53 @@ RenderMacIOSurfaceTextureHostOGL::GetSiz
 
   if (!mSurface) {
     return gfx::IntSize();
   }
   return gfx::IntSize(mSurface->GetDevicePixelWidth(aChannelIndex),
                       mSurface->GetDevicePixelHeight(aChannelIndex));
 }
 
-bool
-RenderMacIOSurfaceTextureHostOGL::Lock()
+wr::WrExternalImage
+RenderMacIOSurfaceTextureHostOGL::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
 {
+  if (mGL.get() != aGL) {
+    // release the texture handle in the previous gl context
+    DeleteTextureHandle();
+    mGL = aGL;
+    mGL->MakeCurrent();
+  }
+
   if (!mSurface || !mGL || !mGL->MakeCurrent()) {
-    return false;
+    return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
   }
 
   if (!mTextureHandles[0]) {
     MOZ_ASSERT(gl::GLContextCGL::Cast(mGL.get())->GetCGLContext());
 
     // The result of GetPlaneCount() is 0 for single plane format, but it will
     // be 2 if the format has 2 planar data.
     CreateTextureForPlane(0, mGL, mSurface, &(mTextureHandles[0]));
     for (size_t i = 1; i < mSurface->GetPlaneCount(); ++i) {
       CreateTextureForPlane(i, mGL, mSurface, &(mTextureHandles[i]));
     }
   }
 
-  return true;
+  gfx::IntSize size = GetSize(aChannelIndex);
+  return NativeTextureToWrExternalImage(GetGLHandle(aChannelIndex), 0, 0,
+                                        size.width, size.height);
 }
 
 void
 RenderMacIOSurfaceTextureHostOGL::Unlock()
 {
 
 }
 
 void
-RenderMacIOSurfaceTextureHostOGL::SetGLContext(gl::GLContext* aContext)
-{
-  if (mGL.get() != aContext) {
-    // release the texture handle in the previous gl context
-    DeleteTextureHandle();
-    mGL = aContext;
-    mGL->MakeCurrent();
-  }
-}
-
-void
 RenderMacIOSurfaceTextureHostOGL::DeleteTextureHandle()
 {
   if (mTextureHandles[0] != 0 && mGL && mGL->MakeCurrent()) {
     // Calling glDeleteTextures on 0 isn't an error. So, just make them a single
     // call.
     mGL->fDeleteTextures(3, mTextureHandles);
     for (size_t i = 0; i < 3; ++i) {
       mTextureHandles[i] = 0;
--- a/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.h
+++ b/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.h
@@ -18,20 +18,18 @@ class SurfaceDescriptorMacIOSurface;
 
 namespace wr {
 
 class RenderMacIOSurfaceTextureHostOGL final : public RenderTextureHostOGL
 {
 public:
   explicit RenderMacIOSurfaceTextureHostOGL(MacIOSurface* aSurface);
 
-  virtual bool Lock() override;
-  virtual void Unlock() override;
-
-  virtual void SetGLContext(gl::GLContext* aContext) override;
+  wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override;
+  void Unlock() override;
 
   virtual gfx::IntSize GetSize(uint8_t aChannelIndex) const override;
   virtual GLuint GetGLHandle(uint8_t aChannelIndex) const override;
 
 private:
   virtual ~RenderMacIOSurfaceTextureHostOGL();
   void DeleteTextureHandle();
 
--- a/gfx/webrender_bindings/RenderTextureHost.h
+++ b/gfx/webrender_bindings/RenderTextureHost.h
@@ -7,34 +7,36 @@
 #define MOZILLA_GFX_RENDERTEXTUREHOST_H
 
 #include "nsISupportsImpl.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/layers/LayersSurfaces.h"
 #include "mozilla/RefPtr.h"
 
 namespace mozilla {
+
+namespace gl {
+class GLContext;
+}
+
 namespace wr {
 
 class RenderBufferTextureHost;
 class RenderTextureHostOGL;
 
 class RenderTextureHost
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RenderTextureHost)
 
 public:
   RenderTextureHost();
 
-  virtual bool Lock() = 0;
+  virtual wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) = 0;
   virtual void Unlock() = 0;
 
-  virtual RenderBufferTextureHost* AsBufferTextureHost() { return nullptr; }
-  virtual RenderTextureHostOGL* AsTextureHostOGL() { return nullptr; }
-
 protected:
   virtual ~RenderTextureHost();
 };
 
 } // namespace wr
 } // namespace mozilla
 
 #endif // MOZILLA_GFX_RENDERTEXTUREHOST_H
--- a/gfx/webrender_bindings/RenderTextureHostOGL.h
+++ b/gfx/webrender_bindings/RenderTextureHostOGL.h
@@ -16,23 +16,19 @@ class GLContext;
 
 namespace wr {
 
 class RenderTextureHostOGL : public RenderTextureHost
 {
 public:
   RenderTextureHostOGL();
 
-  virtual void SetGLContext(gl::GLContext* aContext) = 0;
-
   virtual gfx::IntSize GetSize(uint8_t aChannelIndex) const = 0;
   virtual GLuint GetGLHandle(uint8_t aChannelIndex) const = 0;
 
-  virtual RenderTextureHostOGL* AsTextureHostOGL()  override { return this; }
-
 protected:
   virtual ~RenderTextureHostOGL();
 };
 
 } // namespace wr
 } // namespace mozilla
 
 #endif // MOZILLA_GFX_RENDERTEXTUREHOSTOGL_H
--- a/gfx/webrender_bindings/RendererOGL.cpp
+++ b/gfx/webrender_bindings/RendererOGL.cpp
@@ -17,47 +17,18 @@
 
 namespace mozilla {
 namespace wr {
 
 wr::WrExternalImage LockExternalImage(void* aObj, wr::WrExternalImageId aId, uint8_t aChannelIndex)
 {
   RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
   RenderTextureHost* texture = renderer->GetRenderTexture(aId);
-
-  if (texture->AsBufferTextureHost()) {
-    RenderBufferTextureHost* bufferTexture = texture->AsBufferTextureHost();
-    MOZ_ASSERT(bufferTexture);
-
-    if (bufferTexture->Lock()) {
-      RenderBufferTextureHost::RenderBufferData data =
-          bufferTexture->GetBufferDataForRender(aChannelIndex);
-
-      return RawDataToWrExternalImage(data.mData, data.mBufferSize);
-    } else {
-      return RawDataToWrExternalImage(nullptr, 0);
-    }
-  } else {
-    // texture handle case
-    RenderTextureHostOGL* textureOGL = texture->AsTextureHostOGL();
-    MOZ_ASSERT(textureOGL);
-
-    textureOGL->SetGLContext(renderer->mGL);
-    gfx::IntSize size = textureOGL->GetSize(aChannelIndex);
-    if (textureOGL->Lock()) {
-      return NativeTextureToWrExternalImage(textureOGL->GetGLHandle(aChannelIndex),
-                                            0, 0,
-                                            size.width, size.height);
-    } else {
-      // Just use 0 for the gl handle if the lock() was failed.
-      return NativeTextureToWrExternalImage(0,
-                                            0, 0,
-                                            size.width, size.height);
-    }
-  }
+  MOZ_ASSERT(texture);
+  return texture->Lock(aChannelIndex, renderer->mGL);
 }
 
 void UnlockExternalImage(void* aObj, wr::WrExternalImageId aId, uint8_t aChannelIndex)
 {
   RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
   RenderTextureHost* texture = renderer->GetRenderTexture(aId);
   MOZ_ASSERT(texture);
   texture->Unlock();