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

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

Issue 27147: Linux: server side backing stores (Closed)
Patch Set: ... Created 11 years, 10 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
diff --git a/chrome/browser/renderer_host/backing_store_x.cc b/chrome/browser/renderer_host/backing_store_x.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b4a7caed6f321d63ffa41c5b1c6e632814da601f
--- /dev/null
+++ b/chrome/browser/renderer_host/backing_store_x.cc
@@ -0,0 +1,169 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/renderer_host/backing_store.h"
+
+#include <utility>
+
+#include "base/logging.h"
+#include "chrome/common/transport_dib.h"
+#include "chrome/common/x11_util.h"
+#include "chrome/common/x11_util_internal.h"
+
+// X Backing Stores:
+//
+// Unlike Windows, where the backing store is kept in heap memory, we keep our
+// backing store in the X server, as a pixmap. Thus expose events just require
+// instructing the X server to copy from the backing store to the window.
+//
+// The backing store is in the same format as the visual which our main window
+// is using. Bitmaps from the renderer are uploaded to the X server, either via
+// shared memory or over the wire, and XRENDER is used to convert them to the
+// correct format for the backing store.
+
+BackingStore::BackingStore(const gfx::Size& size,
+ Display* display,
+ int depth,
+ void* visual,
+ Drawable parent_window,
+ bool use_shared_memory)
+ : size_(size),
+ display_(display),
+ use_shared_memory_(use_shared_memory),
+ parent_window_(parent_window) {
+ const int width = size.width();
+ const int height = size.height();
+
+ pixmap_ = XCreatePixmap(display_, parent_window, width, height, depth);
+ picture_ = XRenderCreatePicture(
+ display_, pixmap_,
+ x11_util::GetRenderVisualFormat(display_, static_cast<Visual*>(visual)),
+ 0, NULL);
+ pixmap_gc_ = XCreateGC(display_, pixmap_, 0, NULL);
+}
+
+BackingStore::BackingStore(const gfx::Size& size)
+ : size_(size),
+ display_(NULL),
+ use_shared_memory_(false),
+ parent_window_(0) {
+}
+
+BackingStore::~BackingStore() {
+ // In unit tests, display_ may be NULL.
+ if (!display_)
+ return;
+
+ XRenderFreePicture(display_, picture_);
+ XFreePixmap(display_, pixmap_);
+ XFreeGC(display_, static_cast<GC>(pixmap_gc_));
+}
+
+void BackingStore::PaintRect(base::ProcessHandle process,
+ TransportDIB* bitmap,
+ const gfx::Rect& bitmap_rect) {
+ if (!display_)
+ return;
+
+ const int width = bitmap_rect.width();
+ const int height = bitmap_rect.height();
+ Picture picture;
+ Pixmap pixmap;
+
+ if (use_shared_memory_) {
+ const XID shmseg = bitmap->MapToX(display_);
+
+ XShmSegmentInfo shminfo;
+ memset(&shminfo, 0, sizeof(shminfo));
+ shminfo.shmseg = shmseg;
+
+ // 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
+ // assumes that we have the shared memory segment mapped into our memory,
+ // which we don't, and it's trying to calculate an offset by taking the
+ // 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_, parent_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());
+
+ pixmap = XCreatePixmap(display_, parent_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);
+ XFreeGC(display_, gc);
+ }
+
+ picture = x11_util::CreatePictureFromSkiaPixmap(display_, pixmap);
+ XRenderComposite(display_, PictOpSrc, picture /* source */, 0 /* mask */,
+ picture_ /* dest */, 0, 0 /* source x, y */,
+ 0, 0 /* mask x, y */,
+ bitmap_rect.x(), bitmap_rect.y() /* target x, y */,
+ width, 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_)
+ XSync(display_, False);
+
+ XRenderFreePicture(display_, picture);
+ XFreePixmap(display_, pixmap);
+}
+
+void BackingStore::ScrollRect(base::ProcessHandle process,
+ TransportDIB* bitmap,
+ const gfx::Rect& bitmap_rect,
+ int dx, int dy,
+ const gfx::Rect& clip_rect,
+ const gfx::Size& view_size) {
+ if (!display_)
+ return;
+
+ // We only support scrolling in one direction at a time.
+ DCHECK(dx == 0 || dy == 0);
+
+ if (dy) {
+ // Positive values of |dy| scroll up
+ XCopyArea(display_, pixmap_, pixmap_, static_cast<GC>(pixmap_gc_),
+ 0, std::max(0, -dy) /* source x, y */,
+ size_.width(), size_.height() - abs(dy),
+ 0, std::max(0, dy) /* dest x, y */);
+ } else if (dx) {
+ // Positive values of |dx| scroll right
+ XCopyArea(display_, pixmap_, pixmap_, static_cast<GC>(pixmap_gc_),
+ std::max(0, -dx), 0 /* source x, y */,
+ size_.width() - abs(dx), size_.height(),
+ std::max(0, dx), 0 /* dest x, y */);
+ }
+
+ PaintRect(process, bitmap, bitmap_rect);
+}
+
+void BackingStore::ShowRect(const gfx::Rect& rect) {
+ XCopyArea(display_, pixmap_, parent_window_, static_cast<GC>(pixmap_gc_),
+ rect.x(), rect.y(), rect.width(), rect.height(),
+ rect.x(), rect.y());
+}
« no previous file with comments | « chrome/browser/renderer_host/backing_store_win.cc ('k') | chrome/browser/renderer_host/backing_store_xcb.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698