author | Chris Jones <jones.chris.g@gmail.com> |
Fri, 05 Nov 2010 02:17:07 -0500 | |
changeset 56899 | bffc3f0cf9499b91e1fb4db27e7f23abfb9c1e2b |
parent 56898 | dc526c0277432c0f597fd56273aad35290d771c6 |
child 56900 | 4f4736cb9e70d54254a16582f8140bea2ce2cd2f |
push id | 16725 |
push user | cjones@mozilla.com |
push date | Fri, 05 Nov 2010 07:21:46 +0000 |
treeherder | mozilla-central@0aa98eae87ed [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | roc, vlad |
bugs | 603885 |
milestone | 2.0b8pre |
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/basic/BasicLayers.cpp +++ b/gfx/layers/basic/BasicLayers.cpp @@ -1400,17 +1400,19 @@ public: virtual Layer* AsLayer() { return this; } virtual ShadowableLayer* AsShadowableLayer() { return this; } virtual bool MustRetainContent() { return HasShadow(); } virtual PRBool SupportsSurfaceDescriptor() const { return PR_TRUE; } void SetBackBufferAndAttrs(const ThebesBuffer& aBuffer, const nsIntRegion& aValidRegion, - float aXResolution, float aYResolution); + float aXResolution, float aYResolution, + const OptionalThebesBuffer& aReadOnlyFrontBuffer, + const nsIntRegion& aFrontUpdatedRegion); virtual void Disconnect() { mBackBuffer = SurfaceDescriptor(); BasicShadowableLayer::Disconnect(); } virtual BasicShadowableThebesLayer* AsThebes() { return this; } @@ -1441,25 +1443,34 @@ private: SurfaceDescriptor mNewFrontBuffer; nsIntSize mBufferSize; }; void BasicShadowableThebesLayer::SetBackBufferAndAttrs(const ThebesBuffer& aBuffer, const nsIntRegion& aValidRegion, float aXResolution, - float aYResolution); + float aYResolution, + const OptionalThebesBuffer& aReadOnlyFrontBuffer, + const nsIntRegion& aFrontUpdatedRegion) { mBackBuffer = aBuffer.buffer(); - mValidRegion = aValidRegion; - mXResolution = aXResolution; - mYResolution = aYResolution; + nsRefPtr<gfxASurface> backBuffer = BasicManager()->OpenDescriptor(mBackBuffer); - nsRefPtr<gfxASurface> backBuffer = BasicManager()->OpenDescriptor(mBackBuffer); - mBuffer.SetBackingBuffer(backBuffer, aBuffer.rect(), aBuffer.rotation()); + if (OptionalThebesBuffer::Tnull_t == aReadOnlyFrontBuffer.type()) { + // We didn't get back a read-only ref to our old back buffer (the + // parent's new front buffer). If the parent is pushing updates + // to a texture it owns, then we probably got back the same buffer + // we pushed in the update and all is well. If not, ... + mValidRegion = aValidRegion; + mXResolution = aXResolution; + mYResolution = aYResolution; + mBuffer.SetBackingBuffer(backBuffer, aBuffer.rect(), aBuffer.rotation()); + return; + } } void BasicShadowableThebesLayer::PaintBuffer(gfxContext* aContext, const nsIntRegion& aRegionToDraw, const nsIntRegion& aRegionToInvalidate, LayerManager::DrawThebesLayerCallback aCallback, void* aCallbackData) @@ -1840,17 +1851,18 @@ public: { DestroyFrontBuffer(); ShadowThebesLayer::Disconnect(); } virtual void Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion, ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, - float* aNewXResolution, float* aNewYResolution); + float* aNewXResolution, float* aNewYResolution, + OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion); virtual void DestroyFrontBuffer() { mFrontBuffer.Clear(); mValidRegion.SetEmpty(); mOldValidRegion.SetEmpty(); mOldXResolution = 1.0; mOldYResolution = 1.0; @@ -1902,17 +1914,19 @@ BasicShadowThebesLayer::SetFrontBuffer(c mFrontBufferDescriptor = aNewFront.buffer(); } void BasicShadowThebesLayer::Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion, ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, - float* aNewXResolution, float* aNewYResolution) + float* aNewXResolution, float* aNewYResolution, + OptionalThebesBuffer* aReadOnlyFront, + nsIntRegion* aFrontUpdatedRegion) { // This code relies on Swap() arriving *after* attribute mutations. aNewBack->buffer() = mFrontBufferDescriptor; // We have to invalidate the pixels painted into the new buffer. // They might overlap with our old pixels. if (mOldXResolution == mXResolution && mOldYResolution == mYResolution) { aNewBackValidRegion->Sub(mOldValidRegion, aUpdatedRegion); } else { @@ -1937,16 +1951,19 @@ BasicShadowThebesLayer::Swap(const Thebe BasicManager()->OpenDescriptor(aNewFront.buffer()); nsRefPtr<gfxASurface> unused; mFrontBuffer.Swap( newFrontBuffer, aNewFront.rect(), aNewFront.rotation(), getter_AddRefs(unused), &aNewBack->rect(), &aNewBack->rotation()); mFrontBufferDescriptor = aNewFront.buffer(); + + *aReadOnlyFront = null_t(); + aFrontUpdatedRegion->SetEmpty(); } void BasicShadowThebesLayer::Paint(gfxContext* aContext, LayerManager::DrawThebesLayerCallback aCallback, void* aCallbackData, float aOpacity) { @@ -2368,17 +2385,18 @@ BasicShadowLayerManager::EndTransaction( switch (reply.type()) { case EditReply::TOpThebesBufferSwap: { MOZ_LAYERS_LOG(("[LayersForwarder] ThebesBufferSwap")); const OpThebesBufferSwap& obs = reply.get_OpThebesBufferSwap(); BasicShadowableThebesLayer* thebes = GetBasicShadowable(obs)->AsThebes(); thebes->SetBackBufferAndAttrs( obs.newBackBuffer(), - obs.newValidRegion(), obs.newXResolution(), obs.newYResolution()); + obs.newValidRegion(), obs.newXResolution(), obs.newYResolution(), + obs.readOnlyFrontBuffer(), obs.frontUpdatedRegion()); break; } case EditReply::TOpBufferSwap: { MOZ_LAYERS_LOG(("[LayersForwarder] BufferSwap")); const OpBufferSwap& obs = reply.get_OpBufferSwap(); const SurfaceDescriptor& descr = obs.newBackBuffer(); BasicShadowableLayer* layer = GetBasicShadowable(obs);
--- a/gfx/layers/ipc/PLayers.ipdl +++ b/gfx/layers/ipc/PLayers.ipdl @@ -82,16 +82,17 @@ union SurfaceDescriptor { SurfaceDescriptorX11; }; struct ThebesBuffer { SurfaceDescriptor buffer; nsIntRect rect; nsIntPoint rotation; }; +union OptionalThebesBuffer { ThebesBuffer; null_t; }; struct OpCreateThebesBuffer { PLayer layer; ThebesBuffer initialFront; nsIntRegion frontValidRegion; float xResolution; float yResolution; }; @@ -209,16 +210,24 @@ union Edit { struct OpBufferSwap { PLayer layer; SurfaceDescriptor newBackBuffer; }; struct OpThebesBufferSwap { PLayer layer; ThebesBuffer newBackBuffer; nsIntRegion newValidRegion; float newXResolution; float newYResolution; + // If the parent took the child's old back buffer and returned its + // old front buffer, |readOnlyFrontBuffer| may (if non-null) contain + // the child's old back buffer (parent's new front buffer). This + // buffer can be used to read back the newly updated region into the + // child's new back buffer. This buffer must be considered + // read-only, but sadly that's not enforced. + OptionalThebesBuffer readOnlyFrontBuffer; + nsIntRegion frontUpdatedRegion; }; // Unit of a "changeset reply". This is a weird abstraction, probably // only to be used for buffer swapping. union EditReply { OpBufferSwap; OpThebesBufferSwap; };
--- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -48,16 +48,17 @@ class gfxSharedImageSurface; namespace mozilla { namespace layers { struct Edit; struct EditReply; +class OptionalThebesBuffer; class PLayerChild; class PLayersChild; class PLayersParent; class ShadowableLayer; class ShadowThebesLayer; class ShadowContainerLayer; class ShadowImageLayer; class ShadowColorLayer; @@ -500,17 +501,18 @@ public: * * Publish the remote layer's back ThebesLayerBuffer to this shadow, * swapping out the old front ThebesLayerBuffer (the new back buffer * for the remote layer). */ virtual void Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion, ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, - float* aNewXResolution, float* aNewYResolution) = 0; + float* aNewXResolution, float* aNewYResolution, + OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion) = 0; /** * CONSTRUCTION PHASE ONLY * * Destroy the current front buffer. */ virtual void DestroyFrontBuffer() = 0;
--- a/gfx/layers/ipc/ShadowLayersParent.cpp +++ b/gfx/layers/ipc/ShadowLayersParent.cpp @@ -371,22 +371,26 @@ ShadowLayersParent::RecvUpdate(const nsT ShadowLayerParent* shadow = AsShadowLayer(op); ShadowThebesLayer* thebes = static_cast<ShadowThebesLayer*>(shadow->AsLayer()); const ThebesBuffer& newFront = op.newFrontBuffer(); ThebesBuffer newBack; nsIntRegion newValidRegion; float newXResolution, newYResolution; + OptionalThebesBuffer readonlyFront; + nsIntRegion frontUpdatedRegion; thebes->Swap(newFront, op.updatedRegion(), - &newBack, &newValidRegion, &newXResolution, &newYResolution); + &newBack, &newValidRegion, &newXResolution, &newYResolution, + &readonlyFront, &frontUpdatedRegion); replyv.push_back( OpThebesBufferSwap( shadow, NULL, - newBack, newValidRegion, newXResolution, newYResolution)); + newBack, newValidRegion, newXResolution, newYResolution, + readonlyFront, frontUpdatedRegion)); break; } case Edit::TOpPaintCanvas: { MOZ_LAYERS_LOG(("[ParentSide] Paint CanvasLayer")); const OpPaintCanvas& op = edit.get_OpPaintCanvas(); ShadowLayerParent* shadow = AsShadowLayer(op); ShadowCanvasLayer* canvas =
--- a/gfx/layers/opengl/ThebesLayerOGL.cpp +++ b/gfx/layers/opengl/ThebesLayerOGL.cpp @@ -645,27 +645,31 @@ ShadowThebesLayerOGL::SetFrontBuffer(con mDeadweight = aNewFront.buffer(); } void ShadowThebesLayerOGL::Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion, ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, - float* aNewXResolution, float* aNewYResolution) + float* aNewXResolution, float* aNewYResolution, + OptionalThebesBuffer* aReadOnlyFront, + nsIntRegion* aFrontUpdatedRegion) { if (!mDestroyed && mBuffer) { nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront.buffer()); mBuffer->Upload(surf, aUpdatedRegion, aNewFront.rect(), aNewFront.rotation()); } *aNewBack = aNewFront; *aNewBackValidRegion = mValidRegion; *aNewXResolution = 1.0; *aNewYResolution = 1.0; + *aReadOnlyFront = null_t(); + aFrontUpdatedRegion->SetEmpty(); } void ShadowThebesLayerOGL::DestroyFrontBuffer() { mBuffer = nsnull; if (SurfaceDescriptor::T__None != mDeadweight.type()) { mOGLManager->DestroySharedSurface(&mDeadweight, mAllocator);
--- a/gfx/layers/opengl/ThebesLayerOGL.h +++ b/gfx/layers/opengl/ThebesLayerOGL.h @@ -96,17 +96,18 @@ public: // ShadowThebesLayer impl virtual void SetFrontBuffer(const ThebesBuffer& aNewFront, const nsIntRegion& aValidRegion, float aXResolution, float aYResolution); virtual void Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion, ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, - float* aNewXResolution, float* aNewYResolution); + float* aNewXResolution, float* aNewYResolution, + OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion); virtual void DestroyFrontBuffer(); // LayerOGL impl void Destroy(); Layer* GetLayer(); virtual PRBool IsEmpty(); virtual void RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset);