From b01db32e07d7f19cd3a7219ec39ba26893057d26 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Wed, 15 Feb 2012 16:03:05 -0500 Subject: [PATCH] Bug 725209 - Mark TextureImage as valid when self copying, and correctly mark the region needing to be redrawn. r=joe --- gfx/gl/GLContext.h | 8 ++++++++ gfx/layers/opengl/ThebesLayerOGL.cpp | 29 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 0fa1da06e326..38bf03944a13 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -247,6 +247,12 @@ public: EndUpdate(); } + /** + * Mark this texture as having valid contents. Call this after modifying + * the texture contents externally. + */ + virtual void MarkValid() {} + /** * aSurf - the source surface to update from * aRegion - the region in this image to update @@ -392,6 +398,8 @@ public: virtual already_AddRefed GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt); + virtual void MarkValid() { mTextureState = Valid; } + // Call when drawing into the update surface is complete. // Returns true if textures should be upload with a relative // offset - See UploadSurfaceToTexture. diff --git a/gfx/layers/opengl/ThebesLayerOGL.cpp b/gfx/layers/opengl/ThebesLayerOGL.cpp index 7e6889ed27bb..76801f6513c5 100644 --- a/gfx/layers/opengl/ThebesLayerOGL.cpp +++ b/gfx/layers/opengl/ThebesLayerOGL.cpp @@ -591,15 +591,44 @@ BasicBufferOGL::BeginPaint(ContentType aContentType, nsIntRect srcRect(overlap), dstRect(overlap); srcRect.MoveBy(- mBufferRect.TopLeft() + mBufferRotation); dstRect.MoveBy(- destBufferRect.TopLeft()); + + if (mBufferRotation != nsIntPoint(0, 0)) { + // If mBuffer is rotated, then BlitTextureImage will only be copying the bottom-right section + // of the buffer. We need to invalidate the remaining sections so that they get redrawn too. + // Alternatively we could teach BlitTextureImage to rearrange the rotated segments onto + // the new buffer. + + // When the rotated buffer is reorganised, the bottom-right section will be drawn in the top left. + // Find the point where this content ends. + nsIntPoint rotationPoint(mBufferRect.x + mBufferRect.width - mBufferRotation.x, + mBufferRect.y + mBufferRect.height - mBufferRotation.y); + + // Mark the remaining quadrants (bottom-left&right, top-right) as invalid. + nsIntRect bottom(mBufferRect.x, rotationPoint.y, mBufferRect.width, mBufferRotation.y); + nsIntRect topright(rotationPoint.x, mBufferRect.y, mBufferRotation.x, rotationPoint.y - mBufferRect.y); + + if (!bottom.IsEmpty()) { + nsIntRegion temp; + temp.And(destBufferRect, bottom); + result.mRegionToDraw.Or(result.mRegionToDraw, temp); + } + if (!topright.IsEmpty()) { + nsIntRegion temp; + temp.And(destBufferRect, topright); + result.mRegionToDraw.Or(result.mRegionToDraw, temp); + } + } destBuffer->Resize(destBufferRect.Size()); gl()->BlitTextureImage(mTexImage, srcRect, destBuffer, dstRect); + destBuffer->MarkValid(); if (mode == Layer::SURFACE_COMPONENT_ALPHA) { destBufferOnWhite->Resize(destBufferRect.Size()); gl()->BlitTextureImage(mTexImageOnWhite, srcRect, destBufferOnWhite, dstRect); + destBufferOnWhite->MarkValid(); } } else { // can't blit, just draw everything