diff options
author | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-22 17:58:51 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-22 17:58:51 +0000 |
commit | c6036166832b540d1a0d32fc94fbfd87f5510f88 (patch) | |
tree | db6cd5d5e9bc8623c138f9c7d3bb59e8361284e6 /chrome | |
parent | 390e55e7e0e4e749e1380093a6ca2be3a491ac65 (diff) | |
download | chromium_src-c6036166832b540d1a0d32fc94fbfd87f5510f88.zip chromium_src-c6036166832b540d1a0d32fc94fbfd87f5510f88.tar.gz chromium_src-c6036166832b540d1a0d32fc94fbfd87f5510f88.tar.bz2 |
Flip red and blue channels for painting in 24-bit bpp without Xrender.
Also clean up the code a bit.
BUG=12206
TEST=Start VNC4 with -depth 24, make sure Chromium displays red and blue coorectly on webpages.
Review URL: http://codereview.chromium.org/126256
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18915 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/renderer_host/backing_store.h | 7 | ||||
-rw-r--r-- | chrome/browser/renderer_host/backing_store_x.cc | 92 |
2 files changed, 49 insertions, 50 deletions
diff --git a/chrome/browser/renderer_host/backing_store.h b/chrome/browser/renderer_host/backing_store.h index 2214518..3438bda3 100644 --- a/chrome/browser/renderer_host/backing_store.h +++ b/chrome/browser/renderer_host/backing_store.h @@ -54,10 +54,8 @@ class BackingStore { // Returns true if we should convert to the monitor profile when painting. static bool ColorManagementEnabled(); - #elif defined(OS_MACOSX) skia::PlatformCanvas* canvas() { return &canvas_; } - #elif defined(OS_LINUX) // Copy from the server-side backing store to the target window // display: the display of the backing store and target window @@ -91,7 +89,6 @@ class BackingStore { gfx::Size size_; #if defined(OS_WIN) - // The backing store dc. HDC hdc_; // Handle to the backing store dib. @@ -110,13 +107,15 @@ class BackingStore { // This is the connection to the X server where this backing store will be // displayed. - Display *const display_; + Display* const display_; // If this is true, then |connection_| is good for MIT-SHM (X shared memory). const bool use_shared_memory_; // If this is true, then we can use Xrender to composite our pixmaps. const bool use_render_; // If |use_render_| is false, this is the number of bits-per-pixel for |depth| int pixmap_bpp_; + // if |use_render_| is false, we need the Visual to get the RGB masks. + void* const visual_; // This is the depth of the target window. const int visual_depth_; // The parent window (probably a GtkDrawingArea) for this backing store. diff --git a/chrome/browser/renderer_host/backing_store_x.cc b/chrome/browser/renderer_host/backing_store_x.cc index de32370..9083dfc 100644 --- a/chrome/browser/renderer_host/backing_store_x.cc +++ b/chrome/browser/renderer_host/backing_store_x.cc @@ -34,6 +34,7 @@ BackingStore::BackingStore(RenderWidgetHost* widget, display_(x11_util::GetXDisplay()), use_shared_memory_(x11_util::QuerySharedMemorySupport(display_)), use_render_(x11_util::QueryRenderSupport(display_)), + visual_(visual), visual_depth_(depth), root_window_(x11_util::GetX11RootWindow()) { COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian); @@ -61,6 +62,7 @@ BackingStore::BackingStore(RenderWidgetHost* widget, const gfx::Size& size) display_(NULL), use_shared_memory_(false), use_render_(false), + visual_(NULL), visual_depth_(-1), root_window_(0) { } @@ -91,52 +93,54 @@ void BackingStore::PaintRectWithoutXrender(TransportDIB* bitmap, image.byte_order = LSBFirst; image.bitmap_unit = 8; image.bitmap_bit_order = LSBFirst; - image.red_mask = 0xff; - image.green_mask = 0xff00; - image.blue_mask = 0xff0000; + image.depth = visual_depth_; + image.bits_per_pixel = pixmap_bpp_; + image.bytes_per_line = width * pixmap_bpp_ / 8; if (pixmap_bpp_ == 32) { - // If the X server depth is already 32-bits, then our job is easy. - image.depth = visual_depth_; - image.bits_per_pixel = 32; - image.bytes_per_line = width * 4; - image.data = static_cast<char*>(bitmap->memory()); - - XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image, - 0, 0 /* source x, y */, 0, 0 /* dest x, y */, - width, height); - } else if (pixmap_bpp_ == 24) { - // In this case we just need to strip the alpha channel out of each - // pixel. This is the case which covers VNC servers since they don't - // support Xrender but typically have 24-bit visuals. - // - // It's possible to use some fancy SSE tricks here, but since this is the - // slow path anyway, we do it slowly. - - uint8_t* bitmap24 = static_cast<uint8_t*>(malloc(3 * width * height)); - if (!bitmap24) - return; - const uint32_t* bitmap_in = static_cast<const uint32_t*>(bitmap->memory()); - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - const uint32_t pixel = *(bitmap_in++); - bitmap24[0] = (pixel >> 16) & 0xff; - bitmap24[1] = (pixel >> 8) & 0xff; - bitmap24[2] = pixel & 0xff; - bitmap24 += 3; + image.red_mask = 0xff0000; + image.green_mask = 0xff00; + image.blue_mask = 0xff; + + // If the X server depth is already 32-bits and the color masks match, + // then our job is easy. + Visual* vis = static_cast<Visual*>(visual_); + if (image.red_mask == vis->red_mask && + image.green_mask == vis->green_mask && + image.blue_mask == vis->blue_mask) { + image.data = static_cast<char*>(bitmap->memory()); + XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image, + 0, 0 /* source x, y */, 0, 0 /* dest x, y */, + width, height); + } else { + // Otherwise, we need to shuffle the colors around. Assume red and blue + // need to be swapped. + // + // It's possible to use some fancy SSE tricks here, but since this is the + // slow path anyway, we do it slowly. + + uint8_t* bitmap32 = static_cast<uint8_t*>(malloc(4 * width * height)); + if (!bitmap32) + return; + uint8_t* const orig_bitmap32 = bitmap32; + const uint32_t* bitmap_in = + static_cast<const uint32_t*>(bitmap->memory()); + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + const uint32_t pixel = *(bitmap_in++); + bitmap32[0] = (pixel >> 16) & 0xff; // Red + bitmap32[1] = (pixel >> 8) & 0xff; // Green + bitmap32[2] = pixel & 0xff; // Blue + bitmap32[3] = (pixel >> 24) & 0xff; // Alpha + bitmap32 += 4; + } } + image.data = reinterpret_cast<char*>(orig_bitmap32); + XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image, + 0, 0 /* source x, y */, 0, 0 /* dest x, y */, + width, height); + free(orig_bitmap32); } - - image.depth = visual_depth_; - image.bits_per_pixel = 24; - image.bytes_per_line = width * 3; - image.data = reinterpret_cast<char*>(bitmap24); - - XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image, - 0, 0 /* source x, y */, 0, 0 /* dest x, y */, - width, height); - - free(bitmap24); } else if (pixmap_bpp_ == 16) { // Some folks have VNC setups which still use 16-bit visuals and VNC // doesn't include Xrender. @@ -156,11 +160,7 @@ void BackingStore::PaintRectWithoutXrender(TransportDIB* bitmap, } } - image.depth = visual_depth_; - image.bits_per_pixel = 16; - image.bytes_per_line = width * 2; image.data = reinterpret_cast<char*>(orig_bitmap16); - image.red_mask = 0xf800; image.green_mask = 0x07e0; image.blue_mask = 0x001f; |