зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1097116 - Fix readback for EGLImageImage r=jgilbert
This commit is contained in:
Родитель
60e6a04aff
Коммит
1664129cd2
|
@ -305,6 +305,7 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
|
|||
GLuint *fragShaderPtr;
|
||||
const char* fragShaderSource;
|
||||
switch (target) {
|
||||
case ConvertEGLImage:
|
||||
case BlitTex2D:
|
||||
programPtr = &mTex2DBlit_Program;
|
||||
fragShaderPtr = &mTex2DBlit_FragShader;
|
||||
|
@ -451,6 +452,7 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
|
|||
switch (target) {
|
||||
case BlitTex2D:
|
||||
case BlitTexRect:
|
||||
case ConvertEGLImage:
|
||||
case ConvertSurfaceTexture:
|
||||
case ConvertGralloc: {
|
||||
#ifdef ANDROID
|
||||
|
@ -666,25 +668,26 @@ GLBlitHelper::BindAndUploadYUVTexture(Channel which,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
void
|
||||
GLBlitHelper::BindAndUploadExternalTexture(EGLImage image)
|
||||
GLBlitHelper::BindAndUploadEGLImage(EGLImage image, GLuint target)
|
||||
{
|
||||
MOZ_ASSERT(image != EGL_NO_IMAGE, "Bad EGLImage");
|
||||
|
||||
if (!mSrcTexEGL) {
|
||||
mGL->fGenTextures(1, &mSrcTexEGL);
|
||||
mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, mSrcTexEGL);
|
||||
mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
|
||||
mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
|
||||
mGL->fBindTexture(target, mSrcTexEGL);
|
||||
mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
|
||||
mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
|
||||
} else {
|
||||
mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, mSrcTexEGL);
|
||||
mGL->fBindTexture(target, mSrcTexEGL);
|
||||
}
|
||||
mGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL_OES, image);
|
||||
mGL->fEGLImageTargetTexture2D(target, image);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip)
|
||||
{
|
||||
|
@ -705,7 +708,7 @@ GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip)
|
|||
int oldBinding = 0;
|
||||
mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_EXTERNAL_OES, &oldBinding);
|
||||
|
||||
BindAndUploadExternalTexture(image);
|
||||
BindAndUploadEGLImage(image, LOCAL_GL_TEXTURE_EXTERNAL_OES);
|
||||
|
||||
mGL->fUniform1f(mYFlipLoc, yFlip ? (float)1.0f : (float)0.0f);
|
||||
|
||||
|
@ -720,13 +723,14 @@ GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip)
|
|||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage)
|
||||
GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool yFlip)
|
||||
{
|
||||
AndroidSurfaceTexture* surfaceTexture = stImage->GetData()->mSurfTex;
|
||||
bool yFlip = stImage->GetData()->mInverted;
|
||||
if (stImage->GetData()->mInverted) {
|
||||
yFlip = !yFlip;
|
||||
}
|
||||
|
||||
ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
|
||||
mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if (NS_FAILED(surfaceTexture->Attach(mGL))) {
|
||||
return false;
|
||||
|
@ -751,6 +755,39 @@ GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage)
|
|||
mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, oldBinding);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image, bool yFlip)
|
||||
{
|
||||
EGLImage eglImage = image->GetData()->mImage;
|
||||
EGLSync eglSync = image->GetData()->mSync;
|
||||
|
||||
if (image->GetData()->mInverted) {
|
||||
yFlip = !yFlip;
|
||||
}
|
||||
|
||||
if (eglSync) {
|
||||
EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), eglSync, 0, LOCAL_EGL_FOREVER);
|
||||
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
|
||||
|
||||
int oldBinding = 0;
|
||||
mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldBinding);
|
||||
|
||||
BindAndUploadEGLImage(eglImage, LOCAL_GL_TEXTURE_2D);
|
||||
|
||||
mGL->fUniform1f(mYFlipLoc, yFlip ? 1.0f : 0.0f);
|
||||
|
||||
mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, oldBinding);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool
|
||||
|
@ -816,6 +853,9 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
|
|||
case ImageFormat::SURFACE_TEXTURE:
|
||||
type = ConvertSurfaceTexture;
|
||||
break;
|
||||
case ImageFormat::EGLIMAGE:
|
||||
type = ConvertEGLImage;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
|
@ -848,7 +888,11 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
|
|||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (type == ConvertSurfaceTexture) {
|
||||
layers::SurfaceTextureImage* stImage = static_cast<layers::SurfaceTextureImage*>(srcImage);
|
||||
return BlitSurfaceTextureImage(stImage);
|
||||
return BlitSurfaceTextureImage(stImage, yFlip);
|
||||
}
|
||||
if (type == ConvertEGLImage) {
|
||||
layers::EGLImageImage* eglImage = static_cast<layers::EGLImageImage*>(srcImage);
|
||||
return BlitEGLImageImage(eglImage, yFlip);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ class Image;
|
|||
class PlanarYCbCrImage;
|
||||
class GrallocImage;
|
||||
class SurfaceTextureImage;
|
||||
class EGLImageImage;
|
||||
}
|
||||
|
||||
namespace gl {
|
||||
|
@ -98,7 +99,8 @@ class GLBlitHelper MOZ_FINAL
|
|||
BlitTexRect,
|
||||
ConvertGralloc,
|
||||
ConvertPlanarYCbCr,
|
||||
ConvertSurfaceTexture
|
||||
ConvertSurfaceTexture,
|
||||
ConvertEGLImage
|
||||
};
|
||||
// The GLContext is the sole owner of the GLBlitHelper.
|
||||
GLContext* mGL;
|
||||
|
@ -140,14 +142,15 @@ class GLBlitHelper MOZ_FINAL
|
|||
bool InitTexQuadProgram(BlitType target = BlitTex2D);
|
||||
void DeleteTexBlitProgram();
|
||||
void BindAndUploadYUVTexture(Channel which, uint32_t width, uint32_t height, void* data, bool allocation);
|
||||
void BindAndUploadEGLImage(EGLImage image, GLuint target);
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
void BindAndUploadExternalTexture(EGLImage image);
|
||||
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);
|
||||
bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool yFlip = false);
|
||||
bool BlitEGLImageImage(layers::EGLImageImage* eglImage, bool yFlip = false);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
|
|
@ -35,16 +35,16 @@ EGLImageImage::~EGLImageImage()
|
|||
}
|
||||
}
|
||||
|
||||
TemporaryRef<gfx::SourceSurface>
|
||||
SurfaceTextureImage::GetAsSourceSurface()
|
||||
TemporaryRef<SourceSurface>
|
||||
GLImage::GetAsSourceSurface()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread");
|
||||
|
||||
if (!sSnapshotContext) {
|
||||
SurfaceCaps caps = SurfaceCaps::ForRGBA();
|
||||
sSnapshotContext = GLContextProvider::CreateOffscreen(gfxIntSize(16, 16), caps);
|
||||
sSnapshotContext = GLContextProvider::CreateHeadless();
|
||||
|
||||
if (!sSnapshotContext) {
|
||||
NS_WARNING("Failed to create snapshot GLContext");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -52,8 +52,10 @@ SurfaceTextureImage::GetAsSourceSurface()
|
|||
sSnapshotContext->MakeCurrent();
|
||||
ScopedTexture scopedTex(sSnapshotContext);
|
||||
ScopedBindTexture boundTex(sSnapshotContext, scopedTex.Texture());
|
||||
|
||||
gfx::IntSize size = GetSize();
|
||||
sSnapshotContext->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA,
|
||||
mData.mSize.width, mData.mSize.height, 0,
|
||||
size.width, size.height, 0,
|
||||
LOCAL_GL_RGBA,
|
||||
LOCAL_GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
|
@ -62,11 +64,11 @@ SurfaceTextureImage::GetAsSourceSurface()
|
|||
|
||||
GLBlitHelper helper(sSnapshotContext);
|
||||
|
||||
helper.BlitImageToFramebuffer(this, mData.mSize, fb.FB(), false);
|
||||
helper.BlitImageToFramebuffer(this, size, fb.FB(), false);
|
||||
ScopedBindFramebuffer bind(sSnapshotContext, fb.FB());
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> source =
|
||||
gfx::Factory::CreateDataSourceSurface(mData.mSize, gfx::SurfaceFormat::B8G8R8A8);
|
||||
gfx::Factory::CreateDataSourceSurface(size, gfx::SurfaceFormat::B8G8R8A8);
|
||||
if (NS_WARN_IF(!source)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,14 @@ class AndroidSurfaceTexture;
|
|||
}
|
||||
namespace layers {
|
||||
|
||||
class EGLImageImage : public Image {
|
||||
class GLImage : public Image {
|
||||
public:
|
||||
GLImage(ImageFormat aFormat) : Image(nullptr, aFormat){}
|
||||
|
||||
virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
class EGLImageImage : public GLImage {
|
||||
public:
|
||||
struct Data {
|
||||
EGLImage mImage;
|
||||
|
@ -37,12 +44,7 @@ public:
|
|||
|
||||
gfx::IntSize GetSize() { return mData.mSize; }
|
||||
|
||||
virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EGLImageImage() : Image(nullptr, ImageFormat::EGLIMAGE) {}
|
||||
EGLImageImage() : GLImage(ImageFormat::EGLIMAGE) {}
|
||||
|
||||
protected:
|
||||
virtual ~EGLImageImage();
|
||||
|
@ -53,7 +55,7 @@ private:
|
|||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
class SurfaceTextureImage : public Image {
|
||||
class SurfaceTextureImage : public GLImage {
|
||||
public:
|
||||
struct Data {
|
||||
mozilla::gl::AndroidSurfaceTexture* mSurfTex;
|
||||
|
@ -66,9 +68,7 @@ public:
|
|||
|
||||
gfx::IntSize GetSize() { return mData.mSize; }
|
||||
|
||||
virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE;
|
||||
|
||||
SurfaceTextureImage() : Image(nullptr, ImageFormat::SURFACE_TEXTURE) {}
|
||||
SurfaceTextureImage() : GLImage(ImageFormat::SURFACE_TEXTURE) {}
|
||||
|
||||
private:
|
||||
Data mData;
|
||||
|
|
Загрузка…
Ссылка в новой задаче