Backed out 9 changesets (bug 1399692) for failing reftest/tests/layout/reftests/svg/dynamic-text-06.svg Windows 10 x64 Stylo Disabled debug R-e10s2 r=backout on a CLOSED TREE

Backed out changeset 7d9324e2ab34 (bug 1399692)
Backed out changeset 76bf99decf09 (bug 1399692)
Backed out changeset 0fc2414f146d (bug 1399692)
Backed out changeset f235b12eda6e (bug 1399692)
Backed out changeset 467532fd5b7a (bug 1399692)
Backed out changeset dce585be0737 (bug 1399692)
Backed out changeset b971c1aa5a78 (bug 1399692)
Backed out changeset 8ba8bda8521a (bug 1399692)
Backed out changeset 2c41a712dff2 (bug 1399692)
This commit is contained in:
Andreea Pavel
2017-11-09 21:55:32 +02:00
parent 3ee1ef0c18
commit 18f448db0b
12 changed files with 233 additions and 572 deletions

View File

@@ -23,7 +23,6 @@
#include "mozilla/layers/LayerManagerComposite.h"
#include "mozilla/layers/LayersMessages.h" // for ThebesBufferData
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/PaintThread.h"
#include "nsDebug.h" // for NS_ASSERTION, NS_WARNING, etc
#include "nsISupportsImpl.h" // for gfxContext::Release, etc
#include "nsIWidget.h" // for nsIWidget
@@ -128,17 +127,17 @@ ContentClient::BeginPaint(PaintedLayer* aLayer,
MOZ_ASSERT(dest.mValidRegion.IsEmpty());
result.mRegionToInvalidate = aLayer->GetValidRegion();
Clear();
#if defined(MOZ_DUMP_PAINTING)
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
if (result.mContentType != mBuffer->GetContentType()) {
if (result.mContentType != BufferContentType()) {
printf_stderr("Invalidating entire rotated buffer (layer %p): content type changed\n", aLayer);
} else if ((dest.mBufferMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) != mBuffer->HaveBufferOnWhite()) {
printf_stderr("Invalidating entire rotated buffer (layer %p): component alpha changed\n", aLayer);
}
}
#endif
Clear();
}
result.mRegionToDraw.Sub(dest.mNeededRegion,
@@ -147,6 +146,25 @@ ContentClient::BeginPaint(PaintedLayer* aLayer,
if (result.mRegionToDraw.IsEmpty())
return result;
OpenMode lockMode = aFlags & PAINT_ASYNC ? OpenMode::OPEN_READ_ASYNC_WRITE
: OpenMode::OPEN_READ_WRITE;
if (mBuffer) {
if (mBuffer->Lock(lockMode)) {
// Do not modify result.mRegionToDraw or result.mContentType after this call.
// Do not modify the back buffer's bufferRect, bufferRotation, or didSelfCopy.
FinalizeFrame(result.mRegionToDraw);
} else {
// Abandon everything and redraw it all. Ideally we'd reallocate and copy
// the old to the new and then call FinalizeFrame on the new buffer so that
// we only need to draw the latest bits, but we need a big refactor to support
// that ordering.
result.mRegionToDraw = dest.mNeededRegion;
dest.mCanReuseBuffer = false;
Clear();
}
}
// We need to disable rotation if we're going to be resampled when
// drawing, because we might sample across the rotation boundary.
// Also disable buffer rotation when using webrender.
@@ -154,90 +172,38 @@ ContentClient::BeginPaint(PaintedLayer* aLayer,
!(aFlags & (PAINT_WILL_RESAMPLE | PAINT_NO_ROTATION)) &&
!(aLayer->Manager()->AsWebRenderLayerManager());
bool canDrawRotated = aFlags & PAINT_CAN_DRAW_ROTATED;
bool asyncPaint = (aFlags & PAINT_ASYNC);
IntRect drawBounds = result.mRegionToDraw.GetBounds();
OpenMode lockMode = asyncPaint ? OpenMode::OPEN_READ_ASYNC_WRITE
: OpenMode::OPEN_READ_WRITE;
if (dest.mCanReuseBuffer) {
MOZ_ASSERT(mBuffer);
bool canReuseBuffer = false;
if (mBuffer->Lock(lockMode)) {
RefPtr<CapturedBufferState> bufferState = new CapturedBufferState();
// Do not modify result.mRegionToDraw or result.mContentType after this call.
FinalizeFrame(result.mRegionToDraw, bufferState);
auto newParameters = mBuffer->AdjustedParameters(dest.mBufferRect);
if ((!canHaveRotation && newParameters.IsRotated()) ||
(!canDrawRotated && newParameters.RectWrapsBuffer(drawBounds))) {
bufferState->mBufferUnrotate = Some(CapturedBufferState::Unrotate {
newParameters,
mBuffer->ShallowCopy(),
});
}
// If we're async painting then return the buffer state to
// be dispatched to the paint thread, otherwise do it now
if (asyncPaint) {
// We cannot do a buffer unrotate if the buffer is already rotated
// and we're async painting as that may fail
if (!bufferState->mBufferUnrotate ||
mBuffer->BufferRotation() == IntPoint(0,0)) {
result.mBufferState = bufferState;
// We can then assume that preparing the buffer will always
// succeed and update our parameters unconditionally
if (bufferState->mBufferUnrotate) {
newParameters.SetUnrotated();
}
mBuffer->SetParameters(newParameters);
canReuseBuffer = true;
}
} else {
if (bufferState->PrepareBuffer()) {
if (bufferState->mBufferUnrotate) {
newParameters.SetUnrotated();
}
mBuffer->SetParameters(newParameters);
canReuseBuffer = true;
}
}
}
if (!canReuseBuffer) {
if (mBuffer->IsLocked()) {
mBuffer->Unlock();
}
dest.mBufferRect = ComputeBufferRect(dest.mNeededRegion.GetBounds());
dest.mCanReuseBuffer = false;
dest.mMustRemoveFrontBuffer = true;
}
RefPtr<RotatedBuffer> newBuffer;
uint32_t bufferFlags = 0;
if (dest.mBufferMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
bufferFlags |= BUFFER_COMPONENT_ALPHA;
}
if (dest.mCanReuseBuffer && mBuffer) {
if (!mBuffer->AdjustTo(dest.mBufferRect,
drawBounds,
canHaveRotation,
canDrawRotated)) {
dest.mBufferRect = ComputeBufferRect(dest.mNeededRegion.GetBounds());
newBuffer = CreateBuffer(result.mContentType, dest.mBufferRect, bufferFlags);
NS_ASSERTION(!(aFlags & PAINT_WILL_RESAMPLE) || dest.mBufferRect == dest.mNeededRegion.GetBounds(),
"If we're resampling, we need to validate the entire buffer");
// We never had a buffer, the buffer wasn't big enough, the content changed
// types, or we failed to unrotate the buffer when requested. In any case,
// we need to allocate a new one and prepare it for drawing.
if (!dest.mCanReuseBuffer) {
uint32_t bufferFlags = 0;
if (dest.mBufferMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
bufferFlags |= BUFFER_COMPONENT_ALPHA;
if (!newBuffer) {
if (Factory::ReasonableSurfaceSize(IntSize(dest.mBufferRect.Width(), dest.mBufferRect.Height()))) {
gfxCriticalNote << "Failed 1 buffer for "
<< dest.mBufferRect.x << ", "
<< dest.mBufferRect.y << ", "
<< dest.mBufferRect.Width() << ", "
<< dest.mBufferRect.Height();
}
return result;
}
}
RefPtr<RotatedBuffer> newBuffer = CreateBuffer(result.mContentType,
dest.mBufferRect,
bufferFlags);
} else {
// The buffer's not big enough, so allocate a new one
newBuffer = CreateBuffer(result.mContentType, dest.mBufferRect, bufferFlags);
if (!newBuffer) {
if (Factory::ReasonableSurfaceSize(IntSize(dest.mBufferRect.Width(), dest.mBufferRect.Height()))) {
gfxCriticalNote << "Failed buffer for "
gfxCriticalNote << "Failed 2 buffer for "
<< dest.mBufferRect.x << ", "
<< dest.mBufferRect.y << ", "
<< dest.mBufferRect.Width() << ", "
@@ -245,44 +211,31 @@ ContentClient::BeginPaint(PaintedLayer* aLayer,
}
return result;
}
}
NS_ASSERTION(!(aFlags & PAINT_WILL_RESAMPLE) || dest.mBufferRect == dest.mNeededRegion.GetBounds(),
"If we're resampling, we need to validate the entire buffer");
// If needed, copy the old buffer over to the new one
if (newBuffer) {
if (!newBuffer->Lock(lockMode)) {
gfxCriticalNote << "Failed to lock new back buffer.";
Clear();
return result;
}
// If we have an existing front buffer, copy it into the new back buffer
if (RefPtr<RotatedBuffer> frontBuffer = GetFrontBuffer()) {
nsIntRegion updateRegion = newBuffer->BufferRect();
updateRegion.Sub(updateRegion, result.mRegionToDraw);
if (mBuffer) {
newBuffer->UpdateDestinationFrom(*mBuffer, newBuffer->BufferRect());
if (!updateRegion.IsEmpty()) {
RefPtr<CapturedBufferState> bufferState = new CapturedBufferState();
bufferState->mBufferCopy = Some(CapturedBufferState::Copy {
frontBuffer->ShallowCopy(),
newBuffer->ShallowCopy(),
updateRegion.GetBounds(),
});
// If we're async painting then return the buffer state to
// be dispatched to the paint thread, otherwise do it now
if (asyncPaint) {
MOZ_ASSERT(!result.mBufferState);
result.mBufferState = bufferState;
} else {
if (!bufferState->PrepareBuffer()) {
gfxCriticalNote << "Failed to copy front buffer to back buffer.";
return result;
}
}
}
if (dest.mMustRemoveFrontBuffer) {
Clear();
}
// We are done with the old back buffer now and it is about to be
// destroyed, so unlock it.
mBuffer->Unlock();
}
// Ensure our reference to the front buffer is released
// as well as the old back buffer.
Clear();
mBuffer = newBuffer;
}
@@ -419,8 +372,6 @@ ContentClient::CalculateBufferForPaint(PaintedLayer* aLayer,
aLayer->CanUseOpaqueSurface() ? gfxContentType::COLOR :
gfxContentType::COLOR_ALPHA;
RefPtr<RotatedBuffer> frontBuffer = GetFrontBuffer();
SurfaceMode mode;
gfxContentType contentType;
IntRect destBufferRect;
@@ -429,14 +380,11 @@ ContentClient::CalculateBufferForPaint(PaintedLayer* aLayer,
bool canReuseBuffer = !!mBuffer;
bool canKeepBufferContents = true;
bool mustRemoveFrontBuffer = false;
while (true) {
mode = aLayer->GetSurfaceMode();
neededRegion = aLayer->GetVisibleRegion().ToUnknownRegion();
canReuseBuffer = canReuseBuffer && ValidBufferSize(mBufferSizePolicy,
mBuffer->BufferRect().Size(),
neededRegion.GetBounds().Size());
canReuseBuffer = canReuseBuffer && BufferSizeOkFor(neededRegion.GetBounds().Size());
contentType = layerContentType;
if (canReuseBuffer) {
@@ -451,22 +399,8 @@ ContentClient::CalculateBufferForPaint(PaintedLayer* aLayer,
destBufferRect = neededRegion.GetBounds();
}
} else {
// We won't be reusing the buffer. Compute a new rect.
if (frontBuffer) {
// We must create a buffer that is the same size as the front buffer,
// or else we need to remove the front buffer
if (ValidBufferSize(mBufferSizePolicy,
frontBuffer->BufferRect().Size(),
neededRegion.GetBounds().Size())) {
destBufferRect = frontBuffer->BufferRect();
destBufferRect.MoveTo(neededRegion.GetBounds().TopLeft());
} else {
destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
mustRemoveFrontBuffer = true;
}
} else {
destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
}
// We won't be reusing the buffer. Compute a new rect.
destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
}
if (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
@@ -501,20 +435,11 @@ ContentClient::CalculateBufferForPaint(PaintedLayer* aLayer,
// If we have an existing buffer, but the content type has changed or we
// have transitioned into/out of component alpha, then we need to recreate it.
bool needsComponentAlpha = (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA);
bool backBufferChangedSurface = mBuffer &&
(contentType != mBuffer->GetContentType() ||
needsComponentAlpha != mBuffer->HaveBufferOnWhite());
if (canKeepBufferContents && backBufferChangedSurface) {
// We cannot reuse the back buffer if the surface type or content type
// changed. We may have to also invalidate, but only if the front buffer
// also changed.
canReuseBuffer = false;
}
bool frontBufferChangedSurface = frontBuffer &&
(contentType != frontBuffer->GetContentType() ||
needsComponentAlpha != frontBuffer->HaveBufferOnWhite());
if (canKeepBufferContents && frontBufferChangedSurface) {
if (canKeepBufferContents &&
mBuffer &&
(contentType != BufferContentType() ||
(mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) != mBuffer->HaveBufferOnWhite()))
{
// Restart the decision process; we won't re-enter since we guard on
// being able to keep the buffer contents.
canReuseBuffer = false;
@@ -537,24 +462,25 @@ ContentClient::CalculateBufferForPaint(PaintedLayer* aLayer,
dest.mBufferContentType = contentType;
dest.mCanReuseBuffer = canReuseBuffer;
dest.mCanKeepBufferContents = canKeepBufferContents;
dest.mMustRemoveFrontBuffer = mustRemoveFrontBuffer;
return dest;
}
bool
ContentClient::ValidBufferSize(BufferSizePolicy aPolicy,
const gfx::IntSize& aBufferSize,
const gfx::IntSize& aVisibleBoundsSize)
gfxContentType
ContentClient::BufferContentType()
{
return (aVisibleBoundsSize == aBufferSize ||
(SizedToVisibleBounds != aPolicy &&
aVisibleBoundsSize < aBufferSize));
if (mBuffer) {
return ContentForFormat(mBuffer->GetFormat());
}
return gfxContentType::SENTINEL;
}
RefPtr<RotatedBuffer>
ContentClient::GetFrontBuffer() const
bool
ContentClient::BufferSizeOkFor(const IntSize& aSize)
{
return mBuffer;
MOZ_ASSERT(mBuffer);
return (aSize == mBuffer->BufferRect().Size() ||
(SizedToVisibleBounds != mBufferSizePolicy &&
aSize < mBuffer->BufferRect().Size()));
}
void
@@ -915,18 +841,32 @@ ContentClient::PaintState
ContentClientDoubleBuffered::BeginPaint(PaintedLayer* aLayer,
uint32_t aFlags)
{
EnsureBackBufferIfFrontBuffer();
mIsNewBuffer = false;
if (!mFrontBuffer || !mBuffer) {
mFrontAndBackBufferDiffer = false;
}
return ContentClient::BeginPaint(aLayer, aFlags);
}
if (mFrontAndBackBufferDiffer) {
if (mFrontBuffer->DidSelfCopy()) {
// We can't easily draw our front buffer into us, since we're going to be
// copying stuff around anyway it's easiest if we just move our situation
// to non-rotated while we're at it. If this situation occurs we'll have
// hit a self-copy path in PaintThebes before as well anyway.
gfx::IntRect backBufferRect = mBuffer->BufferRect();
backBufferRect.MoveTo(mFrontBuffer->BufferRect().TopLeft());
RefPtr<RotatedBuffer>
ContentClientDoubleBuffered::GetFrontBuffer() const
{
return mFrontBuffer;
mBuffer->SetBufferRect(backBufferRect);
mBuffer->SetBufferRotation(IntPoint(0,0));
} else {
mBuffer->SetBufferRect(mFrontBuffer->BufferRect());
mBuffer->SetBufferRotation(mFrontBuffer->BufferRotation());
}
}
return ContentClient::BeginPaint(aLayer, aFlags);
}
// Sync front/back buffers content
@@ -934,17 +874,14 @@ ContentClientDoubleBuffered::GetFrontBuffer() const
// the new front buffer, and mValidRegion et al. are correct wrt the new
// back buffer (i.e. as they were for the old back buffer)
void
ContentClientDoubleBuffered::FinalizeFrame(const nsIntRegion& aRegionToDraw,
CapturedBufferState* aPrepareState)
ContentClientDoubleBuffered::FinalizeFrame(const nsIntRegion& aRegionToDraw)
{
if (!mFrontAndBackBufferDiffer) {
MOZ_ASSERT(!mFrontBuffer || !mFrontBuffer->DidSelfCopy(),
"If the front buffer did a self copy then our front and back buffer must be different.");
MOZ_ASSERT(!mFrontBuffer->DidSelfCopy(), "If we have to copy the world, then our buffers are different, right?");
return;
}
MOZ_ASSERT(mFrontBuffer && mBuffer);
if (!mFrontBuffer || !mBuffer) {
MOZ_ASSERT(mFrontBuffer);
if (!mFrontBuffer) {
return;
}
@@ -957,20 +894,8 @@ ContentClientDoubleBuffered::FinalizeFrame(const nsIntRegion& aRegionToDraw,
mFrontAndBackBufferDiffer = false;
// Move the back buffer rect and rotation to the front buffer rect and rotation
// so that we can update the pixels that changed between frames
gfx::IntRect backBufferRect = mBuffer->BufferRect();
backBufferRect.MoveTo(mFrontBuffer->BufferRect().TopLeft());
mBuffer->SetBufferRect(backBufferRect);
mBuffer->SetBufferRotation(mFrontBuffer->BufferRotation());
// Calculate the region to update
nsIntRegion updateRegion = mFrontUpdatedRegion;
if (mFrontBuffer->DidSelfCopy()) {
// If we did an unrotate operation on the front buffer we might as well
// unrotate as well because we will be reading back the whole front buffer
mBuffer->SetBufferRotation(IntPoint(0,0));
mFrontBuffer->ClearDidSelfCopy();
updateRegion = mBuffer->BufferRect();
}
@@ -982,12 +907,25 @@ ContentClientDoubleBuffered::FinalizeFrame(const nsIntRegion& aRegionToDraw,
return;
}
MOZ_ASSERT(!aPrepareState->mBufferCopy);
aPrepareState->mBufferCopy = Some(CapturedBufferState::Copy {
mFrontBuffer->ShallowCopy(),
mBuffer->ShallowCopy(),
updateRegion.GetBounds(),
});
if (!mBuffer) {
return;
}
if (mFrontBuffer->Lock(OpenMode::OPEN_READ_ONLY)) {
mBuffer->UpdateDestinationFrom(*mFrontBuffer, updateRegion.GetBounds());
mFrontBuffer->Unlock();
}
}
void
ContentClientDoubleBuffered::EnsureBackBufferIfFrontBuffer()
{
if (!mBuffer && mFrontBuffer) {
mBuffer = CreateBufferInternal(mFrontBuffer->BufferRect(),
mFrontBuffer->GetFormat(),
mTextureFlags);
MOZ_ASSERT(mBuffer);
}
}
} // namespace layers