summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-22 17:58:51 +0000
committerthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-22 17:58:51 +0000
commitc6036166832b540d1a0d32fc94fbfd87f5510f88 (patch)
treedb6cd5d5e9bc8623c138f9c7d3bb59e8361284e6 /chrome
parent390e55e7e0e4e749e1380093a6ca2be3a491ac65 (diff)
downloadchromium_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.h7
-rw-r--r--chrome/browser/renderer_host/backing_store_x.cc92
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;