Bug 593248: Release old shmem surfaces on realloc. r=joe

This commit is contained in:
Chris Jones 2010-09-02 22:05:01 -05:00
Родитель a4c07eb71a
Коммит 81e7d1c97a
5 изменённых файлов: 155 добавлений и 36 удалений

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

@ -1341,6 +1341,13 @@ BasicShadowableThebesLayer::CreateBuffer(Buffer::ContentType aType,
const nsIntSize& aSize)
{
if (HasShadow()) {
if (mBackBuffer) {
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBuffer);
mBackBuffer = nsnull;
BasicManager()->DestroyedThebesBuffer(BasicManager()->Hold(this));
}
nsRefPtr<gfxSharedImageSurface> tmpFront;
// XXX error handling
if (!BasicManager()->AllocDoubleBuffer(gfxIntSize(aSize.width, aSize.height),
@ -1425,6 +1432,13 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext,
if (oldSize != mSize) {
NS_ASSERTION(oldSize == gfxIntSize(0, 0), "video changed size?");
if (mBackSurface) {
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackSurface);
mBackSurface = nsnull;
BasicManager()->DestroyedImageBuffer(BasicManager()->Hold(this));
}
nsRefPtr<gfxSharedImageSurface> tmpFrontSurface;
// XXX error handling?
if (!BasicManager()->AllocDoubleBuffer(
@ -1531,6 +1545,15 @@ BasicShadowableCanvasLayer::Initialize(const Data& aData)
if (!HasShadow())
return;
// XXX won't get here currently; need to figure out what to do on
// canvas resizes
if (mBackBuffer) {
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBuffer);
mBackBuffer = nsnull;
BasicManager()->DestroyedCanvasBuffer(BasicManager()->Hold(this));
}
nsRefPtr<gfxSharedImageSurface> tmpFrontBuffer;
// XXX error handling?
if (!BasicManager()->AllocDoubleBuffer(
@ -1613,7 +1636,11 @@ public:
MOZ_COUNT_DTOR(BasicShadowThebesLayer);
}
virtual void Disconnect();
virtual void Disconnect()
{
DestroyFrontBuffer();
ShadowThebesLayer::Disconnect();
}
virtual already_AddRefed<gfxSharedImageSurface>
Swap(gfxSharedImageSurface* aNewFront,
@ -1623,6 +1650,15 @@ public:
return mFrontBuffer.Swap(aNewFront, aBufferRect, aRotation);
}
virtual void DestroyFrontBuffer()
{
nsRefPtr<gfxSharedImageSurface> frontBuffer =
mFrontBuffer.Swap(0, nsIntRect());
if (frontBuffer) {
BasicManager()->ShadowLayerManager::DestroySharedSurface(frontBuffer);
}
}
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
@ -1637,18 +1673,6 @@ private:
ShadowThebesLayerBuffer mFrontBuffer;
};
void
BasicShadowThebesLayer::Disconnect()
{
nsRefPtr<gfxSharedImageSurface> frontBuffer =
mFrontBuffer.Swap(0, nsIntRect());
if (frontBuffer) {
BasicManager()->ShadowLayerManager::DestroySharedSurface(frontBuffer);
}
ShadowThebesLayer::Disconnect();
}
void
BasicShadowThebesLayer::Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
@ -1689,13 +1713,25 @@ public:
MOZ_COUNT_DTOR(BasicShadowImageLayer);
}
virtual void Disconnect();
virtual void Disconnect()
{
DestroyFrontBuffer();
ShadowImageLayer::Disconnect();
}
virtual PRBool Init(gfxSharedImageSurface* front, const nsIntSize& size);
virtual already_AddRefed<gfxSharedImageSurface>
Swap(gfxSharedImageSurface* newFront);
virtual void DestroyFrontBuffer()
{
if (mFrontSurface) {
BasicManager()->ShadowLayerManager::DestroySharedSurface(mFrontSurface);
}
mFrontSurface = nsnull;
}
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
@ -1712,17 +1748,6 @@ protected:
gfxIntSize mSize;
};
void
BasicShadowImageLayer::Disconnect()
{
if (mFrontSurface) {
BasicManager()->ShadowLayerManager::DestroySharedSurface(mFrontSurface);
}
mFrontSurface = nsnull;
ShadowImageLayer::Disconnect();
}
PRBool
BasicShadowImageLayer::Init(gfxSharedImageSurface* front,
const nsIntSize& size)
@ -1769,7 +1794,11 @@ public:
MOZ_COUNT_DTOR(BasicShadowCanvasLayer);
}
virtual void Disconnect();
virtual void Disconnect()
{
DestroyFrontBuffer();
ShadowCanvasLayer::Disconnect();
}
virtual void Initialize(const Data& aData);
@ -1779,6 +1808,14 @@ public:
virtual already_AddRefed<gfxSharedImageSurface>
Swap(gfxSharedImageSurface* newFront);
virtual void DestroyFrontBuffer()
{
if (mFrontSurface) {
BasicManager()->ShadowLayerManager::DestroySharedSurface(mFrontSurface);
}
mFrontSurface = nsnull;
}
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
@ -1794,16 +1831,6 @@ private:
nsIntRect mBounds;
};
void
BasicShadowCanvasLayer::Disconnect()
{
if (mFrontSurface) {
BasicManager()->ShadowLayerManager::DestroySharedSurface(mFrontSurface);
}
mFrontSurface = nsnull;
ShadowCanvasLayer::Disconnect();
}
void
BasicShadowCanvasLayer::Initialize(const Data& aData)

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

