From 2f5e014ed0da5715a5104d4625236156f7a1d61a Mon Sep 17 00:00:00 2001 From: Oleg Romashin Date: Fri, 11 Jun 2010 05:33:22 -0400 Subject: [PATCH] Bug 545632 - Add 16bpp format support enabler. r=jmuizelaar --- gfx/layers/basic/BasicImages.cpp | 2 +- gfx/thebes/public/gfxASurface.h | 3 +++ gfx/thebes/src/gfxASurface.cpp | 18 ++++++++++++++++++ gfx/thebes/src/gfxImageSurface.cpp | 2 ++ gfx/thebes/src/gfxPlatformGtk.cpp | 30 ++++++------------------------ gfx/thebes/src/gfxQtPlatform.cpp | 28 ++++++---------------------- gfx/thebes/src/gfxXlibSurface.cpp | 22 ++++++++++++++++++++++ widget/src/qt/nsNativeThemeQt.cpp | 2 ++ widget/src/qt/nsWindow.cpp | 5 +++++ 9 files changed, 65 insertions(+), 47 deletions(-) diff --git a/gfx/layers/basic/BasicImages.cpp b/gfx/layers/basic/BasicImages.cpp index d424c7ea0522..bbc62e3fd798 100644 --- a/gfx/layers/basic/BasicImages.cpp +++ b/gfx/layers/basic/BasicImages.cpp @@ -188,7 +188,7 @@ BasicPlanarYCbCrImage::GetAsSurface() } nsRefPtr imgSurface = new gfxImageSurface(mBuffer, mSize, - mSize.width * 4, + mSize.width * gfxASurface::BytePerPixelFromFormat(gfxASurface::ImageFormatRGB24), gfxASurface::ImageFormatRGB24); if (!imgSurface) { return nsnull; diff --git a/gfx/thebes/public/gfxASurface.h b/gfx/thebes/public/gfxASurface.h index 3ffa85a876bc..904f9b887d20 100644 --- a/gfx/thebes/public/gfxASurface.h +++ b/gfx/thebes/public/gfxASurface.h @@ -68,6 +68,7 @@ public: ImageFormatRGB24, ///< xRGB data in native endianness ImageFormatA8, ///< Only an alpha channel ImageFormatA1, ///< Packed transparency information (one byte refers to 8 pixels) + ImageFormatRGB16_565, ///< RGB_565 data in native endianness ImageFormatUnknown } gfxImageFormat; @@ -187,6 +188,8 @@ public: PRInt32 KnownMemoryUsed() { return mBytesRecorded; } + static PRInt32 BytePerPixelFromFormat(gfxImageFormat format); + protected: gfxASurface() : mSurface(nsnull), mFloatingRefs(0), mBytesRecorded(0), mSurfaceValid(PR_FALSE) { } diff --git a/gfx/thebes/src/gfxASurface.cpp b/gfx/thebes/src/gfxASurface.cpp index f2d79fb56f77..bdfe409e8f13 100644 --- a/gfx/thebes/src/gfxASurface.cpp +++ b/gfx/thebes/src/gfxASurface.cpp @@ -406,6 +406,7 @@ gfxASurface::ContentFromFormat(gfxImageFormat format) case ImageFormatARGB32: return CONTENT_COLOR_ALPHA; case ImageFormatRGB24: + case ImageFormatRGB16_565: return CONTENT_COLOR; case ImageFormatA8: case ImageFormatA1: @@ -417,6 +418,23 @@ gfxASurface::ContentFromFormat(gfxImageFormat format) } } +PRInt32 +gfxASurface::BytePerPixelFromFormat(gfxImageFormat format) +{ + switch (format) { + case ImageFormatARGB32: + case ImageFormatRGB24: + return 4; + case ImageFormatRGB16_565: + return 2; + case ImageFormatA8: + return 1; + default: + NS_WARNING("Unknown byte per pixel value for Image format"); + } + return 0; +} + /** Memory reporting **/ static const char *sSurfaceNamesForSurfaceType[] = { diff --git a/gfx/thebes/src/gfxImageSurface.cpp b/gfx/thebes/src/gfxImageSurface.cpp index 93fbc156a79d..f7f1085634ce 100644 --- a/gfx/thebes/src/gfxImageSurface.cpp +++ b/gfx/thebes/src/gfxImageSurface.cpp @@ -146,6 +146,8 @@ gfxImageSurface::ComputeStride() const stride = mSize.width * 4; else if (mFormat == ImageFormatRGB24) stride = mSize.width * 4; + else if (mFormat == ImageFormatRGB16_565) + stride = mSize.width * 2; else if (mFormat == ImageFormatA8) stride = mSize.width; else if (mFormat == ImageFormatA1) { diff --git a/gfx/thebes/src/gfxPlatformGtk.cpp b/gfx/thebes/src/gfxPlatformGtk.cpp index 89a773be804f..b2f4e8a79580 100644 --- a/gfx/thebes/src/gfxPlatformGtk.cpp +++ b/gfx/thebes/src/gfxPlatformGtk.cpp @@ -171,29 +171,6 @@ gfxPlatformGtk::CreateOffscreenSurface(const gfxIntSize& size, sizeOk = PR_FALSE; #ifdef MOZ_X11 - int glitzf; - int xrenderFormatID; - switch (imageFormat) { - case gfxASurface::ImageFormatARGB32: - glitzf = 0; // GLITZ_STANDARD_ARGB32; - xrenderFormatID = PictStandardARGB32; - break; - case gfxASurface::ImageFormatRGB24: - glitzf = 1; // GLITZ_STANDARD_RGB24; - xrenderFormatID = PictStandardRGB24; - break; - case gfxASurface::ImageFormatA8: - glitzf = 2; // GLITZ_STANDARD_A8; - xrenderFormatID = PictStandardA8; - break; - case gfxASurface::ImageFormatA1: - glitzf = 3; // GLITZ_STANDARD_A1; - xrenderFormatID = PictStandardA1; - break; - default: - return nsnull; - } - // XXX we really need a different interface here, something that passes // in more context, including the display and/or target surface type that // we should try to match @@ -202,8 +179,13 @@ gfxPlatformGtk::CreateOffscreenSurface(const gfxIntSize& size, return nsnull; GdkPixmap* pixmap = nsnull; + // try to optimize it for 16bpp default screen + if (gfxASurface::ImageFormatRGB24 == imageFormat + && 16 == gdk_visual_get_system()->depth) + imageFormat = gfxASurface::ImageFormatRGB16_565; + XRenderPictFormat* xrenderFormat = - XRenderFindStandardFormat(display, xrenderFormatID); + gfxXlibSurface::FindRenderFormat(display, imageFormat); if (xrenderFormat && sizeOk) { pixmap = gdk_pixmap_new(nsnull, size.width, size.height, diff --git a/gfx/thebes/src/gfxQtPlatform.cpp b/gfx/thebes/src/gfxQtPlatform.cpp index 016195da5eb1..4338892ea01b 100644 --- a/gfx/thebes/src/gfxQtPlatform.cpp +++ b/gfx/thebes/src/gfxQtPlatform.cpp @@ -194,6 +194,11 @@ gfxQtPlatform::CreateOffscreenSurface(const gfxIntSize& size, { nsRefPtr newSurface = nsnull; + // try to optimize it for 16bpp screen + if (gfxASurface::ImageFormatRGB24 == imageFormat + && 16 == QX11Info().depth()) + imageFormat = gfxASurface::ImageFormatRGB16_565; + if (mRenderMode == RENDER_QPAINTER) { newSurface = new gfxQPainterSurface(size, gfxASurface::ContentFromFormat(imageFormat)); return newSurface.forget(); @@ -206,29 +211,8 @@ gfxQtPlatform::CreateOffscreenSurface(const gfxIntSize& size, } #ifdef MOZ_X11 - int xrenderFormatID = -1; - switch (imageFormat) { - case gfxASurface::ImageFormatARGB32: - xrenderFormatID = PictStandardARGB32; - break; - case gfxASurface::ImageFormatRGB24: - xrenderFormatID = PictStandardRGB24; - break; - case gfxASurface::ImageFormatA8: - xrenderFormatID = PictStandardA8; - break; - case gfxASurface::ImageFormatA1: - xrenderFormatID = PictStandardA1; - break; - default: - return nsnull; - } - - // XXX we really need a different interface here, something that passes - // in more context, including the display and/or target surface type that - // we should try to match XRenderPictFormat* xrenderFormat = - XRenderFindStandardFormat(QX11Info().display(), xrenderFormatID); + gfxXlibSurface::FindRenderFormat(QX11Info().display(), imageFormat); newSurface = new gfxXlibSurface((Display*)QX11Info().display(), xrenderFormat, diff --git a/gfx/thebes/src/gfxXlibSurface.cpp b/gfx/thebes/src/gfxXlibSurface.cpp index 356acf1732b5..2ac7d0ff0e20 100644 --- a/gfx/thebes/src/gfxXlibSurface.cpp +++ b/gfx/thebes/src/gfxXlibSurface.cpp @@ -158,6 +158,28 @@ gfxXlibSurface::FindRenderFormat(Display *dpy, gfxImageFormat format) case ImageFormatRGB24: return XRenderFindStandardFormat (dpy, PictStandardRGB24); break; + case ImageFormatRGB16_565: { + // PictStandardRGB16_565 is not standard Xrender format + // we should try to find related visual + // and find xrender format by visual + Visual *visual = NULL; + Screen *screen = DefaultScreenOfDisplay(dpy); + int j; + for (j = 0; j < screen->ndepths; j++) { + Depth *d = &screen->depths[j]; + if (d->depth == 16 && d->nvisuals && &d->visuals[0]) { + if (d->visuals[0].red_mask == 0xf800 && + d->visuals[0].green_mask == 0x7e0 && + d->visuals[0].blue_mask == 0x1f) + visual = &d->visuals[0]; + break; + } + } + if (!visual) + return NULL; + return XRenderFindVisualFormat(dpy, visual); + break; + } case ImageFormatA8: return XRenderFindStandardFormat (dpy, PictStandardA8); break; diff --git a/widget/src/qt/nsNativeThemeQt.cpp b/widget/src/qt/nsNativeThemeQt.cpp index 43a46db802cd..ab3222059361 100644 --- a/widget/src/qt/nsNativeThemeQt.cpp +++ b/widget/src/qt/nsNativeThemeQt.cpp @@ -105,6 +105,8 @@ _qimage_from_gfximage_format (gfxASurface::gfxImageFormat aFormat) return QImage::Format_ARGB32_Premultiplied; case gfxASurface::ImageFormatRGB24: return QImage::Format_RGB32; + case gfxASurface::ImageFormatRGB16_565: + return QImage::Format_RGB16; case gfxASurface::ImageFormatA8: return QImage::Format_Indexed8; case gfxASurface::ImageFormatA1: diff --git a/widget/src/qt/nsWindow.cpp b/widget/src/qt/nsWindow.cpp index 53719c338560..913a4c486236 100644 --- a/widget/src/qt/nsWindow.cpp +++ b/widget/src/qt/nsWindow.cpp @@ -210,6 +210,8 @@ _depth_to_gfximage_format(PRInt32 aDepth) return gfxASurface::ImageFormatARGB32; case 24: return gfxASurface::ImageFormatRGB24; + case 16: + return gfxASurface::ImageFormatRGB16_565; default: return gfxASurface::ImageFormatUnknown; } @@ -220,8 +222,11 @@ _gfximage_to_qformat(gfxASurface::gfxImageFormat aFormat) { switch (aFormat) { case gfxASurface::ImageFormatARGB32: + return QImage::Format_ARGB32_Premultiplied; case gfxASurface::ImageFormatRGB24: return QImage::Format_ARGB32; + case gfxASurface::ImageFormatRGB16_565: + return QImage::Format_RGB16; default: return QImage::Format_Invalid; }