Don't clear the rotated buffer if we incorrectly assume content will be COLOR_ALPHA. (bug 1126045 part 3, r=mattwoodrow)

This commit is contained in:
David Anderson 2015-01-28 15:34:45 -08:00
parent c8b457c9ab
commit 76432172d6

View File

@ -26,6 +26,7 @@
#include "mozilla/layers/TextureClient.h" // for TextureClient
#include "nsSize.h" // for nsIntSize
#include "gfx2DGlue.h"
#include "nsLayoutUtils.h" // for invalidation debugging
namespace mozilla {
@ -446,13 +447,14 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer,
SurfaceMode mode;
nsIntRegion neededRegion;
bool canReuseBuffer;
nsIntRect destBufferRect;
bool canReuseBuffer = HaveBuffer();
while (true) {
mode = aLayer->GetSurfaceMode();
neededRegion = aLayer->GetVisibleRegion();
canReuseBuffer = HaveBuffer() && BufferSizeOkFor(neededRegion.GetBounds().Size());
canReuseBuffer &= BufferSizeOkFor(neededRegion.GetBounds().Size());
result.mContentType = layerContentType;
if (canReuseBuffer) {
@ -488,37 +490,56 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer,
if ((aFlags & PAINT_WILL_RESAMPLE) &&
(!neededRegion.GetBounds().IsEqualInterior(destBufferRect) ||
neededRegion.GetNumRects() > 1)) {
// The area we add to neededRegion might not be painted opaquely
neededRegion.GetNumRects() > 1))
{
// The area we add to neededRegion might not be painted opaquely.
if (mode == SurfaceMode::SURFACE_OPAQUE) {
result.mContentType = gfxContentType::COLOR_ALPHA;
mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
}
// We need to validate the entire buffer, to make sure that only valid
// pixels are sampled
// pixels are sampled.
neededRegion = destBufferRect;
}
// 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.
if (HaveBuffer() &&
if (canReuseBuffer &&
(result.mContentType != BufferContentType() ||
(mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) != HaveBufferOnWhite())) {
// We're effectively clearing the valid region, so we need to draw
// the entire needed region now.
result.mRegionToInvalidate = aLayer->GetValidRegion();
validRegion.SetEmpty();
Clear();
// Restart decision process with the cleared buffer. We can only go
// around the loop one more iteration, since mDTBuffer is null now.
(mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) != HaveBufferOnWhite()))
{
// Restart the decision process; we won't re-enter since we guard on
// being able to re-use the buffer.
canReuseBuffer = false;
continue;
}
break;
}
if (HaveBuffer() &&
(result.mContentType != BufferContentType() ||
(mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) != HaveBufferOnWhite()))
{
// We're effectively clearing the valid region, so we need to draw
// the entire needed region now.
canReuseBuffer = false;
result.mRegionToInvalidate = aLayer->GetValidRegion();
validRegion.SetEmpty();
Clear();
#if defined(MOZ_DUMP_PAINTING)
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
if (result.mContentType != BufferContentType()) {
printf_stderr("Invalidating entire rotated buffer (layer %p): content type changed\n", aLayer);
} else if ((mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) != HaveBufferOnWhite()) {
printf_stderr("Invalidating entire rotated buffer (layer %p): component alpha changed\n", aLayer);
}
}
#endif
}
NS_ASSERTION(destBufferRect.Contains(neededRegion.GetBounds()),
"Destination rect doesn't contain what we need to paint");