Backed out 7 changesets (bug 1399692) failing on browser chrome browser/base/content/test/performance/browser_urlbar_search_reflows.js
Backed out changeset e9349ad2f1f8 (bug 1399692) Backed out changeset cb6507b560aa (bug 1399692) Backed out changeset 3d0da6564096 (bug 1399692) Backed out changeset 926af2eca400 (bug 1399692) Backed out changeset b57a3f0d0847 (bug 1399692) Backed out changeset 9fcb661df79e (bug 1399692) Backed out changeset 744c8fabaa1c (bug 1399692)
This commit is contained in:
@@ -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,89 +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;
|
||||
}
|
||||
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() << ", "
|
||||
@@ -244,37 +211,29 @@ 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()) {
|
||||
RefPtr<CapturedBufferState> bufferState = new CapturedBufferState();
|
||||
if (mBuffer) {
|
||||
newBuffer->UpdateDestinationFrom(*mBuffer, newBuffer->BufferRect());
|
||||
|
||||
bufferState->mBufferCopy = Some(CapturedBufferState::Copy {
|
||||
frontBuffer->ShallowCopy(),
|
||||
newBuffer->ShallowCopy(),
|
||||
newBuffer->BufferRect(),
|
||||
});
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// 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
|
||||
// as well as the old back buffer.
|
||||
Clear();
|
||||
|
||||
mBuffer = newBuffer;
|
||||
@@ -425,9 +384,7 @@ ContentClient::CalculateBufferForPaint(PaintedLayer* aLayer,
|
||||
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) {
|
||||
@@ -478,12 +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.
|
||||
RefPtr<RotatedBuffer> frontBuffer = GetFrontBuffer();
|
||||
bool needsComponentAlpha = (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA);
|
||||
bool changedSurfaceOrContent = frontBuffer &&
|
||||
(contentType != frontBuffer->GetContentType() ||
|
||||
needsComponentAlpha != frontBuffer->HaveBufferOnWhite());
|
||||
if (canKeepBufferContents && changedSurfaceOrContent) {
|
||||
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;
|
||||
@@ -509,20 +465,22 @@ ContentClient::CalculateBufferForPaint(PaintedLayer* aLayer,
|
||||
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
|
||||
@@ -883,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
|
||||
@@ -902,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;
|
||||
}
|
||||
|
||||
@@ -925,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(mBuffer->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();
|
||||
}
|
||||
@@ -950,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
|
||||
|
||||
Reference in New Issue
Block a user