Bug 1245813 - Make TextureHost bullet-proof against changing its compositor. r=dvander

This commit is contained in:
Nicolas Silva 2016-03-22 15:28:27 +01:00
Родитель 5706816622
Коммит 2b867d9c85
7 изменённых файлов: 152 добавлений и 52 удалений

Просмотреть файл

@ -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());
}

Просмотреть файл

@ -442,10 +442,13 @@ BufferTextureHost::SetCompositor(Compositor* aCompositor)
if (mCompositor == aCompositor) {
return;
}
RefPtr<TextureSource> it = mFirstSource;
while (it) {
it->SetCompositor(aCompositor);
it = it->GetNextSibling();
if (aCompositor && mCompositor &&
aCompositor->GetBackendType() == mCompositor->GetBackendType()) {
RefPtr<TextureSource> it = mFirstSource;
while (it) {
it->SetCompositor(aCompositor);
it = it->GetNextSibling();
}
}
if (mFirstSource && mFirstSource->IsOwnedBy(this)) {
mFirstSource->SetOwner(nullptr);

Просмотреть файл

@ -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<CompositorD3D11*>(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<CompositorD3D11*>(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<CompositorD3D11*>(aCompositor);
if (mNextSibling) {
mNextSibling->SetCompositor(aCompositor);

Просмотреть файл

@ -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<CompositorD3D9*>(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<CompositorD3D9*>(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<CompositorD3D9*>(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<CompositorD3D9*>(aCompositor);
}

Просмотреть файл

@ -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<CompositorOGL*>(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<CompositorOGL*>(aCompositor);
if (mNextSibling) {
mNextSibling->SetCompositor(aCompositor);

Просмотреть файл

@ -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<CompositorOGL*>(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<CompositorOGL*>(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<CompositorOGL*>(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<CompositorOGL*>(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<CompositorOGL*>(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<CompositorOGL*>(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

Просмотреть файл

@ -521,6 +521,8 @@ protected:
RefPtr<EGLImageTextureSource> mTextureSource;
};
bool AssertGLCompositor(Compositor* aCompositor);
} // namespace layers
} // namespace mozilla