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

Side by Side Diff: chrome/browser/renderer_host/backing_store_x.cc

Issue 27227: Linux: support displays without Xrender support. (Closed)
Patch Set: ... Created 11 years, 9 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/renderer_host/backing_store.h" 5 #include "chrome/browser/renderer_host/backing_store.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/compiler_specific.h"
9 #include "base/logging.h" 10 #include "base/logging.h"
10 #include "chrome/common/transport_dib.h" 11 #include "chrome/common/transport_dib.h"
11 #include "chrome/common/x11_util.h" 12 #include "chrome/common/x11_util.h"
12 #include "chrome/common/x11_util_internal.h" 13 #include "chrome/common/x11_util_internal.h"
13 14
14 // X Backing Stores: 15 // X Backing Stores:
15 // 16 //
16 // Unlike Windows, where the backing store is kept in heap memory, we keep our 17 // Unlike Windows, where the backing store is kept in heap memory, we keep our
17 // backing store in the X server, as a pixmap. Thus expose events just require 18 // backing store in the X server, as a pixmap. Thus expose events just require
18 // instructing the X server to copy from the backing store to the window. 19 // instructing the X server to copy from the backing store to the window.
19 // 20 //
20 // The backing store is in the same format as the visual which our main window 21 // The backing store is in the same format as the visual which our main window
21 // is using. Bitmaps from the renderer are uploaded to the X server, either via 22 // is using. Bitmaps from the renderer are uploaded to the X server, either via
22 // shared memory or over the wire, and XRENDER is used to convert them to the 23 // shared memory or over the wire, and XRENDER is used to convert them to the
23 // correct format for the backing store. 24 // correct format for the backing store.
24 25
25 BackingStore::BackingStore(const gfx::Size& size, 26 BackingStore::BackingStore(const gfx::Size& size,
26 Display* display, 27 Display* display,
27 int depth, 28 int depth,
28 void* visual, 29 void* visual,
29 Drawable root_window, 30 Drawable root_window,
31 bool use_render,
30 bool use_shared_memory) 32 bool use_shared_memory)
31 : size_(size), 33 : size_(size),
32 display_(display), 34 display_(display),
33 use_shared_memory_(use_shared_memory), 35 use_shared_memory_(use_shared_memory),
36 use_render_(use_render),
37 visual_depth_(depth),
34 root_window_(root_window) { 38 root_window_(root_window) {
35 const int width = size.width(); 39 const int width = size.width();
36 const int height = size.height(); 40 const int height = size.height();
37 41
42 COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian);
43
38 pixmap_ = XCreatePixmap(display_, root_window, width, height, depth); 44 pixmap_ = XCreatePixmap(display_, root_window, width, height, depth);
39 picture_ = XRenderCreatePicture( 45
40 display_, pixmap_, 46 if (use_render_) {
41 x11_util::GetRenderVisualFormat(display_, static_cast<Visual*>(visual)), 47 picture_ = XRenderCreatePicture(
42 0, NULL); 48 display_, pixmap_,
49 x11_util::GetRenderVisualFormat(display_, static_cast<Visual*>(visual)),
50 0, NULL);
51 } else {
52 picture_ = 0;
53 pixmap_bpp_ = x11_util::BitsPerPixelForPixmapDepth(display, depth);
54 }
55
43 pixmap_gc_ = XCreateGC(display_, pixmap_, 0, NULL); 56 pixmap_gc_ = XCreateGC(display_, pixmap_, 0, NULL);
44 } 57 }
45 58
46 BackingStore::BackingStore(const gfx::Size& size) 59 BackingStore::BackingStore(const gfx::Size& size)
47 : size_(size), 60 : size_(size),
48 display_(NULL), 61 display_(NULL),
49 use_shared_memory_(false), 62 use_shared_memory_(false),
63 use_render_(false),
64 visual_depth_(-1),
50 root_window_(0) { 65 root_window_(0) {
51 } 66 }
52 67
53 BackingStore::~BackingStore() { 68 BackingStore::~BackingStore() {
54 // In unit tests, display_ may be NULL. 69 // In unit tests, display_ may be NULL.
55 if (!display_) 70 if (!display_)
56 return; 71 return;
57 72
58 XRenderFreePicture(display_, picture_); 73 XRenderFreePicture(display_, picture_);
59 XFreePixmap(display_, pixmap_); 74 XFreePixmap(display_, pixmap_);
60 XFreeGC(display_, static_cast<GC>(pixmap_gc_)); 75 XFreeGC(display_, static_cast<GC>(pixmap_gc_));
61 } 76 }
62 77
78 void BackingStore::PaintRectWithoutXrender(TransportDIB* bitmap,
79 const gfx::Rect &bitmap_rect) {
80 const int width = bitmap_rect.width();
81 const int height = bitmap_rect.height();
82 Pixmap pixmap = XCreatePixmap(display_, root_window_, width, height,
83 visual_depth_);
84
85 XImage image;
86 memset(&image, 0, sizeof(image));
87
88 image.width = width;
89 image.height = height;
90 image.format = ZPixmap;
91 image.byte_order = LSBFirst;
92 image.bitmap_unit = 8;
93 image.bitmap_bit_order = LSBFirst;
94 image.red_mask = 0xff;
95 image.green_mask = 0xff00;
96 image.blue_mask = 0xff0000;
97
98 if (pixmap_bpp_ == 32) {
99 // If the X server depth is already 32-bits, then our job is easy.
100 image.depth = visual_depth_;
101 image.bits_per_pixel = 32;
102 image.bytes_per_line = width * 4;
103 image.data = static_cast<char*>(bitmap->memory());
104
105 XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image,
106 0, 0 /* source x, y */, 0, 0 /* dest x, y */,
107 width, height);
108 } else if (pixmap_bpp_ == 24) {
109 // In this case we just need to strip the alpha channel out of each
110 // pixel. This is the case which covers VNC servers since they don't
111 // support Xrender but typically have 24-bit visuals.
112 //
113 // It's possible to use some fancy SSE tricks here, but since this is the
114 // slow path anyway, we do it slowly.
115
116 uint8_t* bitmap24 = static_cast<uint8_t*>(malloc(3 * width * height));
117 const uint32_t* bitmap_in = static_cast<const uint32_t*>(bitmap->memory());
118 for (int y = 0; y < height; ++y) {
119 for (int x = 0; x < width; ++x) {
120 const uint32_t pixel = *(bitmap_in++);
121 bitmap24[0] = (pixel >> 16) & 0xff;
122 bitmap24[1] = (pixel >> 8) & 0xff;
123 bitmap24[2] = pixel & 0xff;
124 bitmap24 += 3;
125 }
126 }
127
128 image.depth = visual_depth_;
129 image.bits_per_pixel = 24;
130 image.bytes_per_line = width * 3;
131 image.data = reinterpret_cast<char*>(bitmap24);
132
133 XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image,
134 0, 0 /* source x, y */, 0, 0 /* dest x, y */,
135 width, height);
136
137 free(bitmap24);
138 } else {
139 CHECK(false) << "Sorry, we don't support your visual depth without "
140 "Xrender support (depth:" << visual_depth_
141 << " bpp:" << pixmap_bpp_ << ")";
142 }
143
144 XCopyArea(display_, pixmap /* source */, pixmap_ /* target */,
145 static_cast<GC>(pixmap_gc_),
146 0, 0 /* source x, y */, bitmap_rect.width(), bitmap_rect.height(),
147 bitmap_rect.x(), bitmap_rect.y() /* dest x, y */);
148
149 XFreePixmap(display_, pixmap);
150 }
151
63 void BackingStore::PaintRect(base::ProcessHandle process, 152 void BackingStore::PaintRect(base::ProcessHandle process,
64 TransportDIB* bitmap, 153 TransportDIB* bitmap,
65 const gfx::Rect& bitmap_rect) { 154 const gfx::Rect& bitmap_rect) {
66 if (!display_) 155 if (!display_)
67 return; 156 return;
68 157
158 if (!use_render_)
159 return PaintRectWithoutXrender(bitmap, bitmap_rect);
160
69 const int width = bitmap_rect.width(); 161 const int width = bitmap_rect.width();
70 const int height = bitmap_rect.height(); 162 const int height = bitmap_rect.height();
71 Picture picture; 163 Picture picture;
72 Pixmap pixmap; 164 Pixmap pixmap;
73 165
74 if (use_shared_memory_) { 166 if (use_shared_memory_) {
75 const XID shmseg = bitmap->MapToX(display_); 167 const XID shmseg = bitmap->MapToX(display_);
76 168
77 XShmSegmentInfo shminfo; 169 XShmSegmentInfo shminfo;
78 memset(&shminfo, 0, sizeof(shminfo)); 170 memset(&shminfo, 0, sizeof(shminfo));
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 } 252 }
161 253
162 PaintRect(process, bitmap, bitmap_rect); 254 PaintRect(process, bitmap, bitmap_rect);
163 } 255 }
164 256
165 void BackingStore::ShowRect(const gfx::Rect& rect, XID target) { 257 void BackingStore::ShowRect(const gfx::Rect& rect, XID target) {
166 XCopyArea(display_, pixmap_, target, static_cast<GC>(pixmap_gc_), 258 XCopyArea(display_, pixmap_, target, static_cast<GC>(pixmap_gc_),
167 rect.x(), rect.y(), rect.width(), rect.height(), 259 rect.x(), rect.y(), rect.width(), rect.height(),
168 rect.x(), rect.y()); 260 rect.x(), rect.y());
169 } 261 }
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/backing_store.h ('k') | chrome/browser/renderer_host/render_widget_host_view_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698