Bug 1362049 - Update the texture target and texture format in MacIOSurface. v5. r=mattwoodrow
authorJerryShih <hshih@mozilla.com>
Thu, 18 May 2017 22:59:07 +0800
changeset 359339 d87f22c0cfbe472c8e75d5c9f1d68f83b1a11bda
parent 359338 9f53823528be13959c0abca9f259ad4d9e062610
child 359340 a26381a60aa651f398de86d128c566accebeffc6
push id31852
push userkwierso@gmail.com
push dateFri, 19 May 2017 21:47:27 +0000
treeherdermozilla-central@979f11deabd0 [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 - Update the texture target and texture format in MacIOSurface. v5. r=mattwoodrow Add LOCAL_GL prefix for all GL constant value. Turn to use GL_RED and GL_RB if we use core profile. Turn to use GL_RGB_422_APPLE instead of GL_YCBCR_422_APPLE for core profile. MozReview-Commit-ID: FCwbrUEFUxI
gfx/2d/MacIOSurface.cpp
gfx/2d/MacIOSurface.h
gfx/gl/GLBlitHelper.cpp
gfx/gl/SharedSurfaceIO.cpp
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
widget/cocoa/RectTextureImage.mm
--- a/gfx/2d/MacIOSurface.cpp
+++ b/gfx/2d/MacIOSurface.cpp
@@ -6,16 +6,17 @@
 
 #include "MacIOSurface.h"
 #include <OpenGL/gl.h>
 #include <QuartzCore/QuartzCore.h>
 #include <dlfcn.h>
 #include "mozilla/RefPtr.h"
 #include "mozilla/Assertions.h"
 #include "GLConsts.h"
+#include "GLContextCGL.h"
 
 using namespace mozilla;
 // IOSurface signatures
 #define IOSURFACE_FRAMEWORK_PATH \
   "/System/Library/Frameworks/IOSurface.framework/IOSurface"
 #define OPENGL_FRAMEWORK_PATH \
   "/System/Library/Frameworks/OpenGL.framework/OpenGL"
 #define COREGRAPHICS_FRAMEWORK_PATH \
@@ -505,56 +506,91 @@ MacIOSurface::GetReadFormat()
   } else if (pixelFormat == '2vuy') {
     return SurfaceFormat::R8G8B8X8;
   } else  {
     return HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8;
   }
 }
 
 CGLError
