Bug 1097116 - Add fencing and better lifetime management for EGLImage Images r=jgilbert

--HG--
extra : rebase_source : 8da8c1e9e5ded06c8735ee5d30f8333f829064c5
This commit is contained in:
James Willcox 2014-11-26 15:16:07 -06:00
parent f15f946907
commit 38709a9aed
8 changed files with 47 additions and 21 deletions

View File

@ -8,6 +8,7 @@
#include "GLBlitHelper.h"
#include "GLReadTexImageHelper.h"
#include "AndroidSurfaceTexture.h"
#include "GLLibraryEGL.h"
using namespace mozilla;
using namespace mozilla::gl;
@ -17,6 +18,23 @@ namespace layers {
static nsRefPtr<GLContext> sSnapshotContext;
EGLImageImage::~EGLImageImage()
{
if (!mData.mOwns) {
return;
}
if (mData.mImage) {
sEGLLibrary.fDestroyImage(EGL_DISPLAY(), mData.mImage);
mData.mImage = nullptr;
}
if (mData.mSync) {
sEGLLibrary.fDestroySync(EGL_DISPLAY(), mData.mSync);
mData.mSync = nullptr;
}
}
TemporaryRef<gfx::SourceSurface>
SurfaceTextureImage::GetAsSourceSurface()
{

View File

@ -22,8 +22,10 @@ class EGLImageImage : public Image {
public:
struct Data {
EGLImage mImage;
EGLSync mSync;
gfx::IntSize mSize;
bool mInverted;
bool mOwns;
};
void SetData(const Data& aData) { mData = aData; }
@ -38,6 +40,9 @@ public:
EGLImageImage() : Image(nullptr, ImageFormat::EGLIMAGE) {}
protected:
virtual ~EGLImageImage();
private:
Data mData;
};

View File

@ -192,10 +192,9 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
if (image->GetFormat() == ImageFormat::EGLIMAGE) {
EGLImageImage* typedImage = static_cast<EGLImageImage*>(image);
const EGLImageImage::Data* data = typedImage->GetData();
texture = new EGLImageTextureClient(mTextureFlags, data->mImage,
size, data->mInverted);
texture = new EGLImageTextureClient(mTextureFlags,
typedImage,
size);
#ifdef MOZ_WIDGET_ANDROID
} else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE) {
SurfaceTextureImage* typedImage = static_cast<SurfaceTextureImage*>(image);

View File

@ -63,6 +63,7 @@ struct SurfaceTextureDescriptor {
struct EGLImageDescriptor {
uintptr_t image; // `EGLImage` is a `void*`.
uintptr_t fence;
IntSize size;
};

View File

@ -8,6 +8,7 @@
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/TextureClientOGL.h"
#include "nsSize.h" // for nsIntSize
#include "GLLibraryEGL.h"
using namespace mozilla::gl;
@ -20,9 +21,8 @@ class CompositableForwarder;
// EGLImageTextureClient
EGLImageTextureClient::EGLImageTextureClient(TextureFlags aFlags,
EGLImage aImage,
gfx::IntSize aSize,
bool aInverted)
EGLImageImage* aImage,
gfx::IntSize aSize)
: TextureClient(aFlags)
, mImage(aImage)
, mSize(aSize)
@ -31,26 +31,21 @@ EGLImageTextureClient::EGLImageTextureClient(TextureFlags aFlags,
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default,
"Can't pass an `EGLImage` between processes.");
// Our data is always owned externally.
AddFlags(TextureFlags::DEALLOCATE_CLIENT);
if (aInverted) {
if (aImage->GetData()->mInverted) {
AddFlags(TextureFlags::NEEDS_Y_FLIP);
}
}
EGLImageTextureClient::~EGLImageTextureClient()
{
// Our data is always owned externally.
}
bool
EGLImageTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
{
MOZ_ASSERT(IsValid());
MOZ_ASSERT(IsAllocated());
aOutDescriptor = EGLImageDescriptor((uintptr_t)mImage, mSize);
const EGLImageImage::Data* data = mImage->GetData();
aOutDescriptor = EGLImageDescriptor((uintptr_t)data->mImage, (uintptr_t)data->mSync, mSize);
return true;
}

View File

@ -7,6 +7,7 @@
#define MOZILLA_GFX_TEXTURECLIENTOGL_H
#include "GLContextTypes.h" // for SharedTextureHandle, etc
#include "GLImages.h"
#include "gfxTypes.h"
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
#include "mozilla/gfx/Point.h" // for IntSize
@ -25,11 +26,8 @@ class EGLImageTextureClient : public TextureClient
{
public:
EGLImageTextureClient(TextureFlags aFlags,
EGLImage aImage,
gfx::IntSize aSize,
bool aInverted);
~EGLImageTextureClient();
EGLImageImage* aImage,
gfx::IntSize aSize);
virtual bool IsAllocated() const MOZ_OVERRIDE { return true; }
@ -64,7 +62,7 @@ public:
}
protected:
const EGLImage mImage;
RefPtr<EGLImageImage> mImage;
const gfx::IntSize mSize;
bool mIsLocked;
};

View File

@ -68,6 +68,7 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
const EGLImageDescriptor& desc = aDesc.get_EGLImageDescriptor();
result = new EGLImageTextureHost(aFlags,
(EGLImage)desc.image(),
(EGLSync)desc.fence(),
desc.size());
break;
}
@ -633,9 +634,11 @@ EGLImageTextureSource::GetTextureTransform()
EGLImageTextureHost::EGLImageTextureHost(TextureFlags aFlags,
EGLImage aImage,
EGLSync aSync,
gfx::IntSize aSize)
: TextureHost(aFlags)
, mImage(aImage)
, mSync(aSync)
, mSize(aSize)
, mCompositor(nullptr)
{
@ -658,6 +661,11 @@ EGLImageTextureHost::Lock()
return false;
}
EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSync, 0, LOCAL_EGL_FOREVER);
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
return false;
}
if (!mTextureSource) {
gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
GLenum target = LOCAL_GL_TEXTURE_2D;

View File

@ -476,6 +476,7 @@ class EGLImageTextureHost : public TextureHost
public:
EGLImageTextureHost(TextureFlags aFlags,
EGLImage aImage,
EGLSync aSync,
gfx::IntSize aSize);
virtual ~EGLImageTextureHost();
@ -509,6 +510,7 @@ public:
protected:
const EGLImage mImage;
const EGLSync mSync;
const gfx::IntSize mSize;
RefPtr<CompositorOGL> mCompositor;
RefPtr<EGLImageTextureSource> mTextureSource;