Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(281)

Unified Diff: chrome/browser/renderer_host/backing_store_x.cc

Issue 108040: Send array of paint rects and bitmaps as opposed to a Union (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/renderer_host/backing_store_x.cc
===================================================================
--- chrome/browser/renderer_host/backing_store_x.cc (revision 17347)
+++ chrome/browser/renderer_host/backing_store_x.cc (working copy)
@@ -77,17 +77,23 @@
}
void BackingStore::PaintRectWithoutXrender(TransportDIB* bitmap,
- const gfx::Rect &bitmap_rect) {
- const int width = bitmap_rect.width();
- const int height = bitmap_rect.height();
- Pixmap pixmap = XCreatePixmap(display_, root_window_, width, height,
- visual_depth_);
+ const gfx::Rect& bitmap_rect,
+ const gfx::Rect& paint_rect) {
+ DCHECK(bitmap_rect.Contains(paint_rect) &&
+ paint_rect.x() < kMaxBitmapLengthAllowed &&
+ paint_rect.y() < kMaxBitmapLengthAllowed);
+ const int paint_width = paint_rect.width();
+ const int paint_height = paint_rect.height();
+ Pixmap pixmap = XCreatePixmap(display_, root_window_, paint_width,
+ paint_height, visual_depth_);
+ const int bitmap_width = bitmap_rect.width();
+ const int bitmap_height = bitmap_rect.height();
XImage image;
memset(&image, 0, sizeof(image));
- image.width = width;
- image.height = height;
+ image.width = bitmap_width;
+ image.height = bitmap_height;
image.format = ZPixmap;
image.byte_order = LSBFirst;
image.bitmap_unit = 8;
@@ -96,16 +102,18 @@
image.green_mask = 0xff00;
image.blue_mask = 0xff0000;
+ const int x_offset = paint_rect.x() - bitmap_rect.x();
+ const int y_offset = paint_rect.y() - bitmap_rect.y();
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.bytes_per_line = bitmap_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);
+ x_offset, y_offset /* source x, y */, 0, 0 /* dest x, y */,
+ paint_width, paint_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
@@ -114,48 +122,64 @@
// 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));
+ uint8_t* bitmap24 = static_cast<uint8_t*>(malloc(3 * paint_width *
+ paint_height));
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 int x_limit = paint_rect.right() - bitmap_rect.x();
+ const int y_limit = paint_rect.bottom() - bitmap_rect.y();
+ const int row_length = bitmap_width;
+ bitmap_in += row_length * y_offset;
+ for (int y = y_offset; y < y_limit; ++y) {
+ bitmap_in += x_offset;
+ for (int x = x_offset; x < x_limit; ++x) {
const uint32_t pixel = *(bitmap_in++);
bitmap24[0] = (pixel >> 16) & 0xff;
bitmap24[1] = (pixel >> 8) & 0xff;
bitmap24[2] = pixel & 0xff;
bitmap24 += 3;
}
+ bitmap_in += row_length - x_limit;
}
+ image.width = paint_width;
+ image.height = paint_height;
image.depth = visual_depth_;
image.bits_per_pixel = 24;
- image.bytes_per_line = width * 3;
+ image.bytes_per_line = paint_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);
+ paint_width, paint_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.
- uint16_t* bitmap16 = static_cast<uint16_t*>(malloc(2 * width * height));
+ uint16_t* bitmap16 = static_cast<uint16_t*>(malloc(2 * paint_width *
+ paint_height));
uint16_t* const orig_bitmap16 = bitmap16;
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 int x_limit = paint_rect.right() - bitmap_rect.x();
+ const int y_limit = paint_rect.bottom() - bitmap_rect.y();
+ const int row_length = bitmap_width;
+ bitmap_in += row_length * y_offset;
+ for (int y = y_offset; y < y_limit; ++y) {
+ bitmap_in += x_offset;
+ for (int x = x_offset; x < x_limit; ++x) {
const uint32_t pixel = *(bitmap_in++);
uint16_t out_pixel = ((pixel >> 8) & 0xf800) |
((pixel >> 5) & 0x07e0) |
((pixel >> 3) & 0x001f);
*(bitmap16++) = out_pixel;
}
+ bitmap_in += row_length - x_limit;
}
image.depth = visual_depth_;
image.bits_per_pixel = 16;
- image.bytes_per_line = width * 2;
+ image.bytes_per_line = paint_width * 2;
image.data = reinterpret_cast<char*>(orig_bitmap16);
image.red_mask = 0xf800;
@@ -164,7 +188,7 @@
XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image,
0, 0 /* source x, y */, 0, 0 /* dest x, y */,
- width, height);
+ paint_width, paint_height);
free(orig_bitmap16);
} else {
CHECK(false) << "Sorry, we don't support your visual depth without "
@@ -174,15 +198,19 @@
XCopyArea(display_, pixmap /* source */, pixmap_ /* target */,
static_cast<GC>(pixmap_gc_),
- 0, 0 /* source x, y */, bitmap_rect.width(), bitmap_rect.height(),
- bitmap_rect.x(), bitmap_rect.y() /* dest x, y */);
+ 0, 0 /* source x, y */, paint_width, paint_height,
+ paint_rect.x(), paint_rect.y() /* dest x, y */);
XFreePixmap(display_, pixmap);
}
void BackingStore::PaintRect(base::ProcessHandle process,
TransportDIB* bitmap,
- const gfx::Rect& bitmap_rect) {
+ const gfx::Rect& bitmap_rect,
+ const gfx::Rect& paint_rect) {
+ DCHECK(bitmap_rect.Contains(paint_rect) &&
+ paint_rect.x() < kMaxBitmapLengthAllowed &&
+ paint_rect.y() < kMaxBitmapLengthAllowed);
if (!display_)
return;
@@ -190,10 +218,16 @@
return;
if (!use_render_)
- return PaintRectWithoutXrender(bitmap, bitmap_rect);
+ return PaintRectWithoutXrender(bitmap, bitmap_rect, paint_rect);
- const int width = bitmap_rect.width();
- const int height = bitmap_rect.height();
+ const int paint_width = paint_rect.width();
+ const int paint_height = paint_rect.height();
+
+ // The values for the position of the source rect within the bitmap when
+ // we render the composite depends on the usage of shared memory or not.
+ int src_x = 0;
+ int src_y = 0;
+
Picture picture;
Pixmap pixmap;
@@ -211,8 +245,11 @@
// difference between the |data| pointer and the address of the mapping in
// |shminfo|. Since both are NULL, the offset will be calculated to be 0,
// which is correct for us.
- pixmap = XShmCreatePixmap(display_, root_window_, NULL, &shminfo, width,
- height, 32);
+ pixmap = XShmCreatePixmap(display_, root_window_, NULL, &shminfo,
+ bitmap_rect.width(), bitmap_rect.height(), 32);
+ // Since we use the whole source bitmap, we must offset the source.
+ src_x = paint_rect.x() - bitmap_rect.x();
+ src_y = paint_rect.y() - bitmap_rect.y();
} else {
// No shared memory support, we have to copy the bitmap contents to the X
// server. Xlib wraps the underlying PutImage call behind several layers of
@@ -221,34 +258,36 @@
XImage image;
memset(&image, 0, sizeof(image));
- image.width = width;
- image.height = height;
+ image.width = paint_width;
+ image.height = paint_height;
image.depth = 32;
image.bits_per_pixel = 32;
image.format = ZPixmap;
image.byte_order = LSBFirst;
image.bitmap_unit = 8;
image.bitmap_bit_order = LSBFirst;
- image.bytes_per_line = width * 4;
+ image.bytes_per_line = paint_width * 4;
image.red_mask = 0xff;
image.green_mask = 0xff00;
image.blue_mask = 0xff0000;
+ // TODO(agl): check if we can make this more efficient.
image.data = static_cast<char*>(bitmap->memory());
- pixmap = XCreatePixmap(display_, root_window_, width, height, 32);
+ pixmap = XCreatePixmap(display_, root_window_, paint_width, paint_height,
+ 32);
GC gc = XCreateGC(display_, pixmap, 0, NULL);
- XPutImage(display_, pixmap, gc, &image,
- 0, 0 /* source x, y */, 0, 0 /* dest x, y */,
- width, height);
+ XPutImage(display_, pixmap, gc, &image, paint_rect.x() - bitmap_rect.x(),
+ paint_rect.y() - bitmap_rect.y() /* source x, y */,
+ 0, 0 /* dest x, y */, paint_width, paint_height);
XFreeGC(display_, gc);
}
picture = x11_util::CreatePictureFromSkiaPixmap(display_, pixmap);
XRenderComposite(display_, PictOpSrc, picture /* source */, 0 /* mask */,
- picture_ /* dest */, 0, 0 /* source x, y */,
+ picture_ /* dest */, src_x, src_y /* source x, y */,
0, 0 /* mask x, y */,
- bitmap_rect.x(), bitmap_rect.y() /* target x, y */,
- width, height);
+ paint_rect.x(), paint_rect.y() /* target x, y */,
+ paint_width, paint_height);
// In the case of shared memory, we wait for the composite to complete so that
// we are sure that the X server has finished reading.
@@ -295,7 +334,7 @@
}
}
- PaintRect(process, bitmap, bitmap_rect);
+ PaintRect(process, bitmap, bitmap_rect, bitmap_rect);
}
void BackingStore::ShowRect(const gfx::Rect& rect, XID target) {

Powered by Google App Engine
This is Rietveld 408576698