@ -77,18 +77,22 @@ struct OpCreateThebesBuffer {
nsIntRect bufferRect;
Shmem initialFront;
};
struct OpDestroyThebesFrontBuffer { PLayer layer; };
struct OpCreateCanvasBuffer {
PLayer layer;
nsIntSize size;
Shmem initialFront;
};
struct OpDestroyCanvasFrontBuffer { PLayer layer; };
struct OpCreateImageBuffer {
PLayer layer;
nsIntSize size;
Shmem initialFront;
};
struct OpDestroyImageFrontBuffer { PLayer layer; };
// Change a layer's attributes
struct CommonLayerAttributes {
@ -164,6 +168,9 @@ union Edit {
OpCreateCanvasBuffer;
OpCreateThebesBuffer;
OpCreateImageBuffer;
OpDestroyThebesFrontBuffer;
OpDestroyCanvasFrontBuffer;
OpDestroyImageFrontBuffer;
OpSetLayerAttributes;

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

@ -187,6 +187,24 @@ ShadowLayerForwarder::CreatedCanvasBuffer(ShadowableLayer* aCanvas,
aTempFrontSurface->GetShmem()));
}
void
ShadowLayerForwarder::DestroyedThebesBuffer(ShadowableLayer* aThebes)
{
mTxn->AddEdit(OpDestroyThebesFrontBuffer(NULL, Shadow(aThebes)));
}
void
ShadowLayerForwarder::DestroyedImageBuffer(ShadowableLayer* aImage)
{
mTxn->AddEdit(OpDestroyImageFrontBuffer(NULL, Shadow(aImage)));
}
void
ShadowLayerForwarder::DestroyedCanvasBuffer(ShadowableLayer* aCanvas)
{
mTxn->AddEdit(OpDestroyCanvasFrontBuffer(NULL, Shadow(aCanvas)));
}
void
ShadowLayerForwarder::Mutated(ShadowableLayer* aMutant)
{

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

@ -160,6 +160,16 @@ public:
nsIntSize aSize,
gfxSharedImageSurface* aInitialFrontSurface);
/**
* The specified layer should 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);
void DestroyedImageBuffer(ShadowableLayer* aImage);
void DestroyedCanvasBuffer(ShadowableLayer* aCanvas);
/**
* At least one attribute of |aMutant| has changed, and |aMutant|
* needs to sync to its shadow layer. This initial implementation
@ -343,6 +353,13 @@ public:
const nsIntRect& aBufferRect,
const nsIntPoint& aRotation) = 0;
/**
* CONSTRUCTION PHASE ONLY
*
* Destroy the current front buffer.
*/
virtual void DestroyFrontBuffer() = 0;
MOZ_LAYER_DECL_NAME("ShadowThebesLayer", TYPE_SHADOW)
protected:
@ -364,6 +381,13 @@ public:
virtual already_AddRefed<gfxSharedImageSurface>
Swap(gfxSharedImageSurface* aNewFront) = 0;
/**
* CONSTRUCTION PHASE ONLY
*
* Destroy the current front buffer.
*/
virtual void DestroyFrontBuffer() = 0;
MOZ_LAYER_DECL_NAME("ShadowCanvasLayer", TYPE_SHADOW)
protected:
@ -392,6 +416,13 @@ public:
virtual already_AddRefed<gfxSharedImageSurface>
Swap(gfxSharedImageSurface* newFront) = 0;
/**
* CONSTRUCTION PHASE ONLY
*
* Destroy the current front buffer.
*/
virtual void DestroyFrontBuffer() = 0;
MOZ_LAYER_DECL_NAME("ShadowImageLayer", TYPE_SHADOW)
protected:

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

@ -222,6 +222,42 @@ ShadowLayersParent::RecvUpdate(const nsTArray<Edit>& cset,
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;
}
case Edit::TOpDestroyCanvasFrontBuffer: {
MOZ_LAYERS_LOG(("[ParentSide] DestroyCanvasFrontBuffer"));
const OpDestroyCanvasFrontBuffer& odfb =
edit.get_OpDestroyCanvasFrontBuffer();
ShadowCanvasLayer* canvas = static_cast<ShadowCanvasLayer*>(
AsShadowLayer(odfb)->AsLayer());
canvas->DestroyFrontBuffer();
break;
}
case Edit::TOpDestroyImageFrontBuffer: {
MOZ_LAYERS_LOG(("[ParentSide] DestroyImageFrontBuffer"));
const OpDestroyImageFrontBuffer& odfb =
edit.get_OpDestroyImageFrontBuffer();
ShadowImageLayer* image = static_cast<ShadowImageLayer*>(
AsShadowLayer(odfb)->AsLayer());
image->DestroyFrontBuffer();
break;
}
// Attributes
case Edit::TOpSetLayerAttributes: {