Bug 1191534 - Implement BlitImageToFramebuffer for IOSurface. r=jgilbert

This commit is contained in:
Matt Woodrow 2015-08-14 11:50:48 -04:00
Родитель d44b678bfa
Коммит f9ad8060cc
2 изменённых файлов: 127 добавлений и 1 удалений

Просмотреть файл

@ -24,6 +24,11 @@
#include "GLLibraryEGL.h"
#endif
#ifdef XP_MACOSX
#include "MacIOSurfaceImage.h"
#include "GLContextCGL.h"
#endif
using mozilla::layers::PlanarYCbCrImage;
using mozilla::layers::PlanarYCbCrData;
@ -155,8 +160,10 @@ GLBlitHelper::GLBlitHelper(GLContext* gl)
, mTextureTransformLoc(-1)
, mTexExternalBlit_FragShader(0)
, mTexYUVPlanarBlit_FragShader(0)
, mTexNV12PlanarBlit_FragShader(0)
, mTexExternalBlit_Program(0)
, mTexYUVPlanarBlit_Program(0)
, mTexNV12PlanarBlit_Program(0)
, mFBO(0)
, mSrcTexY(0)
, mSrcTexCb(0)
@ -301,6 +308,33 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
} \n\
";
#ifdef XP_MACOSX
const char kTexNV12PlanarBlit_FragShaderSource[] = "\
#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;
@ -331,6 +365,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;
}
@ -483,6 +524,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;
}
}
MOZ_ASSERT(mGL->fGetAttribLocation(program, "aPosition") == 0);
mYFlipLoc = mGL->fGetUniformLocation(program, "uYflip");
@ -565,6 +624,10 @@ GLBlitHelper::DeleteTexBlitProgram()
mGL->fDeleteShader(mTexYUVPlanarBlit_FragShader);
mTexYUVPlanarBlit_FragShader = 0;
}
if (mTexNV12PlanarBlit_FragShader) {
mGL->fDeleteShader(mTexNV12PlanarBlit_FragShader);
mTexNV12PlanarBlit_FragShader = 0;
}
if (mTexExternalBlit_Program) {
mGL->fDeleteProgram(mTexExternalBlit_Program);
mTexExternalBlit_Program = 0;
@ -573,6 +636,10 @@ GLBlitHelper::DeleteTexBlitProgram()
mGL->fDeleteProgram(mTexYUVPlanarBlit_Program);
mTexYUVPlanarBlit_Program = 0;
}
if (mTexNV12PlanarBlit_Program) {
mGL->fDeleteProgram(mTexNV12PlanarBlit_Program);
mTexNV12PlanarBlit_Program = 0;
}
}
void
@ -816,6 +883,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,
@ -852,6 +960,12 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
srcOrigin = static_cast<layers::EGLImageImage*>(srcImage)->GetData()->mOriginPos;
break;
#endif
#ifdef XP_MACOSX
case ImageFormat::MAC_IOSURFACE:
type = ConvertMacIOSurfaceImage;
srcOrigin = OriginPos::TopLeft;
break;
#endif
default:
return false;
@ -887,6 +1001,11 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
return BlitEGLImageImage(static_cast<layers::EGLImageImage*>(srcImage));
#endif
#ifdef XP_MACOSX
case ConvertMacIOSurfaceImage:
return BlitMacIOSurfaceImage(static_cast<layers::MacIOSurfaceImage*>(srcImage));
#endif
default:
return false;
}

Просмотреть файл

@ -20,6 +20,7 @@ class Image;
class PlanarYCbCrImage;
class GrallocImage;
class SurfaceTextureImage;
class MacIOSurfaceImage;
class EGLImageImage;
} // namespace layers
@ -100,7 +101,8 @@ class GLBlitHelper final
ConvertGralloc,
ConvertPlanarYCbCr,
ConvertSurfaceTexture,
ConvertEGLImage
ConvertEGLImage,
ConvertMacIOSurfaceImage
};
// The GLContext is the sole owner of the GLBlitHelper.
GLContext* mGL;
@ -119,8 +121,10 @@ class GLBlitHelper final
// Data for image blit path
GLuint mTexExternalBlit_FragShader;
GLuint mTexYUVPlanarBlit_FragShader;
GLuint mTexNV12PlanarBlit_FragShader;
GLuint mTexExternalBlit_Program;
GLuint mTexYUVPlanarBlit_Program;
GLuint mTexNV12PlanarBlit_Program;
GLuint mFBO;
GLuint mSrcTexY;
GLuint mSrcTexCb;
@ -153,6 +157,9 @@ class GLBlitHelper final
bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage);
bool BlitEGLImageImage(layers::EGLImageImage* eglImage);
#endif
#ifdef XP_MACOSX
bool BlitMacIOSurfaceImage(layers::MacIOSurfaceImage* ioImage);
#endif
explicit GLBlitHelper(GLContext* gl);