Backed out changeset 703df62e855b due to crashes reported in bug 693086

This commit is contained in:
Brad Lassey 2011-10-10 11:00:16 -04:00
Родитель 0ee3091dc8
Коммит 1dbd9c50c8
12 изменённых файлов: 228 добавлений и 114 удалений

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

@ -532,9 +532,6 @@ public:
ThebesLayer::ComputeEffectiveTransforms(aTransformToSurface); ThebesLayer::ComputeEffectiveTransforms(aTransformToSurface);
} }
// Sync front/back buffers content
virtual void SyncFrontBufferToBackBuffer() {}
protected: protected:
BasicLayerManager* BasicManager() BasicLayerManager* BasicManager()
{ {
@ -659,7 +656,6 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
if (aReadback && UsedForReadback()) { if (aReadback && UsedForReadback()) {
aReadback->GetThebesLayerUpdates(this, &readbackUpdates); aReadback->GetThebesLayerUpdates(this, &readbackUpdates);
} }
SyncFrontBufferToBackBuffer();
bool canUseOpaqueSurface = CanUseOpaqueSurface(); bool canUseOpaqueSurface = CanUseOpaqueSurface();
Buffer::ContentType contentType = Buffer::ContentType contentType =
@ -2158,13 +2154,13 @@ public:
BasicShadowableThebesLayer(BasicShadowLayerManager* aManager) BasicShadowableThebesLayer(BasicShadowLayerManager* aManager)
: BasicThebesLayer(aManager) : BasicThebesLayer(aManager)
, mIsNewBuffer(false) , mIsNewBuffer(false)
, mFrontAndBackBufferDiffer(false)
{ {
MOZ_COUNT_CTOR(BasicShadowableThebesLayer); MOZ_COUNT_CTOR(BasicShadowableThebesLayer);
} }
virtual ~BasicShadowableThebesLayer() virtual ~BasicShadowableThebesLayer()
{ {
DestroyBackBuffer(); if (IsSurfaceDescriptorValid(mBackBuffer))
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer);
MOZ_COUNT_DTOR(BasicShadowableThebesLayer); MOZ_COUNT_DTOR(BasicShadowableThebesLayer);
} }
@ -2177,7 +2173,7 @@ public:
virtual ShadowableLayer* AsShadowableLayer() { return this; } virtual ShadowableLayer* AsShadowableLayer() { return this; }
virtual bool MustRetainContent() { return HasShadow(); } virtual bool MustRetainContent() { return HasShadow(); }
void SetBackBufferAndAttrs(const OptionalThebesBuffer& aBuffer, void SetBackBufferAndAttrs(const ThebesBuffer& aBuffer,
const nsIntRegion& aValidRegion, const nsIntRegion& aValidRegion,
const OptionalThebesBuffer& aReadOnlyFrontBuffer, const OptionalThebesBuffer& aReadOnlyFrontBuffer,
const nsIntRegion& aFrontUpdatedRegion); const nsIntRegion& aFrontUpdatedRegion);
@ -2190,8 +2186,6 @@ public:
virtual BasicShadowableThebesLayer* AsThebes() { return this; } virtual BasicShadowableThebesLayer* AsThebes() { return this; }
virtual void SyncFrontBufferToBackBuffer();
private: private:
BasicShadowLayerManager* BasicManager() BasicShadowLayerManager* BasicManager()
{ {
@ -2210,89 +2204,46 @@ private:
NS_OVERRIDE virtual already_AddRefed<gfxASurface> NS_OVERRIDE virtual already_AddRefed<gfxASurface>
CreateBuffer(Buffer::ContentType aType, const nsIntSize& aSize); CreateBuffer(Buffer::ContentType aType, const nsIntSize& aSize);
void DestroyBackBuffer()
{
if (IsSurfaceDescriptorValid(mBackBuffer)) {
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer);
}
}
// This describes the gfxASurface we hand to mBuffer. We keep a // This describes the gfxASurface we hand to mBuffer. We keep a
// copy of the descriptor here so that we can call // copy of the descriptor here so that we can call
// DestroySharedSurface() on the descriptor. // DestroySharedSurface() on the descriptor.
SurfaceDescriptor mBackBuffer; SurfaceDescriptor mBackBuffer;
nsIntRect mBackBufferRect;
nsIntPoint mBackBufferRectRotation;
bool mIsNewBuffer; bool mIsNewBuffer;
OptionalThebesBuffer mROFrontBuffer;
nsIntRegion mFrontUpdatedRegion;
nsIntRegion mFrontValidRegion;
PRPackedBool mFrontAndBackBufferDiffer;
}; };
void void
BasicShadowableThebesLayer::SetBackBufferAndAttrs(const OptionalThebesBuffer& aBuffer, BasicShadowableThebesLayer::SetBackBufferAndAttrs(const ThebesBuffer& aBuffer,
const nsIntRegion& aValidRegion, const nsIntRegion& aValidRegion,
const OptionalThebesBuffer& aReadOnlyFrontBuffer, const OptionalThebesBuffer& aReadOnlyFrontBuffer,
const nsIntRegion& aFrontUpdatedRegion) const nsIntRegion& aFrontUpdatedRegion)
{ {
if (OptionalThebesBuffer::Tnull_t == aBuffer.type()) { mBackBuffer = aBuffer.buffer();
mBackBuffer = SurfaceDescriptor(); nsRefPtr<gfxASurface> backBuffer = BasicManager()->OpenDescriptor(mBackBuffer);
} else {
mBackBuffer = aBuffer.get_ThebesBuffer().buffer();
mBackBufferRect = aBuffer.get_ThebesBuffer().rect();
mBackBufferRectRotation = aBuffer.get_ThebesBuffer().rotation();
}
mFrontAndBackBufferDiffer = true;
mROFrontBuffer = aReadOnlyFrontBuffer;
mFrontUpdatedRegion = aFrontUpdatedRegion;
mFrontValidRegion = aValidRegion;
}
void if (OptionalThebesBuffer::Tnull_t == aReadOnlyFrontBuffer.type()) {
BasicShadowableThebesLayer::SyncFrontBufferToBackBuffer()
{
if (!mFrontAndBackBufferDiffer) {
return;
}
nsRefPtr<gfxASurface> backBuffer;
if (!IsSurfaceDescriptorValid(mBackBuffer)) {
NS_ABORT_IF_FALSE(mROFrontBuffer.type() == OptionalThebesBuffer::TThebesBuffer,
"should have a front RO buffer by now");
const ThebesBuffer roFront = mROFrontBuffer.get_ThebesBuffer();
nsRefPtr<gfxASurface> roFrontBuffer = BasicManager()->OpenDescriptor(roFront.buffer());
backBuffer = CreateBuffer(roFrontBuffer->GetContentType(), roFrontBuffer->GetSize());
} else {
backBuffer = BasicManager()->OpenDescriptor(mBackBuffer);
}
mFrontAndBackBufferDiffer = false;
if (OptionalThebesBuffer::Tnull_t == mROFrontBuffer.type()) {
// We didn't get back a read-only ref to our old back buffer (the // 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 // parent's new front buffer). If the parent is pushing updates
// to a texture it owns, then we probably got back the same buffer // to a texture it owns, then we probably got back the same buffer
// we pushed in the update and all is well. If not, ... // we pushed in the update and all is well. If not, ...
mValidRegion = mFrontValidRegion; mValidRegion = aValidRegion;
mBuffer.SetBackingBuffer(backBuffer, mBackBufferRect, mBackBufferRectRotation); mBuffer.SetBackingBuffer(backBuffer, aBuffer.rect(), aBuffer.rotation());
return; return;
} }
MOZ_LAYERS_LOG(("BasicShadowableThebes(%p): reading back <x=%d,y=%d,w=%d,h=%d>", MOZ_LAYERS_LOG(("BasicShadowableThebes(%p): reading back <x=%d,y=%d,w=%d,h=%d>",
this, this,
mFrontUpdatedRegion.GetBounds().x, aFrontUpdatedRegion.GetBounds().x,
mFrontUpdatedRegion.GetBounds().y, aFrontUpdatedRegion.GetBounds().y,
mFrontUpdatedRegion.GetBounds().width, aFrontUpdatedRegion.GetBounds().width,
mFrontUpdatedRegion.GetBounds().height)); aFrontUpdatedRegion.GetBounds().height));
const ThebesBuffer roFront = mROFrontBuffer.get_ThebesBuffer(); const ThebesBuffer roFront = aReadOnlyFrontBuffer.get_ThebesBuffer();
nsRefPtr<gfxASurface> roFrontBuffer = BasicManager()->OpenDescriptor(roFront.buffer()); nsRefPtr<gfxASurface> roFrontBuffer = BasicManager()->OpenDescriptor(roFront.buffer());
mBuffer.SetBackingBufferAndUpdateFrom( mBuffer.SetBackingBufferAndUpdateFrom(
backBuffer, backBuffer,
roFrontBuffer, roFront.rect(), roFront.rotation(), roFrontBuffer, roFront.rect(), roFront.rotation(),
mFrontUpdatedRegion); aFrontUpdatedRegion);
mIsNewBuffer = false;
// Now the new back buffer has the same (interesting) pixels as the // Now the new back buffer has the same (interesting) pixels as the
// new front buffer, and mValidRegion et al. are correct wrt the new // new front buffer, and mValidRegion et al. are correct wrt the new
// back buffer (i.e. as they were for the old back buffer) // back buffer (i.e. as they were for the old back buffer)
@ -2354,21 +2305,36 @@ BasicShadowableThebesLayer::CreateBuffer(Buffer::ContentType aType,
aSize.width, aSize.height)); aSize.width, aSize.height));
if (IsSurfaceDescriptorValid(mBackBuffer)) { if (IsSurfaceDescriptorValid(mBackBuffer)) {
BasicManager()->DestroyedThebesBuffer(BasicManager()->Hold(this),
mBackBuffer);
mBackBuffer = SurfaceDescriptor(); mBackBuffer = SurfaceDescriptor();
} }
// XXX error handling // XXX error handling
SurfaceDescriptor tmpFront;
if (BasicManager()->ShouldDoubleBuffer()) {
if (!BasicManager()->AllocDoubleBuffer(gfxIntSize(aSize.width, aSize.height),
aType,
&tmpFront,
&mBackBuffer)) {
NS_RUNTIMEABORT("creating ThebesLayer 'back buffer' failed!");
}
} else {
if (!BasicManager()->AllocBuffer(gfxIntSize(aSize.width, aSize.height), if (!BasicManager()->AllocBuffer(gfxIntSize(aSize.width, aSize.height),
aType, aType,
&mBackBuffer)) { &mBackBuffer)) {
NS_RUNTIMEABORT("creating ThebesLayer 'back buffer' failed!"); NS_RUNTIMEABORT("creating ThebesLayer 'back buffer' failed!");
} }
}
NS_ABORT_IF_FALSE(!mIsNewBuffer, NS_ABORT_IF_FALSE(!mIsNewBuffer,
"Bad! Did we create a buffer twice without painting?"); "Bad! Did we create a buffer twice without painting?");
mIsNewBuffer = true; mIsNewBuffer = true;
BasicManager()->CreatedThebesBuffer(BasicManager()->Hold(this),
nsIntRegion(),
nsIntRect(),
tmpFront);
return BasicManager()->OpenDescriptor(mBackBuffer); return BasicManager()->OpenDescriptor(mBackBuffer);
} }
@ -2715,6 +2681,9 @@ public:
MOZ_COUNT_DTOR(BasicShadowThebesLayer); MOZ_COUNT_DTOR(BasicShadowThebesLayer);
} }
virtual void SetFrontBuffer(const OptionalThebesBuffer& aNewFront,
const nsIntRegion& aValidRegion);
virtual void SetValidRegion(const nsIntRegion& aRegion) virtual void SetValidRegion(const nsIntRegion& aRegion)
{ {
mOldValidRegion = mValidRegion; mOldValidRegion = mValidRegion;
@ -2729,7 +2698,7 @@ public:
virtual void virtual void
Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion, Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion,
OptionalThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion,
OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion); OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion);
virtual void DestroyFrontBuffer() virtual void DestroyFrontBuffer()
@ -2740,7 +2709,6 @@ public:
if (IsSurfaceDescriptorValid(mFrontBufferDescriptor)) { if (IsSurfaceDescriptorValid(mFrontBufferDescriptor)) {
mAllocator->DestroySharedSurface(&mFrontBufferDescriptor); mAllocator->DestroySharedSurface(&mFrontBufferDescriptor);
mFrontBufferDescriptor = SurfaceDescriptor();
} }
} }
@ -2765,46 +2733,48 @@ private:
nsIntRegion mOldValidRegion; nsIntRegion mOldValidRegion;
}; };
void
BasicShadowThebesLayer::SetFrontBuffer(const OptionalThebesBuffer& aNewFront,
const nsIntRegion& aValidRegion)
{
mValidRegion = mOldValidRegion = aValidRegion;
NS_ABORT_IF_FALSE(OptionalThebesBuffer::Tnull_t != aNewFront.type(),
"aNewFront must be valid here!");
const ThebesBuffer newFront = aNewFront.get_ThebesBuffer();
nsRefPtr<gfxASurface> newFrontBuffer =
BasicManager()->OpenDescriptor(newFront.buffer());
nsRefPtr<gfxASurface> unused;
nsIntRect unusedRect;
nsIntPoint unusedRotation;
mFrontBuffer.Swap(newFrontBuffer, newFront.rect(), newFront.rotation(),
getter_AddRefs(unused), &unusedRect, &unusedRotation);
mFrontBufferDescriptor = newFront.buffer();
}
void void
BasicShadowThebesLayer::Swap(const ThebesBuffer& aNewFront, BasicShadowThebesLayer::Swap(const ThebesBuffer& aNewFront,
const nsIntRegion& aUpdatedRegion, const nsIntRegion& aUpdatedRegion,
OptionalThebesBuffer* aNewBack, ThebesBuffer* aNewBack,
nsIntRegion* aNewBackValidRegion, nsIntRegion* aNewBackValidRegion,
OptionalThebesBuffer* aReadOnlyFront, OptionalThebesBuffer* aReadOnlyFront,
nsIntRegion* aFrontUpdatedRegion) nsIntRegion* aFrontUpdatedRegion)
{ {
nsRefPtr<gfxASurface> newFrontBuffer =
BasicManager()->OpenDescriptor(aNewFront.buffer());
if (IsSurfaceDescriptorValid(mFrontBufferDescriptor)) {
nsRefPtr<gfxASurface> currentFront = BasicManager()->OpenDescriptor(mFrontBufferDescriptor);
if (currentFront->GetSize() != newFrontBuffer->GetSize()) {
// Current front buffer is obsolete
DestroyFrontBuffer();
}
}
// This code relies on Swap() arriving *after* attribute mutations. // This code relies on Swap() arriving *after* attribute mutations.
if (IsSurfaceDescriptorValid(mFrontBufferDescriptor)) { aNewBack->buffer() = mFrontBufferDescriptor;
*aNewBack = ThebesBuffer();
aNewBack->get_ThebesBuffer().buffer() = mFrontBufferDescriptor;
} else {
*aNewBack = null_t();
}
// We have to invalidate the pixels painted into the new buffer. // We have to invalidate the pixels painted into the new buffer.
// They might overlap with our old pixels. // They might overlap with our old pixels.
aNewBackValidRegion->Sub(mOldValidRegion, aUpdatedRegion); aNewBackValidRegion->Sub(mOldValidRegion, aUpdatedRegion);
nsRefPtr<gfxASurface> newFrontBuffer =
BasicManager()->OpenDescriptor(aNewFront.buffer());
nsRefPtr<gfxASurface> unused; nsRefPtr<gfxASurface> unused;
nsIntRect backRect;
nsIntPoint backRotation;
mFrontBuffer.Swap( mFrontBuffer.Swap(
newFrontBuffer, aNewFront.rect(), aNewFront.rotation(), newFrontBuffer, aNewFront.rect(), aNewFront.rotation(),
getter_AddRefs(unused), &backRect, &backRotation); getter_AddRefs(unused), &aNewBack->rect(), &aNewBack->rotation());
if (aNewBack->type() != OptionalThebesBuffer::Tnull_t) {
aNewBack->get_ThebesBuffer().rect() = backRect;
aNewBack->get_ThebesBuffer().rotation() = backRotation;
}
mFrontBufferDescriptor = aNewFront.buffer(); mFrontBufferDescriptor = aNewFront.buffer();

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

@ -729,6 +729,11 @@ LayerManagerD3D10::Render()
windowLayer = new WindowLayer(this); windowLayer = new WindowLayer(this);
windowLayer->SetShadow(ConstructShadowFor(windowLayer)); windowLayer->SetShadow(ConstructShadowFor(windowLayer));
CreatedThebesLayer(windowLayer); CreatedThebesLayer(windowLayer);
ShadowLayerForwarder::CreatedThebesBuffer(windowLayer,
contentRect,
contentRect,
SurfaceDescriptor());
mRootForShadowTree->InsertAfter(windowLayer, nsnull); mRootForShadowTree->InsertAfter(windowLayer, nsnull);
ShadowLayerForwarder::InsertAfter(mRootForShadowTree, windowLayer); ShadowLayerForwarder::InsertAfter(mRootForShadowTree, windowLayer);
} }

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

