diff --git a/gfx/gl/ScopedGLHelpers.cpp b/gfx/gl/ScopedGLHelpers.cpp index 73706eb92eb..18ae2d122e6 100644 --- a/gfx/gl/ScopedGLHelpers.cpp +++ b/gfx/gl/ScopedGLHelpers.cpp @@ -124,6 +124,7 @@ ScopedBindTexture::Init(GLenum aTarget) GLenum bindingTarget = (aTarget == LOCAL_GL_TEXTURE_2D) ? LOCAL_GL_TEXTURE_BINDING_2D : (aTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) ? LOCAL_GL_TEXTURE_BINDING_RECTANGLE_ARB : (aTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? LOCAL_GL_TEXTURE_BINDING_CUBE_MAP + : (aTarget == LOCAL_GL_TEXTURE_EXTERNAL) ? LOCAL_GL_TEXTURE_EXTERNAL : LOCAL_GL_NONE; MOZ_ASSERT(bindingTarget != LOCAL_GL_NONE); mGL->GetUIntegerv(bindingTarget, &mOldTex); diff --git a/gfx/gl/SharedSurfaceEGL.cpp b/gfx/gl/SharedSurfaceEGL.cpp index 0e502cde7a4..3525b71defe 100644 --- a/gfx/gl/SharedSurfaceEGL.cpp +++ b/gfx/gl/SharedSurfaceEGL.cpp @@ -27,18 +27,30 @@ SharedSurface_EGLImage::Create(GLContext* prodGL, { GLLibraryEGL* egl = &sEGLLibrary; MOZ_ASSERT(egl); + MOZ_ASSERT(context); - if (!HasExtensions(egl, prodGL)) + if (!HasExtensions(egl, prodGL)) { return nullptr; + } MOZ_ALWAYS_TRUE(prodGL->MakeCurrent()); GLuint prodTex = CreateTextureForOffscreen(prodGL, formats, size); - if (!prodTex) + if (!prodTex) { return nullptr; + } + + EGLClientBuffer buffer = reinterpret_cast(prodTex); + EGLImage image = egl->fCreateImage(egl->Display(), context, + LOCAL_EGL_GL_TEXTURE_2D, buffer, + nullptr); + if (!image) { + prodGL->fDeleteTextures(1, &prodTex); + return nullptr; + } return new SharedSurface_EGLImage(prodGL, egl, size, hasAlpha, - formats, prodTex); + formats, prodTex, image); } @@ -47,7 +59,7 @@ SharedSurface_EGLImage::HasExtensions(GLLibraryEGL* egl, GLContext* gl) { return egl->HasKHRImageBase() && egl->IsExtensionSupported(GLLibraryEGL::KHR_gl_texture_2D_image) && - gl->IsExtensionSupported(GLContext::OES_EGL_image); + gl->IsExtensionSupported(GLContext::OES_EGL_image_external); } SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl, @@ -55,7 +67,8 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl, const gfx::IntSize& size, bool hasAlpha, const GLFormats& formats, - GLuint prodTex) + GLuint prodTex, + EGLImage image) : SharedSurface_GL(SharedSurfaceType::EGLImageShare, AttachmentType::GLTexture, gl, @@ -65,14 +78,10 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl, , mEGL(egl) , mFormats(formats) , mProdTex(prodTex) - , mProdTexForPipe(0) - , mImage(0) + , mImage(image) , mCurConsGL(nullptr) , mConsTex(0) , mSync(0) - , mPipeFailed(false) - , mPipeComplete(false) - , mPipeActive(false) {} SharedSurface_EGLImage::~SharedSurface_EGLImage() @@ -84,11 +93,6 @@ SharedSurface_EGLImage::~SharedSurface_EGLImage() mGL->fDeleteTextures(1, &mProdTex); mProdTex = 0; - if (mProdTexForPipe) { - mGL->fDeleteTextures(1, &mProdTexForPipe); - mProdTexForPipe = 0; - } - if (mConsTex) { MOZ_ASSERT(mGarbageBin); mGarbageBin->Trash(mConsTex); @@ -103,94 +107,12 @@ SharedSurface_EGLImage::~SharedSurface_EGLImage() } } -void -SharedSurface_EGLImage::LockProdImpl() -{ - MutexAutoLock lock(mMutex); - - if (!mPipeComplete) - return; - - if (mPipeActive) - return; - - mGL->BlitHelper()->BlitTextureToTexture(mProdTex, mProdTexForPipe, Size(), Size()); - mGL->fDeleteTextures(1, &mProdTex); - mProdTex = mProdTexForPipe; - mProdTexForPipe = 0; - mPipeActive = true; -} - -static bool -CreateTexturePipe(GLLibraryEGL* const egl, GLContext* const gl, - const GLFormats& formats, const gfx::IntSize& size, - GLuint* const out_tex, EGLImage* const out_image) -{ - MOZ_ASSERT(out_tex && out_image); - *out_tex = 0; - *out_image = 0; - - GLuint tex = CreateTextureForOffscreen(gl, formats, size); - if (!tex) - return false; - - EGLContext context = GLContextEGL::Cast(gl)->GetEGLContext(); - MOZ_ASSERT(context); - EGLClientBuffer buffer = reinterpret_cast(tex); - EGLImage image = egl->fCreateImage(egl->Display(), context, - LOCAL_EGL_GL_TEXTURE_2D, buffer, - nullptr); - if (!image) { - gl->fDeleteTextures(1, &tex); - return false; - } - - // Success. - *out_tex = tex; - *out_image = image; - return true; -} - void SharedSurface_EGLImage::Fence() { MutexAutoLock lock(mMutex); mGL->MakeCurrent(); - if (!mPipeActive) { - MOZ_ASSERT(!mSync); - MOZ_ASSERT(!mPipeComplete); - - if (!mPipeFailed) { - if (!CreateTexturePipe(mEGL, mGL, mFormats, Size(), - &mProdTexForPipe, &mImage)) - { - mPipeFailed = true; - } - } - - if (!mPixels) { - SurfaceFormat format = - HasAlpha() ? SurfaceFormat::B8G8R8A8 - : SurfaceFormat::B8G8R8X8; - mPixels = Factory::CreateDataSourceSurface(Size(), format); - } - - DataSourceSurface::MappedSurface map; - mPixels->Map(DataSourceSurface::MapType::WRITE, &map); - - nsRefPtr wrappedData = - new gfxImageSurface(map.mData, - ThebesIntSize(mPixels->GetSize()), - map.mStride, - SurfaceFormatToImageFormat(mPixels->GetFormat())); - ReadScreenIntoImageSurface(mGL, wrappedData); - mPixels->Unmap(); - return; - } - MOZ_ASSERT(mPipeActive); - MOZ_ASSERT(mCurConsGL); - if (mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) && mGL->IsExtensionSupported(GLContext::OES_EGL_sync)) { @@ -249,42 +171,28 @@ SharedSurface_EGLImage::Display() const return mEGL->Display(); } -GLuint -SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL) +void +SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target) { MutexAutoLock lock(mMutex); MOZ_ASSERT(!mCurConsGL || consGL == mCurConsGL); - if (mPipeFailed) - return 0; - - if (mPipeActive) { - MOZ_ASSERT(mConsTex); - - return mConsTex; - } if (!mConsTex) { consGL->fGenTextures(1, &mConsTex); - ScopedBindTexture autoTex(consGL, mConsTex); - consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, mImage); + MOZ_ASSERT(mConsTex); + + ScopedBindTexture autoTex(consGL, mConsTex, LOCAL_GL_TEXTURE_EXTERNAL); + consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL, mImage); - mPipeComplete = true; mCurConsGL = consGL; mGarbageBin = consGL->TexGarbageBin(); } MOZ_ASSERT(consGL == mCurConsGL); - return 0; + *out_texture = mConsTex; + *out_target = LOCAL_GL_TEXTURE_EXTERNAL; } -DataSourceSurface* -SharedSurface_EGLImage::GetPixels() const -{ - MutexAutoLock lock(mMutex); - return mPixels; -} - - SurfaceFactory_EGLImage* SurfaceFactory_EGLImage::Create(GLContext* prodGL, @@ -292,6 +200,11 @@ SurfaceFactory_EGLImage::Create(GLContext* prodGL, { EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext(); + GLLibraryEGL* egl = &sEGLLibrary; + if (!SharedSurface_EGLImage::HasExtensions(egl, prodGL)) { + return nullptr; + } + return new SurfaceFactory_EGLImage(prodGL, context, caps); } diff --git a/gfx/gl/SharedSurfaceEGL.h b/gfx/gl/SharedSurfaceEGL.h index 03339f44bb7..fbb662acf2d 100644 --- a/gfx/gl/SharedSurfaceEGL.h +++ b/gfx/gl/SharedSurfaceEGL.h @@ -35,37 +35,34 @@ public: return (SharedSurface_EGLImage*)surf; } + static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl); + protected: mutable Mutex mMutex; GLLibraryEGL* const mEGL; const GLFormats mFormats; GLuint mProdTex; - RefPtr mPixels; - GLuint mProdTexForPipe; // Moves to mProdTex when mPipeActive becomes true. EGLImage mImage; GLContext* mCurConsGL; GLuint mConsTex; nsRefPtr mGarbageBin; EGLSync mSync; - bool mPipeFailed; // Pipe creation failed, and has been abandoned. - bool mPipeComplete; // Pipe connects (mPipeActive ? mProdTex : mProdTexForPipe) to mConsTex. - bool mPipeActive; // Pipe is complete and in use for production. SharedSurface_EGLImage(GLContext* gl, GLLibraryEGL* egl, const gfx::IntSize& size, bool hasAlpha, const GLFormats& formats, - GLuint prodTex); + GLuint prodTex, + EGLImage image); EGLDisplay Display() const; - static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl); public: virtual ~SharedSurface_EGLImage(); - virtual void LockProdImpl(); + virtual void LockProdImpl() {} virtual void UnlockProdImpl() {} @@ -78,11 +75,8 @@ public: } // Implementation-specific functions below: - // Returns 0 if the pipe isn't ready. If 0, use GetPixels below. - GLuint AcquireConsumerTexture(GLContext* consGL); - - // Will be void if AcquireConsumerTexture returns non-zero. - gfx::DataSourceSurface* GetPixels() const; + // Returns texture and target + void AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target); }; @@ -91,7 +85,7 @@ class SurfaceFactory_EGLImage : public SurfaceFactory_GL { public: - // Infallible: + // Fallible: static SurfaceFactory_EGLImage* Create(GLContext* prodGL, const SurfaceCaps& caps); diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp index 10ea33ec845..dd1ef6d921e 100644 --- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -515,15 +515,10 @@ StreamTextureSourceOGL::RetrieveTextureFromStream() SharedSurface_EGLImage* eglImageSurf = SharedSurface_EGLImage::Cast(sharedSurf); - mTextureHandle = eglImageSurf->AcquireConsumerTexture(gl()); - mTextureTarget = eglImageSurf->TextureTarget(); - if (!mTextureHandle) { - toUpload = eglImageSurf->GetPixels(); - MOZ_ASSERT(toUpload); - } else { - mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 - : SurfaceFormat::R8G8B8X8; - } + eglImageSurf->AcquireConsumerTexture(gl(), &mTextureHandle, &mTextureTarget); + MOZ_ASSERT(mTextureHandle); + mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 + : SurfaceFormat::R8G8B8X8; break; } #ifdef XP_MACOSX diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp index 3c65c4cf5e0..740dda797d6 100644 --- a/gfx/thebes/gfxAndroidPlatform.cpp +++ b/gfx/thebes/gfxAndroidPlatform.cpp @@ -22,6 +22,10 @@ #include "gfxPrefs.h" #include "cairo.h" +#ifdef MOZ_WIDGET_ANDROID +#include "AndroidBridge.h" +#endif + #include "ft2build.h" #include FT_FREETYPE_H #include FT_MODULE_H @@ -418,3 +422,16 @@ gfxAndroidPlatform::GetScreenDepth() const { return mScreenDepth; } + +bool +gfxAndroidPlatform::UseAcceleratedSkiaCanvas() +{ +#ifdef MOZ_WIDGET_ANDROID + if (AndroidBridge::Bridge()->GetAPIVersion() < 11) { + // It's slower than software due to not having a compositing fast path + return false; + } +#endif + + return gfxPlatform::UseAcceleratedSkiaCanvas(); +} diff --git a/gfx/thebes/gfxAndroidPlatform.h b/gfx/thebes/gfxAndroidPlatform.h index 4d71ac58243..5d4c4ee867f 100644 --- a/gfx/thebes/gfxAndroidPlatform.h +++ b/gfx/thebes/gfxAndroidPlatform.h @@ -81,6 +81,8 @@ public: virtual int GetScreenDepth() const; + virtual bool UseAcceleratedSkiaCanvas() MOZ_OVERRIDE; + private: int mScreenDepth; gfxImageFormat mOffscreenFormat;