2013-08-09 15:23:46 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
// * This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "GLContext.h"
|
|
|
|
#include "gfxImageSurface.h"
|
|
|
|
#include "gfx2DGlue.h"
|
|
|
|
#include <ui/GraphicBuffer.h>
|
2013-09-12 09:40:26 +00:00
|
|
|
#include "GrallocImages.h" // for GrallocImage
|
2013-08-09 15:23:46 +00:00
|
|
|
#include "mozilla/layers/GrallocTextureHost.h"
|
|
|
|
#include "mozilla/layers/CompositorOGL.h"
|
2013-12-10 05:47:19 +00:00
|
|
|
#include "EGLImageHelpers.h"
|
2014-01-02 15:17:29 +00:00
|
|
|
#include "GLReadTexImageHelper.h"
|
2013-08-09 15:23:46 +00:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
|
|
|
|
|
|
using namespace android;
|
|
|
|
|
|
|
|
static gfx::SurfaceFormat
|
|
|
|
SurfaceFormatForAndroidPixelFormat(android::PixelFormat aFormat,
|
|
|
|
bool swapRB = false)
|
|
|
|
{
|
|
|
|
switch (aFormat) {
|
|
|
|
case android::PIXEL_FORMAT_BGRA_8888:
|
2014-01-10 19:06:16 +00:00
|
|
|
return swapRB ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::B8G8R8A8;
|
2013-08-09 15:23:46 +00:00
|
|
|
case android::PIXEL_FORMAT_RGBA_8888:
|
2014-01-10 19:06:16 +00:00
|
|
|
return swapRB ? gfx::SurfaceFormat::B8G8R8A8 : gfx::SurfaceFormat::R8G8B8A8;
|
2013-08-09 15:23:46 +00:00
|
|
|
case android::PIXEL_FORMAT_RGBX_8888:
|
2014-01-10 19:06:16 +00:00
|
|
|
return swapRB ? gfx::SurfaceFormat::B8G8R8X8 : gfx::SurfaceFormat::R8G8B8X8;
|
2013-08-09 15:23:46 +00:00
|
|
|
case android::PIXEL_FORMAT_RGB_565:
|
2014-01-10 19:06:16 +00:00
|
|
|
return gfx::SurfaceFormat::R5G6B5;
|
2013-08-09 15:23:46 +00:00
|
|
|
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
|
|
|
|
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
|
|
|
|
case HAL_PIXEL_FORMAT_YCbCr_422_I:
|
2013-09-12 09:40:26 +00:00
|
|
|
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
|
|
|
|
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
|
2013-08-09 15:23:46 +00:00
|
|
|
case HAL_PIXEL_FORMAT_YV12:
|
2014-01-10 19:06:16 +00:00
|
|
|
return gfx::SurfaceFormat::B8G8R8A8; // yup, use SurfaceFormat::B8G8R8A8 even though it's a YUV texture. This is an external texture.
|
2013-08-09 15:23:46 +00:00
|
|
|
default:
|
|
|
|
if (aFormat >= 0x100 && aFormat <= 0x1FF) {
|
|
|
|
// Reserved range for HAL specific formats.
|
2014-01-10 19:06:16 +00:00
|
|
|
return gfx::SurfaceFormat::B8G8R8A8;
|
2013-08-09 15:23:46 +00:00
|
|
|
} else {
|
|
|
|
// This is not super-unreachable, there's a bunch of hypothetical pixel
|
|
|
|
// formats we don't deal with.
|
|
|
|
// We only want to abort in debug builds here, since if we crash here
|
|
|
|
// we'll take down the compositor process and thus the phone. This seems
|
|
|
|
// like undesirable behaviour. We'd rather have a subtle artifact.
|
|
|
|
printf_stderr(" xxxxx unknow android format %i\n", (int)aFormat);
|
|
|
|
MOZ_ASSERT(false, "Unknown Android pixel format.");
|
2014-01-10 19:06:16 +00:00
|
|
|
return gfx::SurfaceFormat::UNKNOWN;
|
2013-08-09 15:23:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static GLenum
|
|
|
|
TextureTargetForAndroidPixelFormat(android::PixelFormat aFormat)
|
|
|
|
{
|
|
|
|
switch (aFormat) {
|
|
|
|
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
|
|
|
|
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
|
|
|
|
case HAL_PIXEL_FORMAT_YCbCr_422_I:
|
2013-09-12 09:40:26 +00:00
|
|
|
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
|
|
|
|
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
|
2013-08-09 15:23:46 +00:00
|
|
|
case HAL_PIXEL_FORMAT_YV12:
|
|
|
|
return LOCAL_GL_TEXTURE_EXTERNAL;
|
|
|
|
case android::PIXEL_FORMAT_RGBA_8888:
|
|
|
|
case android::PIXEL_FORMAT_RGBX_8888:
|
|
|
|
case android::PIXEL_FORMAT_RGB_565:
|
|
|
|
return LOCAL_GL_TEXTURE_2D;
|
|
|
|
default:
|
|
|
|
if (aFormat >= 0x100 && aFormat <= 0x1FF) {
|
|
|
|
// Reserved range for HAL specific formats.
|
|
|
|
return LOCAL_GL_TEXTURE_EXTERNAL;
|
|
|
|
} else {
|
|
|
|
// This is not super-unreachable, there's a bunch of hypothetical pixel
|
|
|
|
// formats we don't deal with.
|
|
|
|
// We only want to abort in debug builds here, since if we crash here
|
|
|
|
// we'll take down the compositor process and thus the phone. This seems
|
|
|
|
// like undesirable behaviour. We'd rather have a subtle artifact.
|
|
|
|
MOZ_ASSERT(false, "Unknown Android pixel format.");
|
|
|
|
return LOCAL_GL_TEXTURE_EXTERNAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GrallocTextureSourceOGL::GrallocTextureSourceOGL(CompositorOGL* aCompositor,
|
|
|
|
android::GraphicBuffer* aGraphicBuffer,
|
|
|
|
gfx::SurfaceFormat aFormat)
|
|
|
|
: mCompositor(aCompositor)
|
|
|
|
, mGraphicBuffer(aGraphicBuffer)
|
|
|
|
, mEGLImage(0)
|
|
|
|
, mFormat(aFormat)
|
2014-03-13 17:55:52 +00:00
|
|
|
, mNeedsReset(true)
|
2013-08-09 15:23:46 +00:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(mGraphicBuffer.get());
|
|
|
|
}
|
|
|
|
|
2013-09-13 02:39:26 +00:00
|
|
|
GrallocTextureSourceOGL::~GrallocTextureSourceOGL()
|
|
|
|
{
|
|
|
|
DeallocateDeviceData();
|
|
|
|
mCompositor = nullptr;
|
|
|
|
}
|
|
|
|
|
2014-03-07 21:34:04 +00:00
|
|
|
void
|
2014-03-13 00:37:17 +00:00
|
|
|
GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
|
2013-08-09 15:23:46 +00:00
|
|
|
{
|
2014-03-13 17:55:52 +00:00
|
|
|
/*
|
|
|
|
* The job of this function is to ensure that the texture is tied to the
|
|
|
|
* android::GraphicBuffer, so that texturing will source the GraphicBuffer.
|
|
|
|
*
|
|
|
|
* To this effect we create an EGLImage wrapping this GraphicBuffer,
|
|
|
|
* using EGLImageCreateFromNativeBuffer, and then we tie this EGLImage to our
|
|
|
|
* texture using fEGLImageTargetTexture2D.
|
|
|
|
*/
|
2013-08-09 15:23:46 +00:00
|
|
|
MOZ_ASSERT(gl());
|
2014-02-27 14:40:48 +00:00
|
|
|
if (!IsValid()) {
|
|
|
|
return;
|
|
|
|
}
|
2013-08-09 15:23:46 +00:00
|
|
|
gl()->MakeCurrent();
|
|
|
|
|
2013-09-17 13:29:19 +00:00
|
|
|
GLuint tex = GetGLTexture();
|
2013-08-09 15:23:46 +00:00
|
|
|
GLuint textureTarget = GetTextureTarget();
|
|
|
|
|
|
|
|
gl()->fActiveTexture(aTextureUnit);
|
|
|
|
gl()->fBindTexture(textureTarget, tex);
|
2014-03-07 21:34:04 +00:00
|
|
|
|
2014-03-13 17:55:52 +00:00
|
|
|
if (mCompositableBackendData) {
|
|
|
|
// There are two paths for locking/unlocking - if mCompositableBackendData is
|
|
|
|
// set, we use the texture on there, otherwise we use
|
|
|
|
// CompositorBackendSpecificData from the compositor and bind the EGLImage
|
|
|
|
// only in Lock().
|
|
|
|
if (!mEGLImage) {
|
|
|
|
mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
|
|
|
|
}
|
|
|
|
gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
|
|
|
|
}
|
|
|
|
|
2014-03-13 00:37:17 +00:00
|
|
|
ApplyFilterToBoundTexture(gl(), aFilter, textureTarget);
|
2014-03-07 21:34:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GrallocTextureSourceOGL::Lock()
|
|
|
|
{
|
2014-03-13 17:55:52 +00:00
|
|
|
if (mCompositableBackendData) return;
|
|
|
|
|
2014-03-07 21:34:04 +00:00
|
|
|
MOZ_ASSERT(IsValid());
|
|
|
|
|
2014-03-13 17:55:52 +00:00
|
|
|
CompositorOGLGonkBackendSpecificData* backendData =
|
|
|
|
static_cast<CompositorOGLGonkBackendSpecificData*>(mCompositor->GetCompositorBackendSpecificData());
|
|
|
|
mTexture = backendData->GetTexture();
|
2014-03-07 21:34:04 +00:00
|
|
|
|
|
|
|
GLuint textureTarget = GetTextureTarget();
|
|
|
|
|
|
|
|
gl()->MakeCurrent();
|
|
|
|
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
|
|
|
gl()->fBindTexture(textureTarget, mTexture);
|
2014-01-24 13:30:41 +00:00
|
|
|
if (!mEGLImage) {
|
|
|
|
mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
|
|
|
|
}
|
|
|
|
gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
|
2013-08-09 15:23:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
GrallocTextureSourceOGL::IsValid() const
|
|
|
|
{
|
2014-03-13 17:55:52 +00:00
|
|
|
return !!gl() && !!mGraphicBuffer.get() && (!!mCompositor || !!mCompositableBackendData);
|
2013-08-09 15:23:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gl::GLContext*
|
|
|
|
GrallocTextureSourceOGL::gl() const
|
|
|
|
{
|
|
|
|
return mCompositor ? mCompositor->gl() : nullptr;
|
|
|
|
}
|
|
|
|
|
2013-09-13 02:39:26 +00:00
|
|
|
void
|
2014-01-08 19:25:52 +00:00
|
|
|
GrallocTextureSourceOGL::SetCompositor(Compositor* aCompositor)
|
2013-09-13 02:39:26 +00:00
|
|
|
{
|
|
|
|
if (mCompositor && !aCompositor) {
|
|
|
|
DeallocateDeviceData();
|
|
|
|
}
|
2014-01-08 19:25:52 +00:00
|
|
|
mCompositor = static_cast<CompositorOGL*>(aCompositor);
|
2013-09-13 02:39:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-09 15:23:46 +00:00
|
|
|
GLenum
|
|
|
|
GrallocTextureSourceOGL::GetTextureTarget() const
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mGraphicBuffer.get());
|
2014-02-27 14:40:48 +00:00
|
|
|
if (!mGraphicBuffer.get()) {
|
|
|
|
return LOCAL_GL_TEXTURE_EXTERNAL;
|
|
|
|
}
|
2013-08-09 15:23:46 +00:00
|
|
|
return TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
|
|
|
|
}
|
|
|
|
|
|
|
|
gfx::SurfaceFormat
|
2013-08-30 14:24:05 +00:00
|
|
|
GrallocTextureSourceOGL::GetFormat() const {
|
2013-08-09 15:23:46 +00:00
|
|
|
if (!mGraphicBuffer.get()) {
|
2014-01-10 19:06:16 +00:00
|
|
|
return gfx::SurfaceFormat::UNKNOWN;
|
2013-08-09 15:23:46 +00:00
|
|
|
}
|
|
|
|
if (GetTextureTarget() == LOCAL_GL_TEXTURE_EXTERNAL) {
|
2014-01-10 19:06:16 +00:00
|
|
|
return gfx::SurfaceFormat::R8G8B8A8;
|
2013-08-09 15:23:46 +00:00
|
|
|
}
|
|
|
|
return mFormat;
|
|
|
|
}
|
|
|
|
|
2014-03-13 17:55:52 +00:00
|
|
|
void
|
|
|
|
GrallocTextureSourceOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
|
|
|
|
{
|
|
|
|
if (!aBackendData) {
|
|
|
|
mCompositableBackendData = nullptr;
|
|
|
|
DeallocateDeviceData();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mCompositableBackendData != aBackendData) {
|
|
|
|
mNeedsReset = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mNeedsReset) {
|
|
|
|
// Update binding to the EGLImage
|
|
|
|
gl()->MakeCurrent();
|
|
|
|
GLuint tex = GetGLTexture();
|
|
|
|
GLuint textureTarget = GetTextureTarget();
|
|
|
|
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
|
|
|
gl()->fBindTexture(textureTarget, tex);
|
|
|
|
gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mCompositableBackendData = aBackendData;
|
|
|
|
|
|
|
|
if (!mCompositor) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// delete old EGLImage
|
|
|
|
DeallocateDeviceData();
|
|
|
|
|
|
|
|
gl()->MakeCurrent();
|
|
|
|
GLuint tex = GetGLTexture();
|
|
|
|
GLuint textureTarget = GetTextureTarget();
|
|
|
|
|
|
|
|
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
|
|
|
gl()->fBindTexture(textureTarget, tex);
|
|
|
|
// create new EGLImage
|
|
|
|
mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
|
|
|
|
gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
|
|
|
|
mNeedsReset = false;
|
|
|
|
}
|
|
|
|
|
2013-08-09 15:23:46 +00:00
|
|
|
gfx::IntSize
|
|
|
|
GrallocTextureSourceOGL::GetSize() const
|
|
|
|
{
|
|
|
|
if (!IsValid()) {
|
|
|
|
NS_WARNING("Trying to access the size of an invalid GrallocTextureSourceOGL");
|
|
|
|
return gfx::IntSize(0, 0);
|
|
|
|
}
|
|
|
|
return gfx::IntSize(mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight());
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
GrallocTextureSourceOGL::DeallocateDeviceData()
|
|
|
|
{
|
|
|
|
if (mEGLImage) {
|
|
|
|
MOZ_ASSERT(gl());
|
|
|
|
gl()->MakeCurrent();
|
2013-12-10 05:47:19 +00:00
|
|
|
EGLImageDestroy(gl(), mEGLImage);
|
|
|
|
mEGLImage = EGL_NO_IMAGE;
|
2013-08-09 15:23:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-12 01:44:47 +00:00
|
|
|
GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags,
|
2013-08-09 15:23:46 +00:00
|
|
|
const NewSurfaceDescriptorGralloc& aDescriptor)
|
2013-12-12 01:44:47 +00:00
|
|
|
: TextureHost(aFlags)
|
2013-08-09 15:23:46 +00:00
|
|
|
{
|
2014-02-27 14:40:48 +00:00
|
|
|
android::GraphicBuffer* graphicBuffer = nullptr;
|
|
|
|
gfx::SurfaceFormat format = gfx::SurfaceFormat::UNKNOWN;
|
|
|
|
|
|
|
|
mSize = aDescriptor.size();
|
2013-08-09 15:23:46 +00:00
|
|
|
mGrallocActor =
|
|
|
|
static_cast<GrallocBufferActor*>(aDescriptor.bufferParent());
|
|
|
|
|
2014-02-27 14:40:48 +00:00
|
|
|
if (mGrallocActor) {
|
|
|
|
mGrallocActor->AddTextureHost(this);
|
|
|
|
graphicBuffer = mGrallocActor->GetGraphicBuffer();
|
|
|
|
}
|
2013-08-09 15:23:46 +00:00
|
|
|
|
2014-02-27 14:40:48 +00:00
|
|
|
if (graphicBuffer) {
|
|
|
|
format =
|
|
|
|
SurfaceFormatForAndroidPixelFormat(graphicBuffer->getPixelFormat(),
|
|
|
|
aFlags & TEXTURE_RB_SWAPPED);
|
|
|
|
}
|
2013-08-09 15:23:46 +00:00
|
|
|
mTextureSource = new GrallocTextureSourceOGL(nullptr,
|
|
|
|
graphicBuffer,
|
|
|
|
format);
|
|
|
|
}
|
|
|
|
|
|
|
|
GrallocTextureHostOGL::~GrallocTextureHostOGL()
|
|
|
|
{
|
|
|
|
mTextureSource = nullptr;
|
2014-02-07 01:32:29 +00:00
|
|
|
if (mGrallocActor) {
|
|
|
|
mGrallocActor->RemoveTextureHost();
|
|
|
|
mGrallocActor = nullptr;
|
|
|
|
}
|
2013-08-09 15:23:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
GrallocTextureHostOGL::SetCompositor(Compositor* aCompositor)
|
|
|
|
{
|
|
|
|
mTextureSource->SetCompositor(static_cast<CompositorOGL*>(aCompositor));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
GrallocTextureHostOGL::Lock()
|
|
|
|
{
|
2014-03-07 21:34:04 +00:00
|
|
|
if (IsValid()) {
|
|
|
|
mTextureSource->Lock();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2013-08-09 15:23:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
GrallocTextureHostOGL::Unlock()
|
|
|
|
{
|
|
|
|
// Unlock is done internally by binding the texture to another gralloc buffer
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
GrallocTextureHostOGL::IsValid() const
|
|
|
|
{
|
|
|
|
return mTextureSource->IsValid();
|
|
|
|
}
|
|
|
|
|
|
|
|
gfx::SurfaceFormat
|
|
|
|
GrallocTextureHostOGL::GetFormat() const
|
|
|
|
{
|
|
|
|
return mTextureSource->GetFormat();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
GrallocTextureHostOGL::DeallocateSharedData()
|
|
|
|
{
|
|
|
|
if (mTextureSource) {
|
|
|
|
mTextureSource->ForgetBuffer();
|
|
|
|
}
|
2014-02-07 01:32:29 +00:00
|
|
|
if (mGrallocActor) {
|
|
|
|
PGrallocBufferParent::Send__delete__(mGrallocActor);
|
|
|
|
}
|
2013-08-09 15:23:46 +00:00
|
|
|
}
|
|
|
|
|
2013-12-12 01:44:45 +00:00
|
|
|
void
|
|
|
|
GrallocTextureHostOGL::ForgetSharedData()
|
|
|
|
{
|
|
|
|
if (mTextureSource) {
|
|
|
|
mTextureSource->ForgetBuffer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-09 15:23:46 +00:00
|
|
|
void
|
|
|
|
GrallocTextureHostOGL::DeallocateDeviceData()
|
|
|
|
{
|
|
|
|
mTextureSource->DeallocateDeviceData();
|
|
|
|
}
|
|
|
|
|
|
|
|
LayerRenderState
|
|
|
|
GrallocTextureHostOGL::GetRenderState()
|
|
|
|
{
|
|
|
|
if (IsValid()) {
|
|
|
|
uint32_t flags = 0;
|
|
|
|
if (mFlags & TEXTURE_NEEDS_Y_FLIP) {
|
|
|
|
flags |= LAYER_RENDER_STATE_Y_FLIPPED;
|
|
|
|
}
|
|
|
|
if (mFlags & TEXTURE_RB_SWAPPED) {
|
|
|
|
flags |= LAYER_RENDER_STATE_FORMAT_RB_SWAP;
|
|
|
|
}
|
|
|
|
return LayerRenderState(mTextureSource->mGraphicBuffer.get(),
|
|
|
|
gfx::ThebesIntSize(mSize),
|
2014-02-25 04:23:41 +00:00
|
|
|
flags,
|
|
|
|
this);
|
2013-08-09 15:23:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return LayerRenderState();
|
|
|
|
}
|
|
|
|
|
2013-11-27 09:59:01 +00:00
|
|
|
TemporaryRef<gfx::DataSourceSurface>
|
2013-08-09 15:23:46 +00:00
|
|
|
GrallocTextureHostOGL::GetAsSurface() {
|
|
|
|
return mTextureSource ? mTextureSource->GetAsSurface()
|
|
|
|
: nullptr;
|
|
|
|
}
|
|
|
|
|
2013-11-27 09:59:01 +00:00
|
|
|
TemporaryRef<gfx::DataSourceSurface>
|
2013-08-09 15:23:46 +00:00
|
|
|
GrallocTextureSourceOGL::GetAsSurface() {
|
|
|
|
MOZ_ASSERT(gl());
|
2014-02-27 14:40:48 +00:00
|
|
|
if (!IsValid()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2013-08-09 15:23:46 +00:00
|
|
|
gl()->MakeCurrent();
|
|
|
|
|
2013-09-17 13:29:19 +00:00
|
|
|
GLuint tex = GetGLTexture();
|
2013-08-09 15:23:46 +00:00
|
|
|
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
|
|
|
gl()->fBindTexture(GetTextureTarget(), tex);
|
|
|
|
if (!mEGLImage) {
|
2013-12-10 05:47:19 +00:00
|
|
|
mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
|
2013-08-09 15:23:46 +00:00
|
|
|
}
|
|
|
|
gl()->fEGLImageTargetTexture2D(GetTextureTarget(), mEGLImage);
|
|
|
|
|
2013-11-27 09:59:01 +00:00
|
|
|
RefPtr<gfx::DataSourceSurface> surf =
|
|
|
|
IsValid() ? ReadBackSurface(gl(), tex, false, GetFormat())
|
|
|
|
: nullptr;
|
2013-08-09 15:23:46 +00:00
|
|
|
|
|
|
|
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
|
|
|
return surf.forget();
|
|
|
|
}
|
|
|
|
|
2013-09-17 13:29:19 +00:00
|
|
|
GLuint
|
|
|
|
GrallocTextureSourceOGL::GetGLTexture()
|
|
|
|
{
|
2014-03-13 17:55:52 +00:00
|
|
|
if (mCompositableBackendData) {
|
|
|
|
mCompositableBackendData->SetCompositor(mCompositor);
|
|
|
|
return static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get())->GetTexture();
|
|
|
|
}
|
|
|
|
|
2014-03-07 21:34:04 +00:00
|
|
|
return mTexture;
|
2013-09-17 13:29:19 +00:00
|
|
|
}
|
|
|
|
|
2013-09-13 02:39:26 +00:00
|
|
|
void
|
2013-09-30 12:14:38 +00:00
|
|
|
GrallocTextureHostOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
|
2013-09-13 02:39:26 +00:00
|
|
|
{
|
2013-09-30 12:14:38 +00:00
|
|
|
mCompositableBackendData = aBackendData;
|
2013-09-13 02:39:26 +00:00
|
|
|
if (mTextureSource) {
|
2013-09-30 12:14:38 +00:00
|
|
|
mTextureSource->SetCompositableBackendSpecificData(aBackendData);
|
2013-09-13 02:39:26 +00:00
|
|
|
}
|
2014-02-25 04:23:41 +00:00
|
|
|
// Register this object to CompositableBackendSpecificData
|
|
|
|
// as current TextureHost.
|
|
|
|
if (aBackendData) {
|
|
|
|
aBackendData->SetCurrentReleaseFenceTexture(this);
|
|
|
|
}
|
2013-09-13 02:39:26 +00:00
|
|
|
}
|
|
|
|
|
2013-08-09 15:23:46 +00:00
|
|
|
} // namepsace layers
|
|
|
|
} // namepsace mozilla
|