mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 565875. Part 3: Recycle temporary buffer used by PlanarYCbCrImageOGL to avoid reallocation/recommit costs (especially on Mac). r=bas
This commit is contained in:
parent
a36e98ca1e
commit
e3d9ccde5f
@ -116,8 +116,40 @@ GLTexture::Release()
|
||||
mTexture = 0;
|
||||
}
|
||||
|
||||
RecycleBin::RecycleBin()
|
||||
: mLock("mozilla.layers.RecycleBin.mLock")
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RecycleBin::RecycleBuffer(PRUint8* aBuffer, PRUint32 aSize)
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
|
||||
if (!mRecycledBuffers.IsEmpty() && aSize != mRecycledBufferSize) {
|
||||
mRecycledBuffers.Clear();
|
||||
}
|
||||
mRecycledBufferSize = aSize;
|
||||
mRecycledBuffers.AppendElement(aBuffer);
|
||||
}
|
||||
|
||||
PRUint8*
|
||||
RecycleBin::TakeBuffer(PRUint32 aSize)
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
|
||||
if (mRecycledBuffers.IsEmpty() || mRecycledBufferSize != aSize)
|
||||
return new PRUint8[aSize];
|
||||
|
||||
PRUint32 last = mRecycledBuffers.Length() - 1;
|
||||
PRUint8* result = mRecycledBuffers[last].forget();
|
||||
mRecycledBuffers.RemoveElementAt(last);
|
||||
return result;
|
||||
}
|
||||
|
||||
ImageContainerOGL::ImageContainerOGL(LayerManagerOGL *aManager)
|
||||
: ImageContainer(aManager)
|
||||
, mRecycleBin(new RecycleBin())
|
||||
, mActiveImageLock("mozilla.layers.ImageContainerOGL.mActiveImageLock")
|
||||
{
|
||||
}
|
||||
@ -131,7 +163,7 @@ ImageContainerOGL::CreateImage(const Image::Format *aFormats,
|
||||
}
|
||||
nsRefPtr<Image> img;
|
||||
if (aFormats[0] == Image::PLANAR_YCBCR) {
|
||||
img = new PlanarYCbCrImageOGL();
|
||||
img = new PlanarYCbCrImageOGL(mRecycleBin);
|
||||
} else if (aFormats[0] == Image::CAIRO_SURFACE) {
|
||||
img = new CairoImageOGL(static_cast<LayerManagerOGL*>(mManager));
|
||||
}
|
||||
@ -141,9 +173,17 @@ ImageContainerOGL::CreateImage(const Image::Format *aFormats,
|
||||
void
|
||||
ImageContainerOGL::SetCurrentImage(Image *aImage)
|
||||
{
|
||||
nsRefPtr<Image> oldImage;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mActiveImageLock);
|
||||
|
||||
oldImage = mActiveImage.forget();
|
||||
mActiveImage = aImage;
|
||||
}
|
||||
|
||||
// Make sure oldImage is released outside the lock, so it can take our
|
||||
// lock in RecycleBuffer
|
||||
}
|
||||
|
||||
already_AddRefed<Image>
|
||||
@ -278,11 +318,18 @@ ImageLayerOGL::RenderLayer(int)
|
||||
}
|
||||
}
|
||||
|
||||
PlanarYCbCrImageOGL::PlanarYCbCrImageOGL()
|
||||
: PlanarYCbCrImage(nsnull), mHasData(PR_FALSE)
|
||||
PlanarYCbCrImageOGL::PlanarYCbCrImageOGL(RecycleBin *aRecycleBin)
|
||||
: PlanarYCbCrImage(nsnull), mRecycleBin(aRecycleBin), mHasData(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
PlanarYCbCrImageOGL::~PlanarYCbCrImageOGL()
|
||||
{
|
||||
if (mBuffer) {
|
||||
mRecycleBin->RecycleBuffer(mBuffer.forget(), mBufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PlanarYCbCrImageOGL::SetData(const PlanarYCbCrImage::Data &aData)
|
||||
{
|
||||
@ -313,8 +360,13 @@ PlanarYCbCrImageOGL::SetData(const PlanarYCbCrImage::Data &aData)
|
||||
mData.mCbCrSize.height = aData.mPicSize.height >> height_shift;
|
||||
mData.mYSize = aData.mPicSize;
|
||||
mData.mYStride = mData.mYSize.width;
|
||||
mBuffer = new PRUint8[mData.mCbCrStride * mData.mCbCrSize.height * 2 +
|
||||
mData.mYStride * mData.mYSize.height];
|
||||
|
||||
mBufferSize = mData.mCbCrStride * mData.mCbCrSize.height * 2 +
|
||||
mData.mYStride * mData.mYSize.height;
|
||||
mBuffer = mRecycleBin->TakeBuffer(mBufferSize);
|
||||
if (!mBuffer)
|
||||
return;
|
||||
|
||||
mData.mYChannel = mBuffer;
|
||||
mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height;
|
||||
mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height;
|
||||
@ -441,8 +493,10 @@ PlanarYCbCrImageOGL::AllocateTextures(LayerManagerOGL *aManager)
|
||||
// Reset alignment to default
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
|
||||
|
||||
// Free main-memory buffer now that we've got the data in our textures
|
||||
mBuffer = nsnull;
|
||||
// Recycle main-memory buffer now that we've got the data in our textures
|
||||
if (mBuffer) {
|
||||
mRecycleBin->RecycleBuffer(mBuffer.forget(), mBufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
CairoImageOGL::CairoImageOGL(LayerManagerOGL *aManager) : CairoImage(nsnull)
|
||||
|
@ -85,6 +85,36 @@ private:
|
||||
GLuint mTexture;
|
||||
};
|
||||
|
||||
/**
|
||||
* A RecycleBin is owned by an ImageContainerOGL. We store buffers
|
||||
* and textures in it that we want to recycle from one image to the next.
|
||||
* It's a separate object from ImageContainerOGL because images need to store
|
||||
* a strong ref to their RecycleBin and we must avoid creating a
|
||||
* reference loop between an ImageContainerOGL and its active image.
|
||||
*/
|
||||
class RecycleBin {
|
||||
THEBES_INLINE_DECL_THREADSAFE_REFCOUNTING(RecycleBin)
|
||||
|
||||
public:
|
||||
RecycleBin();
|
||||
|
||||
void RecycleBuffer(PRUint8* aBuffer, PRUint32 aSize);
|
||||
// Returns a recycled buffer of the right size, or allocates a new buffer.
|
||||
PRUint8* TakeBuffer(PRUint32 aSize);
|
||||
|
||||
private:
|
||||
typedef mozilla::Mutex Mutex;
|
||||
|
||||
// This protects mRecycledBuffers and mRecycledBufferSize
|
||||
Mutex mLock;
|
||||
|
||||
// We should probably do something to prune this list on a timer so we don't
|
||||
// eat excess memory while video is paused...
|
||||
nsTArray<nsAutoArrayPtr<PRUint8> > mRecycledBuffers;
|
||||
// This is only valid if mRecycledBuffers is non-empty
|
||||
PRUint32 mRecycledBufferSize;
|
||||
};
|
||||
|
||||
class THEBES_API ImageContainerOGL : public ImageContainer
|
||||
{
|
||||
public:
|
||||
@ -105,9 +135,12 @@ public:
|
||||
private:
|
||||
typedef mozilla::Mutex Mutex;
|
||||
|
||||
nsRefPtr<Image> mActiveImage;
|
||||
nsRefPtr<RecycleBin> mRecycleBin;
|
||||
|
||||
// This protects mActiveImage
|
||||
Mutex mActiveImageLock;
|
||||
|
||||
nsRefPtr<Image> mActiveImage;
|
||||
};
|
||||
|
||||
class THEBES_API ImageLayerOGL : public ImageLayer,
|
||||
@ -134,7 +167,8 @@ class THEBES_API PlanarYCbCrImageOGL : public PlanarYCbCrImage
|
||||
typedef mozilla::gl::GLContext GLContext;
|
||||
|
||||
public:
|
||||
PlanarYCbCrImageOGL();
|
||||
PlanarYCbCrImageOGL(RecycleBin *aRecycleBin);
|
||||
~PlanarYCbCrImageOGL();
|
||||
|
||||
virtual void SetData(const Data &aData);
|
||||
|
||||
@ -151,6 +185,8 @@ public:
|
||||
}
|
||||
|
||||
nsAutoArrayPtr<PRUint8> mBuffer;
|
||||
PRUint32 mBufferSize;
|
||||
nsRefPtr<RecycleBin> mRecycleBin;
|
||||
GLTexture mTextures[3];
|
||||
Data mData;
|
||||
gfxIntSize mSize;
|
||||
|
Loading…
Reference in New Issue
Block a user