-MacIOSurface::CGLTexImageIOSurface2D(CGLContextObj ctx, size_t plane)
+MacIOSurface::CGLTexImageIOSurface2D(mozilla::gl::GLContext* aGL,
+                                     CGLContextObj ctx,
+                                     size_t plane,
+                                     mozilla::gfx::SurfaceFormat* aOutReadFormat)
 {
   MOZ_ASSERT(plane >= 0);
+  bool isCompatibilityProfile = aGL->IsCompatibilityProfile();
   OSType pixelFormat = GetPixelFormat();
 
   GLenum internalFormat;
   GLenum format;
   GLenum type;
   if (pixelFormat == '420v') {
     MOZ_ASSERT(GetPlaneCount() == 2);
     MOZ_ASSERT(plane < 2);
 
+    // The LOCAL_GL_LUMINANCE and LOCAL_GL_LUMINANCE_ALPHA are the deprecated
+    // format. So, use LOCAL_GL_RED and LOCAL_GL_RB if we use core profile.
+    // https://www.khronos.org/opengl/wiki/Image_Format#Legacy_Image_Formats
     if (plane == 0) {
-      internalFormat = format = GL_LUMINANCE;
+      internalFormat = format = (isCompatibilityProfile) ? (LOCAL_GL_LUMINANCE)
+                                                          : (LOCAL_GL_RED);
     } else {
-      internalFormat = format = GL_LUMINANCE_ALPHA;
+      internalFormat = format = (isCompatibilityProfile) ? (LOCAL_GL_LUMINANCE_ALPHA)
+                                                          : (LOCAL_GL_RG);
     }
-    type = GL_UNSIGNED_BYTE;
+    type = LOCAL_GL_UNSIGNED_BYTE;
+    if (aOutReadFormat) {
+      *aOutReadFormat = mozilla::gfx::SurfaceFormat::NV12;
+    }
   } else if (pixelFormat == '2vuy') {
     MOZ_ASSERT(plane == 0);
-
-    internalFormat = GL_RGB;
-    format = LOCAL_GL_YCBCR_422_APPLE;
-    type = GL_UNSIGNED_SHORT_8_8_APPLE;
+    // The YCBCR_422_APPLE ext is only available in compatibility profile. So,
+    // we should use RGB_422_APPLE for core profile. The difference between
+    // YCBCR_422_APPLE and RGB_422_APPLE is that the YCBCR_422_APPLE converts
+    // the YCbCr value to RGB with REC 601 conversion. But the RGB_422_APPLE
+    // doesn't contain color conversion. You should do the color conversion by
+    // yourself for RGB_422_APPLE.
+    //
+    // https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_ycbcr_422.txt
+    // https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_rgb_422.txt
+    if (isCompatibilityProfile) {
+      format = LOCAL_GL_YCBCR_422_APPLE;
+      if (aOutReadFormat) {
+        *aOutReadFormat = mozilla::gfx::SurfaceFormat::R8G8B8X8;
+      }
+    } else {
+      format = LOCAL_GL_RGB_422_APPLE;
+      if (aOutReadFormat) {
+        *aOutReadFormat = mozilla::gfx::SurfaceFormat::YUV422;
+      }
+    }
+    internalFormat = LOCAL_GL_RGB;
+    type = LOCAL_GL_UNSIGNED_SHORT_8_8_APPLE;
   } else  {
     MOZ_ASSERT(plane == 0);
 
-    internalFormat = HasAlpha() ? GL_RGBA : GL_RGB;
-    format = GL_BGRA;
-    type = GL_UNSIGNED_INT_8_8_8_8_REV;
+    internalFormat = HasAlpha() ? LOCAL_GL_RGBA : LOCAL_GL_RGB;
+    format = LOCAL_GL_BGRA;
+    type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
+    if (aOutReadFormat) {
+      *aOutReadFormat = HasAlpha() ? mozilla::gfx::SurfaceFormat::R8G8B8A8
+                                  : mozilla::gfx::SurfaceFormat::R8G8B8X8;
+    }
   }
-  CGLError temp =  MacIOSurfaceLib::CGLTexImageIOSurface2D(ctx,
-                                                GL_TEXTURE_RECTANGLE_ARB,
-                                                internalFormat,
-                                                GetDevicePixelWidth(plane),
-                                                GetDevicePixelHeight(plane),
-                                                format,
-                                                type,
-                                                mIOSurfacePtr, plane);
-  return temp;
+
+  return MacIOSurfaceLib::CGLTexImageIOSurface2D(ctx,
+                                                 LOCAL_GL_TEXTURE_RECTANGLE_ARB,
+                                                 internalFormat,
+                                                 GetDevicePixelWidth(plane),
+                                                 GetDevicePixelHeight(plane),
+                                                 format,
+                                                 type,
+                                                 mIOSurfacePtr,
+                                                 plane);
 }
 
 static
 CGColorSpaceRef CreateSystemColorSpace() {
   CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID());
   if (!cspace) {
     cspace = ::CGColorSpaceCreateDeviceRGB();
   }
@@ -591,25 +627,22 @@ already_AddRefed<MacIOSurface> MacIOSurf
   RefPtr<MacIOSurface> ioSurface = new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha);
   if (!ioSurface) {
     ::CFRelease(surfaceRef);
     return nullptr;
   }
   return ioSurface.forget();
 }
 
-
 CGContextType GetContextType(CGContextRef ref)
 {
   if (!MacIOSurfaceLib::isInit() || !MacIOSurfaceLib::sCGContextGetTypePtr)
     return CG_CONTEXT_TYPE_UNKNOWN;
 
   unsigned int type = MacIOSurfaceLib::sCGContextGetTypePtr(ref);
   if (type == CG_CONTEXT_TYPE_BITMAP) {
     return CG_CONTEXT_TYPE_BITMAP;
   } else if (type == CG_CONTEXT_TYPE_IOSURFACE) {
     return CG_CONTEXT_TYPE_IOSURFACE;
   } else {
     return CG_CONTEXT_TYPE_UNKNOWN;
   }
 }
-
-
--- a/gfx/2d/MacIOSurface.h
+++ b/gfx/2d/MacIOSurface.h
@@ -6,16 +6,22 @@
 
 #ifndef MacIOSurface_h__
 #define MacIOSurface_h__
 #ifdef XP_DARWIN
 #include <QuartzCore/QuartzCore.h>
 #include <CoreVideo/CoreVideo.h>
 #include <dlfcn.h>
 
+namespace mozilla {
+namespace gl {
+class GLContext;
+}
+}
+
 struct _CGLContextObject;
 
 typedef _CGLContextObject* CGLContextObj;
 typedef struct CGContext* CGContextRef;
 typedef struct CGImage* CGImageRef;
 typedef uint32_t IOSurfaceID;
 
 #ifdef XP_IOS
@@ -115,17 +121,20 @@ public:
   void IncrementUseCount();
   void DecrementUseCount();
   bool HasAlpha() { return mHasAlpha; }
   mozilla::gfx::SurfaceFormat GetFormat();
   mozilla::gfx::SurfaceFormat GetReadFormat();
 
   // We would like to forward declare NSOpenGLContext, but it is an @interface
   // and this file is also used from c++, so we use a void *.
