diff -r -x CVS -x .svn a/gfx/src/thebes/nsThebesImage.cpp b/gfx/src/thebes/nsThebesImage.cpp 23a24 > * Francis Robichaud 50a52,56 > #ifdef XP_UNIX > static gfxFloat gImageThreshold = 0.5; > #include "nsIPrefBranch.h" > #include "nsIPrefService.h" > #endif 72,73c78,79 < static PRBool hasCheckedOptimize = PR_FALSE; < if (!hasCheckedOptimize) { --- > static PRBool hasLoadedStatic = PR_FALSE; > if (!hasLoadedStatic) { 77c83,93 < hasCheckedOptimize = PR_TRUE; --- > nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); > if (prefs) { > PRInt32 threshold; > nsresult rv = prefs->GetIntPref("browser.gdk_interpolation_threshold_percent", &threshold); > if (NS_SUCCEEDED(rv)) { > // Store a value between 1 and 100 > threshold = (threshold > 0 || threshold <= 100) ? threshold: gImageThreshold*100; > gImageThreshold = gfxFloat(threshold) / 100; > } > } > hasLoadedStatic = PR_TRUE; 82a99,102 > #ifdef XP_UNIX > mTinySurf = nsnull; > mSentFullImage = PR_FALSE; > #endif 333a354 > #ifndef XP_UNIX 335a357,358 > #endif > 337a361 > #ifndef XP_UNIX 338a363 > #endif 488a514,593 > #ifdef XP_UNIX > // We optimize the image surface to it's visible size and use scaling algorithms > // to reduce X memory consumption, bug 395260. > if (!mSentFullImage && > (subimageRect.size.width > (destRect.size.width / gImageThreshold) || > subimageRect.size.height > (destRect.size.height / gImageThreshold) || > xscale < (1.0 * gImageThreshold) || yscale < (1.0 * gImageThreshold) || > xscale > (1.0 / gImageThreshold) || yscale > (1.0 / gImageThreshold))) { > > gfxIntSize tinySize(NS_lroundf(destRect.size.width), NS_lroundf(destRect.size.height)); > GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(mImageSurface->Data(), GDK_COLORSPACE_RGB, > PR_TRUE, 8, mWidth, mHeight, > mStride, nsnull, nsnull); > if (!pixbuf) > return NS_ERROR_FAILURE; > > GdkPixbuf* tinyPix = pixbuf; > if (subimageRect.Height() > destRect.Height() || subimageRect.Width() > destRect.Width()) > tinyPix = gdk_pixbuf_new_subpixbuf(pixbuf, > NS_lroundf(srcRect.pos.x), > NS_lroundf(srcRect.pos.y), > NS_lroundf(srcRect.size.width), > NS_lroundf(srcRect.size.height)); > if (!tinyPix) > return NS_ERROR_FAILURE; > > // XXX Cairo should have it's own scaling algorithm for image surfaces and use Sun's mediaLib > // We can't allow a 1x1 downscaling, causes badalloc with gdk_pixbufs > if ((xscale != 1.0 || yscale != 1.0) && > (tinySize.width != 1 && tinySize.height != 1)) { > // Scales down the pixbuf, R and B channels are inverted but this should not cause any issue. > // XXX we should still verify how GDK_INTERP_BILINEAR reacts to this abstraction. > tinyPix = gdk_pixbuf_scale_simple(tinyPix, tinySize.width, tinySize.height, GDK_INTERP_BILINEAR); > if (!tinyPix) > return NS_ERROR_FAILURE; > > // Disables further scaling operation to avoid bug 364968 explained below. > xscale = 1.0; > yscale = 1.0; > } > > unsigned char* pixels = gdk_pixbuf_get_pixels(tinyPix); > PRInt32 stride = gdk_pixbuf_get_rowstride(tinyPix); > > // We generate a new tiny surface > mTinySurf = new gfxImageSurface(tinySize, mFormat); > > for (int i=0; i < tinySize.height; i++) { > unsigned char* src = pixels + stride*i; > memcpy(mTinySurf->Data() + mTinySurf->Stride()*i, src, mTinySurf->Stride()); > } > > mOptSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(tinySize, mFormat); > if (!mOptSurface || mOptSurface->CairoStatus() != 0) > return NS_ERROR_FAILURE; > > gfxContext tmpCtx(mOptSurface); > tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE); > tmpCtx.SetSource(mTinySurf); > tmpCtx.Paint(); > > // Release the gdk objects without affecting the actual image data > g_object_unref(tinyPix); > g_object_unref(pixbuf); > > // Origin could be different than (0,0) > subimageRect.pos.x -= srcRect.pos.x; > srcRect.pos.x -= srcRect.pos.x; > subimageRect.pos.y -= srcRect.pos.y; > srcRect.pos.y -= srcRect.pos.y; > > } else if (!mSentFullImage && (mTinySurf || !mOptSurface)) { > // We were using a tiny surface and we now see the full image, restore the complete pixmap > mTinySurf = nsnull; > // Send image to X > mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mImageSurface, mFormat); > mSentFullImage = GetIsImageComplete(); > } > #endif > 639c744 < --- > diff -r -x CVS -x .svn a/gfx/src/thebes/nsThebesImage.h b/gfx/src/thebes/nsThebesImage.h 43c43,47 < --- > #if defined(XP_UNIX) > #include > #include > #include "nsIServiceManager.h" > #endif 137c141 < --- > 173a178,181 > #if defined(XP_UNIX) > nsRefPtr mTinySurf; > PRBool mSentFullImage; > #endif