@ -469,10 +469,18 @@ ShadowThebesLayerD3D10::~ShadowThebesLayerD3D10()
{ {
} }
void
ShadowThebesLayerD3D10::SetFrontBuffer(const OptionalThebesBuffer& aNewFront,
const nsIntRegion& aValidRegion)
{
NS_ABORT_IF_FALSE(OptionalThebesBuffer::Tnull_t == aNewFront.type(),
"Expected dummy front buffer initially");
}
void void
ShadowThebesLayerD3D10::Swap( ShadowThebesLayerD3D10::Swap(
const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion, const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion,
OptionalThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion,
OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion) OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion)
{ {
nsRefPtr<ID3D10Texture2D> newBackBuffer = mTexture; nsRefPtr<ID3D10Texture2D> newBackBuffer = mTexture;
@ -482,7 +490,7 @@ ShadowThebesLayerD3D10::Swap(
// The content process tracks back/front buffers on its own, so // The content process tracks back/front buffers on its own, so
// the newBack is in essence unused. // the newBack is in essence unused.
aNewBack->get_ThebesBuffer().buffer() = aNewFront.buffer(); aNewBack->buffer() = aNewFront.buffer();
// The content process doesn't need to read back from the front // The content process doesn't need to read back from the front
// buffer (yet). // buffer (yet).

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

@ -108,9 +108,12 @@ public:
ShadowThebesLayerD3D10(LayerManagerD3D10* aManager); ShadowThebesLayerD3D10(LayerManagerD3D10* aManager);
virtual ~ShadowThebesLayerD3D10(); virtual ~ShadowThebesLayerD3D10();
// ShadowThebesLayer impl
virtual void SetFrontBuffer(const OptionalThebesBuffer& aNewFront,
const nsIntRegion& aValidRegion);
virtual void virtual void
Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion, Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion,
OptionalThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion,
OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion); OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion);
virtual void DestroyFrontBuffer(); virtual void DestroyFrontBuffer();

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

@ -619,17 +619,25 @@ ShadowThebesLayerD3D9::~ShadowThebesLayerD3D9()
{} {}
void void
ShadowThebesLayerD3D9::Swap(const ThebesBuffer& aNewFront, ShadowThebesLayerD3D9::SetFrontBuffer(const OptionalThebesBuffer& aNewFront,
const nsIntRegion& aUpdatedRegion, const nsIntRegion& aValidRegion)
OptionalThebesBuffer* aNewBack,
nsIntRegion* aNewBackValidRegion,
OptionalThebesBuffer* aReadOnlyFront,
nsIntRegion* aFrontUpdatedRegion)
{ {
if (!mBuffer) { if (!mBuffer) {
mBuffer = new ShadowBufferD3D9(this); mBuffer = new ShadowBufferD3D9(this);
} }
NS_ASSERTION(OptionalThebesBuffer::Tnull_t == aNewFront.type(),
"Only one system-memory buffer expected");
}
void
ShadowThebesLayerD3D9::Swap(const ThebesBuffer& aNewFront,
const nsIntRegion& aUpdatedRegion,
ThebesBuffer* aNewBack,
nsIntRegion* aNewBackValidRegion,
OptionalThebesBuffer* aReadOnlyFront,
nsIntRegion* aFrontUpdatedRegion)
{
if (mBuffer) { if (mBuffer) {
nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront.buffer()); nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront.buffer());
mBuffer->Upload(surf, GetVisibleRegion().GetBounds()); mBuffer->Upload(surf, GetVisibleRegion().GetBounds());

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

@ -120,9 +120,12 @@ public:
ShadowThebesLayerD3D9(LayerManagerD3D9 *aManager); ShadowThebesLayerD3D9(LayerManagerD3D9 *aManager);
virtual ~ShadowThebesLayerD3D9(); virtual ~ShadowThebesLayerD3D9();
// ShadowThebesLayer impl
virtual void SetFrontBuffer(const OptionalThebesBuffer& aNewFront,
const nsIntRegion& aValidRegion);
virtual void virtual void
Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion, Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion,
OptionalThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion,
OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion); OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion);
virtual void DestroyFrontBuffer(); virtual void DestroyFrontBuffer();

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

@ -109,6 +109,17 @@ union CanvasSurface {
null_t; null_t;
}; };
// For the "buffer creation" operations, we send an initial front
// buffer that only contains (transparent) black pixels just so that
// we can swap it back after the first OpPaint without a special case.
struct OpCreateThebesBuffer {
PLayer layer;
OptionalThebesBuffer initialFront;
nsIntRegion frontValidRegion;
};
struct OpDestroyThebesFrontBuffer { PLayer layer; };
// Change a layer's attributes // Change a layer's attributes
struct CommonLayerAttributes { struct CommonLayerAttributes {
nsIntRegion visibleRegion; nsIntRegion visibleRegion;
@ -183,6 +194,8 @@ union Edit {
OpCreateImageLayer; OpCreateImageLayer;
OpCreateColorLayer; OpCreateColorLayer;
OpCreateCanvasLayer; OpCreateCanvasLayer;
OpCreateThebesBuffer;
OpDestroyThebesFrontBuffer;
OpSetLayerAttributes; OpSetLayerAttributes;
@ -204,7 +217,7 @@ struct OpImageSwap { PLayer layer; SharedImage newBackImage; };
struct OpThebesBufferSwap { struct OpThebesBufferSwap {
PLayer layer; PLayer layer;
OptionalThebesBuffer newBackBuffer; ThebesBuffer newBackBuffer;
nsIntRegion newValidRegion; nsIntRegion newValidRegion;
// If the parent took the child's old back buffer and returned its // If the parent took the child's old back buffer and returned its
// old front buffer, |readOnlyFrontBuffer| may (if non-null) contain // old front buffer, |readOnlyFrontBuffer| may (if non-null) contain

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

@ -184,6 +184,31 @@ ShadowLayerForwarder::CreatedCanvasLayer(ShadowableLayer* aCanvas)
CreatedLayer<OpCreateCanvasLayer>(mTxn, aCanvas); CreatedLayer<OpCreateCanvasLayer>(mTxn, aCanvas);
} }
void
ShadowLayerForwarder::CreatedThebesBuffer(ShadowableLayer* aThebes,
const nsIntRegion& aFrontValidRegion,
const nsIntRect& aBufferRect,
const SurfaceDescriptor& aTempFrontBuffer)
{
OptionalThebesBuffer buffer = null_t();
if (IsSurfaceDescriptorValid(aTempFrontBuffer)) {
buffer = ThebesBuffer(aTempFrontBuffer,
aBufferRect,
nsIntPoint(0, 0));
}
mTxn->AddEdit(OpCreateThebesBuffer(NULL, Shadow(aThebes),
buffer,
aFrontValidRegion));
}
void
ShadowLayerForwarder::DestroyedThebesBuffer(ShadowableLayer* aThebes,
const SurfaceDescriptor& aBackBufferToDestroy)
{
mTxn->AddEdit(OpDestroyThebesFrontBuffer(NULL, Shadow(aThebes)));
mTxn->AddBufferToDestroy(aBackBufferToDestroy);
}
void void
ShadowLayerForwarder::Mutated(ShadowableLayer* aMutant) ShadowLayerForwarder::Mutated(ShadowableLayer* aMutant)
{ {

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

@ -140,6 +140,38 @@ public:
void CreatedColorLayer(ShadowableLayer* aColor); void CreatedColorLayer(ShadowableLayer* aColor);
void CreatedCanvasLayer(ShadowableLayer* aCanvas); void CreatedCanvasLayer(ShadowableLayer* aCanvas);
/**
* Notify the shadow manager that a buffer has been created for the
* specificed layer. |aInitialFrontSurface| is one of the newly
* created, transparent black buffers for the layer; the "real"
* layer holds on to the other as its back buffer. We send it
* across on buffer creation to avoid special cases in the buffer
* swapping logic for Painted*() operations.
*
* It is expected that Created*Buffer() will be followed by a
* Painted*Buffer() in the same transaction, so that
* |aInitialFrontBuffer| is never actually drawn to screen. It is
* OK if it is drawn though.
*/
/**
* |aBufferRect| is the screen rect covered by |aInitialFrontBuffer|.
*/
void CreatedThebesBuffer(ShadowableLayer* aThebes,
const nsIntRegion& aFrontValidRegion,
const nsIntRect& aBufferRect,
const SurfaceDescriptor& aInitialFrontBuffer);
/**
* The specified layer is destroying its buffers.
* |aBackBufferToDestroy| is deallocated when this transaction is
* posted to the parent. During the parent-side transaction, the
* shadow is told to destroy its front buffer. This can happen when
* a new front/back buffer pair have been created because of a layer
* resize, e.g.
*/
void DestroyedThebesBuffer(ShadowableLayer* aThebes,
const SurfaceDescriptor& aBackBufferToDestroy);
/** /**
* At least one attribute of |aMutant| has changed, and |aMutant| * At least one attribute of |aMutant| has changed, and |aMutant|
* needs to sync to its shadow layer. This initial implementation * needs to sync to its shadow layer. This initial implementation
@ -474,6 +506,15 @@ class ShadowThebesLayer : public ShadowLayer,
public ThebesLayer public ThebesLayer
{ {
public: public:
/**
* CONSTRUCTION PHASE ONLY
*
* Override the front buffer and its valid region with the specified
* values. This is called when a new buffer has been created.
*/
virtual void SetFrontBuffer(const OptionalThebesBuffer& aNewFront,
const nsIntRegion& aValidRegion) = 0;
virtual void InvalidateRegion(const nsIntRegion& aRegion) virtual void InvalidateRegion(const nsIntRegion& aRegion)
{ {
NS_RUNTIMEABORT("ShadowThebesLayers can't fill invalidated regions"); NS_RUNTIMEABORT("ShadowThebesLayers can't fill invalidated regions");
@ -497,7 +538,7 @@ public:
*/ */
virtual void virtual void
Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion, Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion,
OptionalThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion,
OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion) = 0; OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion) = 0;
/** /**

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

@ -203,7 +203,29 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
AsShadowLayer(edit.get_OpCreateCanvasLayer())->Bind(layer); AsShadowLayer(edit.get_OpCreateCanvasLayer())->Bind(layer);
break; break;
} }
case Edit::TOpCreateThebesBuffer: {
MOZ_LAYERS_LOG(("[ParentSide] CreateThebesBuffer"));
const OpCreateThebesBuffer& otb = edit.get_OpCreateThebesBuffer();
ShadowThebesLayer* thebes = static_cast<ShadowThebesLayer*>(
AsShadowLayer(otb)->AsLayer());
thebes->SetFrontBuffer(otb.initialFront(), otb.frontValidRegion());
break;
}
case Edit::TOpDestroyThebesFrontBuffer: {
MOZ_LAYERS_LOG(("[ParentSide] DestroyThebesFrontBuffer"));
const OpDestroyThebesFrontBuffer& odfb =
edit.get_OpDestroyThebesFrontBuffer();
ShadowThebesLayer* thebes = static_cast<ShadowThebesLayer*>(
AsShadowLayer(odfb)->AsLayer());
thebes->DestroyFrontBuffer();
break;
}
// Attributes // Attributes
case Edit::TOpSetLayerAttributes: { case Edit::TOpSetLayerAttributes: {
MOZ_LAYERS_LOG(("[ParentSide] SetLayerAttributes")); MOZ_LAYERS_LOG(("[ParentSide] SetLayerAttributes"));
@ -317,7 +339,7 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
static_cast<ShadowThebesLayer*>(shadow->AsLayer()); static_cast<ShadowThebesLayer*>(shadow->AsLayer());
const ThebesBuffer& newFront = op.newFrontBuffer(); const ThebesBuffer& newFront = op.newFrontBuffer();
OptionalThebesBuffer newBack; ThebesBuffer newBack;
nsIntRegion newValidRegion; nsIntRegion newValidRegion;
OptionalThebesBuffer readonlyFront; OptionalThebesBuffer readonlyFront;
nsIntRegion frontUpdatedRegion; nsIntRegion frontUpdatedRegion;

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

@ -878,18 +878,31 @@ ShadowThebesLayerOGL::ShadowThebesLayerOGL(LayerManagerOGL *aManager)
ShadowThebesLayerOGL::~ShadowThebesLayerOGL() ShadowThebesLayerOGL::~ShadowThebesLayerOGL()
{} {}
void
ShadowThebesLayerOGL::SetFrontBuffer(const OptionalThebesBuffer& aNewFront,
const nsIntRegion& aValidRegion)
{
if (mDestroyed) {
return;
}
if (!mBuffer) {
mBuffer = new ShadowBufferOGL(this);
}
NS_ASSERTION(OptionalThebesBuffer::Tnull_t == aNewFront.type(),
"Only one system-memory buffer expected");
}
void void
ShadowThebesLayerOGL::Swap(const ThebesBuffer& aNewFront, ShadowThebesLayerOGL::Swap(const ThebesBuffer& aNewFront,
const nsIntRegion& aUpdatedRegion, const nsIntRegion& aUpdatedRegion,
OptionalThebesBuffer* aNewBack, ThebesBuffer* aNewBack,
nsIntRegion* aNewBackValidRegion, nsIntRegion* aNewBackValidRegion,
OptionalThebesBuffer* aReadOnlyFront, OptionalThebesBuffer* aReadOnlyFront,
nsIntRegion* aFrontUpdatedRegion) nsIntRegion* aFrontUpdatedRegion)
{ {
if (!mDestroyed) { if (!mDestroyed && mBuffer) {
if (!mBuffer) {
mBuffer = new ShadowBufferOGL(this);
}
nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront.buffer()); nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront.buffer());
mBuffer->Upload(surf, aUpdatedRegion, aNewFront.rect(), aNewFront.rotation()); mBuffer->Upload(surf, aUpdatedRegion, aNewFront.rect(), aNewFront.rotation());
} }

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

@ -91,9 +91,12 @@ public:
ShadowThebesLayerOGL(LayerManagerOGL *aManager); ShadowThebesLayerOGL(LayerManagerOGL *aManager);
virtual ~ShadowThebesLayerOGL(); virtual ~ShadowThebesLayerOGL();
// ShadowThebesLayer impl
virtual void SetFrontBuffer(const OptionalThebesBuffer& aNewFront,
const nsIntRegion& aValidRegion);
virtual void virtual void
Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion, Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion,
OptionalThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion,
OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion); OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion);
virtual void DestroyFrontBuffer(); virtual void DestroyFrontBuffer();