зеркало из https://github.com/mozilla/gecko-dev.git
Bug 735378 - Cache temporary composite surfaces - r=bgirard
This commit is contained in:
Родитель
724fa1a182
Коммит
c962e216ff
|
@ -1081,6 +1081,30 @@ protected:
|
|||
|
||||
bool mGLBufferIsPremultiplied;
|
||||
bool mNeedsYFlip;
|
||||
|
||||
nsRefPtr<gfxImageSurface> mCachedTempSurface;
|
||||
gfxIntSize mCachedSize;
|
||||
gfxImageFormat mCachedFormat;
|
||||
|
||||
gfxImageSurface* GetTempSurface(const gfxIntSize& aSize, const gfxImageFormat aFormat)
|
||||
{
|
||||
if (!mCachedTempSurface ||
|
||||
aSize.width != mCachedSize.width ||
|
||||
aSize.height != mCachedSize.height ||
|
||||
aFormat != mCachedFormat)
|
||||
{
|
||||
mCachedTempSurface = new gfxImageSurface(aSize, aFormat);
|
||||
mCachedSize = aSize;
|
||||
mCachedFormat = aFormat;
|
||||
}
|
||||
|
||||
return mCachedTempSurface;
|
||||
}
|
||||
|
||||
void DiscardTempSurface()
|
||||
{
|
||||
mCachedTempSurface = nsnull;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -1139,7 +1163,7 @@ BasicCanvasLayer::UpdateSurface(gfxASurface* aDestSurface)
|
|||
mGLContext->MakeCurrent();
|
||||
|
||||
#if defined (MOZ_X11) && defined (MOZ_EGL_XRENDER_COMPOSITE)
|
||||
mGLContext->fFinish();
|
||||
mGLContext->GuaranteeResolve();
|
||||
gfxASurface* offscreenSurface = mGLContext->GetOffscreenPixmapSurface();
|
||||
|
||||
// XRender can only blend premuliplied alpha, so only allow xrender
|
||||
|
@ -1147,16 +1171,22 @@ BasicCanvasLayer::UpdateSurface(gfxASurface* aDestSurface)
|
|||
if (offscreenSurface && (mGLBufferIsPremultiplied || (GetContentFlags() & CONTENT_OPAQUE))) {
|
||||
mSurface = offscreenSurface;
|
||||
mNeedsYFlip = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nsRefPtr<gfxImageSurface> isurf = aDestSurface ?
|
||||
static_cast<gfxImageSurface*>(aDestSurface) :
|
||||
new gfxImageSurface(gfxIntSize(mBounds.width, mBounds.height),
|
||||
(GetContentFlags() & CONTENT_OPAQUE)
|
||||
? gfxASurface::ImageFormatRGB24
|
||||
: gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxImageSurface> isurf;
|
||||
if (aDestSurface) {
|
||||
DiscardTempSurface();
|
||||
isurf = static_cast<gfxImageSurface*>(aDestSurface);
|
||||
} else {
|
||||
nsIntSize size(mBounds.width, mBounds.height);
|
||||
gfxImageFormat format = (GetContentFlags() & CONTENT_OPAQUE)
|
||||
? gfxASurface::ImageFormatRGB24
|
||||
: gfxASurface::ImageFormatARGB32;
|
||||
|
||||
isurf = GetTempSurface(size, format);
|
||||
}
|
||||
|
||||
|
||||
if (!isurf || isurf->CairoStatus() != 0) {
|
||||
return;
|
||||
|
@ -1194,7 +1224,6 @@ BasicCanvasLayer::UpdateSurface(gfxASurface* aDestSurface)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicCanvasLayer::Paint(gfxContext* aContext)
|
||||
|
|
|
@ -172,10 +172,13 @@ CanvasLayerD3D10::UpdateSurface()
|
|||
return;
|
||||
}
|
||||
|
||||
const bool stridesMatch = map.RowPitch == mBounds.width * 4;
|
||||
|
||||
PRUint8 *destination;
|
||||
if (map.RowPitch != mBounds.width * 4) {
|
||||
destination = new PRUint8[mBounds.width * mBounds.height * 4];
|
||||
if (!stridesMatch) {
|
||||
destination = GetTempBlob(mBounds.width * mBounds.height * 4);
|
||||
} else {
|
||||
DiscardTempBlob();
|
||||
destination = (PRUint8*)map.pData;
|
||||
}
|
||||
|
||||
|
@ -204,13 +207,12 @@ CanvasLayerD3D10::UpdateSurface()
|
|||
if (currentFramebuffer != mCanvasFramebuffer)
|
||||
mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, currentFramebuffer);
|
||||
|
||||
if (map.RowPitch != mBounds.width * 4) {
|
||||
if (!stridesMatch) {
|
||||
for (int y = 0; y < mBounds.height; y++) {
|
||||
memcpy((PRUint8*)map.pData + map.RowPitch * y,
|
||||
destination + mBounds.width * 4 * y,
|
||||
mBounds.width * 4);
|
||||
}
|
||||
delete [] destination;
|
||||
}
|
||||
mTexture->Unmap(0);
|
||||
} else if (mSurface) {
|
||||
|
|
|
@ -87,6 +87,24 @@ private:
|
|||
bool mIsD2DTexture;
|
||||
bool mUsingSharedTexture;
|
||||
bool mHasAlpha;
|
||||
|
||||
nsAutoArrayPtr<PRUint8> mCachedTempBlob;
|
||||
PRUint32 mCachedTempBlob_Size;
|
||||
|
||||
PRUint8* GetTempBlob(const PRUint32 aSize)
|
||||
{
|
||||
if (!mCachedTempBlob || aSize != mCachedTempBlob_Size) {
|
||||
mCachedTempBlob = new PRUint8[aSize];
|
||||
mCachedTempBlob_Size = aSize;
|
||||
}
|
||||
|
||||
return mCachedTempBlob;
|
||||
}
|
||||
|
||||
void DiscardTempBlob()
|
||||
{
|
||||
mCachedTempBlob = nsnull;
|
||||
}
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
|
|
|
@ -113,10 +113,13 @@ CanvasLayerD3D9::UpdateSurface()
|
|||
|
||||
D3DLOCKED_RECT r = textureLock.GetLockRect();
|
||||
|
||||
const bool stridesMatch = r.Pitch == mBounds.width * 4;
|
||||
|
||||
PRUint8 *destination;
|
||||
if (r.Pitch != mBounds.width * 4) {
|
||||
destination = new PRUint8[mBounds.width * mBounds.height * 4];
|
||||
if (!stridesMatch) {
|
||||
destination = GetTempBlob(mBounds.width * mBounds.height * 4);
|
||||
} else {
|
||||
DiscardTempBlob();
|
||||
destination = (PRUint8*)r.pBits;
|
||||
}
|
||||
|
||||
|
@ -145,13 +148,12 @@ CanvasLayerD3D9::UpdateSurface()
|
|||
if (currentFramebuffer != mCanvasFramebuffer)
|
||||
mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, currentFramebuffer);
|
||||
|
||||
if (r.Pitch != mBounds.width * 4) {
|
||||
if (!stridesMatch) {
|
||||
for (int y = 0; y < mBounds.height; y++) {
|
||||
memcpy((PRUint8*)r.pBits + r.Pitch * y,
|
||||
destination + mBounds.width * 4 * y,
|
||||
mBounds.width * 4);
|
||||
}
|
||||
delete [] destination;
|
||||
}
|
||||
} else {
|
||||
RECT r;
|
||||
|
|
|
@ -92,6 +92,24 @@ protected:
|
|||
bool mDataIsPremultiplied;
|
||||
bool mNeedsYFlip;
|
||||
bool mHasAlpha;
|
||||
|
||||
nsAutoArrayPtr<PRUint8> mCachedTempBlob;
|
||||
PRUint32 mCachedTempBlob_Size;
|
||||
|
||||
PRUint8* GetTempBlob(const PRUint32 aSize)
|
||||
{
|
||||
if (!mCachedTempBlob || aSize != mCachedTempBlob_Size) {
|
||||
mCachedTempBlob = new PRUint8[aSize];
|
||||
mCachedTempBlob_Size = aSize;
|
||||
}
|
||||
|
||||
return mCachedTempBlob;
|
||||
}
|
||||
|
||||
void DiscardTempBlob()
|
||||
{
|
||||
mCachedTempBlob = nsnull;
|
||||
}
|
||||
};
|
||||
|
||||
// NB: eventually we'll have separate shadow canvas2d and shadow
|
||||
|
|
|
@ -178,6 +178,8 @@ CanvasLayerOGL::UpdateSurface()
|
|||
if (mCanvasGLContext &&
|
||||
mCanvasGLContext->GetContextType() == gl()->GetContextType())
|
||||
{
|
||||
DiscardTempSurface();
|
||||
|
||||
// Can texture share, just make sure it's resolved first
|
||||
mCanvasGLContext->MakeCurrent();
|
||||
mCanvasGLContext->GuaranteeResolve();
|
||||
|
@ -190,6 +192,7 @@ CanvasLayerOGL::UpdateSurface()
|
|||
}
|
||||
} else {
|
||||
nsRefPtr<gfxASurface> updatedAreaSurface;
|
||||
|
||||
if (mDrawTarget) {
|
||||
// TODO: This is suboptimal - We should have direct handling for the surface types instead of
|
||||
// going via a gfxASurface.
|
||||
|
@ -197,23 +200,24 @@ CanvasLayerOGL::UpdateSurface()
|
|||
} else if (mCanvasSurface) {
|
||||
updatedAreaSurface = mCanvasSurface;
|
||||
} else if (mCanvasGLContext) {
|
||||
gfxIntSize size(mBounds.width, mBounds.height);
|
||||
nsRefPtr<gfxImageSurface> updatedAreaImageSurface =
|
||||
new gfxImageSurface(gfxIntSize(mBounds.width, mBounds.height),
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
GetTempSurface(size, gfxASurface::ImageFormatARGB32);
|
||||
|
||||
mCanvasGLContext->ReadPixelsIntoImageSurface(0, 0,
|
||||
mBounds.width,
|
||||
mBounds.height,
|
||||
updatedAreaImageSurface);
|
||||
|
||||
updatedAreaSurface = updatedAreaImageSurface;
|
||||
}
|
||||
|
||||
mOGLManager->MakeCurrent();
|
||||
mLayerProgram =
|
||||
gl()->UploadSurfaceToTexture(updatedAreaSurface,
|
||||
mBounds,
|
||||
mTexture,
|
||||
false,
|
||||
nsIntPoint(0, 0));
|
||||
mLayerProgram = gl()->UploadSurfaceToTexture(updatedAreaSurface,
|
||||
mBounds,
|
||||
mTexture,
|
||||
false,
|
||||
nsIntPoint(0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,6 +94,30 @@ protected:
|
|||
#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
|
||||
GLXPixmap mPixmap;
|
||||
#endif
|
||||
|
||||
nsRefPtr<gfxImageSurface> mCachedTempSurface;
|
||||
gfxIntSize mCachedSize;
|
||||
gfxImageFormat mCachedFormat;
|
||||
|
||||
gfxImageSurface* GetTempSurface(const gfxIntSize& aSize, const gfxImageFormat aFormat)
|
||||
{
|
||||
if (!mCachedTempSurface ||
|
||||
aSize.width != mCachedSize.width ||
|
||||
aSize.height != mCachedSize.height ||
|
||||
aFormat != mCachedFormat)
|
||||
{
|
||||
mCachedTempSurface = new gfxImageSurface(aSize, aFormat);
|
||||
mCachedSize = aSize;
|
||||
mCachedFormat = aFormat;
|
||||
}
|
||||
|
||||
return mCachedTempSurface;
|
||||
}
|
||||
|
||||
void DiscardTempSurface()
|
||||
{
|
||||
mCachedTempSurface = nsnull;
|
||||
}
|
||||
};
|
||||
|
||||
// NB: eventually we'll have separate shadow canvas2d and shadow
|
||||
|
|
Загрузка…
Ссылка в новой задаче