зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
5d230e1ed7
Коммит
f2bab4cf0c
|
@ -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;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче