From 4c1166372f98119a449492f16f6ea62b89557c0a Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Mon, 19 Jul 2010 14:54:17 -0700 Subject: [PATCH] b=579696; BasicTextureImage doesn't handle partial updates properly; r=cjones --- gfx/layers/opengl/ThebesLayerOGL.cpp | 33 ++++++++++++++++++---------- gfx/thebes/GLContext.cpp | 14 ++++++++---- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/gfx/layers/opengl/ThebesLayerOGL.cpp b/gfx/layers/opengl/ThebesLayerOGL.cpp index c63607224f38..4fe59ec85586 100644 --- a/gfx/layers/opengl/ThebesLayerOGL.cpp +++ b/gfx/layers/opengl/ThebesLayerOGL.cpp @@ -142,25 +142,36 @@ ThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer, nsIntRegion rgnToPaint = mVisibleRegion; rgnToPaint.Sub(rgnToPaint, mValidRegion); PRBool textureBound = PR_FALSE; - if (!rgnToPaint.IsEmpty()) - { + if (!rgnToPaint.IsEmpty()) { nsIntRect visibleRect = mVisibleRegion.GetBounds(); - // translate repaint region to texture-buffer space - nsIntRegion bufRgnToPaint = rgnToPaint; - bufRgnToPaint.MoveBy(-visibleRect.x, -visibleRect.y); - nsRefPtr ctx = mTexImage->BeginUpdate(bufRgnToPaint); - if (!ctx) - { + + // Offset rgnToPaint by our visible region's origin, before + // passing to BeginUpdate. The TextureImage has no concept of an + // origin, only a size, so it always represents a 0,0 origin area. + // The layer however has a position, represented by its visible + // region. So we have to move things around so that we can + // interact with the TextureImage. + rgnToPaint.MoveBy(-visibleRect.TopLeft()); + + // BeginUpdate is allowed to modify the given region, + // if it wants more to be repainted than we request. + nsRefPtr ctx = mTexImage->BeginUpdate(rgnToPaint); + if (!ctx) { NS_WARNING("unable to get context for update"); return; } - // and translate update context back to screen space + + // Move rgnToPaint back into position so that the thebes callback + // gets the right coordintes. + rgnToPaint.MoveBy(visibleRect.TopLeft()); + + // Translate the context so that we're matching the layer's + // origin, not the 0,0-based TextureImage ctx->Translate(-gfxPoint(visibleRect.x, visibleRect.y)); TextureImage::ContentType contentType = mTexImage->GetContentType(); //ClipToRegion(ctx, rgnToDraw); - if (gfxASurface::CONTENT_COLOR_ALPHA == contentType) - { + if (gfxASurface::CONTENT_COLOR_ALPHA == contentType) { ctx->SetOperator(gfxContext::OPERATOR_CLEAR); ctx->Paint(); ctx->SetOperator(gfxContext::OPERATOR_OVER); diff --git a/gfx/thebes/GLContext.cpp b/gfx/thebes/GLContext.cpp index 4cf2f2e77c21..0a927a2a6123 100644 --- a/gfx/thebes/GLContext.cpp +++ b/gfx/thebes/GLContext.cpp @@ -413,8 +413,7 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion) aRegion = nsIntRegion(mUpdateRect); nsIntSize rgnSize = mUpdateRect.Size(); - if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(mUpdateRect)) - { + if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(mUpdateRect)) { NS_ERROR("update outside of image"); return NULL; } @@ -428,6 +427,8 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion) if (!updateSurface) return NULL; + updateSurface->SetDeviceOffset(gfxPoint(-mUpdateRect.x, -mUpdateRect.y)); + mUpdateContext = new gfxContext(updateSurface); return mUpdateContext; } @@ -438,8 +439,13 @@ BasicTextureImage::EndUpdate() NS_ASSERTION(!!mUpdateContext, "EndUpdate() without BeginUpdate()?"); // FIXME: this is the slow boat. Make me fast (with GLXPixmap?). - nsRefPtr uploadImage = - GetImageForUpload(mUpdateContext->OriginalSurface()); + nsRefPtr originalSurface = mUpdateContext->OriginalSurface(); + + // Undo the device offset that BeginUpdate set; doesn't much matter for us here, + // but important if we ever do anything directly with the surface. + originalSurface->SetDeviceOffset(gfxPoint(0, 0)); + + nsRefPtr uploadImage = GetImageForUpload(originalSurface); if (!uploadImage) return PR_FALSE;