mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 1014614
- Add GLBlitHelper::BlitImageToFramebuffer and support SurfaceTexture images r=jgilbert
--HG-- extra : rebase_source : e823897f3ff6593af7286432903618dc483877dd
This commit is contained in:
parent
068835d9bb
commit
d02dc369ff
@ -10,12 +10,18 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "ImageContainer.h"
|
||||
#include "HeapCopyOfStackArray.h"
|
||||
#include "mozilla/gfx/Matrix.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "GrallocImages.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidSurfaceTexture.h"
|
||||
#include "GLImages.h"
|
||||
#endif
|
||||
|
||||
using mozilla::layers::PlanarYCbCrImage;
|
||||
using mozilla::layers::PlanarYCbCrData;
|
||||
|
||||
@ -144,6 +150,7 @@ GLBlitHelper::GLBlitHelper(GLContext* gl)
|
||||
, mTex2DBlit_Program(0)
|
||||
, mTex2DRectBlit_Program(0)
|
||||
, mYFlipLoc(-1)
|
||||
, mTextureTransformLoc(-1)
|
||||
, mTexExternalBlit_FragShader(0)
|
||||
, mTexYUVPlanarBlit_FragShader(0)
|
||||
, mTexExternalBlit_Program(0)
|
||||
@ -238,21 +245,23 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
|
||||
vTexCoord * uTexCoordMult); \n\
|
||||
} \n\
|
||||
";
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#ifdef ANDROID /* MOZ_WIDGET_ANDROID || MOZ_WIDGET_GONK */
|
||||
const char kTexExternalBlit_FragShaderSource[] = "\
|
||||
#extension GL_OES_EGL_image_external : require \n\
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH \n\
|
||||
precision highp float; \n\
|
||||
#else \n\
|
||||
precision mediump float; \n\
|
||||
#endif \n\
|
||||
varying vec2 vTexCoord; \n\
|
||||
uniform samplerExternalOES uTexUnit; \n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
gl_FragColor = texture2D(uTexUnit, vTexCoord); \n\
|
||||
} \n\
|
||||
#extension GL_OES_EGL_image_external : require \n\
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH \n\
|
||||
precision highp float; \n\
|
||||
#else \n\
|
||||
precision mediump float; \n\
|
||||
#endif \n\
|
||||
varying vec2 vTexCoord; \n\
|
||||
uniform mat4 uTextureTransform; \n\
|
||||
uniform samplerExternalOES uTexUnit; \n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
gl_FragColor = texture2D(uTexUnit, \n\
|
||||
(uTextureTransform * vec4(vTexCoord, 0.0, 1.0)).xy); \n\
|
||||
} \n\
|
||||
";
|
||||
#endif
|
||||
/* From Rec601:
|
||||
@ -306,7 +315,8 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
|
||||
fragShaderPtr = &mTex2DRectBlit_FragShader;
|
||||
fragShaderSource = kTex2DRectBlit_FragShaderSource;
|
||||
break;
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#ifdef ANDROID
|
||||
case ConvertSurfaceTexture:
|
||||
case ConvertGralloc:
|
||||
programPtr = &mTexExternalBlit_Program;
|
||||
fragShaderPtr = &mTexExternalBlit_FragShader;
|
||||
@ -441,8 +451,9 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
|
||||
switch (target) {
|
||||
case BlitTex2D:
|
||||
case BlitTexRect:
|
||||
case ConvertSurfaceTexture:
|
||||
case ConvertGralloc: {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#ifdef ANDROID
|
||||
GLint texUnitLoc = mGL->fGetUniformLocation(program, "uTexUnit");
|
||||
MOZ_ASSERT(texUnitLoc != -1, "uniform uTexUnit not found");
|
||||
mGL->fUniform1i(texUnitLoc, 0);
|
||||
@ -472,6 +483,12 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
|
||||
MOZ_ASSERT(mGL->fGetAttribLocation(program, "aPosition") == 0);
|
||||
mYFlipLoc = mGL->fGetUniformLocation(program, "uYflip");
|
||||
MOZ_ASSERT(mYFlipLoc != -1, "uniform: uYflip not found");
|
||||
mTextureTransformLoc = mGL->fGetUniformLocation(program, "uTextureTransform");
|
||||
if (mTextureTransformLoc >= 0) {
|
||||
// Set identity matrix as default
|
||||
gfx::Matrix4x4 identity;
|
||||
mGL->fUniformMatrix4fv(mTextureTransformLoc, 1, false, &identity._11);
|
||||
}
|
||||
success = true;
|
||||
} while (false);
|
||||
|
||||
@ -700,6 +717,42 @@ GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage)
|
||||
{
|
||||
AndroidSurfaceTexture* surfaceTexture = stImage->GetData()->mSurfTex;
|
||||
bool yFlip = stImage->GetData()->mInverted;
|
||||
|
||||
ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
|
||||
mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if (!surfaceTexture->Attach(mGL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// UpdateTexImage() changes the EXTERNAL binding, so save it here
|
||||
// so we can restore it after.
|
||||
int oldBinding = 0;
|
||||
mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_EXTERNAL, &oldBinding);
|
||||
|
||||
surfaceTexture->UpdateTexImage();
|
||||
|
||||
gfx::Matrix4x4 transform;
|
||||
surfaceTexture->GetTransformMatrix(transform);
|
||||
|
||||
mGL->fUniformMatrix4fv(mTextureTransformLoc, 1, false, &transform._11);
|
||||
mGL->fUniform1f(mYFlipLoc, yFlip ? 1.0f : 0.0f);
|
||||
mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
surfaceTexture->Detach();
|
||||
|
||||
mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, oldBinding);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yFlip)
|
||||
{
|
||||
@ -738,15 +791,14 @@ GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yFli
|
||||
}
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitImageToTexture(layers::Image* srcImage,
|
||||
const gfx::IntSize& destSize,
|
||||
GLuint destTex,
|
||||
GLenum destTarget,
|
||||
bool yFlip,
|
||||
GLuint xoffset,
|
||||
GLuint yoffset,
|
||||
GLuint cropWidth,
|
||||
GLuint cropHeight)
|
||||
GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
|
||||
const gfx::IntSize& destSize,
|
||||
GLuint destFB,
|
||||
bool yFlip,
|
||||
GLuint xoffset,
|
||||
GLuint yoffset,
|
||||
GLuint cropWidth,
|
||||
GLuint cropHeight)
|
||||
{
|
||||
ScopedGLDrawState autoStates(mGL);
|
||||
|
||||
@ -759,6 +811,11 @@ GLBlitHelper::BlitImageToTexture(layers::Image* srcImage,
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
type = ConvertGralloc;
|
||||
break;
|
||||
#endif
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
case ImageFormat::SURFACE_TEXTURE:
|
||||
type = ConvertSurfaceTexture;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
@ -769,12 +826,7 @@ GLBlitHelper::BlitImageToTexture(layers::Image* srcImage,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mFBO) {
|
||||
mGL->fGenFramebuffers(1, &mFBO);
|
||||
}
|
||||
|
||||
ScopedBindFramebuffer boundFB(mGL, mFBO);
|
||||
mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, destTarget, destTex, 0);
|
||||
ScopedBindFramebuffer boundFB(mGL, destFB);
|
||||
mGL->fColorMask(LOCAL_GL_TRUE, LOCAL_GL_TRUE, LOCAL_GL_TRUE, LOCAL_GL_TRUE);
|
||||
mGL->fViewport(0, 0, destSize.width, destSize.height);
|
||||
if (xoffset != 0 && yoffset != 0 && cropWidth != 0 && cropHeight != 0) {
|
||||
@ -793,10 +845,39 @@ GLBlitHelper::BlitImageToTexture(layers::Image* srcImage,
|
||||
PlanarYCbCrImage* yuvImage = static_cast<PlanarYCbCrImage*>(srcImage);
|
||||
return BlitPlanarYCbCrImage(yuvImage, yFlip);
|
||||
}
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (type == ConvertSurfaceTexture) {
|
||||
layers::SurfaceTextureImage* stImage = static_cast<layers::SurfaceTextureImage*>(srcImage);
|
||||
return BlitSurfaceTextureImage(stImage);
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitImageToTexture(layers::Image* srcImage,
|
||||
const gfx::IntSize& destSize,
|
||||
GLuint destTex,
|
||||
GLenum destTarget,
|
||||
bool yFlip,
|
||||
GLuint xoffset,
|
||||
GLuint yoffset,
|
||||
GLuint cropWidth,
|
||||
GLuint cropHeight)
|
||||
{
|
||||
ScopedGLDrawState autoStates(mGL);
|
||||
|
||||
if (!mFBO) {
|
||||
mGL->fGenFramebuffers(1, &mFBO);
|
||||
}
|
||||
|
||||
ScopedBindFramebuffer boundFB(mGL, mFBO);
|
||||
mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, destTarget, destTex, 0);
|
||||
return BlitImageToFramebuffer(srcImage, destSize, mFBO, yFlip, xoffset, yoffset,
|
||||
cropWidth, cropHeight);
|
||||
}
|
||||
|
||||
void
|
||||
GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
|
||||
const gfx::IntSize& srcSize,
|
||||
|
@ -19,6 +19,7 @@ namespace layers {
|
||||
class Image;
|
||||
class PlanarYCbCrImage;
|
||||
class GrallocImage;
|
||||
class SurfaceTextureImage;
|
||||
}
|
||||
|
||||
namespace gl {
|
||||
@ -97,6 +98,7 @@ class GLBlitHelper MOZ_FINAL
|
||||
BlitTexRect,
|
||||
ConvertGralloc,
|
||||
ConvertPlanarYCbCr,
|
||||
ConvertSurfaceTexture
|
||||
};
|
||||
// The GLContext is the sole owner of the GLBlitHelper.
|
||||
GLContext* mGL;
|
||||
@ -110,6 +112,8 @@ class GLBlitHelper MOZ_FINAL
|
||||
|
||||
GLint mYFlipLoc;
|
||||
|
||||
GLint mTextureTransformLoc;
|
||||
|
||||
// Data for image blit path
|
||||
GLuint mTexExternalBlit_FragShader;
|
||||
GLuint mTexYUVPlanarBlit_FragShader;
|
||||
@ -142,6 +146,9 @@ class GLBlitHelper MOZ_FINAL
|
||||
bool BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip = false);
|
||||
#endif
|
||||
bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yFlip = false);
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@ -175,6 +182,9 @@ public:
|
||||
const gfx::IntSize& destSize,
|
||||
GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
|
||||
GLenum destTarget = LOCAL_GL_TEXTURE_2D);
|
||||
bool BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize,
|
||||
GLuint destFB, bool yFlip = false, GLuint xoffset = 0,
|
||||
GLuint yoffset = 0, GLuint width = 0, GLuint height = 0);
|
||||
bool BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize,
|
||||
GLuint destTex, GLenum destTarget, bool yFlip = false, GLuint xoffset = 0,
|
||||
GLuint yoffset = 0, GLuint width = 0, GLuint height = 0);
|
||||
|
Loading…
Reference in New Issue
Block a user