summaryrefslogtreecommitdiffstats
path: root/gfx/layers/opengl/TextureHostOGL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/opengl/TextureHostOGL.cpp')
-rw-r--r--gfx/layers/opengl/TextureHostOGL.cpp771
1 files changed, 771 insertions, 0 deletions
diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp
new file mode 100644
index 000000000..854160bc6
--- /dev/null
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -0,0 +1,771 @@
+/* -*- 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 "TextureHostOGL.h"
+
+#include "EGLUtils.h"
+#include "GLContext.h" // for GLContext, etc
+#include "GLLibraryEGL.h" // for GLLibraryEGL
+#include "GLUploadHelpers.h"
+#include "GLReadTexImageHelper.h"
+#include "gfx2DGlue.h" // for ContentForFormat, etc
+#include "mozilla/gfx/2D.h" // for DataSourceSurface
+#include "mozilla/gfx/BaseSize.h" // for BaseSize
+#include "mozilla/gfx/Logging.h" // for gfxCriticalError
+#include "mozilla/layers/ISurfaceAllocator.h"
+#include "nsRegion.h" // for nsIntRegion
+#include "AndroidSurfaceTexture.h"
+#include "GfxTexturesReporter.h" // for GfxTexturesReporter
+#include "GLBlitTextureImageHelper.h"
+#include "GeckoProfiler.h"
+
+#ifdef XP_MACOSX
+#include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
+#endif
+
+#ifdef GL_PROVIDER_GLX
+#include "mozilla/layers/X11TextureHost.h"
+#endif
+
+using namespace mozilla::gl;
+using namespace mozilla::gfx;
+
+namespace mozilla {
+namespace layers {
+
+class Compositor;
+
+already_AddRefed<TextureHost>
+CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
+ ISurfaceAllocator* aDeallocator,
+ TextureFlags aFlags)
+{
+ RefPtr<TextureHost> result;
+ switch (aDesc.type()) {
+ case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
+ result = CreateBackendIndependentTextureHost(aDesc,
+ aDeallocator, aFlags);
+ break;
+ }
+
+#ifdef MOZ_WIDGET_ANDROID
+ case SurfaceDescriptor::TSurfaceTextureDescriptor: {
+ const SurfaceTextureDescriptor& desc = aDesc.get_SurfaceTextureDescriptor();
+ result = new SurfaceTextureHost(aFlags,
+ (AndroidSurfaceTexture*)desc.surfTex(),
+ desc.size());
+ break;
+ }
+#endif
+
+ case SurfaceDescriptor::TEGLImageDescriptor: {
+ const EGLImageDescriptor& desc = aDesc.get_EGLImageDescriptor();
+ result = new EGLImageTextureHost(aFlags,
+ (EGLImage)desc.image(),
+ (EGLSync)desc.fence(),
+ desc.size(),
+ desc.hasAlpha());
+ break;
+ }
+
+#ifdef XP_MACOSX
+ case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
+ const SurfaceDescriptorMacIOSurface& desc =
+ aDesc.get_SurfaceDescriptorMacIOSurface();
+ result = new MacIOSurfaceTextureHostOGL(aFlags, desc);
+ break;
+ }
+#endif
+
+#ifdef GL_PROVIDER_GLX
+ case SurfaceDescriptor::TSurfaceDescriptorX11: {
+ const auto& desc = aDesc.get_SurfaceDescriptorX11();
+ result = new X11TextureHost(aFlags, desc);
+ 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();
+}
+
+static gl::TextureImage::Flags
+FlagsToGLFlags(TextureFlags aFlags)
+{
+ uint32_t result = TextureImage::NoFlags;
+
+ if (aFlags & TextureFlags::USE_NEAREST_FILTER)
+ result |= TextureImage::UseNearestFilter;
+ if (aFlags & TextureFlags::ORIGIN_BOTTOM_LEFT)
+ result |= TextureImage::OriginBottomLeft;
+ if (aFlags & TextureFlags::DISALLOW_BIGIMAGE)
+ result |= TextureImage::DisallowBigImage;
+
+ return static_cast<gl::TextureImage::Flags>(result);
+}
+
+bool
+TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
+ nsIntRegion* aDestRegion,
+ gfx::IntPoint* aSrcOffset)
+{
+ GLContext *gl = mCompositor->gl();
+ MOZ_ASSERT(gl);
+ if (!gl || !gl->MakeCurrent()) {
+ NS_WARNING("trying to update TextureImageTextureSourceOGL without a GLContext");
+ return false;
+ }
+ if (!aSurface) {
+ gfxCriticalError() << "Invalid surface for OGL update";
+ return false;
+ }
+ MOZ_ASSERT(aSurface);
+
+ IntSize size = aSurface->GetSize();
+ if (!mTexImage ||
+ (mTexImage->GetSize() != size && !aSrcOffset) ||
+ mTexImage->GetContentType() != gfx::ContentForFormat(aSurface->GetFormat())) {
+ if (mFlags & TextureFlags::DISALLOW_BIGIMAGE) {
+ GLint maxTextureSize;
+ gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+ if (size.width > maxTextureSize || size.height > maxTextureSize) {
+ NS_WARNING("Texture exceeds maximum texture size, refusing upload");
+ return false;
+ }
+ // Explicitly use CreateBasicTextureImage instead of CreateTextureImage,
+ // because CreateTextureImage might still choose to create a tiled
+ // texture image.
+ mTexImage = CreateBasicTextureImage(gl, size,
+ gfx::ContentForFormat(aSurface->GetFormat()),
+ LOCAL_GL_CLAMP_TO_EDGE,
+ FlagsToGLFlags(mFlags));
+ } else {
+ // XXX - clarify which size we want to use. IncrementalContentHost will
+ // require the size of the destination surface to be different from
+ // the size of aSurface.
+ // See bug 893300 (tracks the implementation of ContentHost for new textures).
+ mTexImage = CreateTextureImage(gl,
+ size,
+ gfx::ContentForFormat(aSurface->GetFormat()),
+ LOCAL_GL_CLAMP_TO_EDGE,
+ FlagsToGLFlags(mFlags),
+ SurfaceFormatToImageFormat(aSurface->GetFormat()));
+ }
+ ClearCachedFilter();
+
+ if (aDestRegion &&
+ !aSrcOffset &&
+ !aDestRegion->IsEqual(gfx::IntRect(0, 0, size.width, size.height))) {
+ // UpdateFromDataSource will ignore our specified aDestRegion since the texture
+ // hasn't been allocated with glTexImage2D yet. Call Resize() to force the
+ // allocation (full size, but no upload), and then we'll only upload the pixels
+ // we care about below.
+ mTexImage->Resize(size);
+ }
+ }
+
+ mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset);
+
+ return true;
+}
+
+void
+TextureImageTextureSourceOGL::EnsureBuffer(const IntSize& aSize,
+ gfxContentType aContentType)
+{
+ if (!mTexImage ||
+ mTexImage->GetSize() != aSize ||
+ mTexImage->GetContentType() != aContentType) {
+ mTexImage = CreateTextureImage(mCompositor->gl(),
+ aSize,
+ aContentType,
+ LOCAL_GL_CLAMP_TO_EDGE,
+ FlagsToGLFlags(mFlags));
+ }
+ mTexImage->Resize(aSize);
+}
+
+void
+TextureImageTextureSourceOGL::CopyTo(const gfx::IntRect& aSourceRect,
+ DataTextureSource *aDest,
+ const gfx::IntRect& aDestRect)
+{
+ MOZ_ASSERT(aDest->AsSourceOGL(), "Incompatible destination type!");
+ TextureImageTextureSourceOGL *dest =
+ aDest->AsSourceOGL()->AsTextureImageTextureSource();
+ MOZ_ASSERT(dest, "Incompatible destination type!");
+
+ mCompositor->BlitTextureImageHelper()->BlitTextureImage(mTexImage, aSourceRect,
+ dest->mTexImage, aDestRect);
+ dest->mTexImage->MarkValid();
+}
+
+CompositorOGL* AssertGLCompositor(Compositor* aCompositor)
+{
+ CompositorOGL* compositor = aCompositor ? aCompositor->AsCompositorOGL()
+ : nullptr;
+ MOZ_ASSERT(!!compositor);
+ return compositor;
+}
+
+void
+TextureImageTextureSourceOGL::SetCompositor(Compositor* aCompositor)
+{
+ CompositorOGL* glCompositor = AssertGLCompositor(aCompositor);
+ if (!glCompositor) {
+ DeallocateDeviceData();
+ return;
+ }
+ if (mCompositor != glCompositor) {
+ DeallocateDeviceData();
+ mCompositor = glCompositor;
+ }
+}
+
+gfx::IntSize
+TextureImageTextureSourceOGL::GetSize() const
+{
+ if (mTexImage) {
+ if (mIterating) {
+ return mTexImage->GetTileRect().Size();
+ }
+ return mTexImage->GetSize();
+ }
+ NS_WARNING("Trying to query the size of an empty TextureSource.");
+ return gfx::IntSize(0, 0);
+}
+
+gfx::SurfaceFormat
+TextureImageTextureSourceOGL::GetFormat() const
+{
+ if (mTexImage) {
+ return mTexImage->GetTextureFormat();
+ }
+ NS_WARNING("Trying to query the format of an empty TextureSource.");
+ return gfx::SurfaceFormat::UNKNOWN;
+}
+
+gfx::IntRect TextureImageTextureSourceOGL::GetTileRect()
+{
+ return mTexImage->GetTileRect();
+}
+
+void
+TextureImageTextureSourceOGL::BindTexture(GLenum aTextureUnit,
+ gfx::SamplingFilter aSamplingFilter)
+{
+ MOZ_ASSERT(mTexImage,
+ "Trying to bind a TextureSource that does not have an underlying GL texture.");
+ mTexImage->BindTexture(aTextureUnit);
+ SetSamplingFilter(mCompositor->gl(), aSamplingFilter);
+}
+
+////////////////////////////////////////////////////////////////////////
+// GLTextureSource
+
+GLTextureSource::GLTextureSource(CompositorOGL* aCompositor,
+ GLuint aTextureHandle,
+ GLenum aTarget,
+ gfx::IntSize aSize,
+ gfx::SurfaceFormat aFormat,
+ bool aExternallyOwned)
+ : mCompositor(aCompositor)
+ , mTextureHandle(aTextureHandle)
+ , mTextureTarget(aTarget)
+ , mSize(aSize)
+ , mFormat(aFormat)
+ , mExternallyOwned(aExternallyOwned)
+{
+ MOZ_COUNT_CTOR(GLTextureSource);
+}
+
+GLTextureSource::~GLTextureSource()
+{
+ MOZ_COUNT_DTOR(GLTextureSource);
+ if (!mExternallyOwned) {
+ DeleteTextureHandle();
+ }
+}
+
+void
+GLTextureSource::DeallocateDeviceData()
+{
+ if (!mExternallyOwned) {
+ DeleteTextureHandle();
+ }
+}
+
+void
+GLTextureSource::DeleteTextureHandle()
+{
+ GLContext* gl = this->gl();
+ if (mTextureHandle != 0 && gl && gl->MakeCurrent()) {
+ gl->fDeleteTextures(1, &mTextureHandle);
+ }
+ mTextureHandle = 0;
+}
+
+void
+GLTextureSource::BindTexture(GLenum aTextureUnit,
+ gfx::SamplingFilter aSamplingFilter)
+{
+ MOZ_ASSERT(mTextureHandle != 0);
+ GLContext* gl = this->gl();
+ if (!gl || !gl->MakeCurrent()) {
+ return;
+ }
+ gl->fActiveTexture(aTextureUnit);
+ gl->fBindTexture(mTextureTarget, mTextureHandle);
+ ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
+}
+
+void
+GLTextureSource::SetCompositor(Compositor* aCompositor)
+{
+ CompositorOGL* glCompositor = AssertGLCompositor(aCompositor);
+ if (!glCompositor) {
+ return;
+ }
+
+ if (mCompositor && mCompositor != glCompositor) {
+ gfxCriticalError() << "GLTextureSource does not support changing compositors";
+ }
+ mCompositor = glCompositor;
+
+ if (mNextSibling) {
+ mNextSibling->SetCompositor(aCompositor);
+ }
+}
+
+bool
+GLTextureSource::IsValid() const
+{
+ return !!gl() && mTextureHandle != 0;
+}
+
+gl::GLContext*
+GLTextureSource::gl() const
+{
+ return mCompositor ? mCompositor->gl() : nullptr;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+// SurfaceTextureHost
+
+#ifdef MOZ_WIDGET_ANDROID
+
+SurfaceTextureSource::SurfaceTextureSource(CompositorOGL* aCompositor,
+ AndroidSurfaceTexture* aSurfTex,
+ gfx::SurfaceFormat aFormat,
+ GLenum aTarget,
+ GLenum aWrapMode,
+ gfx::IntSize aSize)
+ : mCompositor(aCompositor)
+ , mSurfTex(aSurfTex)
+ , mFormat(aFormat)
+ , mTextureTarget(aTarget)
+ , mWrapMode(aWrapMode)
+ , mSize(aSize)
+{
+}
+
+void
+SurfaceTextureSource::BindTexture(GLenum aTextureUnit,
+ gfx::SamplingFilter aSamplingFilter)
+{
+ MOZ_ASSERT(mSurfTex);
+ GLContext* gl = this->gl();
+ if (!gl || !gl->MakeCurrent()) {
+ NS_WARNING("Trying to bind a texture without a GLContext");
+ return;
+ }
+
+ gl->fActiveTexture(aTextureUnit);
+
+ // SurfaceTexture spams us if there are any existing GL errors, so
+ // we'll clear them here in order to avoid that.
+ gl->FlushErrors();
+
+ mSurfTex->UpdateTexImage();
+
+ ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
+}
+
+void
+SurfaceTextureSource::SetCompositor(Compositor* aCompositor)
+{
+ CompositorOGL* glCompositor = AssertGLCompositor(aCompositor);
+ if (!glCompositor) {
+ DeallocateDeviceData();
+ return;
+ }
+ if (mCompositor != glCompositor) {
+ DeallocateDeviceData();
+ }
+
+ mCompositor = glCompositor;
+}
+
+bool
+SurfaceTextureSource::IsValid() const
+{
+ return !!gl();
+}
+
+gl::GLContext*
+SurfaceTextureSource::gl() const
+{
+ return mCompositor ? mCompositor->gl() : nullptr;
+}
+
+gfx::Matrix4x4
+SurfaceTextureSource::GetTextureTransform()
+{
+ MOZ_ASSERT(mSurfTex);
+
+ gfx::Matrix4x4 ret;
+ mSurfTex->GetTransformMatrix(ret);
+
+ return ret;
+}
+
+void
+SurfaceTextureSource::DeallocateDeviceData()
+{
+ mSurfTex = nullptr;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+SurfaceTextureHost::SurfaceTextureHost(TextureFlags aFlags,
+ AndroidSurfaceTexture* aSurfTex,
+ gfx::IntSize aSize)
+ : TextureHost(aFlags)
+ , mSurfTex(aSurfTex)
+ , mSize(aSize)
+ , mCompositor(nullptr)
+{
+}
+
+SurfaceTextureHost::~SurfaceTextureHost()
+{
+}
+
+gl::GLContext*
+SurfaceTextureHost::gl() const
+{
+ return mCompositor ? mCompositor->gl() : nullptr;
+}
+
+bool
+SurfaceTextureHost::Lock()
+{
+ MOZ_ASSERT(mSurfTex);
+ GLContext* gl = this->gl();
+ if (!gl || !gl->MakeCurrent()) {
+ return false;
+ }
+
+ if (!mTextureSource) {
+ gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
+ GLenum target = LOCAL_GL_TEXTURE_EXTERNAL;
+ GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
+ mTextureSource = new SurfaceTextureSource(mCompositor,
+ mSurfTex,
+ format,
+ target,
+ wrapMode,
+ mSize);
+ }
+
+ return NS_SUCCEEDED(mSurfTex->Attach(gl));
+}
+
+void
+SurfaceTextureHost::Unlock()
+{
+ MOZ_ASSERT(mSurfTex);
+ mSurfTex->Detach();
+}
+
+void
+SurfaceTextureHost::SetCompositor(Compositor* aCompositor)
+{
+ CompositorOGL* glCompositor = AssertGLCompositor(aCompositor);
+ if (!glCompositor) {
+ DeallocateDeviceData();
+ return;
+ }
+ mCompositor = glCompositor;
+ if (mTextureSource) {
+ mTextureSource->SetCompositor(glCompositor);
+ }
+}
+
+gfx::SurfaceFormat
+SurfaceTextureHost::GetFormat() const
+{
+ return mTextureSource ? mTextureSource->GetFormat() : gfx::SurfaceFormat::UNKNOWN;
+}
+
+void
+SurfaceTextureHost::DeallocateDeviceData()
+{
+ if (mTextureSource) {
+ mTextureSource->DeallocateDeviceData();
+ }
+ mSurfTex = nullptr;
+}
+
+#endif // MOZ_WIDGET_ANDROID
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+// EGLImage
+
+EGLImageTextureSource::EGLImageTextureSource(CompositorOGL* aCompositor,
+ EGLImage aImage,
+ gfx::SurfaceFormat aFormat,
+ GLenum aTarget,
+ GLenum aWrapMode,
+ gfx::IntSize aSize)
+ : mCompositor(aCompositor)
+ , mImage(aImage)
+ , mFormat(aFormat)
+ , mTextureTarget(aTarget)
+ , mWrapMode(aWrapMode)
+ , mSize(aSize)
+{
+ MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D ||
+ mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL);
+}
+
+void
+EGLImageTextureSource::BindTexture(GLenum aTextureUnit,
+ gfx::SamplingFilter aSamplingFilter)
+{
+ GLContext* gl = this->gl();
+ if (!gl || !gl->MakeCurrent()) {
+ NS_WARNING("Trying to bind a texture without a GLContext");
+ return;
+ }
+
+ MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl),
+ "EGLImage not supported or disabled in runtime");
+
+ GLuint tex = mCompositor->GetTemporaryTexture(mTextureTarget, aTextureUnit);
+
+ gl->fActiveTexture(aTextureUnit);
+ gl->fBindTexture(mTextureTarget, tex);
+
+ gl->fEGLImageTargetTexture2D(mTextureTarget, mImage);
+
+ ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
+}
+
+void
+EGLImageTextureSource::SetCompositor(Compositor* aCompositor)
+{
+ mCompositor = AssertGLCompositor(aCompositor);
+}
+
+bool
+EGLImageTextureSource::IsValid() const
+{
+ return !!gl();
+}
+
+gl::GLContext*
+EGLImageTextureSource::gl() const
+{
+ return mCompositor ? mCompositor->gl() : nullptr;
+}
+
+gfx::Matrix4x4
+EGLImageTextureSource::GetTextureTransform()
+{
+ gfx::Matrix4x4 ret;
+ return ret;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+EGLImageTextureHost::EGLImageTextureHost(TextureFlags aFlags,
+ EGLImage aImage,
+ EGLSync aSync,
+ gfx::IntSize aSize,
+ bool hasAlpha)
+ : TextureHost(aFlags)
+ , mImage(aImage)
+ , mSync(aSync)
+ , mSize(aSize)
+ , mHasAlpha(hasAlpha)
+ , mCompositor(nullptr)
+{}
+
+EGLImageTextureHost::~EGLImageTextureHost()
+{}
+
+gl::GLContext*
+EGLImageTextureHost::gl() const
+{
+ return mCompositor ? mCompositor->gl() : nullptr;
+}
+
+bool
+EGLImageTextureHost::Lock()
+{
+ GLContext* gl = this->gl();
+ if (!gl || !gl->MakeCurrent()) {
+ return false;
+ }
+
+ EGLint status = LOCAL_EGL_CONDITION_SATISFIED;
+
+ if (mSync) {
+ MOZ_ASSERT(sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
+ status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSync, 0, LOCAL_EGL_FOREVER);
+ }
+
+ if (status != LOCAL_EGL_CONDITION_SATISFIED) {
+ MOZ_ASSERT(status != 0,
+ "ClientWaitSync generated an error. Has mSync already been destroyed?");
+ return false;
+ }
+
+ if (!mTextureSource) {
+ gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
+ : gfx::SurfaceFormat::R8G8B8X8;
+ GLenum target = gl->GetPreferredEGLImageTextureTarget();
+ GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
+ mTextureSource = new EGLImageTextureSource(mCompositor,
+ mImage,
+ format,
+ target,
+ wrapMode,
+ mSize);
+ }
+
+ return true;
+}
+
+void
+EGLImageTextureHost::Unlock()
+{
+}
+
+void
+EGLImageTextureHost::SetCompositor(Compositor* aCompositor)
+{
+ CompositorOGL* glCompositor = AssertGLCompositor(aCompositor);
+ if (!glCompositor) {
+ mCompositor = nullptr;
+ mTextureSource = nullptr;
+ return;
+ }
+ mCompositor = glCompositor;
+ if (mTextureSource) {
+ mTextureSource->SetCompositor(glCompositor);
+ }
+}
+
+gfx::SurfaceFormat
+EGLImageTextureHost::GetFormat() const
+{
+ MOZ_ASSERT(mTextureSource);
+ return mTextureSource ? mTextureSource->GetFormat() : gfx::SurfaceFormat::UNKNOWN;
+}
+
+//
+
+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()
+{
+ GLContext* gl = this->gl();
+ if (!gl || !gl->MakeCurrent()) {
+ return false;
+ }
+
+ if (mSync) {
+ if (!gl->MakeCurrent()) {
+ return false;
+ }
+ 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)
+{
+ CompositorOGL* glCompositor = AssertGLCompositor(aCompositor);
+ if (!glCompositor) {
+ mCompositor = nullptr;
+ mTextureSource = nullptr;
+ return;
+ }
+ mCompositor = glCompositor;
+ if (mTextureSource) {
+ mTextureSource->SetCompositor(glCompositor);
+ }
+}
+
+gfx::SurfaceFormat
+GLTextureHost::GetFormat() const
+{
+ MOZ_ASSERT(mTextureSource);
+ return mTextureSource ? mTextureSource->GetFormat() : gfx::SurfaceFormat::UNKNOWN;
+}
+
+} // namespace layers
+} // namespace mozilla