author | Chris Jones <jones.chris.g@gmail.com> |
Tue, 14 Sep 2010 00:23:08 -0500 | |
changeset 54100 | 324632361f18ce038234184757d878b5fe21f550 |
parent 54099 | 16b228558c58fd66ee3bfb95821f9fa92e204feb |
child 54101 | 5004f6392fb29c0a3a3a54d4b2ffc7ac5bbec4bf |
push id | 15768 |
push user | dougt@mozilla.com |
push date | Thu, 16 Sep 2010 01:40:23 +0000 |
treeherder | mozilla-central@cdb90b48f19f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | roc |
bugs | 570625 |
milestone | 2.0b6pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/layers/ThebesLayerBuffer.cpp +++ b/gfx/layers/ThebesLayerBuffer.cpp @@ -173,22 +173,23 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye Clear(); } if (result.mRegionToDraw.IsEmpty()) return result; nsIntRect drawBounds = result.mRegionToDraw.GetBounds(); nsIntRect visibleBounds = aLayer->GetVisibleRegion().GetBounds(); - nsIntSize scaledBufferSize = ScaledSize(visibleBounds.Size(), - aXResolution, aYResolution); + nsIntSize destBufferDims = ScaledSize(visibleBounds.Size(), + aXResolution, aYResolution); nsRefPtr<gfxASurface> destBuffer; nsIntRect destBufferRect; + PRBool bufferDimsChanged = PR_FALSE; - if (BufferSizeOkFor(scaledBufferSize)) { + if (BufferSizeOkFor(destBufferDims)) { NS_ASSERTION(curXRes == aXResolution && curYRes == aYResolution, "resolution changes must Clear()!"); // The current buffer is big enough to hold the visible area. if (mBufferRect.Contains(visibleBounds)) { // We don't need to adjust mBufferRect. destBufferRect = mBufferRect; } else { @@ -214,19 +215,20 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye // The stuff we need to redraw will wrap around an edge of the // buffer, so we will need to do a self-copy if (mBufferRotation == nsIntPoint(0,0)) { destBuffer = mBuffer; } else { // We can't do a real self-copy because the buffer is rotated. // So allocate a new buffer for the destination. destBufferRect = visibleBounds; - destBuffer = CreateBuffer(aContentType, - ScaledSize(destBufferRect.Size(), - aXResolution, aYResolution)); + destBufferDims = ScaledSize(destBufferRect.Size(), + aXResolution, aYResolution); + bufferDimsChanged = PR_TRUE; + destBuffer = CreateBuffer(aContentType, destBufferDims); if (!destBuffer) return result; } } else { mBufferRect = destBufferRect; mBufferRotation = newRotation; } } else { @@ -234,19 +236,20 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye // will be redrawn, so we don't need to copy anything, so we don't // set destBuffer. mBufferRect = destBufferRect; mBufferRotation = nsIntPoint(0,0); } } else { // The buffer's not big enough, so allocate a new one destBufferRect = visibleBounds; - destBuffer = CreateBuffer(aContentType, - ScaledSize(destBufferRect.Size(), - aXResolution, aYResolution)); + destBufferDims = ScaledSize(destBufferRect.Size(), + aXResolution, aYResolution); + bufferDimsChanged = PR_TRUE; + destBuffer = CreateBuffer(aContentType, destBufferDims); if (!destBuffer) return result; } // If we have no buffered data already, then destBuffer will be a fresh buffer // and we do not need to clear it below. PRBool isClear = mBuffer == nsnull; @@ -262,16 +265,19 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye "resolution changes must Clear()!"); DrawBufferWithRotation(tmpCtx, 1.0, aXResolution, aYResolution); } mBuffer = destBuffer.forget(); mBufferRect = destBufferRect; mBufferRotation = nsIntPoint(0,0); } + if (bufferDimsChanged) { + mBufferDims = destBufferDims; + } nsIntRegion invalidate; invalidate.Sub(aLayer->GetValidRegion(), destBufferRect); result.mRegionToInvalidate.Or(result.mRegionToInvalidate, invalidate); result.mContext = new gfxContext(mBuffer); // Figure out which quadrant to draw in
--- a/gfx/layers/ThebesLayerBuffer.h +++ b/gfx/layers/ThebesLayerBuffer.h @@ -77,33 +77,35 @@ public: * fit visible bounds. May be larger. */ enum BufferSizePolicy { SizedToVisibleBounds, ContainsVisibleBounds }; ThebesLayerBuffer(BufferSizePolicy aBufferSizePolicy) - : mBufferRotation(0,0) + : mBufferDims(0,0) + , mBufferRotation(0,0) , mBufferSizePolicy(aBufferSizePolicy) { MOZ_COUNT_CTOR(ThebesLayerBuffer); } virtual ~ThebesLayerBuffer() { MOZ_COUNT_DTOR(ThebesLayerBuffer); } /** * Wipe out all retained contents. Call this when the entire * buffer becomes invalid. */ void Clear() { mBuffer = nsnull; + mBufferDims.SizeTo(0, 0); mBufferRect.Empty(); } /** * This is returned by BeginPaint. The caller should draw into mContext. * mRegionToDraw must be drawn. mRegionToInvalidate has been invalidated * by ThebesLayerBuffer and must be redrawn on the screen. * mRegionToInvalidate is set when the buffer has changed from @@ -152,35 +154,42 @@ protected: float aOpacity, float aXRes, float aYRes); void DrawBufferWithRotation(gfxContext* aTarget, float aOpacity, float aXRes, float aYRes); const nsIntRect& BufferRect() const { return mBufferRect; } const nsIntPoint& BufferRotation() const { return mBufferRotation; } already_AddRefed<gfxASurface> - SetBuffer(gfxASurface* aBuffer, + SetBuffer(gfxASurface* aBuffer, const nsIntSize& aBufferDims, const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation) { nsRefPtr<gfxASurface> tmp = mBuffer.forget(); mBuffer = aBuffer; + mBufferDims = aBufferDims; mBufferRect = aBufferRect; mBufferRotation = aBufferRotation; return tmp.forget(); } private: PRBool BufferSizeOkFor(const nsIntSize& aSize) { - return (aSize == mBufferRect.Size() || + return (aSize == mBufferDims || (SizedToVisibleBounds != mBufferSizePolicy && - aSize < mBufferRect.Size())); + aSize < mBufferDims)); } nsRefPtr<gfxASurface> mBuffer; + /** + * The actual dimensions of mBuffer. For the ContainsVisibleBounds + * policy or with resolution-scaled drawing, mBufferDims might be + * different than mBufferRect.Size(). + */ + nsIntSize mBufferDims; /** The area of the ThebesLayer that is covered by the buffer as a whole */ nsIntRect mBufferRect; /** * The x and y rotation of the buffer. Conceptually the buffer * has its origin translated to mBufferRect.TopLeft() - mBufferRotation, * is tiled to fill the plane, and the result is clipped to mBufferRect. * So the pixel at mBufferRotation within the buffer is what gets painted at * mBufferRect.TopLeft().
--- a/gfx/layers/basic/BasicLayers.cpp +++ b/gfx/layers/basic/BasicLayers.cpp @@ -1659,21 +1659,22 @@ public: } ~ShadowThebesLayerBuffer() { MOZ_COUNT_DTOR(ShadowThebesLayerBuffer); } already_AddRefed<gfxSharedImageSurface> - Swap(gfxSharedImageSurface* aNewFrontBuffer, + Swap(gfxSharedImageSurface* aNewFrontBuffer, const nsIntSize& aBufferDims, const nsIntRect& aBufferRect, const nsIntPoint& aRotation=nsIntPoint(0, 0)) { nsRefPtr<gfxASurface> newBackBuffer = SetBuffer(aNewFrontBuffer, + aBufferDims, aBufferRect, aRotation); return static_cast<gfxSharedImageSurface*>(newBackBuffer.forget().get()); } protected: virtual already_AddRefed<gfxASurface> CreateBuffer(ContentType aType, const nsIntSize& aSize) { @@ -1703,23 +1704,25 @@ public: ShadowThebesLayer::Disconnect(); } virtual already_AddRefed<gfxSharedImageSurface> Swap(gfxSharedImageSurface* aNewFront, const nsIntRect& aBufferRect, const nsIntPoint& aRotation) { - return mFrontBuffer.Swap(aNewFront, aBufferRect, aRotation); + gfxIntSize size = aNewFront->GetSize(); + return mFrontBuffer.Swap(aNewFront, nsIntSize(size.width, size.height), + aBufferRect, aRotation); } virtual void DestroyFrontBuffer() { nsRefPtr<gfxSharedImageSurface> frontBuffer = - mFrontBuffer.Swap(0, nsIntRect()); + mFrontBuffer.Swap(0, nsIntSize(), nsIntRect()); if (frontBuffer) { BasicManager()->ShadowLayerManager::DestroySharedSurface(frontBuffer); } } virtual void Paint(gfxContext* aContext, LayerManager::DrawThebesLayerCallback aCallback, void* aCallbackData,