From 9f800c9f4593dba4c2a8cb5d551fd46e93830adb Mon Sep 17 00:00:00 2001 From: Milan Sreckovic Date: Wed, 13 Apr 2016 09:56:00 +0200 Subject: [PATCH] Bug 1262681 - Draw target also has to be valid for us to demand a snapshot. r=bas --- gfx/layers/RotatedBuffer.cpp | 45 +++++++++++++++++++++++------------- gfx/layers/RotatedBuffer.h | 4 ++-- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/gfx/layers/RotatedBuffer.cpp b/gfx/layers/RotatedBuffer.cpp index 0dfff9ca15a3..0fec87c9c150 100644 --- a/gfx/layers/RotatedBuffer.cpp +++ b/gfx/layers/RotatedBuffer.cpp @@ -99,6 +99,11 @@ RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget, MOZ_ASSERT(aSource != BUFFER_BOTH); RefPtr snapshot = GetSourceSurface(aSource); + if (!snapshot) { + gfxCriticalError() << "Invalid snapshot in RotatedBuffer::DrawBufferQuadrant"; + return; + } + // direct2d is much slower when using OP_SOURCE so use OP_OVER and // (maybe) a clear instead. Normally we need to draw in a single operation // (to avoid flickering) but direct2d is ok since it defers rendering. @@ -275,7 +280,7 @@ RotatedContentBuffer::BorrowDrawTargetForQuadrantUpdate(const IntRect& aBounds, if (!EnsureBufferOnWhite()) { return nullptr; } - MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite); + MOZ_ASSERT(mDTBuffer && mDTBuffer->IsValid() && mDTBufferOnWhite && mDTBufferOnWhite->IsValid()); mLoanedDrawTarget = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite); } else if (aSource == BUFFER_WHITE) { if (!EnsureBufferOnWhite()) { @@ -318,12 +323,12 @@ BorrowDrawTarget::ReturnDrawTarget(gfx::DrawTarget*& aReturned) gfxContentType RotatedContentBuffer::BufferContentType() { - if (mBufferProvider || mDTBuffer) { - SurfaceFormat format; + if (mBufferProvider || (mDTBuffer && mDTBuffer->IsValid())) { + SurfaceFormat format = SurfaceFormat::B8G8R8A8; if (mBufferProvider) { format = mBufferProvider->GetFormat(); - } else if (mDTBuffer) { + } else if (mDTBuffer && mDTBuffer->IsValid()) { format = mDTBuffer->GetFormat(); } @@ -344,13 +349,13 @@ bool RotatedContentBuffer::EnsureBuffer() { NS_ASSERTION(!mLoanedDrawTarget, "Loaned draw target must be returned"); - if (!mDTBuffer) { + if (!mDTBuffer || !mDTBuffer->IsValid()) { if (mBufferProvider) { mDTBuffer = mBufferProvider->BorrowDrawTarget(); } } - NS_WARN_IF_FALSE(mDTBuffer, "no buffer"); + NS_WARN_IF_FALSE(mDTBuffer && mDTBuffer->IsValid(), "no buffer"); return !!mDTBuffer; } @@ -372,13 +377,13 @@ RotatedContentBuffer::EnsureBufferOnWhite() bool RotatedContentBuffer::HaveBuffer() const { - return mDTBuffer || mBufferProvider; + return mBufferProvider || (mDTBuffer && mDTBuffer->IsValid()); } bool RotatedContentBuffer::HaveBufferOnWhite() const { - return mDTBufferOnWhite || mBufferProviderOnWhite; + return mBufferProviderOnWhite || (mDTBufferOnWhite && mDTBufferOnWhite->IsValid()); } static void @@ -591,13 +596,13 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, if (mBufferRotation == IntPoint(0,0)) { IntRect srcRect(IntPoint(0, 0), mBufferRect.Size()); IntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft(); - MOZ_ASSERT(mDTBuffer); + MOZ_ASSERT(mDTBuffer && mDTBuffer->IsValid()); mDTBuffer->CopyRect(srcRect, dest); if (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) { if (!EnsureBufferOnWhite()) { return result; } - MOZ_ASSERT(mDTBufferOnWhite); + MOZ_ASSERT(mDTBufferOnWhite && mDTBufferOnWhite->IsValid()); mDTBufferOnWhite->CopyRect(srcRect, dest); } result.mDidSelfCopy = true; @@ -625,7 +630,7 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, if (!EnsureBufferOnWhite()) { return result; } - MOZ_ASSERT(mDTBufferOnWhite); + MOZ_ASSERT(mDTBufferOnWhite && mDTBufferOnWhite->IsValid()); mDTBufferOnWhite->LockBits(&data, &size, &stride, &format); uint8_t bytesPerPixel = BytesPerPixel(format); BufferUnrotate(data, @@ -692,7 +697,7 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, if (!EnsureBuffer()) { return result; } - MOZ_ASSERT(mDTBuffer, "Have we got a Thebes buffer for some reason?"); + MOZ_ASSERT(mDTBuffer && mDTBuffer->IsValid(), "Have we got a Thebes buffer for some reason?"); DrawBufferWithRotation(destDTBuffer, BUFFER_BLACK, 1.0, CompositionOp::OP_SOURCE); destDTBuffer->SetTransform(Matrix()); @@ -700,7 +705,7 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, if (!destDTBufferOnWhite || !EnsureBufferOnWhite()) { return result; } - MOZ_ASSERT(mDTBufferOnWhite, "Have we got a Thebes buffer for some reason?"); + MOZ_ASSERT(mDTBufferOnWhite && mDTBufferOnWhite->IsValid(), "Have we got a Thebes buffer for some reason?"); destDTBufferOnWhite->SetTransform(mat); DrawBufferWithRotation(destDTBufferOnWhite, BUFFER_WHITE, 1.0, CompositionOp::OP_SOURCE); destDTBufferOnWhite->SetTransform(Matrix()); @@ -753,7 +758,8 @@ RotatedContentBuffer::BorrowDrawTargetForPainting(PaintState& aPaintState, } if (aPaintState.mMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) { - if (!mDTBuffer || !mDTBufferOnWhite) { + if (!mDTBuffer || !mDTBuffer->IsValid() || + !mDTBufferOnWhite || !mDTBufferOnWhite->IsValid()) { // This can happen in release builds if allocating one of the two buffers // failed. This in turn can happen if unreasonably large textures are // requested. @@ -780,11 +786,18 @@ RotatedContentBuffer::BorrowDrawTargetForPainting(PaintState& aPaintState, already_AddRefed RotatedContentBuffer::GetSourceSurface(ContextSource aSource) const { - MOZ_ASSERT(mDTBuffer); + if (!mDTBuffer || !mDTBuffer->IsValid()) { + gfxCriticalNote << "Invalid buffer in RotatedContentBuffer::GetSourceSurface " << gfx::hexa(mDTBuffer); + return nullptr; + } + if (aSource == BUFFER_BLACK) { return mDTBuffer->Snapshot(); } else { - MOZ_ASSERT(mDTBufferOnWhite); + if (!mDTBufferOnWhite || !mDTBufferOnWhite->IsValid()) { + gfxCriticalNote << "Invalid buffer on white in RotatedContentBuffer::GetSourceSurface " << gfx::hexa(mDTBufferOnWhite); + return nullptr; + } MOZ_ASSERT(aSource == BUFFER_WHITE); return mDTBufferOnWhite->Snapshot(); } diff --git a/gfx/layers/RotatedBuffer.h b/gfx/layers/RotatedBuffer.h index 0e2ecaaf3d0f..4c3f4f125150 100644 --- a/gfx/layers/RotatedBuffer.h +++ b/gfx/layers/RotatedBuffer.h @@ -339,7 +339,7 @@ protected: { // Only this buffer provider can give us a buffer. If we // already have one, something has gone wrong. - MOZ_ASSERT(!aClient || !mDTBuffer); + MOZ_ASSERT(!aClient || !mDTBuffer || !mDTBuffer->IsValid()); mBufferProvider = aClient; if (!mBufferProvider) { @@ -351,7 +351,7 @@ protected: { // Only this buffer provider can give us a buffer. If we // already have one, something has gone wrong. - MOZ_ASSERT(!aClient || !mDTBufferOnWhite); + MOZ_ASSERT(!aClient || !mDTBufferOnWhite || !mDTBufferOnWhite->IsValid()); mBufferProviderOnWhite = aClient; if (!mBufferProviderOnWhite) {