From 2b867d9c8575703b88053bbdb5a486685a382dc4 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Tue, 22 Mar 2016 15:28:27 +0100 Subject: [PATCH] Bug 1245813 - Make TextureHost bullet-proof against changing its compositor. r=dvander --- gfx/layers/composite/ImageHost.cpp | 2 +- gfx/layers/composite/TextureHost.cpp | 11 +- gfx/layers/d3d11/TextureD3D11.cpp | 25 ++++- gfx/layers/d3d9/TextureD3D9.cpp | 30 +++++- .../opengl/MacIOSurfaceTextureHostOGL.cpp | 32 ++++-- gfx/layers/opengl/TextureHostOGL.cpp | 102 ++++++++++++------ gfx/layers/opengl/TextureHostOGL.h | 2 + 7 files changed, 152 insertions(+), 52 deletions(-) diff --git a/gfx/layers/composite/ImageHost.cpp b/gfx/layers/composite/ImageHost.cpp index 81b92cf394fe..74bfb1759ca0 100644 --- a/gfx/layers/composite/ImageHost.cpp +++ b/gfx/layers/composite/ImageHost.cpp @@ -330,9 +330,9 @@ ImageHost::Composite(LayerComposite* aLayer, } TimedImage* img = &mImages[imageIndex]; + img->mTextureHost->SetCompositor(GetCompositor()); SetCurrentTextureHost(img->mTextureHost); // Make sure the front buffer has a compositor - mCurrentTextureHost->SetCompositor(GetCompositor()); if (mCurrentTextureSource) { mCurrentTextureSource->SetCompositor(GetCompositor()); } diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index fb2897f1540e..e66b9cfda39c 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -442,10 +442,13 @@ BufferTextureHost::SetCompositor(Compositor* aCompositor) if (mCompositor == aCompositor) { return; } - RefPtr it = mFirstSource; - while (it) { - it->SetCompositor(aCompositor); - it = it->GetNextSibling(); + if (aCompositor && mCompositor && + aCompositor->GetBackendType() == mCompositor->GetBackendType()) { + RefPtr it = mFirstSource; + while (it) { + it->SetCompositor(aCompositor); + it = it->GetNextSibling(); + } } if (mFirstSource && mFirstSource->IsOwnedBy(this)) { mFirstSource->SetOwner(nullptr); diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp index 5b2ff0808168..667f88dada29 100644 --- a/gfx/layers/d3d11/TextureD3D11.cpp +++ b/gfx/layers/d3d11/TextureD3D11.cpp @@ -634,10 +634,21 @@ DXGITextureHostD3D11::GetDevice() return device; } +static bool AssertD3D11Compositor(Compositor* aCompositor) +{ + bool ok = aCompositor && aCompositor->GetBackendType() == LayersBackend::LAYERS_D3D11; + MOZ_ASSERT(ok); + return ok; +} + void DXGITextureHostD3D11::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertD3D11Compositor(aCompositor)) { + mCompositor = nullptr; + mTextureSource = nullptr; + return; + } mCompositor = static_cast(aCompositor); if (mTextureSource) { mTextureSource->SetCompositor(aCompositor); @@ -744,7 +755,13 @@ DXGIYCbCrTextureHostD3D11::GetDevice() void DXGIYCbCrTextureHostD3D11::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertD3D11Compositor(aCompositor)) { + mCompositor = nullptr; + mTextureSources[0] = nullptr; + mTextureSources[1] = nullptr; + mTextureSources[2] = nullptr; + return; + } mCompositor = static_cast(aCompositor); if (mTextureSources[0]) { mTextureSources[0]->SetCompositor(aCompositor); @@ -971,7 +988,9 @@ DataTextureSourceD3D11::GetTileRect() void DataTextureSourceD3D11::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertD3D11Compositor(aCompositor)) { + return; + } mCompositor = static_cast(aCompositor); if (mNextSibling) { mNextSibling->SetCompositor(aCompositor); diff --git a/gfx/layers/d3d9/TextureD3D9.cpp b/gfx/layers/d3d9/TextureD3D9.cpp index 975167913bb5..3c18afa3b830 100644 --- a/gfx/layers/d3d9/TextureD3D9.cpp +++ b/gfx/layers/d3d9/TextureD3D9.cpp @@ -493,10 +493,19 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface, return true; } +static bool AssertD3D9Compositor(Compositor* aCompositor) +{ + bool ok = aCompositor && aCompositor->GetBackendType() == LayersBackend::LAYERS_D3D9; + MOZ_ASSERT(ok); + return ok; +} + void DataTextureSourceD3D9::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertD3D9Compositor(aCompositor)) { + return; + } CompositorD3D9* d3dCompositor = static_cast(aCompositor); if (mCompositor && mCompositor != d3dCompositor) { Reset(); @@ -907,6 +916,11 @@ TextureHostD3D9::GetDevice() void TextureHostD3D9::SetCompositor(Compositor* aCompositor) { + if (!AssertD3D9Compositor(aCompositor)) { + mCompositor = nullptr; + mTextureSource = nullptr; + return; + } mCompositor = static_cast(aCompositor); if (mTextureSource) { mTextureSource->SetCompositor(aCompositor); @@ -1025,7 +1039,11 @@ DXGITextureHostD3D9::Unlock() void DXGITextureHostD3D9::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertD3D9Compositor(aCompositor)) { + mCompositor = nullptr; + mTextureSource = nullptr; + return; + } mCompositor = static_cast(aCompositor); } @@ -1057,7 +1075,13 @@ DXGIYCbCrTextureHostD3D9::GetDevice() void DXGIYCbCrTextureHostD3D9::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertD3D9Compositor(aCompositor)) { + mCompositor = nullptr; + mTextureSources[0] = nullptr; + mTextureSources[1] = nullptr; + mTextureSources[2] = nullptr; + return; + } mCompositor = static_cast(aCompositor); } diff --git a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp index 7fa69134e823..859c27461812 100644 --- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp +++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp @@ -48,7 +48,7 @@ MacIOSurfaceTextureHostOGL::CreateTextureSourceForPlane(size_t aPlane) bool MacIOSurfaceTextureHostOGL::Lock() { - if (!mCompositor || !mSurface) { + if (!gl() || !mSurface) { return false; } @@ -68,6 +68,11 @@ MacIOSurfaceTextureHostOGL::Lock() void MacIOSurfaceTextureHostOGL::SetCompositor(Compositor* aCompositor) { + if (!AssertGLCompositor(aCompositor)) { + mTextureSource = nullptr; + mCompositor = nullptr; + return; + } CompositorOGL* glCompositor = static_cast(aCompositor); mCompositor = glCompositor; if (mTextureSource) { @@ -94,12 +99,19 @@ MacIOSurfaceTextureHostOGL::GetSize() const { mSurface->GetDevicePixelHeight()); } +gl::GLContext* +MacIOSurfaceTextureHostOGL::gl() const +{ + return mCompositor ? mCompositor->gl() : nullptr; +} + MacIOSurfaceTextureSourceOGL::MacIOSurfaceTextureSourceOGL( CompositorOGL* aCompositor, MacIOSurface* aSurface) : mCompositor(aCompositor) , mSurface(aSurface) { + MOZ_ASSERT(aCompositor); MOZ_COUNT_CTOR(MacIOSurfaceTextureSourceOGL); } @@ -125,21 +137,27 @@ MacIOSurfaceTextureSourceOGL::GetFormat() const void MacIOSurfaceTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) { - if (!gl()) { - NS_WARNING("Trying to bind a texture without a GLContext"); + gl::GLContext* gl = this->gl(); + if (!gl || !gl->MakeCurrent()) { + NS_WARNING("Trying to bind a texture without a working GLContext"); return; } GLuint tex = mCompositor->GetTemporaryTexture(GetTextureTarget(), aTextureUnit); - gl()->fActiveTexture(aTextureUnit); - gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, tex); - mSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(gl())->GetCGLContext()); - ApplyFilterToBoundTexture(gl(), aFilter, LOCAL_GL_TEXTURE_RECTANGLE_ARB); + gl->fActiveTexture(aTextureUnit); + gl->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, tex); + mSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(gl)->GetCGLContext()); + ApplyFilterToBoundTexture(gl, aFilter, LOCAL_GL_TEXTURE_RECTANGLE_ARB); } void MacIOSurfaceTextureSourceOGL::SetCompositor(Compositor* aCompositor) { + if (!AssertGLCompositor(aCompositor)) { + mCompositor = nullptr; + return; + } + mCompositor = static_cast(aCompositor); if (mNextSibling) { mNextSibling->SetCompositor(aCompositor); diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp index 52123d5737bb..22fb5fdb07e0 100644 --- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -139,7 +139,7 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface, { GLContext *gl = mCompositor->gl(); MOZ_ASSERT(gl); - if (!gl) { + if (!gl || !gl->MakeCurrent()) { NS_WARNING("trying to update TextureImageTextureSourceOGL without a GLContext"); return false; } @@ -231,13 +231,22 @@ TextureImageTextureSourceOGL::CopyTo(const gfx::IntRect& aSourceRect, dest->mTexImage->MarkValid(); } +bool AssertGLCompositor(Compositor* aCompositor) +{ + bool ok = aCompositor && aCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL; + MOZ_ASSERT(ok); + return ok; +} + void TextureImageTextureSourceOGL::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertGLCompositor(aCompositor)) { + DeallocateDeviceData(); + return; + } CompositorOGL* glCompositor = static_cast(aCompositor); - - if (!glCompositor || (mCompositor != glCompositor)) { + if (mCompositor != glCompositor) { DeallocateDeviceData(); mCompositor = glCompositor; } @@ -327,20 +336,23 @@ GLTextureSource::DeleteTextureHandle() void GLTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) { - MOZ_ASSERT(gl()); MOZ_ASSERT(mTextureHandle != 0); - if (!gl()) { + GLContext* gl = this->gl(); + if (gl || !gl->MakeCurrent()) { + MOZ_ASSERT(false); return; } - gl()->fActiveTexture(aTextureUnit); - gl()->fBindTexture(mTextureTarget, mTextureHandle); - ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget); + gl->fActiveTexture(aTextureUnit); + gl->fBindTexture(mTextureTarget, mTextureHandle); + ApplyFilterToBoundTexture(gl, aFilter, mTextureTarget); } void GLTextureSource::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertGLCompositor(aCompositor)) { + return; + } mCompositor = static_cast(aCompositor); if (mNextSibling) { mNextSibling->SetCompositor(aCompositor); @@ -384,26 +396,30 @@ void SurfaceTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) { MOZ_ASSERT(mSurfTex); - if (!gl()) { + GLContext* gl = this->gl(); + if (!gl || !gl->MakeCurrent()) { NS_WARNING("Trying to bind a texture without a GLContext"); return; } - gl()->fActiveTexture(aTextureUnit); + gl->fActiveTexture(aTextureUnit); // SurfaceTexture spams us if there are any existing GL errors, so // we'll clear them here in order to avoid that. - gl()->FlushErrors(); + gl->FlushErrors(); mSurfTex->UpdateTexImage(); - ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget); + ApplyFilterToBoundTexture(gl, aFilter, mTextureTarget); } void SurfaceTextureSource::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertGLCompositor(aCompositor)) { + DeallocateDeviceData(); + return; + } if (mCompositor != aCompositor) { DeallocateDeviceData(); } @@ -466,7 +482,7 @@ bool SurfaceTextureHost::Lock() { MOZ_ASSERT(mSurfTex); - if (!mCompositor) { + if (!gl()) { return false; } @@ -495,7 +511,10 @@ SurfaceTextureHost::Unlock() void SurfaceTextureHost::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertGLCompositor(aCompositor)) { + DeallocateDeviceData(); + return; + } CompositorOGL* glCompositor = static_cast(aCompositor); mCompositor = glCompositor; if (mTextureSource) { @@ -507,7 +526,7 @@ gfx::SurfaceFormat SurfaceTextureHost::GetFormat() const { MOZ_ASSERT(mTextureSource); - return mTextureSource->GetFormat(); + return mTextureSource ? mTextureSource->GetFormat() : gfx::SurfaceFormat::UNKNOWN; } void @@ -545,28 +564,32 @@ EGLImageTextureSource::EGLImageTextureSource(CompositorOGL* aCompositor, void EGLImageTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) { - if (!gl()) { + GLContext* gl = this->gl(); + if (!gl || !gl->MakeCurrent()) { NS_WARNING("Trying to bind a texture without a GLContext"); return; } - MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl()), + MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl), "EGLImage not supported or disabled in runtime"); GLuint tex = mCompositor->GetTemporaryTexture(mTextureTarget, aTextureUnit); - gl()->fActiveTexture(aTextureUnit); - gl()->fBindTexture(mTextureTarget, tex); + gl->fActiveTexture(aTextureUnit); + gl->fBindTexture(mTextureTarget, tex); - gl()->fEGLImageTargetTexture2D(mTextureTarget, mImage); + gl->fEGLImageTargetTexture2D(mTextureTarget, mImage); - ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget); + ApplyFilterToBoundTexture(gl, aFilter, mTextureTarget); } void EGLImageTextureSource::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertGLCompositor(aCompositor)) { + mCompositor = nullptr; + return; + } mCompositor = static_cast(aCompositor); } @@ -616,7 +639,7 @@ EGLImageTextureHost::gl() const bool EGLImageTextureHost::Lock() { - if (!mCompositor) { + if (!gl()) { return false; } @@ -657,7 +680,11 @@ EGLImageTextureHost::Unlock() void EGLImageTextureHost::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertGLCompositor(aCompositor)) { + mCompositor = nullptr; + mTextureSource = nullptr; + return; + } CompositorOGL* glCompositor = static_cast(aCompositor); mCompositor = glCompositor; if (mTextureSource) { @@ -669,7 +696,7 @@ gfx::SurfaceFormat EGLImageTextureHost::GetFormat() const { MOZ_ASSERT(mTextureSource); - return mTextureSource->GetFormat(); + return mTextureSource ? mTextureSource->GetFormat() : gfx::SurfaceFormat::UNKNOWN; } // @@ -701,14 +728,17 @@ GLTextureHost::gl() const bool GLTextureHost::Lock() { - if (!mCompositor) { + GLContext* gl = this->gl(); + if (!gl) { return false; } if (mSync) { - gl()->MakeCurrent(); - gl()->fWaitSync(mSync, 0, LOCAL_GL_TIMEOUT_IGNORED); - gl()->fDeleteSync(mSync); + if (!gl->MakeCurrent()) { + return false; + } + gl->fWaitSync(mSync, 0, LOCAL_GL_TIMEOUT_IGNORED); + gl->fDeleteSync(mSync); mSync = 0; } @@ -728,7 +758,11 @@ GLTextureHost::Lock() void GLTextureHost::SetCompositor(Compositor* aCompositor) { - MOZ_ASSERT(aCompositor); + if (!AssertGLCompositor(aCompositor)) { + mCompositor = nullptr; + mTextureSource = nullptr; + return; + } CompositorOGL* glCompositor = static_cast(aCompositor); mCompositor = glCompositor; if (mTextureSource) { @@ -740,7 +774,7 @@ gfx::SurfaceFormat GLTextureHost::GetFormat() const { MOZ_ASSERT(mTextureSource); - return mTextureSource->GetFormat(); + return mTextureSource ? mTextureSource->GetFormat() : gfx::SurfaceFormat::UNKNOWN; } } // namespace layers diff --git a/gfx/layers/opengl/TextureHostOGL.h b/gfx/layers/opengl/TextureHostOGL.h index 9f36411d8084..e09f68b82001 100644 --- a/gfx/layers/opengl/TextureHostOGL.h +++ b/gfx/layers/opengl/TextureHostOGL.h @@ -521,6 +521,8 @@ protected: RefPtr mTextureSource; }; +bool AssertGLCompositor(Compositor* aCompositor); + } // namespace layers } // namespace mozilla