Bug 1208513 - Resurrect SharedSurface_GLTexture for use on iOS r=jgilbert

This commit is contained in:
James Willcox 2015-09-24 09:11:53 -05:00
parent 55c2c64332
commit 0706108b13
8 changed files with 299 additions and 0 deletions

View File

@ -82,6 +82,8 @@ GLScreenBuffer::CreateFactory(GLContext* gl,
#elif defined(GL_PROVIDER_GLX)
if (sGLXLibrary.UseSurfaceSharing())
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, forwarder, flags);
#elif defined(MOZ_WIDGET_UIKIT)
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, forwarder, mFlags);
#else
if (gl->GetContextType() == GLContextType::EGL) {
if (XRE_IsParentProcess()) {

View File

@ -95,6 +95,7 @@ SharedSurface_Basic::~SharedSurface_Basic()
mGL->fDeleteTextures(1, &mTex);
}
////////////////////////////////////////////////////////////////////////
SurfaceFactory_Basic::SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps,
@ -102,6 +103,88 @@ SurfaceFactory_Basic::SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& cap
: SurfaceFactory(SharedSurfaceType::Basic, gl, caps, nullptr, flags)
{ }
////////////////////////////////////////////////////////////////////////
// SharedSurface_GLTexture
/*static*/ UniquePtr<SharedSurface_GLTexture>
SharedSurface_GLTexture::Create(GLContext* prodGL,
const GLFormats& formats,
const IntSize& size,
bool hasAlpha)
{
MOZ_ASSERT(prodGL);
prodGL->MakeCurrent();
UniquePtr<SharedSurface_GLTexture> ret;
GLContext::LocalErrorScope localError(*prodGL);
GLuint tex = CreateTextureForOffscreen(prodGL, formats, size);
GLenum err = localError.GetError();
MOZ_ASSERT_IF(err, err == LOCAL_GL_OUT_OF_MEMORY);
if (err) {
prodGL->fDeleteTextures(1, &tex);
return Move(ret);
}
ret.reset(new SharedSurface_GLTexture(prodGL, size,
hasAlpha, tex));
return Move(ret);
}
SharedSurface_GLTexture::~SharedSurface_GLTexture()
{
if (!mGL->MakeCurrent())
return;
if (mTex) {
mGL->fDeleteTextures(1, &mTex);
}
if (mSync) {
mGL->fDeleteSync(mSync);
}
}
void
SharedSurface_GLTexture::ProducerReleaseImpl()
{
mGL->MakeCurrent();
if (mGL->IsExtensionSupported(GLContext::ARB_sync)) {
if (mSync) {
mGL->fDeleteSync(mSync);
mSync = 0;
}
mSync = mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
if (mSync) {
mGL->fFlush();
return;
}
}
MOZ_ASSERT(!mSync);
mGL->fFinish();
}
bool
SharedSurface_GLTexture::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
{
*out_descriptor = layers::SurfaceDescriptorSharedGLTexture(ProdTexture(),
ProdTextureTarget(),
(uintptr_t)mSync,
mSize,
mHasAlpha);
// Transfer ownership of the fence to the host
mSync = nullptr;
return true;
}
} // namespace gl
} /* namespace mozilla */

View File

@ -93,6 +93,78 @@ public:
}
};
// Using shared GL textures:
class SharedSurface_GLTexture
: public SharedSurface
{
public:
static UniquePtr<SharedSurface_GLTexture> Create(GLContext* prodGL,
const GLFormats& formats,
const gfx::IntSize& size,
bool hasAlpha);
static SharedSurface_GLTexture* Cast(SharedSurface* surf) {
MOZ_ASSERT(surf->mType == SharedSurfaceType::SharedGLTexture);
return (SharedSurface_GLTexture*)surf;
}
protected:
const GLuint mTex;
GLsync mSync;
SharedSurface_GLTexture(GLContext* prodGL,
const gfx::IntSize& size,
bool hasAlpha,
GLuint tex)
: SharedSurface(SharedSurfaceType::SharedGLTexture,
AttachmentType::GLTexture,
prodGL,
size,
hasAlpha, true)
, mTex(tex)
, mSync(0)
{
}
public:
virtual ~SharedSurface_GLTexture();
virtual void LockProdImpl() override {}
virtual void UnlockProdImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual void Fence() override {}
virtual bool WaitSync() override { MOZ_CRASH("should not be called"); }
virtual bool PollSync() override { MOZ_CRASH("should not be called"); }
virtual GLuint ProdTexture() override {
return mTex;
}
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
};
class SurfaceFactory_GLTexture
: public SurfaceFactory
{
public:
SurfaceFactory_GLTexture(GLContext* prodGL,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags)
: SurfaceFactory(SharedSurfaceType::SharedGLTexture, prodGL, caps, allocator, flags)
{
}
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
bool hasAlpha = mReadCaps.alpha;
return SharedSurface_GLTexture::Create(mGL, mFormats, size, hasAlpha);
}
};
} // namespace gl
} /* namespace mozilla */

View File

@ -77,6 +77,7 @@ enum class SharedSurfaceType : uint8_t {
Gralloc,
IOSurface,
GLXDrawable,
SharedGLTexture,
Max
};

View File

@ -215,6 +215,7 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
case SurfaceDescriptor::TEGLImageDescriptor:
case SurfaceDescriptor::TSurfaceTextureDescriptor:
case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture:
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
case SurfaceDescriptor::TNewSurfaceDescriptorGralloc:

View File

@ -82,6 +82,14 @@ struct EGLImageDescriptor {
bool hasAlpha;
};
struct SurfaceDescriptorSharedGLTexture {
uint32_t texture;
uint32_t target;
uintptr_t fence;
IntSize size;
bool hasAlpha;
};
struct NewSurfaceDescriptorGralloc {
MaybeMagicGrallocBufferHandle buffer;
bool isOpaque;
@ -116,6 +124,7 @@ union SurfaceDescriptor {
EGLImageDescriptor;
SurfaceDescriptorMacIOSurface;
NewSurfaceDescriptorGralloc;
SurfaceDescriptorSharedGLTexture;
null_t;
};

View File

@ -104,6 +104,16 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
break;
}
#endif
case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture: {
const auto& desc = aDesc.get_SurfaceDescriptorSharedGLTexture();
result = new GLTextureHost(aFlags, desc.texture(),
desc.target(),
(GLsync)desc.fence(),
desc.size(),
desc.hasAlpha());
break;
}
default: return nullptr;
}
return result.forget();
@ -645,5 +655,76 @@ EGLImageTextureHost::GetFormat() const
return mTextureSource->GetFormat();
}
//
GLTextureHost::GLTextureHost(TextureFlags aFlags,
GLuint aTextureHandle,
GLenum aTarget,
GLsync aSync,
gfx::IntSize aSize,
bool aHasAlpha)
: TextureHost(aFlags)
, mTexture(aTextureHandle)
, mTarget(aTarget)
, mSync(aSync)
, mSize(aSize)
, mHasAlpha(aHasAlpha)
, mCompositor(nullptr)
{}
GLTextureHost::~GLTextureHost()
{}
gl::GLContext*
GLTextureHost::gl() const
{
return mCompositor ? mCompositor->gl() : nullptr;
}
bool
GLTextureHost::Lock()
{
if (!mCompositor) {
return false;
}
if (mSync) {
gl()->MakeCurrent();
gl()->fWaitSync(mSync, 0, LOCAL_GL_TIMEOUT_IGNORED);
gl()->fDeleteSync(mSync);
mSync = 0;
}
if (!mTextureSource) {
gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
: gfx::SurfaceFormat::R8G8B8X8;
mTextureSource = new GLTextureSource(mCompositor,
mTexture,
mTarget,
mSize,
format,
false /* owned by the client */);
}
return true;
}
void
GLTextureHost::SetCompositor(Compositor* aCompositor)
{
MOZ_ASSERT(aCompositor);
CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor);
mCompositor = glCompositor;
if (mTextureSource) {
mTextureSource->SetCompositor(glCompositor);
}
}
gfx::SurfaceFormat
GLTextureHost::GetFormat() const
{
MOZ_ASSERT(mTextureSource);
return mTextureSource->GetFormat();
}
} // namespace layers
} // namespace mozilla

View File

@ -279,6 +279,56 @@ protected:
bool mExternallyOwned;
};
class GLTextureHost : public TextureHost
{
public:
GLTextureHost(TextureFlags aFlags,
GLuint aTextureHandle,
GLenum aTarget,
GLsync aSync,
gfx::IntSize aSize,
bool aHasAlpha);
virtual ~GLTextureHost();
// We don't own anything.
virtual void DeallocateDeviceData() override {}
virtual void SetCompositor(Compositor* aCompositor) override;
virtual bool Lock() override;
virtual void Unlock() override {}
virtual gfx::SurfaceFormat GetFormat() const override;
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override
{
aTexture = mTextureSource;
return !!aTexture;
}
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
{
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
}
gl::GLContext* gl() const;
virtual gfx::IntSize GetSize() const override { return mSize; }
virtual const char* Name() override { return "GLTextureHost"; }
protected:
const GLuint mTexture;
const GLenum mTarget;
GLsync mSync;
const gfx::IntSize mSize;
const bool mHasAlpha;
RefPtr<CompositorOGL> mCompositor;
RefPtr<GLTextureSource> mTextureSource;
};
////////////////////////////////////////////////////////////////////////
// SurfaceTexture