Bug 1362049 - Handle multiple-channel format for RenderMacIOSurfaceTextureHostOGL. v4. r=mattwoodrow
authorJerryShih <hshih@mozilla.com>
Thu, 18 May 2017 22:59:08 +0800
changeset 407461 74c0e29fa0fb7bd263f6820dd90364514b658554
parent 407460 c74b9d026772b929b60ebc9faf241ed72b83f40d
child 407462 ee2ef506dfb9e257e930520014269aeec20aee05
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1362049
milestone55.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 1362049 - Handle multiple-channel format for RenderMacIOSurfaceTextureHostOGL. v4. r=mattwoodrow We could use NV12 or YCbCr-planar format for video playback. There will be up to 3 channels in the MacIOSurface. MozReview-Commit-ID: 77RYntphjYy
gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.cpp
gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.h
--- a/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.cpp
@@ -7,48 +7,91 @@
 
 #include "GLContextCGL.h"
 #include "mozilla/gfx/Logging.h"
 #include "ScopedGLHelpers.h"
 
 namespace mozilla {
 namespace wr {
 
+static CGLError
+CreateTextureForPlane(uint8_t aPlaneID, gl::GLContext* aGL, MacIOSurface* aSurface, GLuint* aTexture)
+{
+  MOZ_ASSERT(aGL && aSurface && aTexture);
+
+  aGL->fGenTextures(1, aTexture);
+  aGL->fActiveTexture(LOCAL_GL_TEXTURE0);
+  aGL->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, *aTexture);
+  aGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+  aGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+
+  CGLError result = kCGLNoError;
+  gfx::SurfaceFormat readFormat = gfx::SurfaceFormat::UNKNOWN;
+  result = aSurface->CGLTexImageIOSurface2D(aGL,
+                                            gl::GLContextCGL::Cast(aGL)->GetCGLContext(),
+                                            aPlaneID,
+                                            &readFormat);
+  // If this is a yuv format, the Webrender only supports YUV422 interleaving format.
+  MOZ_ASSERT(aSurface->GetFormat() != gfx::SurfaceFormat::YUV422 || readFormat == gfx::SurfaceFormat::YUV422);
+
+  return result;
+}
+
 RenderMacIOSurfaceTextureHostOGL::RenderMacIOSurfaceTextureHostOGL(MacIOSurface* aSurface)
-  : mTextureHandle(0)
+  : mSurface(aSurface)
+  , mTextureHandles{ 0, 0, 0 }
 {
   MOZ_COUNT_CTOR_INHERITED(RenderMacIOSurfaceTextureHostOGL, RenderTextureHostOGL);
-
-  mSurface = aSurface;
 }
 
 RenderMacIOSurfaceTextureHostOGL::~RenderMacIOSurfaceTextureHostOGL()
 {
   MOZ_COUNT_DTOR_INHERITED(RenderMacIOSurfaceTextureHostOGL, RenderTextureHostOGL);
   DeleteTextureHandle();
 }
 
+GLuint
+RenderMacIOSurfaceTextureHostOGL::GetGLHandle(uint8_t aChannelIndex) const
+{
+  MOZ_ASSERT(mSurface);
+  MOZ_ASSERT((mSurface->GetPlaneCount() == 0) ? (aChannelIndex == mSurface->GetPlaneCount())
+                                              : (aChannelIndex < mSurface->GetPlaneCount()));
+  return mTextureHandles[aChannelIndex];
+}
+
+gfx::IntSize
+RenderMacIOSurfaceTextureHostOGL::GetSize(uint8_t aChannelIndex) const
+{
+  MOZ_ASSERT(mSurface);
+  MOZ_ASSERT((mSurface->GetPlaneCount() == 0) ? (aChannelIndex == mSurface->GetPlaneCount())
+                                              : (aChannelIndex < mSurface->GetPlaneCount()));
+
+  if (!mSurface) {
+    return gfx::IntSize();
+  }
+  return gfx::IntSize(mSurface->GetDevicePixelWidth(aChannelIndex),
+                      mSurface->GetDevicePixelHeight(aChannelIndex));
+}
+
 bool
 RenderMacIOSurfaceTextureHostOGL::Lock()
 {
   if (!mSurface || !mGL || !mGL->MakeCurrent()) {
     return false;
   }
 
-  if (!mTextureHandle) {
-    // xxx: should we need to handle the PlaneCount 3 iosurface?
-    MOZ_ASSERT(mSurface->GetPlaneCount() == 0);
+  if (!mTextureHandles[0]) {
     MOZ_ASSERT(gl::GLContextCGL::Cast(mGL.get())->GetCGLContext());
 
-    mGL->fGenTextures(1, &mTextureHandle);
-    mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
-    gl::ScopedBindTexture texture(mGL, mTextureHandle, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
-    mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
-    mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
-    mSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(mGL.get())->GetCGLContext(), 0);
+    // 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;
 }
 
 void
 RenderMacIOSurfaceTextureHostOGL::Unlock()
 {
@@ -63,16 +106,20 @@ RenderMacIOSurfaceTextureHostOGL::SetGLC
     DeleteTextureHandle();
     mGL = aContext;
   }
 }
 
 void
 RenderMacIOSurfaceTextureHostOGL::DeleteTextureHandle()
 {
-  if (mTextureHandle != 0 && mGL && mGL->MakeCurrent()) {
-    mGL->fDeleteTextures(1, &mTextureHandle);
+  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;
+    }
   }
-  mTextureHandle = 0;
 }
 
 } // namespace wr
 } // namespace mozilla
--- a/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.h
+++ b/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.h
@@ -37,15 +37,15 @@ public:
   virtual GLuint GetGLHandle(uint8_t aChannelIndex) const override;
 
 private:
   virtual ~RenderMacIOSurfaceTextureHostOGL();
   void DeleteTextureHandle();
 
   RefPtr<MacIOSurface> mSurface;
   RefPtr<gl::GLContext> mGL;
-  GLuint mTextureHandle;
+  GLuint mTextureHandles[3];
 };
 
 } // namespace wr
 } // namespace mozilla
 
 #endif // MOZILLA_GFX_RENDERMACIOSURFACETEXTUREHOSTOGL_H