-  CGLError CGLTexImageIOSurface2D(CGLContextObj ctxt, size_t plane = 0);
+  CGLError CGLTexImageIOSurface2D(mozilla::gl::GLContext* aGL,
+                                  CGLContextObj ctxt,
+                                  size_t plane,
+                                  mozilla::gfx::SurfaceFormat* aOutReadFormat = nullptr);
   already_AddRefed<SourceSurface> GetAsSurface();
   CGContextRef CreateIOSurfaceContext();
 
   // FIXME This doesn't really belong here
   static CGImageRef CreateImageFromIOSurfaceContext(CGContextRef aContext);
   static already_AddRefed<MacIOSurface> IOSurfaceContextGetSurface(CGContextRef aContext,
                                                                         double aContentsScaleFactor = 1.0,
                                                                         bool aHasAlpha = true);
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -773,24 +773,28 @@ GLBlitHelper::BlitMacIOSurfaceImage(laye
 
     GLuint textures[2];
     mGL->fGenTextures(2, textures);
 
     mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
     mGL->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, textures[0]);
     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);
-    surf->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(mGL)->GetCGLContext(), 0);
+    surf->CGLTexImageIOSurface2D(mGL,
+                                 gl::GLContextCGL::Cast(mGL)->GetCGLContext(),
+                                 0);
     mGL->fUniform2f(mYTexScaleLoc, surf->GetWidth(0), surf->GetHeight(0));
 
     mGL->fActiveTexture(LOCAL_GL_TEXTURE1);
     mGL->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, textures[1]);
     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);
-    surf->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(mGL)->GetCGLContext(), 1);
+    surf->CGLTexImageIOSurface2D(mGL,
+                                 gl::GLContextCGL::Cast(mGL)->GetCGLContext(),
+                                 1);
     mGL->fUniform2f(mCbCrTexScaleLoc, surf->GetWidth(1), surf->GetHeight(1));
 
     mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
     for (int i = 0; i < 2; i++) {
         mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
         mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, oldTex[i]);
     }
 
--- a/gfx/gl/SharedSurfaceIO.cpp
+++ b/gfx/gl/SharedSurfaceIO.cpp
@@ -137,17 +137,17 @@ BackTextureWithIOSurf(GLContext* gl, GLu
                         LOCAL_GL_CLAMP_TO_EDGE);
     gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
                         LOCAL_GL_TEXTURE_WRAP_T,
                         LOCAL_GL_CLAMP_TO_EDGE);
 
     CGLContextObj cgl = GLContextCGL::Cast(gl)->GetCGLContext();
     MOZ_ASSERT(cgl);
 
-    ioSurf->CGLTexImageIOSurface2D(cgl);
+    ioSurf->CGLTexImageIOSurface2D(gl, cgl, 0);
 }
 
 SharedSurface_IOSurface::SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
                                                  GLContext* gl,
                                                  const gfx::IntSize& size,
                                                  bool hasAlpha)
   : SharedSurface(SharedSurfaceType::IOSurface,
                   AttachmentType::GLTexture,
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
@@ -30,17 +30,23 @@ MacIOSurfaceTextureHostOGL::CreateTextur
 {
   GLuint textureHandle;
   gl::GLContext* gl = mProvider->GetGLContext();
   gl->fGenTextures(1, &textureHandle);
   gl->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, textureHandle);
   gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
   gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
 
-  mSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(gl)->GetCGLContext(), aPlane);
+  gfx::SurfaceFormat readFormat = gfx::SurfaceFormat::UNKNOWN;
+  mSurface->CGLTexImageIOSurface2D(gl,
+                                   gl::GLContextCGL::Cast(gl)->GetCGLContext(),
+                                   aPlane,
+                                   &readFormat);
+  // With compositorOGL, we doesn't support the yuv interleaving format yet.
+  MOZ_ASSERT(readFormat != gfx::SurfaceFormat::YUV422);
 
   return new GLTextureSource(mProvider, textureHandle, LOCAL_GL_TEXTURE_RECTANGLE_ARB,
                              gfx::IntSize(mSurface->GetDevicePixelWidth(aPlane),
                                           mSurface->GetDevicePixelHeight(aPlane)),
                              // XXX: This isn't really correct (but isn't used), we should be using the
                              // format of the individual plane, not of the whole buffer.
                              mSurface->GetFormat());
 }
--- a/widget/cocoa/RectTextureImage.mm
+++ b/widget/cocoa/RectTextureImage.mm
@@ -157,15 +157,17 @@ RectTextureImage::BindIOSurfaceToTexture
                         LOCAL_GL_LINEAR);
     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);
 
-    mIOSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(aGL)->GetCGLContext());
+    mIOSurface->CGLTexImageIOSurface2D(aGL,
+                                       gl::GLContextCGL::Cast(aGL)->GetCGLContext(),
+                                       0);
     mGLContext = aGL;
   }
 }
 
 } // namespace widget
 } // namespace mozilla