Bug 640444: Self-copies end up changing all buffer content, so we need to read back the entire buffer after swapping. r=Bas a=b

This commit is contained in:
Chris Jones 2011-03-11 23:22:39 -06:00
Родитель 0f1e24c309
Коммит 8617d00c98
3 изменённых файлов: 15 добавлений и 2 удалений

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

@ -222,6 +222,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
PRUint32 aFlags) PRUint32 aFlags)
{ {
PaintState result; PaintState result;
result.mDidSelfCopy = PR_FALSE;
float curXRes = aLayer->GetXResolution(); float curXRes = aLayer->GetXResolution();
float curYRes = aLayer->GetYResolution(); float curYRes = aLayer->GetYResolution();
@ -336,6 +337,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
nsIntRect srcRect(nsIntPoint(0, 0), mBufferRect.Size()); nsIntRect srcRect(nsIntPoint(0, 0), mBufferRect.Size());
nsIntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft(); nsIntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft();
MovePixels(mBuffer, srcRect, dest, curXRes, curYRes); MovePixels(mBuffer, srcRect, dest, curXRes, curYRes);
result.mDidSelfCopy = PR_TRUE;
// Don't set destBuffer; we special-case self-copies, and // Don't set destBuffer; we special-case self-copies, and
// just did the necessary work above. // just did the necessary work above.
mBufferRect = destBufferRect; mBufferRect = destBufferRect;

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

@ -110,12 +110,14 @@ public:
* by ThebesLayerBuffer and must be redrawn on the screen. * by ThebesLayerBuffer and must be redrawn on the screen.
* mRegionToInvalidate is set when the buffer has changed from * mRegionToInvalidate is set when the buffer has changed from
* opaque to transparent or vice versa, since the details of rendering can * opaque to transparent or vice versa, since the details of rendering can
* depend on the buffer type. * depend on the buffer type. mDidSelfCopy is true if we kept our buffer
* but used MovePixels() to shift its content.
*/ */
struct PaintState { struct PaintState {
nsRefPtr<gfxContext> mContext; nsRefPtr<gfxContext> mContext;
nsIntRegion mRegionToDraw; nsIntRegion mRegionToDraw;
nsIntRegion mRegionToInvalidate; nsIntRegion mRegionToInvalidate;
PRPackedBool mDidSelfCopy;
}; };
enum { enum {

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

@ -428,6 +428,7 @@ protected:
const nsIntRegion& aRegionToDraw, const nsIntRegion& aRegionToDraw,
const nsIntRegion& aExtendedRegionToDraw, const nsIntRegion& aExtendedRegionToDraw,
const nsIntRegion& aRegionToInvalidate, const nsIntRegion& aRegionToInvalidate,
PRBool aDidSelfCopy,
LayerManager::DrawThebesLayerCallback aCallback, LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData) void* aCallbackData)
{ {
@ -608,6 +609,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
SetAntialiasingFlags(this, state.mContext); SetAntialiasingFlags(this, state.mContext);
PaintBuffer(state.mContext, PaintBuffer(state.mContext,
state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate, state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
state.mDidSelfCopy,
aCallback, aCallbackData); aCallback, aCallbackData);
Mutated(); Mutated();
} else { } else {
@ -1800,6 +1802,7 @@ private:
const nsIntRegion& aRegionToDraw, const nsIntRegion& aRegionToDraw,
const nsIntRegion& aExtendedRegionToDraw, const nsIntRegion& aExtendedRegionToDraw,
const nsIntRegion& aRegionToInvalidate, const nsIntRegion& aRegionToInvalidate,
PRBool aDidSelfCopy,
LayerManager::DrawThebesLayerCallback aCallback, LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData); void* aCallbackData);
@ -1860,21 +1863,27 @@ BasicShadowableThebesLayer::PaintBuffer(gfxContext* aContext,
const nsIntRegion& aRegionToDraw, const nsIntRegion& aRegionToDraw,
const nsIntRegion& aExtendedRegionToDraw, const nsIntRegion& aExtendedRegionToDraw,
const nsIntRegion& aRegionToInvalidate, const nsIntRegion& aRegionToInvalidate,
PRBool aDidSelfCopy,
LayerManager::DrawThebesLayerCallback aCallback, LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData) void* aCallbackData)
{ {
Base::PaintBuffer(aContext, Base::PaintBuffer(aContext,
aRegionToDraw, aExtendedRegionToDraw, aRegionToInvalidate, aRegionToDraw, aExtendedRegionToDraw, aRegionToInvalidate,
aDidSelfCopy,
aCallback, aCallbackData); aCallback, aCallbackData);
if (!HasShadow()) { if (!HasShadow()) {
return; return;
} }
nsIntRegion updatedRegion; nsIntRegion updatedRegion;
if (mIsNewBuffer) { if (mIsNewBuffer || aDidSelfCopy) {
// A buffer reallocation clears both buffers. The front buffer has all the // A buffer reallocation clears both buffers. The front buffer has all the
// content by now, but the back buffer is still clear. Here, in effect, we // content by now, but the back buffer is still clear. Here, in effect, we
// are saying to copy all of the pixels of the front buffer to the back. // are saying to copy all of the pixels of the front buffer to the back.
// Also when we self-copied in the buffer, the buffer space
// changes and some changed buffer content isn't reflected in the
// draw or invalidate region (on purpose!). When this happens, we
// need to read back the entire buffer too.
updatedRegion = mVisibleRegion; updatedRegion = mVisibleRegion;
mIsNewBuffer = false; mIsNewBuffer = false;
} else { } else {