Bug 364221 - "[cairo] bad page scrolling performance with large background images" [p=alfredkayser@nl.ibm.com (Alfred Kayser) / vladimir@pobox.com (Vladimir Vukicevic [vlad]) r=stuart sr=tor a=blocking1.9+]

This commit is contained in:
reed%reedloden.com 2007-11-27 09:35:19 +00:00
Родитель 5d230e1ed7
Коммит f2bab4cf0c
6 изменённых файлов: 43 добавлений и 21 удалений

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

@ -66,6 +66,7 @@ nsThebesImage::nsThebesImage()
mDecoded(0,0,0,0),
mImageComplete(PR_FALSE),
mSinglePixel(PR_FALSE),
mFormatChanged(PR_FALSE),
mAlphaDepth(0)
{
static PRBool hasCheckedOptimize = PR_FALSE;
@ -254,6 +255,8 @@ nsThebesImage::Optimize(nsIDeviceContext* aContext)
if (ShouldUseImageSurfaces())
return NS_OK;
mOptSurface = nsnull;
#ifdef XP_WIN
// we need to special-case windows here, because windows has
// a distinction between DIB and DDB and we want to use DDBs as much
@ -288,21 +291,22 @@ nsThebesImage::Optimize(nsIDeviceContext* aContext)
mOptSurface = wsurf;
}
}
if (!mOptSurface) {
// just use the DIB
if (!mOptSurface && !mFormatChanged) {
// just use the DIB if the format has not changed
mOptSurface = mWinSurface;
}
} else {
mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mImageSurface);
}
mWinSurface = nsnull;
#else
mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mImageSurface);
#endif
mImageSurface = nsnull;
if (mOptSurface == nsnull)
mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mImageSurface, mFormat);
if (mOptSurface) {
mImageSurface = nsnull;
#ifdef XP_WIN
mWinSurface = nsnull;
#endif
}
return NS_OK;
}
@ -636,6 +640,8 @@ nsThebesImage::ShouldUseImageSurfaces()
void
nsThebesImage::SetHasNoAlpha()
{
if (mFormat == gfxASurface::ImageFormatARGB32)
if (mFormat == gfxASurface::ImageFormatARGB32) {
mFormat = gfxASurface::ImageFormatRGB24;
mFormatChanged = PR_TRUE;
}
}

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

@ -142,6 +142,7 @@ protected:
nsRect mDecoded;
PRPackedBool mImageComplete;
PRPackedBool mSinglePixel;
PRPackedBool mFormatChanged;
#ifdef XP_WIN
PRPackedBool mIsDDBSurface;
#endif

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

@ -87,15 +87,14 @@ public:
/**
* Create an offscreen surface of the given dimensions
* and image format. If fastPixelAccess is TRUE,
* create a surface that is optimized for rapid pixel
* changing.
* and image format.
*/
virtual already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
gfxASurface::gfxImageFormat imageFormat) = 0;
virtual already_AddRefed<gfxASurface> OptimizeImage(gfxImageSurface *aSurface);
virtual already_AddRefed<gfxASurface> OptimizeImage(gfxImageSurface *aSurface,
gfxASurface::gfxImageFormat format);
/*
* Font bits

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

@ -195,15 +195,13 @@ gfxPlatform::SetUseGlitz(PRBool use)
}
already_AddRefed<gfxASurface>
gfxPlatform::OptimizeImage(gfxImageSurface *aSurface)
gfxPlatform::OptimizeImage(gfxImageSurface *aSurface,
gfxASurface::gfxImageFormat format)
{
const gfxIntSize& surfaceSize = aSurface->GetSize();
gfxASurface::gfxImageFormat realFormat = aSurface->Format();
nsRefPtr<gfxASurface> optSurface = CreateOffscreenSurface(surfaceSize, realFormat);
if (!optSurface)
nsRefPtr<gfxASurface> optSurface = CreateOffscreenSurface(surfaceSize, format);
if (!optSurface || optSurface->CairoStatus() != 0)
return nsnull;
nsRefPtr<gfxContext> tmpCtx(new gfxContext(optSurface));

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

@ -121,6 +121,7 @@ nsGIFDecoder2::nsGIFDecoder2()
, mLastFlushedPass(0)
, mOldColor(0)
, mGIFOpen(PR_FALSE)
, mSawTransparency(PR_FALSE)
{
// Clear out the structure, excluding the arrays
memset(&mGIFStruct, 0, sizeof(mGIFStruct));
@ -380,6 +381,11 @@ void nsGIFDecoder2::EndImageFrame()
mGIFStruct.screen_height - realFrameHeight);
mObserver->OnDataAvailable(nsnull, mImageFrame, &r);
}
// This transparency check is only valid for first frame
if (mGIFStruct.is_transparent && !mSawTransparency) {
nsCOMPtr<nsIImage> img(do_GetInterface(mImageFrame));
img->SetHasNoAlpha();
}
}
mCurrentRow = mLastFlushedRow = -1;
mCurrentPass = mLastFlushedPass = 0;
@ -458,6 +464,17 @@ PRUint32 nsGIFDecoder2::OutputRow()
*--to = cmap[*--from];
}
// check for alpha (only for first frame)
if (mGIFStruct.is_transparent && !mSawTransparency) {
const PRUint32 *rgb = (PRUint32*)rowp;
for (PRUint32 i = mGIFStruct.width; i > 0; i--) {
if (*rgb++ == 0) {
mSawTransparency = PR_TRUE;
break;
}
}
}
// Duplicate rows
if (drow_end > drow_start) {
// irow is the current row filled

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

@ -99,6 +99,7 @@ private:
PRUint8 mCurrentPass;
PRUint8 mLastFlushedPass;
PRPackedBool mGIFOpen;
PRPackedBool mSawTransparency;
gif_struct mGIFStruct;
};