diff options
author | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-30 21:18:07 +0000 |
---|---|---|
committer | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-30 21:18:07 +0000 |
commit | 74681d3483621cf8081c6f42bb63b4cff8d349f3 (patch) | |
tree | e640a4593fad44adc4ca480160d1011d6cd4283e /chrome/browser | |
parent | 295f61885be7e1104502185f3322e3bcacdc5f00 (diff) | |
download | chromium_src-74681d3483621cf8081c6f42bb63b4cff8d349f3.zip chromium_src-74681d3483621cf8081c6f42bb63b4cff8d349f3.tar.gz chromium_src-74681d3483621cf8081c6f42bb63b4cff8d349f3.tar.bz2 |
linux: use XShmPutImage when SHM Pixmap APIs unavailable
SHM Pixmaps were frequently unavailable (which makes some
sense: you're asking for a shared memory handle into a
graphics-card-side memory buffer). But we can still do
an SHM copy from pixels->pixmap as long as we only go in
write only direction, via the XShmPutImage API.
BUG=31301
Review URL: http://codereview.chromium.org/522023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35390 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/renderer_host/backing_store.h | 4 | ||||
-rw-r--r-- | chrome/browser/renderer_host/backing_store_x.cc | 99 |
2 files changed, 62 insertions, 41 deletions
diff --git a/chrome/browser/renderer_host/backing_store.h b/chrome/browser/renderer_host/backing_store.h index d52e560..28640ba 100644 --- a/chrome/browser/renderer_host/backing_store.h +++ b/chrome/browser/renderer_host/backing_store.h @@ -160,8 +160,8 @@ class BackingStore { // This is the connection to the X server where this backing store will be // displayed. Display* const display_; - // If this is true, then |connection_| is good for MIT-SHM (X shared memory). - const bool use_shared_memory_; + // What flavor, if any, MIT-SHM (X shared memory) support we have. + const x11_util::SharedMemorySupport shared_memory_support_; // 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| diff --git a/chrome/browser/renderer_host/backing_store_x.cc b/chrome/browser/renderer_host/backing_store_x.cc index a1173b8..1cf4620 100644 --- a/chrome/browser/renderer_host/backing_store_x.cc +++ b/chrome/browser/renderer_host/backing_store_x.cc @@ -52,7 +52,7 @@ BackingStore::BackingStore(RenderWidgetHost* widget, : render_widget_host_(widget), size_(size), display_(x11_util::GetXDisplay()), - use_shared_memory_(x11_util::QuerySharedMemorySupport(display_)), + shared_memory_support_(x11_util::QuerySharedMemorySupport(display_)), use_render_(x11_util::QueryRenderSupport(display_)), visual_(visual), visual_depth_(depth), @@ -80,7 +80,7 @@ BackingStore::BackingStore(RenderWidgetHost* widget, const gfx::Size& size) : render_widget_host_(widget), size_(size), display_(NULL), - use_shared_memory_(false), + shared_memory_support_(x11_util::SHARED_MEMORY_NONE), use_render_(false), visual_(NULL), visual_depth_(-1), @@ -241,12 +241,9 @@ void BackingStore::PaintRect(base::ProcessHandle process, Picture picture; Pixmap pixmap; - if (use_shared_memory_) { - const XID shmseg = bitmap->MapToX(display_); - - XShmSegmentInfo shminfo; - memset(&shminfo, 0, sizeof(shminfo)); - shminfo.shmseg = shmseg; + if (shared_memory_support_ == x11_util::SHARED_MEMORY_PIXMAP) { + XShmSegmentInfo shminfo = {0}; + shminfo.shmseg = bitmap->MapToX(display_); // The NULL in the following is the |data| pointer: this is an artifact of // Xlib trying to be helpful, rather than just exposing the X protocol. It @@ -255,35 +252,58 @@ void BackingStore::PaintRect(base::ProcessHandle process, // 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, + width, height, 32); } 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 - // functions which try to convert the image into the format which the X - // server expects. The following values hopefully disable all conversions. - XImage image; - memset(&image, 0, sizeof(image)); - - image.width = width; - image.height = 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.red_mask = 0xff; - image.green_mask = 0xff00; - image.blue_mask = 0xff0000; - image.data = static_cast<char*>(bitmap->memory()); - + // We don't have shared memory pixmaps. Fall back to creating a pixmap + // ourselves and putting an image on it. pixmap = XCreatePixmap(display_, root_window_, width, 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); + + if (shared_memory_support_ == x11_util::SHARED_MEMORY_PUTIMAGE) { + const XID shmseg = bitmap->MapToX(display_); + + XShmSegmentInfo shminfo; + memset(&shminfo, 0, sizeof(shminfo)); + shminfo.shmseg = shmseg; + shminfo.shmaddr = static_cast<char*>(bitmap->memory()); + + // TODO(evanm): verify that Xlib isn't doing any conversions here. + XImage* image = XShmCreateImage(display_, static_cast<Visual*>(visual_), + 32, ZPixmap, + shminfo.shmaddr, &shminfo, + width, height); + XShmPutImage(display_, pixmap, gc, image, + 0, 0 /* source x, y */, 0, 0 /* dest x, y */, + width, height, False /* send_event */); + XDestroyImage(image); + } else { // case SHARED_MEMORY_NONE + // 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 functions which try to convert the + // image into the format which the X server expects. The + // following values hopefully disable all conversions. + XImage image; + memset(&image, 0, sizeof(image)); + + image.width = width; + image.height = 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.red_mask = 0xff; + image.green_mask = 0xff00; + image.blue_mask = 0xff0000; + image.data = static_cast<char*>(bitmap->memory()); + + XPutImage(display_, pixmap, gc, &image, + 0, 0 /* source x, y */, 0, 0 /* dest x, y */, + width, height); + } XFreeGC(display_, gc); } @@ -303,8 +323,9 @@ void BackingStore::PaintRect(base::ProcessHandle process, copy_rect.height()); // 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. - if (use_shared_memory_) + // we are sure that the X server has finished reading from the shared memory + // segment. + if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE) XSync(display_, False); XRenderFreePicture(display_, picture); @@ -383,7 +404,7 @@ SkBitmap BackingStore::PaintRectToBitmap(const gfx::Rect& rect) { XImage* image; XShmSegmentInfo shminfo; // Used only when shared memory is enabled. - if (use_shared_memory_) { + if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE) { // Use shared memory for faster copies when it's available. Visual* visual = static_cast<Visual*>(visual_); memset(&shminfo, 0, sizeof(shminfo)); @@ -422,7 +443,7 @@ SkBitmap BackingStore::PaintRectToBitmap(const gfx::Rect& rect) { // TODO(jhawkins): Need to convert the image data if the image bits per pixel // is not 32. if (image->bits_per_pixel != 32) { - if (use_shared_memory_) + if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE) DestroySharedImage(display_, image, &shminfo); else XDestroyImage(image); @@ -439,7 +460,7 @@ SkBitmap BackingStore::PaintRectToBitmap(const gfx::Rect& rect) { reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)); memcpy(bitmap_data, image->data, image->bytes_per_line * height); - if (use_shared_memory_) + if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE) DestroySharedImage(display_, image, &shminfo); else XDestroyImage(image); |