diff options
Diffstat (limited to 'gfx/gl/GLBlitHelper.cpp')
-rw-r--r-- | gfx/gl/GLBlitHelper.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp index 12e30c8804..da7f5b462d 100644 --- a/gfx/gl/GLBlitHelper.cpp +++ b/gfx/gl/GLBlitHelper.cpp @@ -14,6 +14,11 @@ #include "mozilla/gfx/Matrix.h" #include "mozilla/UniquePtr.h" +#ifdef XP_MACOSX +#include "MacIOSurfaceImage.h" +#include "GLContextCGL.h" +#endif + using mozilla::layers::PlanarYCbCrImage; using mozilla::layers::PlanarYCbCrData; @@ -181,6 +186,34 @@ GLBlitHelper::InitTexQuadProgram(BlitType target) } \n\ "; +#ifdef XP_MACOSX + const char kTexNV12PlanarBlit_FragShaderSource[] = "\ + #version 100 \n\ + #extension GL_ARB_texture_rectangle : require \n\ + #ifdef GL_ES \n\ + precision mediump float \n\ + #endif \n\ + varying vec2 vTexCoord; \n\ + uniform sampler2DRect uYTexture; \n\ + uniform sampler2DRect uCbCrTexture; \n\ + uniform vec2 uYTexScale; \n\ + uniform vec2 uCbCrTexScale; \n\ + void main() \n\ + { \n\ + float y = texture2DRect(uYTexture, vTexCoord * uYTexScale).r; \n\ + float cb = texture2DRect(uCbCrTexture, vTexCoord * uCbCrTexScale).r; \n\ + float cr = texture2DRect(uCbCrTexture, vTexCoord * uCbCrTexScale).a; \n\ + y = (y - 0.06275) * 1.16438; \n\ + cb = cb - 0.50196; \n\ + cr = cr - 0.50196; \n\ + gl_FragColor.r = y + cr * 1.59603; \n\ + gl_FragColor.g = y - 0.81297 * cr - 0.39176 * cb; \n\ + gl_FragColor.b = y + cb * 2.01723; \n\ + gl_FragColor.a = 1.0; \n\ + } \n\ + "; +#endif + bool success = false; GLuint* programPtr; @@ -203,6 +236,13 @@ GLBlitHelper::InitTexQuadProgram(BlitType target) fragShaderPtr = &mTexYUVPlanarBlit_FragShader; fragShaderSource = kTexYUVPlanarBlit_FragShaderSource; break; +#ifdef XP_MACOSX + case ConvertMacIOSurfaceImage: + programPtr = &mTexNV12PlanarBlit_Program; + fragShaderPtr = &mTexNV12PlanarBlit_FragShader; + fragShaderSource = kTexNV12PlanarBlit_FragShaderSource; + break; +#endif default: return false; } @@ -353,6 +393,24 @@ GLBlitHelper::InitTexQuadProgram(BlitType target) mGL->fUniform1i(texCr, Channel_Cr); break; } + case ConvertMacIOSurfaceImage: { +#ifdef XP_MACOSX + GLint texY = mGL->fGetUniformLocation(program, "uYTexture"); + GLint texCbCr = mGL->fGetUniformLocation(program, "uCbCrTexture"); + mYTexScaleLoc = mGL->fGetUniformLocation(program, "uYTexScale"); + mCbCrTexScaleLoc= mGL->fGetUniformLocation(program, "uCbCrTexScale"); + + DebugOnly<bool> hasUniformLocations = texY != -1 && + texCbCr != -1 && + mYTexScaleLoc != -1 && + mCbCrTexScaleLoc != -1; + MOZ_ASSERT(hasUniformLocations, "uniforms not found"); + + mGL->fUniform1i(texY, Channel_Y); + mGL->fUniform1i(texCbCr, Channel_Cb); +#endif + break; + } default: return false; } @@ -620,6 +678,47 @@ GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage) return true; } +#ifdef XP_MACOSX +bool +GLBlitHelper::BlitMacIOSurfaceImage(layers::MacIOSurfaceImage* ioImage) +{ + ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0); + MacIOSurface* surf = ioImage->GetSurface(); + + GLint oldTex[2]; + for (int i = 0; i < 2; i++) { + mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + i); + mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldTex[i]); + } + + 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); + 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); + 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]); + } + + mGL->fDeleteTextures(2, textures); + return true; +} +#endif + bool GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize, @@ -637,6 +736,13 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage, srcOrigin = OriginPos::BottomLeft; break; +#ifdef XP_MACOSX + case ImageFormat::MAC_IOSURFACE: + type = ConvertMacIOSurfaceImage; + srcOrigin = OriginPos::TopLeft; + break; +#endif + default: return false; } @@ -662,6 +768,11 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage, return ret; } +#ifdef XP_MACOSX + case ConvertMacIOSurfaceImage: + return BlitMacIOSurfaceImage(srcImage->AsMacIOSurfaceImage()); +#endif + default: return false; } |