diff -r -x CVS a/gfx/src/thebes/nsThebesImage.cpp b/gfx/src/thebes/nsThebesImage.cpp 23a24 > * Francis Robichaud 82a84,86 > #ifdef XP_UNIX > mTinySurf = nsnull; > #endif 333a338 > #ifndef XP_UNIX 335a341,342 > #endif > 337a345 > #ifndef XP_UNIX 338a347 > #endif 458a468,541 > #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 (subimageRect.Height() > destRect.Height() || > subimageRect.Width() > destRect.Width() || > xscale < 1.0 || yscale < 1.0) { > > gfxIntSize tinySize(NS_lroundf(destRect.Width()), NS_lroundf(destRect.Height())); > GdkPixbuf* tinyPix; > GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(mImageSurface->Data(), GDK_COLORSPACE_RGB, > PR_TRUE, 8, mWidth, mHeight, > mStride, nsnull, nsnull); > // We generate a new tiny surface > mTinySurf = new gfxImageSurface(tinySize, mFormat); > > if (!pixbuf) > return NS_ERROR_FAILURE; > > 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)); > } else { > tinyPix = pixbuf; > } > > if (!tinyPix) > return NS_ERROR_FAILURE; > > // XXX Shouldn't Cairo 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); > for (int i=0; i unsigned char* src = pixels + stride*i; > memcpy(mTinySurf->Data() + mTinySurf->Stride()*i, src, mTinySurf->Stride()); > } > > mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mTinySurf, mFormat); > > // 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) > // We always set these values when using a tiny surface > 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 (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); > } > #endif > diff -r -x CVS a/gfx/src/thebes/nsThebesImage.h b/gfx/src/thebes/nsThebesImage.h 43c43,46 < --- > #if defined(XP_UNIX) > #include > #include > #endif 173a177,179 > #if defined(XP_UNIX) > nsRefPtr mTinySurf; > #endif