diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index 16bd81d0fd8..eb70a3c8378 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -56,9 +56,10 @@ using namespace mozilla::dom; #include "GLContextProvider.h" #include "GLContext.h" #include "TexturePoolOGL.h" -#include "GLSharedHandleHelpers.h" #include "SurfaceTypes.h" +#include "EGLUtils.h" +using namespace mozilla; using namespace mozilla::gl; typedef nsNPAPIPluginInstance::VideoInfo VideoInfo; @@ -127,7 +128,7 @@ public: mLock.Unlock(); } - SharedTextureHandle CreateSharedHandle() + EGLImage CreateEGLImage() { MutexAutoLock lock(mLock); @@ -137,18 +138,15 @@ public: if (mTextureInfo.mWidth == 0 || mTextureInfo.mHeight == 0) return 0; - SharedTextureHandle handle = - gl::CreateSharedHandle(sPluginContext, - gl::SharedTextureShareType::SameProcess, - (void*)mTextureInfo.mTexture, - gl::SharedTextureBufferType::TextureID); + GLuint& tex = mTextureInfo.mTexture; + EGLImage image = gl::CreateEGLImage(sPluginContext, tex); // We want forget about this now, so delete the texture. Assigning it to zero // ensures that we create a new one in Lock() - sPluginContext->fDeleteTextures(1, &mTextureInfo.mTexture); - mTextureInfo.mTexture = 0; + sPluginContext->fDeleteTextures(1, &tex); + tex = 0; - return handle; + return image; } private: @@ -985,17 +983,22 @@ void* nsNPAPIPluginInstance::AcquireContentWindow() return mContentSurface->GetNativeWindow(); } -SharedTextureHandle nsNPAPIPluginInstance::CreateSharedHandle() +EGLImage +nsNPAPIPluginInstance::AsEGLImage() { - if (mContentTexture) { - return mContentTexture->CreateSharedHandle(); - } else if (mContentSurface) { - EnsureGLContext(); - return gl::CreateSharedHandle(sPluginContext, - gl::SharedTextureShareType::SameProcess, - mContentSurface, - gl::SharedTextureBufferType::SurfaceTexture); - } else return 0; + if (!mContentTexture) + return 0; + + return mContentTexture->CreateEGLImage(); +} + +nsSurfaceTexture* +nsNPAPIPluginInstance::AsSurfaceTexture() +{ + if (!mContentSurface) + return nullptr; + + return mContentSurface; } void* nsNPAPIPluginInstance::AcquireVideoWindow() diff --git a/dom/plugins/base/nsNPAPIPluginInstance.h b/dom/plugins/base/nsNPAPIPluginInstance.h index e99843e1e7f..0910ed5fd61 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.h +++ b/dom/plugins/base/nsNPAPIPluginInstance.h @@ -191,7 +191,8 @@ public: // For ANPNativeWindow void* AcquireContentWindow(); - mozilla::gl::SharedTextureHandle CreateSharedHandle(); + EGLImage AsEGLImage(); + nsSurfaceTexture* AsSurfaceTexture(); // For ANPVideo class VideoInfo { diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 23b1ee43f07..e6b97419295 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -22,7 +22,7 @@ using mozilla::DefaultXDisplay; #include "nsSize.h" #include "nsDisplayList.h" #include "ImageLayers.h" -#include "SharedTextureImage.h" +#include "GLImages.h" #include "nsObjectFrame.h" #include "nsIPluginDocument.h" #include "nsIStringStream.h" @@ -49,7 +49,7 @@ using mozilla::DefaultXDisplay; #include "ImageContainer.h" #include "nsIDOMHTMLCollection.h" #include "GLContext.h" -#include "GLSharedHandleHelpers.h" +#include "EGLUtils.h" #include "nsIContentInlines.h" #include "mozilla/MiscEvents.h" #include "mozilla/MouseEvents.h" @@ -148,6 +148,62 @@ nsPluginInstanceOwner::NotifyPaintWaiter(nsDisplayListBuilder* aBuilder) } } +#if MOZ_WIDGET_ANDROID +static void +AttachToContainerAsEGLImage(ImageContainer* container, + nsNPAPIPluginInstance* instance, + const LayoutDeviceRect& rect, + nsRefPtr* out_image) +{ + MOZ_ASSERT(out_image); + MOZ_ASSERT(!*out_image); + + EGLImage image = instance->AsEGLImage(); + if (!image) { + return; + } + + nsRefPtr img = container->CreateImage(ImageFormat::EGLIMAGE); + + EGLImageImage::Data data; + data.mImage = image; + data.mSize = gfx::IntSize(rect.width, rect.height); + data.mInverted = instance->Inverted(); + + EGLImageImage* typedImg = static_cast(img.get()); + typedImg->SetData(data); + + *out_image = img; +} + +static void +AttachToContainerAsSurfaceTexture(ImageContainer* container, + nsNPAPIPluginInstance* instance, + const LayoutDeviceRect& rect, + nsRefPtr* out_image) +{ + MOZ_ASSERT(out_image); + MOZ_ASSERT(!*out_image); + + nsSurfaceTexture* surfTex = instance->AsSurfaceTexture(); + if (!surfTex) { + return; + } + + nsRefPtr img = container->CreateImage(ImageFormat::SURFACE_TEXTURE); + + SurfaceTextureImage::Data data; + data.mSurfTex = surfTex; + data.mSize = gfx::IntSize(rect.width, rect.height); + data.mInverted = instance->Inverted(); + + SurfaceTextureImage* typedImg = static_cast(img.get()); + typedImg->SetData(data); + + *out_image = img; +} +#endif + already_AddRefed nsPluginInstanceOwner::GetImageContainer() { @@ -172,23 +228,19 @@ nsPluginInstanceOwner::GetImageContainer() container = LayerManager::CreateImageContainer(); - nsRefPtr img = container->CreateImage(ImageFormat::SHARED_TEXTURE); - - SharedTextureImage::Data data; - data.mSize = gfx::IntSize(r.width, r.height); - data.mHandle = mInstance->CreateSharedHandle(); - data.mShareType = mozilla::gl::SharedTextureShareType::SameProcess; - data.mInverted = mInstance->Inverted(); - - SharedTextureImage* pluginImage = static_cast(img.get()); - pluginImage->SetData(data); + // Try to get it as an EGLImage first. + nsRefPtr img; + AttachToContainerAsEGLImage(container, mInstance, r, &img); + if (!img) { + AttachToContainerAsSurfaceTexture(container, mInstance, r, &img); + } + MOZ_ASSERT(img); container->SetCurrentImageInTransaction(img); - - return container.forget(); +#else + mInstance->GetImageContainer(getter_AddRefs(container)); #endif - mInstance->GetImageContainer(getter_AddRefs(container)); return container.forget(); } @@ -1113,7 +1165,8 @@ void nsPluginInstanceOwner::RemovePluginView() sFullScreenInstance = nullptr; } -void nsPluginInstanceOwner::GetVideos(nsTArray& aVideos) +void +nsPluginInstanceOwner::GetVideos(nsTArray& aVideos) { if (!mInstance) return; @@ -1121,27 +1174,25 @@ void nsPluginInstanceOwner::GetVideos(nsTArrayGetVideos(aVideos); } -already_AddRefed nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo) +already_AddRefed +nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo) { nsRefPtr container = LayerManager::CreateImageContainer(); - nsRefPtr img = container->CreateImage(ImageFormat::SHARED_TEXTURE); + nsRefPtr img = container->CreateImage(ImageFormat::SURFACE_TEXTURE); - SharedTextureImage::Data data; + SurfaceTextureImage::Data data; - data.mShareType = gl::SharedTextureShareType::SameProcess; - data.mHandle = gl::CreateSharedHandle(mInstance->GLContext(), - data.mShareType, - aVideoInfo->mSurfaceTexture, - gl::SharedTextureBufferType::SurfaceTexture); + data.mSurfTex = aVideoInfo->mSurfaceTexture; // The logic below for Honeycomb is just a guess, but seems to work. We don't have a separate // inverted flag for video. data.mInverted = AndroidBridge::Bridge()->IsHoneycomb() ? true : mInstance->Inverted(); data.mSize = gfx::IntSize(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height); - SharedTextureImage* pluginImage = static_cast(img.get()); - pluginImage->SetData(data); + SurfaceTextureImage* typedImg = static_cast(img.get()); + typedImg->SetData(data); + container->SetCurrentImageInTransaction(img); return container.forget(); diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index d426bb3aca7..fa23e89280b 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -28,7 +28,7 @@ #include "gfxUtils.h" #include "mozilla/gfx/2D.h" #include "Layers.h" -#include "SharedTextureImage.h" +#include "ImageContainer.h" #include "GLContext.h" #include "GLContextProvider.h" diff --git a/gfx/gl/EGLUtils.cpp b/gfx/gl/EGLUtils.cpp new file mode 100644 index 00000000000..e87458bfba6 --- /dev/null +++ b/gfx/gl/EGLUtils.cpp @@ -0,0 +1,114 @@ +/* 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 "EGLUtils.h" + +#include "GLContextEGL.h" + +namespace mozilla { +namespace gl { + +bool +DoesEGLContextSupportSharingWithEGLImage(GLContext* gl) +{ + return sEGLLibrary.HasKHRImageBase() && + sEGLLibrary.HasKHRImageTexture2D() && + gl->IsExtensionSupported(GLContext::OES_EGL_image); +} + +EGLImage +CreateEGLImage(GLContext* gl, GLuint tex) +{ + MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl)); + + EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex); + EGLContext eglContext = GLContextEGL::Cast(gl)->GetEGLContext(); + EGLImage image = sEGLLibrary.fCreateImage(EGL_DISPLAY(), + eglContext, + LOCAL_EGL_GL_TEXTURE_2D, + clientBuffer, + nullptr); + return image; +} + +//////////////////////////////////////////////////////////////////////// +// EGLImageWrapper + +/*static*/ EGLImageWrapper* +EGLImageWrapper::Create(GLContext* gl, GLuint tex) +{ + MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl)); + + GLLibraryEGL& library = sEGLLibrary; + EGLDisplay display = EGL_DISPLAY(); + EGLContext eglContext = GLContextEGL::Cast(gl)->GetEGLContext(); + EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex); + EGLImage image = library.fCreateImage(display, + eglContext, + LOCAL_EGL_GL_TEXTURE_2D, + clientBuffer, + nullptr); + if (!image) { +#ifdef DEBUG + printf_stderr("Could not create EGL images: ERROR (0x%04x)\n", + sEGLLibrary.fGetError()); +#endif + return nullptr; + } + + return new EGLImageWrapper(library, display, image); +} + +EGLImageWrapper::~EGLImageWrapper() +{ + mLibrary.fDestroyImage(mDisplay, mImage); +} + +bool +EGLImageWrapper::FenceSync(GLContext* gl) +{ + MOZ_ASSERT(!mSync); + + if (mLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync)) { + mSync = mLibrary.fCreateSync(mDisplay, + LOCAL_EGL_SYNC_FENCE, + nullptr); + // We need to flush to make sure the sync object enters the command stream; + // we can't use EGL_SYNC_FLUSH_COMMANDS_BIT at wait time, because the wait + // happens on a different thread/context. + gl->fFlush(); + } + + if (!mSync) { + // we failed to create one, so just do a finish + gl->fFinish(); + } + + return true; +} + +bool +EGLImageWrapper::ClientWaitSync() +{ + if (!mSync) { + // if we have no sync object, then we did a Finish() earlier + return true; + } + + // wait at most 1 second; this should really be never/rarely hit + const uint64_t ns_per_ms = 1000 * 1000; + EGLTime timeout = 1000 * ns_per_ms; + + EGLint result = mLibrary.fClientWaitSync(mDisplay, + mSync, + 0, + timeout); + mLibrary.fDestroySync(mDisplay, mSync); + mSync = nullptr; + + return result == LOCAL_EGL_CONDITION_SATISFIED; +} + +} // namespace gl +} // namespace mozilla diff --git a/gfx/gl/EGLUtils.h b/gfx/gl/EGLUtils.h new file mode 100644 index 00000000000..71ca01e9cbf --- /dev/null +++ b/gfx/gl/EGLUtils.h @@ -0,0 +1,60 @@ +/* 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/. */ + +#ifndef EGLUTILS_H_ +#define EGLUTILS_H_ + +#include "GLContextTypes.h" +#include "GLTypes.h" +#include "mozilla/Assertions.h" + +namespace mozilla { +namespace gl { + +class GLLibraryEGL; + +bool DoesEGLContextSupportSharingWithEGLImage(GLContext* gl); +EGLImage CreateEGLImage(GLContext* gl, GLuint tex); + +//////////////////////////////////////////////////////////////////////// +// EGLImageWrapper + +class EGLImageWrapper +{ +public: + static EGLImageWrapper* Create(GLContext* gl, GLuint tex); + +private: + GLLibraryEGL& mLibrary; + const EGLDisplay mDisplay; +public: + const EGLImage mImage; +private: + EGLSync mSync; + + EGLImageWrapper(GLLibraryEGL& library, + EGLDisplay display, + EGLImage image) + : mLibrary(library) + , mDisplay(display) + , mImage(image) + , mSync(0) + { + MOZ_ASSERT(mImage); + } + +public: + ~EGLImageWrapper(); + + // Insert a sync point on the given context, which should be the current active + // context. + bool FenceSync(GLContext* gl); + + bool ClientWaitSync(); +}; + +} // namespace gl +} // namespace mozilla + +#endif diff --git a/gfx/gl/GLContextTypes.h b/gfx/gl/GLContextTypes.h index bd6532c69d7..27ae4813d75 100644 --- a/gfx/gl/GLContextTypes.h +++ b/gfx/gl/GLContextTypes.h @@ -14,19 +14,6 @@ namespace gl { class GLContext; -typedef uintptr_t SharedTextureHandle; - -MOZ_BEGIN_ENUM_CLASS(SharedTextureShareType) - SameProcess = 0, - CrossProcess -MOZ_END_ENUM_CLASS(SharedTextureShareType) - -MOZ_BEGIN_ENUM_CLASS(SharedTextureBufferType) - TextureID, - SurfaceTexture, - IOSurface -MOZ_END_ENUM_CLASS(SharedTextureBufferType) - MOZ_BEGIN_ENUM_CLASS(GLContextType) Unknown, WGL, diff --git a/gfx/gl/GLSharedHandleHelpers.cpp b/gfx/gl/GLSharedHandleHelpers.cpp deleted file mode 100644 index 345235d07c6..00000000000 --- a/gfx/gl/GLSharedHandleHelpers.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* 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 "GLContextEGL.h" -#include "GLSharedHandleHelpers.h" -#ifdef MOZ_WIDGET_ANDROID -#include "nsSurfaceTexture.h" -#endif - -namespace mozilla { -namespace gl { - -enum SharedHandleType { - SharedHandleType_Image -#ifdef MOZ_WIDGET_ANDROID - , SharedHandleType_SurfaceTexture -#endif -}; - -class SharedTextureHandleWrapper -{ -public: - explicit SharedTextureHandleWrapper(SharedHandleType aHandleType) : mHandleType(aHandleType) - { - } - - virtual ~SharedTextureHandleWrapper() - { - } - - SharedHandleType Type() { return mHandleType; } - - SharedHandleType mHandleType; -}; - -#ifdef MOZ_WIDGET_ANDROID - -class SurfaceTextureWrapper: public SharedTextureHandleWrapper -{ -public: - SurfaceTextureWrapper(nsSurfaceTexture* aSurfaceTexture) : - SharedTextureHandleWrapper(SharedHandleType_SurfaceTexture) - , mSurfaceTexture(aSurfaceTexture) - { - } - - virtual ~SurfaceTextureWrapper() { - mSurfaceTexture = nullptr; - } - - nsSurfaceTexture* SurfaceTexture() { return mSurfaceTexture; } - - nsRefPtr mSurfaceTexture; -}; - -#endif // MOZ_WIDGET_ANDROID - -class EGLTextureWrapper : public SharedTextureHandleWrapper -{ -public: - EGLTextureWrapper() : - SharedTextureHandleWrapper(SharedHandleType_Image) - , mEGLImage(nullptr) - , mSyncObject(nullptr) - { - } - - // Args are the active GL context, and a texture in that GL - // context for which to create an EGLImage. After the EGLImage - // is created, the texture is unused by EGLTextureWrapper. - bool CreateEGLImage(GLContext *ctx, uintptr_t texture) { - MOZ_ASSERT(!mEGLImage && texture && sEGLLibrary.HasKHRImageBase()); - static const EGLint eglAttributes[] = { - LOCAL_EGL_NONE - }; - EGLContext eglContext = GLContextEGL::Cast(ctx)->GetEGLContext(); - mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), eglContext, LOCAL_EGL_GL_TEXTURE_2D, - (EGLClientBuffer)texture, eglAttributes); - if (!mEGLImage) { -#ifdef DEBUG - printf_stderr("Could not create EGL images: ERROR (0x%04x)\n", sEGLLibrary.fGetError()); -#endif - return false; - } - return true; - } - - virtual ~EGLTextureWrapper() { - if (mEGLImage) { - sEGLLibrary.fDestroyImage(EGL_DISPLAY(), mEGLImage); - mEGLImage = nullptr; - } - } - - const EGLImage GetEGLImage() { - return mEGLImage; - } - - // Insert a sync point on the given context, which should be the current active - // context. - bool MakeSync(GLContext *ctx) { - MOZ_ASSERT(mSyncObject == nullptr); - - if (sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync)) { - mSyncObject = sEGLLibrary.fCreateSync(EGL_DISPLAY(), LOCAL_EGL_SYNC_FENCE, nullptr); - // We need to flush to make sure the sync object enters the command stream; - // we can't use EGL_SYNC_FLUSH_COMMANDS_BIT at wait time, because the wait - // happens on a different thread/context. - ctx->fFlush(); - } - - if (mSyncObject == EGL_NO_SYNC) { - // we failed to create one, so just do a finish - ctx->fFinish(); - } - - return true; - } - - bool WaitSync() { - if (!mSyncObject) { - // if we have no sync object, then we did a Finish() earlier - return true; - } - - // wait at most 1 second; this should really be never/rarely hit - const uint64_t ns_per_ms = 1000 * 1000; - EGLTime timeout = 1000 * ns_per_ms; - - EGLint result = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSyncObject, 0, timeout); - sEGLLibrary.fDestroySync(EGL_DISPLAY(), mSyncObject); - mSyncObject = nullptr; - - return result == LOCAL_EGL_CONDITION_SATISFIED; - } - -private: - EGLImage mEGLImage; - EGLSync mSyncObject; -}; - -static bool DoesEGLContextSupportSharingWithEGLImage(GLContext *gl) -{ - return sEGLLibrary.HasKHRImageBase() && - sEGLLibrary.HasKHRImageTexture2D() && - gl->IsExtensionSupported(GLContext::OES_EGL_image); -} - -SharedTextureHandle CreateSharedHandle(GLContext* gl, - SharedTextureShareType shareType, - void* buffer, - SharedTextureBufferType bufferType) -{ - // unimplemented outside of EGL - if (gl->GetContextType() != GLContextType::EGL) - return 0; - - // Both EGLImage and SurfaceTexture only support same-process currently, but - // it's possible to make SurfaceTexture work across processes. We should do that. - if (shareType != SharedTextureShareType::SameProcess) - return 0; - - switch (bufferType) { -#ifdef MOZ_WIDGET_ANDROID - case SharedTextureBufferType::SurfaceTexture: - if (!gl->IsExtensionSupported(GLContext::OES_EGL_image_external)) { - NS_WARNING("Missing GL_OES_EGL_image_external"); - return 0; - } - - return (SharedTextureHandle) new SurfaceTextureWrapper(reinterpret_cast(buffer)); -#endif - case SharedTextureBufferType::TextureID: { - if (!DoesEGLContextSupportSharingWithEGLImage(gl)) - return 0; - - GLuint texture = (uintptr_t)buffer; - EGLTextureWrapper* tex = new EGLTextureWrapper(); - if (!tex->CreateEGLImage(gl, texture)) { - NS_ERROR("EGLImage creation for EGLTextureWrapper failed"); - delete tex; - return 0; - } - - return (SharedTextureHandle)tex; - } - default: - NS_ERROR("Unknown shared texture buffer type"); - return 0; - } -} - -void ReleaseSharedHandle(GLContext* gl, - SharedTextureShareType shareType, - SharedTextureHandle sharedHandle) -{ - // unimplemented outside of EGL - if (gl->GetContextType() != GLContextType::EGL) - return; - - if (shareType != SharedTextureShareType::SameProcess) { - NS_ERROR("Implementation not available for this sharing type"); - return; - } - - SharedTextureHandleWrapper* wrapper = reinterpret_cast(sharedHandle); - - switch (wrapper->Type()) { -#ifdef MOZ_WIDGET_ANDROID - case SharedHandleType_SurfaceTexture: - delete wrapper; - break; -#endif - - case SharedHandleType_Image: { - NS_ASSERTION(DoesEGLContextSupportSharingWithEGLImage(gl), "EGLImage not supported or disabled in runtime"); - - EGLTextureWrapper* wrap = (EGLTextureWrapper*)sharedHandle; - delete wrap; - break; - } - - default: - NS_ERROR("Unknown shared handle type"); - return; - } -} - -bool GetSharedHandleDetails(GLContext* gl, - SharedTextureShareType shareType, - SharedTextureHandle sharedHandle, - SharedHandleDetails& details) -{ - // unimplemented outside of EGL - if (gl->GetContextType() != GLContextType::EGL) - return false; - - if (shareType != SharedTextureShareType::SameProcess) - return false; - - SharedTextureHandleWrapper* wrapper = reinterpret_cast(sharedHandle); - - switch (wrapper->Type()) { -#ifdef MOZ_WIDGET_ANDROID - case SharedHandleType_SurfaceTexture: { - SurfaceTextureWrapper* surfaceWrapper = reinterpret_cast(wrapper); - - details.mTarget = LOCAL_GL_TEXTURE_EXTERNAL; - details.mTextureFormat = gfx::SurfaceFormat::R8G8B8A8; - surfaceWrapper->SurfaceTexture()->GetTransformMatrix(details.mTextureTransform); - break; - } -#endif - - case SharedHandleType_Image: - details.mTarget = LOCAL_GL_TEXTURE_2D; - details.mTextureFormat = gfx::SurfaceFormat::R8G8B8A8; - break; - - default: - NS_ERROR("Unknown shared handle type"); - return false; - } - - return true; -} - -bool AttachSharedHandle(GLContext* gl, - SharedTextureShareType shareType, - SharedTextureHandle sharedHandle) -{ - // unimplemented outside of EGL - if (gl->GetContextType() != GLContextType::EGL) - return false; - - if (shareType != SharedTextureShareType::SameProcess) - return false; - - SharedTextureHandleWrapper* wrapper = reinterpret_cast(sharedHandle); - - switch (wrapper->Type()) { -#ifdef MOZ_WIDGET_ANDROID - case SharedHandleType_SurfaceTexture: { -#ifndef DEBUG - /* - * NOTE: SurfaceTexture spams us if there are any existing GL errors, so we'll clear - * them here in order to avoid that. - */ - gl->GetAndClearError(); -#endif - SurfaceTextureWrapper* surfaceTextureWrapper = reinterpret_cast(wrapper); - - // FIXME: SurfaceTexture provides a transform matrix which is supposed to - // be applied to the texture coordinates. We should return that here - // so we can render correctly. Bug 775083 - surfaceTextureWrapper->SurfaceTexture()->UpdateTexImage(); - break; - } -#endif // MOZ_WIDGET_ANDROID - - case SharedHandleType_Image: { - NS_ASSERTION(DoesEGLContextSupportSharingWithEGLImage(gl), "EGLImage not supported or disabled in runtime"); - - EGLTextureWrapper* wrap = (EGLTextureWrapper*)sharedHandle; - wrap->WaitSync(); - gl->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, wrap->GetEGLImage()); - break; - } - - default: - NS_ERROR("Unknown shared handle type"); - return false; - } - - return true; -} - -/** - * Detach Shared GL Handle from GL_TEXTURE_2D target - */ -void DetachSharedHandle(GLContext*, - SharedTextureShareType, - SharedTextureHandle) -{ - // currently a no-operation -} - -} -} diff --git a/gfx/gl/GLSharedHandleHelpers.h b/gfx/gl/GLSharedHandleHelpers.h deleted file mode 100644 index b1fef5e2ee1..00000000000 --- a/gfx/gl/GLSharedHandleHelpers.h +++ /dev/null @@ -1,73 +0,0 @@ -/* 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/. */ - -#ifndef GLSHAREDHANDLEHELPERS_H_ -#define GLSHAREDHANDLEHELPERS_H_ - -#include "GLContextTypes.h" -#include "mozilla/gfx/Types.h" - -namespace mozilla { -namespace gl { - -/** - * Create a new shared GLContext content handle, using the passed buffer as a source. - * Must be released by ReleaseSharedHandle. - */ -SharedTextureHandle CreateSharedHandle(GLContext* gl, - SharedTextureShareType shareType, - void* buffer, - SharedTextureBufferType bufferType); - -/** - * - It is better to call ReleaseSharedHandle before original GLContext destroyed, - * otherwise warning will be thrown on attempt to destroy Texture associated with SharedHandle, depends on backend implementation. - * - It does not require to be called on context where it was created, - * because SharedHandle suppose to keep Context reference internally, - * or don't require specific context at all, for example IPC SharedHandle. - * - Not recommended to call this between AttachSharedHandle and Draw Target call. - * if it is really required for some special backend, then DetachSharedHandle API must be added with related implementation. - * - It is recommended to stop any possible access to SharedHandle (Attachments, pending GL calls) before calling Release, - * otherwise some artifacts might appear or even crash if API backend implementation does not expect that. - * SharedHandle (currently EGLImage) does not require GLContext because it is EGL call, and can be destroyed - * at any time, unless EGLImage have siblings (which are not expected with current API). - */ -void ReleaseSharedHandle(GLContext* gl, - SharedTextureShareType shareType, - SharedTextureHandle sharedHandle); - - -typedef struct { - GLenum mTarget; - gfx::SurfaceFormat mTextureFormat; - gfx::Matrix4x4 mTextureTransform; -} SharedHandleDetails; - -/** - * Returns information necessary for rendering a shared handle. - * These values change depending on what sharing mechanism is in use - */ -bool GetSharedHandleDetails(GLContext* gl, - SharedTextureShareType shareType, - SharedTextureHandle sharedHandle, - SharedHandleDetails& details); -/** - * Attach Shared GL Handle to GL_TEXTURE_2D target - * GLContext must be current before this call - */ -bool AttachSharedHandle(GLContext* gl, - SharedTextureShareType shareType, - SharedTextureHandle sharedHandle); - -/** - * Detach Shared GL Handle from GL_TEXTURE_2D target - */ -void DetachSharedHandle(GLContext* gl, - SharedTextureShareType shareType, - SharedTextureHandle sharedHandle); - -} -} - -#endif diff --git a/gfx/gl/TextureImageEGL.cpp b/gfx/gl/TextureImageEGL.cpp index c312e32edd5..fa18f67de21 100644 --- a/gfx/gl/TextureImageEGL.cpp +++ b/gfx/gl/TextureImageEGL.cpp @@ -89,8 +89,9 @@ TextureImageEGL::~TextureImageEGL() // if we don't have a context (either real or shared), // then they went away when the contex was deleted, because it // was the only one that had access to it. - mGLContext->MakeCurrent(); - mGLContext->fDeleteTextures(1, &mTexture); + if (mGLContext->MakeCurrent()) { + mGLContext->fDeleteTextures(1, &mTexture); + } ReleaseTexImage(); DestroyEGLSurface(); } diff --git a/gfx/gl/moz.build b/gfx/gl/moz.build index 54f9fbfcdfc..32c173b1294 100644 --- a/gfx/gl/moz.build +++ b/gfx/gl/moz.build @@ -27,6 +27,7 @@ if CONFIG['MOZ_GL_PROVIDER']: EXPORTS += [ 'DecomposeIntoNoRepeatTriangles.h', + 'EGLUtils.h', 'ForceDiscreteGPUHelperCGL.h', 'GfxTexturesReporter.h', 'GLBlitHelper.h', @@ -43,7 +44,6 @@ EXPORTS += [ 'GLLibraryLoader.h', 'GLReadTexImageHelper.h', 'GLScreenBuffer.h', - 'GLSharedHandleHelpers.h', 'GLTextureImage.h', 'GLTypes.h', 'GLUploadHelpers.h', @@ -116,6 +116,7 @@ else: UNIFIED_SOURCES += [ 'DecomposeIntoNoRepeatTriangles.cpp', + 'EGLUtils.cpp', 'GfxTexturesReporter.cpp', 'GLBlitHelper.cpp', 'GLBlitTextureImageHelper.cpp', @@ -127,7 +128,6 @@ UNIFIED_SOURCES += [ 'GLLibraryLoader.cpp', 'GLReadTexImageHelper.cpp', 'GLScreenBuffer.cpp', - 'GLSharedHandleHelpers.cpp', 'GLTextureImage.cpp', 'GLUploadHelpers.cpp', 'ScopedGLHelpers.cpp', diff --git a/gfx/layers/Compositor.h b/gfx/layers/Compositor.h index cef857236b6..9497ba34b21 100644 --- a/gfx/layers/Compositor.h +++ b/gfx/layers/Compositor.h @@ -99,7 +99,7 @@ * under gfx/layers/. To add a new backend, implement at least the following * interfaces: * - Compositor (ex. CompositorOGL) - * - TextureHost (ex. SharedTextureHostOGL) + * - TextureHost (ex. SurfaceTextureHost) * Depending on the type of data that needs to be serialized, you may need to * add specific TextureClient implementations. */ diff --git a/gfx/layers/SharedTextureImage.h b/gfx/layers/GLImages.h similarity index 53% rename from gfx/layers/SharedTextureImage.h rename to gfx/layers/GLImages.h index 4cac350c37d..0b24c451e16 100644 --- a/gfx/layers/SharedTextureImage.h +++ b/gfx/layers/GLImages.h @@ -3,27 +3,24 @@ * 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/. */ -#ifndef GFX_SHAREDTEXTUREIMAGE_H -#define GFX_SHAREDTEXTUREIMAGE_H +#ifndef GFX_GLIMAGES_H +#define GFX_GLIMAGES_H -#include "GLContextProvider.h" // for GLContextProvider +#include "GLTypes.h" #include "ImageContainer.h" // for Image -#include "ImageTypes.h" // for ImageFormat::SHARED_TEXTURE +#include "ImageTypes.h" // for ImageFormat::SHARED_GLTEXTURE #include "nsCOMPtr.h" // for already_AddRefed #include "mozilla/gfx/Point.h" // for IntSize -// Split into a separate header from ImageLayers.h due to GLContext.h dependence -// Implementation remains in ImageLayers.cpp +class nsSurfaceTexture; namespace mozilla { - namespace layers { -class SharedTextureImage : public Image { +class EGLImageImage : public Image { public: struct Data { - gl::SharedTextureHandle mHandle; - gl::SharedTextureShareType mShareType; + EGLImage mImage; gfx::IntSize mSize; bool mInverted; }; @@ -38,13 +35,41 @@ public: return nullptr; } - SharedTextureImage() : Image(nullptr, ImageFormat::SHARED_TEXTURE) {} + EGLImageImage() : Image(nullptr, ImageFormat::EGLIMAGE) {} private: Data mData; }; +#ifdef MOZ_WIDGET_ANDROID + +class SurfaceTextureImage : public Image { +public: + struct Data { + nsSurfaceTexture* mSurfTex; + gfx::IntSize mSize; + bool mInverted; + }; + + void SetData(const Data& aData) { mData = aData; } + const Data* GetData() { return &mData; } + + gfx::IntSize GetSize() { return mData.mSize; } + + virtual TemporaryRef GetAsSourceSurface() MOZ_OVERRIDE + { + return nullptr; + } + + SurfaceTextureImage() : Image(nullptr, ImageFormat::SURFACE_TEXTURE) {} + +private: + Data mData; +}; + +#endif // MOZ_WIDGET_ANDROID + } // layers } // mozilla -#endif // GFX_SHAREDTEXTUREIMAGE_H +#endif // GFX_GLIMAGES_H diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp index 328d3b1606a..2041a05825f 100644 --- a/gfx/layers/ImageContainer.cpp +++ b/gfx/layers/ImageContainer.cpp @@ -6,7 +6,7 @@ #include "ImageContainer.h" #include // for memcpy, memset -#include "SharedTextureImage.h" // for SharedTextureImage +#include "GLImages.h" // for SurfaceTextureImage #include "gfx2DGlue.h" #include "gfxPlatform.h" // for gfxPlatform #include "gfxUtils.h" // for gfxUtils @@ -69,8 +69,14 @@ ImageFactory::CreateImage(ImageFormat aFormat, img = new CairoImage(); return img.forget(); } - if (aFormat == ImageFormat::SHARED_TEXTURE) { - img = new SharedTextureImage(); +#ifdef MOZ_WIDGET_ANDROID + if (aFormat == ImageFormat::SURFACE_TEXTURE) { + img = new SurfaceTextureImage(); + return img.forget(); + } +#endif + if (aFormat == ImageFormat::EGLIMAGE) { + img = new EGLImageImage(); return img.forget(); } #ifdef XP_MACOSX diff --git a/gfx/layers/ImageTypes.h b/gfx/layers/ImageTypes.h index 01b3a09a685..5685a3224d0 100644 --- a/gfx/layers/ImageTypes.h +++ b/gfx/layers/ImageTypes.h @@ -58,9 +58,15 @@ MOZ_BEGIN_ENUM_CLASS(ImageFormat) REMOTE_IMAGE_BITMAP, /** - * A OpenGL texture that can be shared across threads or processes + * An Android SurfaceTexture ID that can be shared across threads and + * processes. */ - SHARED_TEXTURE, + SURFACE_TEXTURE, + + /** + * An EGL Image that can be shared across threads. + */ + EGLIMAGE, /** * An DXGI shared surface handle that can be shared with a remote process. diff --git a/gfx/layers/client/ImageClient.cpp b/gfx/layers/client/ImageClient.cpp index c174e2f7df7..bac80bc5398 100644 --- a/gfx/layers/client/ImageClient.cpp +++ b/gfx/layers/client/ImageClient.cpp @@ -7,7 +7,7 @@ #include // for uint32_t #include "ImageContainer.h" // for Image, PlanarYCbCrImage, etc #include "ImageTypes.h" // for ImageFormat::PLANAR_YCBCR, etc -#include "SharedTextureImage.h" // for SharedTextureImage::Data, etc +#include "GLImages.h" // for SurfaceTextureImage::Data, etc #include "gfx2DGlue.h" // for ImageFormatToSurfaceFormat #include "gfxPlatform.h" // for gfxPlatform #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc @@ -24,7 +24,7 @@ #include "mozilla/layers/SharedPlanarYCbCrImage.h" #include "mozilla/layers/SharedRGBImage.h" #include "mozilla/layers/TextureClient.h" // for TextureClient, etc -#include "mozilla/layers/TextureClientOGL.h" // for SharedTextureClientOGL +#include "mozilla/layers/TextureClientOGL.h" // for SurfaceTextureClient #include "mozilla/mozalloc.h" // for operator delete, etc #include "nsAutoPtr.h" // for nsRefPtr #include "nsCOMPtr.h" // for already_AddRefed @@ -247,9 +247,9 @@ ImageClientSingle::UpdateImageInternal(ImageContainer* aContainer, return false; } - } else if (image->GetFormat() == ImageFormat::SHARED_TEXTURE) { - SharedTextureImage* sharedImage = static_cast(image); - const SharedTextureImage::Data *data = sharedImage->GetData(); + } else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE || + image->GetFormat() == ImageFormat::EGLIMAGE) + { gfx::IntSize size = gfx::IntSize(image->GetSize().width, image->GetSize().height); if (mFrontBuffer) { @@ -257,8 +257,30 @@ ImageClientSingle::UpdateImageInternal(ImageContainer* aContainer, mFrontBuffer = nullptr; } - RefPtr buffer = new SharedTextureClientOGL(mTextureFlags); - buffer->InitWith(data->mHandle, size, data->mShareType, data->mInverted); + RefPtr buffer; + + if (image->GetFormat() == ImageFormat::EGLIMAGE) { + EGLImageImage* typedImage = static_cast(image); + const EGLImageImage::Data* data = typedImage->GetData(); + + buffer = new EGLImageTextureClient(mTextureFlags, + data->mImage, + size, + data->mInverted); +#ifdef MOZ_WIDGET_ANDROID + } else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE) { + SurfaceTextureImage* typedImage = static_cast(image); + const SurfaceTextureImage::Data* data = typedImage->GetData(); + + buffer = new SurfaceTextureClient(mTextureFlags, + data->mSurfTex, + size, + data->mInverted); +#endif + } else { + MOZ_ASSERT(false, "Bad ImageFormat."); + } + mFrontBuffer = buffer; if (!AddTextureClient(mFrontBuffer)) { mFrontBuffer = nullptr; @@ -266,6 +288,7 @@ ImageClientSingle::UpdateImageInternal(ImageContainer* aContainer, } GetForwarder()->UseTexture(this, mFrontBuffer); + } else { RefPtr surface = image->GetAsSourceSurface(); MOZ_ASSERT(surface); diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index 8d67976db44..b60219dd822 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -205,8 +205,9 @@ TextureHost::Create(const SurfaceDescriptor& aDesc, case SurfaceDescriptor::TSurfaceDescriptorDIB: return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags); - case SurfaceDescriptor::TSharedTextureDescriptor: + case SurfaceDescriptor::TEGLImageDescriptor: case SurfaceDescriptor::TNewSurfaceDescriptorGralloc: + case SurfaceDescriptor::TSurfaceTextureDescriptor: return CreateTextureHostOGL(aDesc, aDeallocator, aFlags); case SurfaceDescriptor::TSurfaceStreamDescriptor: diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh index 428a1c6bd38..f78e153aeef 100644 --- a/gfx/layers/ipc/LayersSurfaces.ipdlh +++ b/gfx/layers/ipc/LayersSurfaces.ipdlh @@ -11,8 +11,6 @@ using struct mozilla::layers::GrallocBufferRef from "gfxipc/ShadowLayerUtils.h"; using struct mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h"; using struct mozilla::null_t from "ipc/IPCMessageUtils.h"; using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h"; -using mozilla::gl::SharedTextureHandle from "GLContextTypes.h"; -using mozilla::gl::SharedTextureShareType from "GLContextTypes.h"; using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h"; using mozilla::gfx::IntSize from "mozilla/gfx/Point.h"; using gfxImageFormat from "gfxTypes.h"; @@ -58,11 +56,14 @@ struct SurfaceDescriptorMacIOSurface { bool hasAlpha; }; -struct SharedTextureDescriptor { - SharedTextureShareType shareType; - SharedTextureHandle handle; +struct SurfaceTextureDescriptor { + uintptr_t surfTex; + IntSize size; +}; + +struct EGLImageDescriptor { + uintptr_t image; // `EGLImage` is a `void*`. IntSize size; - bool inverted; }; struct NewSurfaceDescriptorGralloc { @@ -103,7 +104,8 @@ union SurfaceDescriptor { SurfaceDescriptorDIB; SurfaceDescriptorD3D10; SurfaceDescriptorX11; - SharedTextureDescriptor; + SurfaceTextureDescriptor; + EGLImageDescriptor; SurfaceStreamDescriptor; SurfaceDescriptorMacIOSurface; NewSurfaceDescriptorGralloc; diff --git a/gfx/layers/ipc/ShadowLayerUtils.h b/gfx/layers/ipc/ShadowLayerUtils.h index de37f97bbc6..acbc1bfb97c 100644 --- a/gfx/layers/ipc/ShadowLayerUtils.h +++ b/gfx/layers/ipc/ShadowLayerUtils.h @@ -56,29 +56,6 @@ struct ParamTraits { }; #endif // !defined(MOZ_HAVE_XSURFACEDESCRIPTORX11) -template<> -struct ParamTraits -{ - typedef mozilla::gl::SharedTextureShareType paramType; - - static void Write(Message* msg, const paramType& param) - { - static_assert(sizeof(paramType) <= sizeof(int32_t), - "TextureShareType assumes to be int32_t"); - WriteParam(msg, int32_t(param)); - } - - static bool Read(const Message* msg, void** iter, paramType* result) - { - int32_t type; - if (!ReadParam(msg, iter, &type)) - return false; - - *result = paramType(type); - return true; - } -}; - #if !defined(MOZ_HAVE_SURFACEDESCRIPTORGRALLOC) template <> struct ParamTraits { diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 4497b3cba82..93973adab33 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -20,6 +20,7 @@ EXPORTS += [ 'CopyableCanvasLayer.h', 'D3D9SurfaceImage.h', 'FrameMetrics.h', + 'GLImages.h', 'GrallocImages.h', 'ImageContainer.h', 'ImageLayers.h', @@ -38,7 +39,6 @@ EXPORTS += [ 'opengl/TexturePoolOGL.h', 'protobuf/LayerScopePacket.pb.h', 'ReadbackLayer.h', - 'SharedTextureImage.h', 'TiledLayerBuffer.h', ] diff --git a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h index b0003c693a6..723520883a4 100644 --- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h +++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h @@ -64,7 +64,7 @@ public: MacIOSurfaceTextureHostOGL(TextureFlags aFlags, const SurfaceDescriptorMacIOSurface& aDescriptor); - // SharedTextureHostOGL doesn't own any GL texture + // MacIOSurfaceTextureSourceOGL doesn't own any GL texture virtual void DeallocateDeviceData() MOZ_OVERRIDE {} virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; diff --git a/gfx/layers/opengl/TextureClientOGL.cpp b/gfx/layers/opengl/TextureClientOGL.cpp index c61897494ea..600a0a13bea 100644 --- a/gfx/layers/opengl/TextureClientOGL.cpp +++ b/gfx/layers/opengl/TextureClientOGL.cpp @@ -17,52 +17,105 @@ namespace layers { class CompositableForwarder; -SharedTextureClientOGL::SharedTextureClientOGL(TextureFlags aFlags) +//////////////////////////////////////////////////////////////////////// +// EGLImageTextureClient + +EGLImageTextureClient::EGLImageTextureClient(TextureFlags aFlags, + EGLImage aImage, + gfx::IntSize aSize, + bool aInverted) : TextureClient(aFlags) - , mHandle(0) - , mInverted(false) + , mImage(aImage) + , mSize(aSize) , mIsLocked(false) { - // SharedTextureClient is always owned externally. - mFlags |= TextureFlags::DEALLOCATE_CLIENT; -} - -SharedTextureClientOGL::~SharedTextureClientOGL() -{ - // the shared data is owned externally. -} - - -bool -SharedTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) -{ - MOZ_ASSERT(IsValid()); - if (!IsAllocated()) { - return false; - } - aOutDescriptor = SharedTextureDescriptor(mShareType, mHandle, mSize, mInverted); - return true; -} - -void -SharedTextureClientOGL::InitWith(gl::SharedTextureHandle aHandle, - gfx::IntSize aSize, - gl::SharedTextureShareType aShareType, - bool aInverted) -{ - MOZ_ASSERT(IsValid()); - MOZ_ASSERT(!IsAllocated()); - mHandle = aHandle; - mSize = aSize; - mShareType = aShareType; - mInverted = aInverted; - if (mInverted) { + 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) { AddFlags(TextureFlags::NEEDS_Y_FLIP); } } + +EGLImageTextureClient::~EGLImageTextureClient() +{ + // Our data is always owned externally. +} bool -SharedTextureClientOGL::Lock(OpenMode mode) +EGLImageTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) +{ + MOZ_ASSERT(IsValid()); + MOZ_ASSERT(IsAllocated()); + + aOutDescriptor = EGLImageDescriptor((uintptr_t)mImage, mSize); + return true; +} + +bool +EGLImageTextureClient::Lock(OpenMode mode) + { + MOZ_ASSERT(!mIsLocked); + if (!IsValid() || !IsAllocated()) { + return false; + } + mIsLocked = true; + return true; + } + +void +EGLImageTextureClient::Unlock() +{ + MOZ_ASSERT(mIsLocked); + mIsLocked = false; +} + +//////////////////////////////////////////////////////////////////////// +// SurfaceTextureClient + +#ifdef MOZ_WIDGET_ANDROID + +SurfaceTextureClient::SurfaceTextureClient(TextureFlags aFlags, + nsSurfaceTexture* aSurfTex, + gfx::IntSize aSize, + bool aInverted) + : TextureClient(aFlags) + , mSurfTex(aSurfTex) + , mSize(aSize) + , mIsLocked(false) +{ + MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default, + "Can't pass pointers between processes."); + + // Our data is always owned externally. + AddFlags(TextureFlags::DEALLOCATE_CLIENT); + + if (aInverted) { + AddFlags(TextureFlags::NEEDS_Y_FLIP); + } +} + +SurfaceTextureClient::~SurfaceTextureClient() +{ + // Our data is always owned externally. +} + +bool +SurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) +{ + MOZ_ASSERT(IsValid()); + MOZ_ASSERT(IsAllocated()); + + aOutDescriptor = SurfaceTextureDescriptor((uintptr_t)mSurfTex.get(), + mSize); + return true; +} + +bool +SurfaceTextureClient::Lock(OpenMode mode) { MOZ_ASSERT(!mIsLocked); if (!IsValid() || !IsAllocated()) { @@ -73,17 +126,13 @@ SharedTextureClientOGL::Lock(OpenMode mode) } void -SharedTextureClientOGL::Unlock() +SurfaceTextureClient::Unlock() { MOZ_ASSERT(mIsLocked); mIsLocked = false; } -bool -SharedTextureClientOGL::IsAllocated() const -{ - return mHandle != 0; -} +#endif // MOZ_WIDGET_ANDROID } // namespace } // namespace diff --git a/gfx/layers/opengl/TextureClientOGL.h b/gfx/layers/opengl/TextureClientOGL.h index 97436ef5274..a8dd1aeae39 100644 --- a/gfx/layers/opengl/TextureClientOGL.h +++ b/gfx/layers/opengl/TextureClientOGL.h @@ -13,6 +13,7 @@ #include "mozilla/layers/CompositorTypes.h" #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor #include "mozilla/layers/TextureClient.h" // for TextureClient, etc +#include "nsSurfaceTexture.h" namespace mozilla { namespace gl { @@ -25,46 +26,42 @@ namespace layers { class CompositableForwarder; -/** - * A TextureClient implementation to share TextureMemory that is already - * on the GPU, for the OpenGL backend. - */ -class SharedTextureClientOGL : public TextureClient +class EGLImageTextureClient : public TextureClient { public: - explicit SharedTextureClientOGL(TextureFlags aFlags); + EGLImageTextureClient(TextureFlags aFlags, + EGLImage aImage, + gfx::IntSize aSize, + bool aInverted); - ~SharedTextureClientOGL(); + ~EGLImageTextureClient(); - virtual bool IsAllocated() const MOZ_OVERRIDE; + virtual bool IsAllocated() const MOZ_OVERRIDE { return true; } + + virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return false; } + + virtual gfx::IntSize GetSize() const { return mSize; } virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; + // Useless functions. virtual bool Lock(OpenMode mode) MOZ_OVERRIDE; virtual void Unlock() MOZ_OVERRIDE; virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; } - virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return false; } - - void InitWith(gl::SharedTextureHandle aHandle, - gfx::IntSize aSize, - gl::SharedTextureShareType aShareType, - bool aInverted = false); - - virtual gfx::IntSize GetSize() const { return mSize; } - virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return gfx::SurfaceFormat::UNKNOWN; } - // This TextureClient should not be used in a context where we use CreateSimilar - // (ex. component alpha) because the underlying texture data is always created by - // an external producer. virtual TemporaryRef - CreateSimilar(TextureFlags, TextureAllocationFlags) const MOZ_OVERRIDE { return nullptr; } + CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT, + TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const MOZ_OVERRIDE + { + return nullptr; + } virtual bool AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) MOZ_OVERRIDE { @@ -72,13 +69,63 @@ public: } protected: - gl::SharedTextureHandle mHandle; - gfx::IntSize mSize; - gl::SharedTextureShareType mShareType; - bool mInverted; + const EGLImage mImage; + const gfx::IntSize mSize; bool mIsLocked; }; +#ifdef MOZ_WIDGET_ANDROID + +class SurfaceTextureClient : public TextureClient +{ +public: + SurfaceTextureClient(TextureFlags aFlags, + nsSurfaceTexture* aSurfTex, + gfx::IntSize aSize, + bool aInverted); + + ~SurfaceTextureClient(); + + virtual bool IsAllocated() const MOZ_OVERRIDE { return true; } + + virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return false; } + + virtual gfx::IntSize GetSize() const { return mSize; } + + virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; + + // Useless functions. + virtual bool Lock(OpenMode mode) MOZ_OVERRIDE; + + virtual void Unlock() MOZ_OVERRIDE; + + virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; } + + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE + { + return gfx::SurfaceFormat::UNKNOWN; + } + + virtual TemporaryRef + CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT, + TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const MOZ_OVERRIDE + { + return nullptr; + } + + virtual bool AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) MOZ_OVERRIDE + { + return false; + } + +protected: + const nsRefPtr mSurfTex; + const gfx::IntSize mSize; + bool mIsLocked; +}; + +#endif // MOZ_WIDGET_ANDROID + } // namespace } // namespace diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp index a486c7b167e..b590319715e 100644 --- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -4,9 +4,10 @@ * 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 "GLSharedHandleHelpers.h" #include "GLUploadHelpers.h" #include "GLReadTexImageHelper.h" #include "gfx2DGlue.h" // for ContentForFormat, etc @@ -23,6 +24,7 @@ #include "mozilla/layers/GrallocTextureHost.h" #include "nsPoint.h" // for nsIntPoint #include "nsRegion.h" // for nsIntRegion +#include "nsSurfaceTexture.h" #include "GfxTexturesReporter.h" // for GfxTexturesReporter #include "GLBlitTextureImageHelper.h" #ifdef XP_MACOSX @@ -62,15 +64,25 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc, aDeallocator, aFlags); break; } - case SurfaceDescriptor::TSharedTextureDescriptor: { - const SharedTextureDescriptor& desc = aDesc.get_SharedTextureDescriptor(); - result = new SharedTextureHostOGL(aFlags, - desc.shareType(), - desc.handle(), - desc.size(), - desc.inverted()); + +#ifdef MOZ_WIDGET_ANDROID + case SurfaceDescriptor::TSurfaceTextureDescriptor: { + const SurfaceTextureDescriptor& desc = aDesc.get_SurfaceTextureDescriptor(); + result = new SurfaceTextureHost(aFlags, + (nsSurfaceTexture*)desc.surfTex(), + desc.size()); break; } +#endif + + case SurfaceDescriptor::TEGLImageDescriptor: { + const EGLImageDescriptor& desc = aDesc.get_EGLImageDescriptor(); + result = new EGLImageTextureHost(aFlags, + (EGLImage)desc.image(), + desc.size()); + break; + } + #ifdef XP_MACOSX case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: { const SurfaceDescriptorMacIOSurface& desc = @@ -79,6 +91,7 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc, break; } #endif + #ifdef MOZ_WIDGET_GONK case SurfaceDescriptor::TNewSurfaceDescriptorGralloc: { const NewSurfaceDescriptorGralloc& desc = @@ -409,80 +422,6 @@ TextureImageTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilt SetFilter(mGL, aFilter); } -SharedTextureSourceOGL::SharedTextureSourceOGL(CompositorOGL* aCompositor, - gl::SharedTextureHandle aHandle, - gfx::SurfaceFormat aFormat, - GLenum aTarget, - GLenum aWrapMode, - SharedTextureShareType aShareType, - gfx::IntSize aSize) - : mSize(aSize) - , mCompositor(aCompositor) - , mSharedHandle(aHandle) - , mFormat(aFormat) - , mShareType(aShareType) - , mTextureTarget(aTarget) - , mWrapMode(aWrapMode) -{} - -void -SharedTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) -{ - if (!gl()) { - NS_WARNING("Trying to bind a texture without a GLContext"); - return; - } - GLuint tex = mCompositor->GetTemporaryTexture(GetTextureTarget(), aTextureUnit); - - gl()->fActiveTexture(aTextureUnit); - gl()->fBindTexture(mTextureTarget, tex); - if (!AttachSharedHandle(gl(), mShareType, mSharedHandle)) { - NS_ERROR("Failed to bind shared texture handle"); - return; - } - ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget); -} - -void -SharedTextureSourceOGL::DetachSharedHandle() -{ - if (!gl()) { - return; - } - gl::DetachSharedHandle(gl(), mShareType, mSharedHandle); -} - -void -SharedTextureSourceOGL::SetCompositor(Compositor* aCompositor) -{ - mCompositor = static_cast(aCompositor); -} - -bool -SharedTextureSourceOGL::IsValid() const -{ - return !!gl(); -} - -gl::GLContext* -SharedTextureSourceOGL::gl() const -{ - return mCompositor ? mCompositor->gl() : nullptr; -} - -gfx::Matrix4x4 -SharedTextureSourceOGL::GetTextureTransform() -{ - SharedHandleDetails handleDetails; - if (!GetSharedHandleDetails(gl(), mShareType, mSharedHandle, handleDetails)) { - NS_WARNING("Could not get shared handle details"); - return gfx::Matrix4x4(); - } - - return handleDetails.mTextureTransform; -} - - //////////////////////////////////////////////////////////////////////// // GLTextureSource @@ -530,72 +469,125 @@ GLTextureSource::gl() const } //////////////////////////////////////////////////////////////////////// -// SharedTextureHostOGL +//////////////////////////////////////////////////////////////////////// +// SurfaceTextureHost -SharedTextureHostOGL::SharedTextureHostOGL(TextureFlags aFlags, - gl::SharedTextureShareType aShareType, - gl::SharedTextureHandle aSharedHandle, - gfx::IntSize aSize, - bool inverted) - : TextureHost(aFlags) +#ifdef MOZ_WIDGET_ANDROID + +SurfaceTextureSource::SurfaceTextureSource(CompositorOGL* aCompositor, + nsSurfaceTexture* aSurfTex, + gfx::SurfaceFormat aFormat, + GLenum aTarget, + GLenum aWrapMode, + gfx::IntSize aSize) + : mCompositor(aCompositor) + , mSurfTex(aSurfTex) + , mFormat(aFormat) + , mTextureTarget(aTarget) + , mWrapMode(aWrapMode) , mSize(aSize) - , mCompositor(nullptr) - , mSharedHandle(aSharedHandle) - , mShareType(aShareType) { } -SharedTextureHostOGL::~SharedTextureHostOGL() +void +SurfaceTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) { - // If need to deallocate textures, call DeallocateSharedData() before - // the destructor + if (!gl()) { + NS_WARNING("Trying to bind a texture without a GLContext"); + return; + } + GLuint tex = mCompositor->GetTemporaryTexture(GetTextureTarget(), aTextureUnit); + + gl()->fActiveTexture(aTextureUnit); + gl()->fBindTexture(mTextureTarget, tex); +#ifndef DEBUG + // SurfaceTexture spams us if there are any existing GL errors, so + // we'll clear them here in order to avoid that. + gl()->GetAndClearError(); +#endif + mSurfTex->UpdateTexImage(); + + ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget); +} + +void +SurfaceTextureSource::SetCompositor(Compositor* aCompositor) +{ + mCompositor = static_cast(aCompositor); +} + +bool +SurfaceTextureSource::IsValid() const +{ + return !!gl(); } gl::GLContext* -SharedTextureHostOGL::gl() const +SurfaceTextureSource::gl() const +{ + return mCompositor ? mCompositor->gl() : nullptr; +} + +gfx::Matrix4x4 +SurfaceTextureSource::GetTextureTransform() +{ + gfx::Matrix4x4 ret; + mSurfTex->GetTransformMatrix(ret); + + return ret; +} + +//////////////////////////////////////////////////////////////////////// + +SurfaceTextureHost::SurfaceTextureHost(TextureFlags aFlags, + nsSurfaceTexture* 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 -SharedTextureHostOGL::Lock() +SurfaceTextureHost::Lock() { if (!mCompositor) { return false; } if (!mTextureSource) { - // XXX on android GetSharedHandleDetails can call into Java which we'd - // rather not do from the compositor - SharedHandleDetails handleDetails; - if (!GetSharedHandleDetails(gl(), mShareType, mSharedHandle, handleDetails)) { - NS_WARNING("Could not get shared handle details"); - return false; - } - + gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8; + GLenum target = LOCAL_GL_TEXTURE_EXTERNAL; GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE; - mTextureSource = new SharedTextureSourceOGL(mCompositor, - mSharedHandle, - handleDetails.mTextureFormat, - handleDetails.mTarget, - wrapMode, - mShareType, - mSize); + mTextureSource = new SurfaceTextureSource(mCompositor, + mSurfTex, + format, + target, + wrapMode, + mSize); } + return true; } void -SharedTextureHostOGL::Unlock() +SurfaceTextureHost::Unlock() { - if (!mTextureSource) { - return; - } - mTextureSource->DetachSharedHandle(); } void -SharedTextureHostOGL::SetCompositor(Compositor* aCompositor) +SurfaceTextureHost::SetCompositor(Compositor* aCompositor) { CompositorOGL* glCompositor = static_cast(aCompositor); mCompositor = glCompositor; @@ -605,7 +597,141 @@ SharedTextureHostOGL::SetCompositor(Compositor* aCompositor) } gfx::SurfaceFormat -SharedTextureHostOGL::GetFormat() const +SurfaceTextureHost::GetFormat() const +{ + MOZ_ASSERT(mTextureSource); + return mTextureSource->GetFormat(); +} + +#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) +{ +} + +void +EGLImageTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) +{ + if (!gl()) { + 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(GetTextureTarget(), aTextureUnit); + + gl()->fActiveTexture(aTextureUnit); + gl()->fBindTexture(mTextureTarget, tex); + + MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D); + gl()->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, mImage); + + ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget); +} + +void +EGLImageTextureSource::SetCompositor(Compositor* aCompositor) +{ + mCompositor = static_cast(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, + gfx::IntSize aSize) + : TextureHost(aFlags) + , mImage(aImage) + , mSize(aSize) + , mCompositor(nullptr) +{ +} + +EGLImageTextureHost::~EGLImageTextureHost() +{ +} + +gl::GLContext* +EGLImageTextureHost::gl() const +{ + return mCompositor ? mCompositor->gl() : nullptr; +} + +bool +EGLImageTextureHost::Lock() +{ + if (!mCompositor) { + return false; + } + + if (!mTextureSource) { + gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8; + GLenum target = LOCAL_GL_TEXTURE_2D; + 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 = static_cast(aCompositor); + mCompositor = glCompositor; + if (mTextureSource) { + mTextureSource->SetCompositor(glCompositor); + } +} + +gfx::SurfaceFormat +EGLImageTextureHost::GetFormat() const { MOZ_ASSERT(mTextureSource); return mTextureSource->GetFormat(); diff --git a/gfx/layers/opengl/TextureHostOGL.h b/gfx/layers/opengl/TextureHostOGL.h index 575c2074b35..e560eb9b657 100644 --- a/gfx/layers/opengl/TextureHostOGL.h +++ b/gfx/layers/opengl/TextureHostOGL.h @@ -38,6 +38,7 @@ class gfxReusableSurfaceWrapper; class nsIntRegion; +class nsSurfaceTexture; struct nsIntPoint; struct nsIntRect; struct nsIntSize; @@ -294,116 +295,7 @@ protected: }; /** - * A texture source meant for use with SharedTextureHostOGL. - * - * It does not own any GL texture, and attaches its shared handle to one of - * the compositor's temporary textures when binding. - * - * The shared texture handle is owned by the TextureHost. - */ -class SharedTextureSourceOGL : public NewTextureSource - , public TextureSourceOGL -{ -public: - typedef gl::SharedTextureShareType SharedTextureShareType; - - SharedTextureSourceOGL(CompositorOGL* aCompositor, - gl::SharedTextureHandle aHandle, - gfx::SurfaceFormat aFormat, - GLenum aTarget, - GLenum aWrapMode, - SharedTextureShareType aShareType, - gfx::IntSize aSize); - - virtual TextureSourceOGL* AsSourceOGL() { return this; } - - virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE; - - virtual bool IsValid() const MOZ_OVERRIDE; - - virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } - - virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } - - virtual gfx::Matrix4x4 GetTextureTransform() MOZ_OVERRIDE; - - virtual GLenum GetTextureTarget() const { return mTextureTarget; } - - virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return mWrapMode; } - - // SharedTextureSource doesn't own any gl texture - virtual void DeallocateDeviceData() MOZ_OVERRIDE {} - - void DetachSharedHandle(); - - virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; - - gl::GLContext* gl() const; - -protected: - gfx::IntSize mSize; - CompositorOGL* mCompositor; - gl::SharedTextureHandle mSharedHandle; - gfx::SurfaceFormat mFormat; - SharedTextureShareType mShareType; - GLenum mTextureTarget; - GLenum mWrapMode; -}; - -/** - * A TextureHost for shared GL Textures - * - * Most of the logic actually happens in SharedTextureSourceOGL. - */ -class SharedTextureHostOGL : public TextureHost -{ -public: - SharedTextureHostOGL(TextureFlags aFlags, - gl::SharedTextureShareType aShareType, - gl::SharedTextureHandle aSharedhandle, - gfx::IntSize aSize, - bool inverted); - - virtual ~SharedTextureHostOGL(); - - // SharedTextureHostOGL doesn't own any GL texture - virtual void DeallocateDeviceData() MOZ_OVERRIDE {} - - virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; - - virtual bool Lock() MOZ_OVERRIDE; - - virtual void Unlock() MOZ_OVERRIDE; - - virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE; - - virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE - { - return mTextureSource; - } - - virtual TemporaryRef GetAsSurface() MOZ_OVERRIDE - { - return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING) - } - - gl::GLContext* gl() const; - - virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } - - virtual const char* Name() { return "SharedTextureHostOGL"; } - -protected: - gfx::IntSize mSize; - CompositorOGL* mCompositor; - gl::SharedTextureHandle mSharedHandle; - gl::SharedTextureShareType mShareType; - - RefPtr mTextureSource; -}; - -/** - * A texture source meant for use with SharedTextureHostOGL. + * A texture source for GL textures. * * It does not own any GL texture, and attaches its shared handle to one of * the compositor's temporary textures when binding. @@ -414,8 +306,6 @@ class GLTextureSource : public NewTextureSource , public TextureSourceOGL { public: - typedef gl::SharedTextureShareType SharedTextureShareType; - GLTextureSource(CompositorOGL* aCompositor, GLuint aTex, gfx::SurfaceFormat aFormat, @@ -450,6 +340,188 @@ protected: const GLenum mTextureTarget; }; +//////////////////////////////////////////////////////////////////////// +// SurfaceTexture + +#ifdef MOZ_WIDGET_ANDROID + +class SurfaceTextureSource : public NewTextureSource + , public TextureSourceOGL +{ +public: + SurfaceTextureSource(CompositorOGL* aCompositor, + nsSurfaceTexture* aSurfTex, + gfx::SurfaceFormat aFormat, + GLenum aTarget, + GLenum aWrapMode, + gfx::IntSize aSize); + + virtual TextureSourceOGL* AsSourceOGL() { return this; } + + virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE; + + virtual bool IsValid() const MOZ_OVERRIDE; + + virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } + + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } + + virtual gfx::Matrix4x4 GetTextureTransform() MOZ_OVERRIDE; + + virtual GLenum GetTextureTarget() const { return mTextureTarget; } + + virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return mWrapMode; } + + // We don't own anything. + virtual void DeallocateDeviceData() MOZ_OVERRIDE {} + + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; + + gl::GLContext* gl() const; + +protected: + CompositorOGL* mCompositor; + nsSurfaceTexture* const mSurfTex; + const gfx::SurfaceFormat mFormat; + const GLenum mTextureTarget; + const GLenum mWrapMode; + const gfx::IntSize mSize; +}; + +class SurfaceTextureHost : public TextureHost +{ +public: + SurfaceTextureHost(TextureFlags aFlags, + nsSurfaceTexture* aSurfTex, + gfx::IntSize aSize); + + virtual ~SurfaceTextureHost(); + + // We don't own anything. + virtual void DeallocateDeviceData() MOZ_OVERRIDE {} + + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; + + virtual bool Lock() MOZ_OVERRIDE; + + virtual void Unlock() MOZ_OVERRIDE; + + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE; + + virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE + { + return mTextureSource; + } + + virtual TemporaryRef GetAsSurface() MOZ_OVERRIDE + { + return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING) + } + + gl::GLContext* gl() const; + + virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } + + virtual const char* Name() { return "SurfaceTextureHost"; } + +protected: + nsSurfaceTexture* const mSurfTex; + const gfx::IntSize mSize; + CompositorOGL* mCompositor; + RefPtr mTextureSource; +}; + +#endif // MOZ_WIDGET_ANDROID + +//////////////////////////////////////////////////////////////////////// +// EGLImage + +class EGLImageTextureSource : public NewTextureSource + , public TextureSourceOGL +{ +public: + EGLImageTextureSource(CompositorOGL* aCompositor, + EGLImage aImage, + gfx::SurfaceFormat aFormat, + GLenum aTarget, + GLenum aWrapMode, + gfx::IntSize aSize); + + virtual TextureSourceOGL* AsSourceOGL() { return this; } + + virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE; + + virtual bool IsValid() const MOZ_OVERRIDE; + + virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } + + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } + + virtual gfx::Matrix4x4 GetTextureTransform() MOZ_OVERRIDE; + + virtual GLenum GetTextureTarget() const { return mTextureTarget; } + + virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return mWrapMode; } + + // We don't own anything. + virtual void DeallocateDeviceData() MOZ_OVERRIDE {} + + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; + + gl::GLContext* gl() const; + +protected: + CompositorOGL* mCompositor; + const EGLImage mImage; + const gfx::SurfaceFormat mFormat; + const GLenum mTextureTarget; + const GLenum mWrapMode; + const gfx::IntSize mSize; +}; + +class EGLImageTextureHost : public TextureHost +{ +public: + EGLImageTextureHost(TextureFlags aFlags, + EGLImage aImage, + gfx::IntSize aSize); + + virtual ~EGLImageTextureHost(); + + // We don't own anything. + virtual void DeallocateDeviceData() MOZ_OVERRIDE {} + + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; + + virtual bool Lock() MOZ_OVERRIDE; + + virtual void Unlock() MOZ_OVERRIDE; + + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE; + + virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE + { + return mTextureSource; + } + + virtual TemporaryRef GetAsSurface() MOZ_OVERRIDE + { + return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING) + } + + gl::GLContext* gl() const; + + virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } + + virtual const char* Name() { return "EGLImageTextureHost"; } + +protected: + const EGLImage mImage; + const gfx::IntSize mSize; + CompositorOGL* mCompositor; + RefPtr mTextureSource; +}; + } // namespace } // namespace