author | Bas Schouten <bschouten@mozilla.com> |
Thu, 13 Mar 2014 18:55:52 +0100 | |
changeset 191648 | d7e998c17c498d724682113871bc61cc836fc23b |
parent 191647 | beb1b8402d96c3137ce7aeecab7e1f7a7a024945 |
child 191649 | ecedfea04ffc5ae69aa61dced95dbf5082322cb9 |
push id | 474 |
push user | asasaki@mozilla.com |
push date | Mon, 02 Jun 2014 21:01:02 +0000 |
treeherder | mozilla-release@967f4cf1b31c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | backout |
bugs | 983157, 980647 |
milestone | 30.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -129,16 +129,82 @@ DrawQuads(GLContext *aGLContext, aGLContext->fDisableVertexAttribArray(texCoordAttribIndex); } aGLContext->fDrawArrays(aMode, 0, aRects.elements()); aGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); } +#ifdef MOZ_WIDGET_GONK +CompositorOGLGonkBackendSpecificData::CompositorOGLGonkBackendSpecificData(CompositorOGL* aCompositor) + : mCompositor(aCompositor) +{ +} + +CompositorOGLGonkBackendSpecificData::~CompositorOGLGonkBackendSpecificData() +{ + // Delete all textures by calling EndFrame twice + gl()->MakeCurrent(); + EndFrame(); + EndFrame(); +} + +GLContext* +CompositorOGLGonkBackendSpecificData::gl() const +{ + return mCompositor->gl(); +} + +GLuint +CompositorOGLGonkBackendSpecificData::GetTexture() +{ + GLuint texture = 0; + + if (!mUnusedTextures.IsEmpty()) { + // Try to reuse one from the unused pile first + texture = mUnusedTextures[0]; + mUnusedTextures.RemoveElementAt(0); + } else if (gl()->MakeCurrent()) { + // There isn't one to reuse, create one. + gl()->fGenTextures(1, &texture); + } + + if (texture) { + mCreatedTextures.AppendElement(texture); + } + + return texture; +} + +void +CompositorOGLGonkBackendSpecificData::EndFrame() +{ + gl()->MakeCurrent(); + + // Some platforms have issues unlocking Gralloc buffers even when they're + // rebound. + if (gfxPrefs::OverzealousGrallocUnlocking()) { + mUnusedTextures.AppendElements(mCreatedTextures); + mCreatedTextures.Clear(); + } + + // Delete unused textures + for (size_t i = 0; i < mUnusedTextures.Length(); i++) { + GLuint texture = mUnusedTextures[i]; + gl()->fDeleteTextures(1, &texture); + } + mUnusedTextures.Clear(); + + // Move all created textures into the unused pile + mUnusedTextures.AppendElements(mCreatedTextures); + mCreatedTextures.Clear(); +} +#endif + CompositorOGL::CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth, int aSurfaceHeight, bool aUseExternalSurfaceSize) : mWidget(aWidget) , mWidgetSize(-1, -1) , mSurfaceSize(aSurfaceWidth, aSurfaceHeight) , mHasBGRA(0) , mUseExternalSurfaceSize(aUseExternalSurfaceSize) , mFrameInProgress(false) @@ -172,28 +238,48 @@ CompositorOGL::CreateContext() if (!context) { NS_WARNING("Failed to create CompositorOGL context"); } return context.forget(); } +GLuint +CompositorOGL::GetTemporaryTexture(GLenum aTextureUnit) +{ + size_t index = aTextureUnit - LOCAL_GL_TEXTURE0; + // lazily grow the array of temporary textures + if (mTextures.Length() <= index) { + size_t prevLength = mTextures.Length(); + mTextures.SetLength(index + 1); + for(unsigned int i = prevLength; i <= index; ++i) { + mTextures[i] = 0; + } + } + // lazily initialize the temporary textures + if (!mTextures[index]) { + if (!gl()->MakeCurrent()) { + return 0; + } + gl()->fGenTextures(1, &mTextures[index]); + } + return mTextures[index]; +} + void CompositorOGL::Destroy() { if (gl() && gl()->MakeCurrent()) { + if (mTextures.Length() > 0) { + gl()->fDeleteTextures(mTextures.Length(), &mTextures[0]); + } mVBOs.Flush(gl()); } - - if (mTexturePool) { - mTexturePool->Clear(); - mTexturePool = nullptr; - } - + mTextures.SetLength(0); if (!mDestroyed) { mDestroyed = true; CleanupResources(); } } void CompositorOGL::CleanupResources() @@ -1171,19 +1257,21 @@ CompositorOGL::EndFrame() CopyToTarget(mTarget, mCurrentRenderTarget->GetTransform()); mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); mCurrentRenderTarget = nullptr; return; } mCurrentRenderTarget = nullptr; - if (mTexturePool) { - mTexturePool->EndFrame(); +#ifdef MOZ_WIDGET_GONK + if (mCompositorBackendSpecificData) { + static_cast<CompositorOGLGonkBackendSpecificData*>(mCompositorBackendSpecificData.get())->EndFrame(); } +#endif mGLContext->SwapBuffers(); mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); // Unbind all textures mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0); mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, 0); mGLContext->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0); @@ -1294,16 +1382,27 @@ CompositorOGL::Resume() return false; // RenewSurface internally calls MakeCurrent. return gl()->RenewSurface(); #endif return true; } +#ifdef MOZ_WIDGET_GONK +CompositorBackendSpecificData* +CompositorOGL::GetCompositorBackendSpecificData() +{ + if (!mCompositorBackendSpecificData) { + mCompositorBackendSpecificData = new CompositorOGLGonkBackendSpecificData(this); + } + return mCompositorBackendSpecificData; +} +#endif + TemporaryRef<DataTextureSource> CompositorOGL::CreateDataTextureSource(TextureFlags aFlags) { RefPtr<DataTextureSource> result = new TextureImageTextureSourceOGL(mGLContext, aFlags); return result; } @@ -1391,125 +1490,10 @@ CompositorOGL::BindAndDrawQuad(ShaderPro GLuint aDrawMode) { NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized"); BindAndDrawQuad(aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib), aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib), aFlipped, aDrawMode); } -GLuint -CompositorOGL::GetTemporaryTexture(GLenum aUnit) -{ - if (!mTexturePool) { -#ifdef MOZ_WIDGET_GONK - mTexturePool = new PerFrameTexturePoolOGL(gl()); -#else - mTexturePool = new PerUnitTexturePoolOGL(gl()); -#endif - } - return mTexturePool->GetTexture(aUnit); -} - -GLuint -PerUnitTexturePoolOGL::GetTexture(GLenum aTextureUnit) -{ - size_t index = aTextureUnit - LOCAL_GL_TEXTURE0; - // lazily grow the array of temporary textures - if (mTextures.Length() <= index) { - size_t prevLength = mTextures.Length(); - mTextures.SetLength(index + 1); - for(unsigned int i = prevLength; i <= index; ++i) { - mTextures[i] = 0; - } - } - // lazily initialize the temporary textures - if (!mTextures[index]) { - if (!mGL->MakeCurrent()) { - return 0; - } - mGL->fGenTextures(1, &mTextures[index]); - } - return mTextures[index]; -} - -void -PerUnitTexturePoolOGL::DestroyTextures() -{ - if (mGL && mGL->MakeCurrent()) { - if (mTextures.Length() > 0) { - mGL->fDeleteTextures(mTextures.Length(), &mTextures[0]); - } - } - mTextures.SetLength(0); -} - -void -PerFrameTexturePoolOGL::DestroyTextures() -{ - if (!mGL->MakeCurrent()) { - return; - } - - if (mUnusedTextures.Length() > 0) { - mGL->fDeleteTextures(mUnusedTextures.Length(), &mUnusedTextures[0]); - mUnusedTextures.Clear(); - } - - if (mCreatedTextures.Length() > 0) { - mGL->fDeleteTextures(mCreatedTextures.Length(), &mCreatedTextures[0]); - mCreatedTextures.Clear(); - } -} - -GLuint -PerFrameTexturePoolOGL::GetTexture(GLenum) -{ - GLuint texture = 0; - - if (!mUnusedTextures.IsEmpty()) { - // Try to reuse one from the unused pile first - texture = mUnusedTextures[0]; - mUnusedTextures.RemoveElementAt(0); - } else if (mGL->MakeCurrent()) { - // There isn't one to reuse, create one. - mGL->fGenTextures(1, &texture); - } - - if (texture) { - mCreatedTextures.AppendElement(texture); - } - - return texture; -} - -void -PerFrameTexturePoolOGL::EndFrame() -{ - if (!mGL->MakeCurrent()) { - // this means the context got destroyed underneith us somehow, and the driver - // already has destroyed the textures. - mCreatedTextures.Clear(); - mUnusedTextures.Clear(); - return; - } - - // Some platforms have issues unlocking Gralloc buffers even when they're - // rebound. - if (gfxPrefs::OverzealousGrallocUnlocking()) { - mUnusedTextures.AppendElements(mCreatedTextures); - mCreatedTextures.Clear(); - } - - // Delete unused textures - for (size_t i = 0; i < mUnusedTextures.Length(); i++) { - GLuint texture = mUnusedTextures[i]; - mGL->fDeleteTextures(1, &texture); - } - mUnusedTextures.Clear(); - - // Move all created textures into the unused pile - mUnusedTextures.AppendElements(mCreatedTextures); - mCreatedTextures.Clear(); -} - } /* layers */ } /* mozilla */
--- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -50,109 +50,16 @@ namespace layers { class CompositingRenderTarget; class CompositingRenderTargetOGL; class DataTextureSource; class GLManagerCompositor; class TextureSource; struct Effect; struct EffectChain; -/** - * Interface for pools of temporary gl textures for the compositor. - * The textures are fully owned by the pool, so the latter is responsible - * calling fDeleteTextures accordingly. - * Users of GetTexture receive a texture that is only valid for the duration - * of the current frame. - * This is primarily intended for direct texturing APIs that need to attach - * shared objects (such as an EGLImage) to a gl texture. - */ -class CompositorTexturePoolOGL : public RefCounted<CompositorTexturePoolOGL> -{ -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositorTexturePoolOGL) - - virtual ~CompositorTexturePoolOGL() {} - - virtual void Clear() = 0; - - virtual GLuint GetTexture(GLenum aUnit) = 0; - - virtual void EndFrame() = 0; -}; - -/** - * Agressively reuses textures. One gl texture per texture unit in total. - * So far this hasn't shown the best results on b2g. - */ -class PerUnitTexturePoolOGL : public CompositorTexturePoolOGL -{ -public: - PerUnitTexturePoolOGL(gl::GLContext* aGL) - : mGL(aGL) - {} - - virtual ~PerUnitTexturePoolOGL() - { - DestroyTextures(); - } - - virtual void Clear() MOZ_OVERRIDE - { - DestroyTextures(); - } - - virtual GLuint GetTexture(GLenum aUnit) MOZ_OVERRIDE; - - virtual void EndFrame() MOZ_OVERRIDE {} - -protected: - void DestroyTextures(); - - nsTArray<GLuint> mTextures; - RefPtr<gl::GLContext> mGL; -}; - -/** - * Reuse gl textures from a pool of textures that haven't yet been - * used during the current frame. - * All the textures that are not used at the end of a frame are - * deleted. - * This strategy seems to work well with gralloc textures because destroying - * unused textures which are bound to gralloc buffers let drivers know that it - * can unlock the gralloc buffers. - */ -class PerFrameTexturePoolOGL : public CompositorTexturePoolOGL -{ -public: - PerFrameTexturePoolOGL(gl::GLContext* aGL) - : mGL(aGL) - {} - - virtual ~PerFrameTexturePoolOGL() - { - DestroyTextures(); - } - - virtual void Clear() MOZ_OVERRIDE - { - DestroyTextures(); - } - - virtual GLuint GetTexture(GLenum aUnit) MOZ_OVERRIDE; - - virtual void EndFrame() MOZ_OVERRIDE; - -protected: - void DestroyTextures(); - - RefPtr<gl::GLContext> mGL; - nsTArray<GLuint> mCreatedTextures; - nsTArray<GLuint> mUnusedTextures; -}; - class CompositorOGL : public Compositor { typedef mozilla::gl::GLContext GLContext; friend class GLManagerCompositor; std::map<ShaderConfigOGL, ShaderProgramOGL*> mPrograms; public: @@ -250,16 +157,20 @@ public: return LayersBackend::LAYERS_OPENGL; } virtual void Pause() MOZ_OVERRIDE; virtual bool Resume() MOZ_OVERRIDE; virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; } +#ifdef MOZ_WIDGET_GONK + virtual CompositorBackendSpecificData* GetCompositorBackendSpecificData() MOZ_OVERRIDE; +#endif + GLContext* gl() const { return mGLContext; } gfx::SurfaceFormat GetFBOFormat() const { return gfx::SurfaceFormat::R8G8B8A8; } /** * The compositor provides with temporary textures for use with direct * textruing like gralloc texture. @@ -393,23 +304,49 @@ private: * * Indeed, the only coordinate system that OpenGL knows has the y-axis * pointing upwards, but the layers/compositor coordinate system has the * y-axis pointing downwards, for good reason as Web pages are typically * scrolled downwards. So, some flipping has to take place; FlippedY does it. */ GLint FlipY(GLint y) const { return mHeight - y; } - RefPtr<CompositorTexturePoolOGL> mTexturePool; + bool mDestroyed; - bool mDestroyed; + // Textures used for direct texturing of buffers like gralloc. + // The index of the texture in this array must correspond to the texture unit. + nsTArray<GLuint> mTextures; /** * Height of the OpenGL context's primary framebuffer in pixels. Used by * FlipY for the y-flipping calculation. */ GLint mHeight; + +#ifdef MOZ_WIDGET_GONK + RefPtr<CompositorBackendSpecificData> mCompositorBackendSpecificData; +#endif }; +#ifdef MOZ_WIDGET_GONK +class CompositorOGLGonkBackendSpecificData : public CompositorBackendSpecificData +{ +public: + CompositorOGLGonkBackendSpecificData(CompositorOGL* aCompositor); + virtual ~CompositorOGLGonkBackendSpecificData(); + + GLuint GetTexture(); + void EndFrame(); + +private: + gl::GLContext* gl() const; + + RefPtr<CompositorOGL> mCompositor; + + nsTArray<GLuint> mCreatedTextures; + nsTArray<GLuint> mUnusedTextures; +}; +#endif + } } #endif /* MOZILLA_GFX_COMPOSITOROGL_H */
--- a/gfx/layers/opengl/GrallocTextureHost.cpp +++ b/gfx/layers/opengl/GrallocTextureHost.cpp @@ -88,73 +88,89 @@ TextureTargetForAndroidPixelFormat(andro GrallocTextureSourceOGL::GrallocTextureSourceOGL(CompositorOGL* aCompositor, android::GraphicBuffer* aGraphicBuffer, gfx::SurfaceFormat aFormat) : mCompositor(aCompositor) , mGraphicBuffer(aGraphicBuffer) , mEGLImage(0) , mFormat(aFormat) + , mNeedsReset(true) { MOZ_ASSERT(mGraphicBuffer.get()); } GrallocTextureSourceOGL::~GrallocTextureSourceOGL() { DeallocateDeviceData(); mCompositor = nullptr; } void GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) { + /* + * The job of this function is to ensure that the texture is tied to the + * android::GraphicBuffer, so that texturing will source the GraphicBuffer. + * + * To this effect we create an EGLImage wrapping this GraphicBuffer, + * using EGLImageCreateFromNativeBuffer, and then we tie this EGLImage to our + * texture using fEGLImageTargetTexture2D. + */ MOZ_ASSERT(gl()); if (!IsValid()) { return; } gl()->MakeCurrent(); GLuint tex = GetGLTexture(); GLuint textureTarget = GetTextureTarget(); gl()->fActiveTexture(aTextureUnit); gl()->fBindTexture(textureTarget, tex); + if (mCompositableBackendData) { + // There are two paths for locking/unlocking - if mCompositableBackendData is + // set, we use the texture on there, otherwise we use + // CompositorBackendSpecificData from the compositor and bind the EGLImage + // only in Lock(). + if (!mEGLImage) { + mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer()); + } + gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage); + } + ApplyFilterToBoundTexture(gl(), aFilter, textureTarget); } void GrallocTextureSourceOGL::Lock() { - /* - * The job of this function is to ensure that the texture is tied to the - * android::GraphicBuffer, so that texturing will source the GraphicBuffer. - * - * To this effect we create an EGLImage wrapping this GraphicBuffer, - * using EGLImageCreateFromNativeBuffer, and then we tie this EGLImage to our - * texture using fEGLImageTargetTexture2D. - */ + if (mCompositableBackendData) return; + MOZ_ASSERT(IsValid()); - mTexture = mCompositor->GetTemporaryTexture(LOCAL_GL_TEXTURE0); + CompositorOGLGonkBackendSpecificData* backendData = + static_cast<CompositorOGLGonkBackendSpecificData*>(mCompositor->GetCompositorBackendSpecificData()); + mTexture = backendData->GetTexture(); GLuint textureTarget = GetTextureTarget(); gl()->MakeCurrent(); gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->fBindTexture(textureTarget, mTexture); if (!mEGLImage) { mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer()); } gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage); } bool GrallocTextureSourceOGL::IsValid() const { - return !!gl() && !!mGraphicBuffer.get(); + return !!gl() && !!mGraphicBuffer.get() && (!!mCompositor || !!mCompositableBackendData); } gl::GLContext* GrallocTextureSourceOGL::gl() const { return mCompositor ? mCompositor->gl() : nullptr; } @@ -184,16 +200,61 @@ GrallocTextureSourceOGL::GetFormat() con return gfx::SurfaceFormat::UNKNOWN; } if (GetTextureTarget() == LOCAL_GL_TEXTURE_EXTERNAL) { return gfx::SurfaceFormat::R8G8B8A8; } return mFormat; } +void +GrallocTextureSourceOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) +{ + if (!aBackendData) { + mCompositableBackendData = nullptr; + DeallocateDeviceData(); + return; + } + + if (mCompositableBackendData != aBackendData) { + mNeedsReset = true; + } + + if (!mNeedsReset) { + // Update binding to the EGLImage + gl()->MakeCurrent(); + GLuint tex = GetGLTexture(); + GLuint textureTarget = GetTextureTarget(); + gl()->fActiveTexture(LOCAL_GL_TEXTURE0); + gl()->fBindTexture(textureTarget, tex); + gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage); + return; + } + + mCompositableBackendData = aBackendData; + + if (!mCompositor) { + return; + } + + // delete old EGLImage + DeallocateDeviceData(); + + gl()->MakeCurrent(); + GLuint tex = GetGLTexture(); + GLuint textureTarget = GetTextureTarget(); + + gl()->fActiveTexture(LOCAL_GL_TEXTURE0); + gl()->fBindTexture(textureTarget, tex); + // create new EGLImage + mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer()); + gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage); + mNeedsReset = false; +} + gfx::IntSize GrallocTextureSourceOGL::GetSize() const { if (!IsValid()) { NS_WARNING("Trying to access the size of an invalid GrallocTextureSourceOGL"); return gfx::IntSize(0, 0); } return gfx::IntSize(mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight()); @@ -352,16 +413,21 @@ GrallocTextureSourceOGL::GetAsSurface() gl()->fActiveTexture(LOCAL_GL_TEXTURE0); return surf.forget(); } GLuint GrallocTextureSourceOGL::GetGLTexture() { + if (mCompositableBackendData) { + mCompositableBackendData->SetCompositor(mCompositor); + return static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get())->GetTexture(); + } + return mTexture; } void GrallocTextureHostOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) { mCompositableBackendData = aBackendData; if (mTextureSource) {
--- a/gfx/layers/opengl/GrallocTextureHost.h +++ b/gfx/layers/opengl/GrallocTextureHost.h @@ -40,16 +40,18 @@ public: virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE; virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; } + virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) MOZ_OVERRIDE; + void DeallocateDeviceData(); gl::GLContext* gl() const; virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; void ForgetBuffer() { @@ -63,16 +65,17 @@ public: void Lock(); protected: CompositorOGL* mCompositor; android::sp<android::GraphicBuffer> mGraphicBuffer; EGLImage mEGLImage; GLuint mTexture; gfx::SurfaceFormat mFormat; + bool mNeedsReset; }; class GrallocTextureHostOGL : public TextureHost #if MOZ_WIDGET_GONK && ANDROID_VERSION >= 17 , public TextureHostOGL #endif { friend class GrallocBufferActor;
--- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -150,36 +150,60 @@ WrapMode(gl::GLContext *aGl, bool aAllow (aGl->IsExtensionSupported(GLContext::ARB_texture_non_power_of_two) || aGl->IsExtensionSupported(GLContext::OES_texture_npot))) { return LOCAL_GL_REPEAT; } return LOCAL_GL_CLAMP_TO_EDGE; } CompositableDataGonkOGL::CompositableDataGonkOGL() + : mTexture(0) { } CompositableDataGonkOGL::~CompositableDataGonkOGL() { + DeleteTextureIfPresent(); } gl::GLContext* CompositableDataGonkOGL::gl() const { return mCompositor ? mCompositor->gl() : nullptr; } void CompositableDataGonkOGL::SetCompositor(Compositor* aCompositor) { mCompositor = static_cast<CompositorOGL*>(aCompositor); } void CompositableDataGonkOGL::ClearData() { CompositableBackendSpecificData::ClearData(); + DeleteTextureIfPresent(); +} + +GLuint CompositableDataGonkOGL::GetTexture() +{ + if (!mTexture) { + if (gl()->MakeCurrent()) { + gl()->fGenTextures(1, &mTexture); + } + } + return mTexture; +} + +void +CompositableDataGonkOGL::DeleteTextureIfPresent() +{ + if (mTexture) { + if (gl()->MakeCurrent()) { + gl()->fDeleteTextures(1, &mTexture); + } + mTexture = 0; + } } #if MOZ_WIDGET_GONK && ANDROID_VERSION >= 17 bool TextureHostOGL::SetReleaseFence(const android::sp<android::Fence>& aReleaseFence) { if (!aReleaseFence.get() || !aReleaseFence->isValid()) { return false; @@ -707,16 +731,29 @@ TextureImageDeprecatedTextureHostOGL::Up nsIntRegion* aRegion, nsIntPoint* aOffset) { if (!mGL) { NS_WARNING("trying to update TextureImageDeprecatedTextureHostOGL without a compositor?"); return; } +#ifdef MOZ_WIDGET_GONK + if (mCompositableBackendData) { + // on gonk, this class is used as a fallback from gralloc buffer. + // There is a case this class is used with GrallocDeprecatedTextureHostOGL + // under same CompositableHost. if it happens, a gralloc buffer of + // GrallocDeprecatedTextureHostOGL needs to be unbounded from a texture, + // when the gralloc buffer is not rendered. + // Establish the unbound by deleting the texture. + // See Bug 916264. + static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get())->DeleteTextureIfPresent(); + } +#endif + AutoOpenSurface surf(OPEN_READ_ONLY, aImage); gfx::IntSize size = surf.Size(); TextureImage::ImageFormat format = surf.ImageFormat(); if (!mTexture || (mTexture->GetSize() != size && !aOffset) || mTexture->GetContentType() != surf.ContentType() || (mTexture->GetImageFormat() != format && @@ -1159,17 +1196,17 @@ GrallocDeprecatedTextureHostOGL::GetRend return LayerRenderState(); } GLuint GrallocDeprecatedTextureHostOGL::GetGLTexture() { mCompositableBackendData->SetCompositor(mCompositor); - return mCompositor->GetTemporaryTexture(LOCAL_GL_TEXTURE0); + return static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get())->GetTexture(); } #endif // MOZ_WIDGET_GONK TemporaryRef<gfx::DataSourceSurface> TextureImageDeprecatedTextureHostOGL::GetAsSurface() { RefPtr<gfx::DataSourceSurface> surf = IsValid() ? ReadBackSurface(mGL, mTexture->GetTextureID(),
--- a/gfx/layers/opengl/TextureHostOGL.h +++ b/gfx/layers/opengl/TextureHostOGL.h @@ -67,19 +67,22 @@ class TextureImageDeprecatedTextureHostO class CompositableDataGonkOGL : public CompositableBackendSpecificData { public: CompositableDataGonkOGL(); virtual ~CompositableDataGonkOGL(); virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; virtual void ClearData() MOZ_OVERRIDE; + GLuint GetTexture(); + void DeleteTextureIfPresent(); gl::GLContext* gl() const; protected: RefPtr<CompositorOGL> mCompositor; + GLuint mTexture; }; inline void ApplyFilterToBoundTexture(gl::GLContext* aGL, gfx::Filter aFilter, GLuint aTarget = LOCAL_GL_TEXTURE_2D) { GLenum filter = (aFilter == gfx::Filter::POINT ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR);