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

Side by Side 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, 6 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 | Annotate | Revision Log
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 <stdlib.h> 7 #include <stdlib.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 // In unit tests, display_ may be NULL. 70 // In unit tests, display_ may be NULL.
71 if (!display_) 71 if (!display_)
72 return; 72 return;
73 73
74 XRenderFreePicture(display_, picture_); 74 XRenderFreePicture(display_, picture_);
75 XFreePixmap(display_, pixmap_); 75 XFreePixmap(display_, pixmap_);
76 XFreeGC(display_, static_cast<GC>(pixmap_gc_)); 76 XFreeGC(display_, static_cast<GC>(pixmap_gc_));
77 } 77 }
78 78
79 void BackingStore::PaintRectWithoutXrender(TransportDIB* bitmap, 79 void BackingStore::PaintRectWithoutXrender(TransportDIB* bitmap,
80 const gfx::Rect &bitmap_rect) { 80 const gfx::Rect& bitmap_rect,
81 const int width = bitmap_rect.width(); 81 const gfx::Rect& paint_rect) {
82 const int height = bitmap_rect.height(); 82 DCHECK(bitmap_rect.Contains(paint_rect) &&
83 Pixmap pixmap = XCreatePixmap(display_, root_window_, width, height, 83 paint_rect.x() < kMaxBitmapLengthAllowed &&
84 visual_depth_); 84 paint_rect.y() < kMaxBitmapLengthAllowed);
85 const int paint_width = paint_rect.width();
86 const int paint_height = paint_rect.height();
87 Pixmap pixmap = XCreatePixmap(display_, root_window_, paint_width,
88 paint_height, visual_depth_);
85 89
90 const int bitmap_width = bitmap_rect.width();
91 const int bitmap_height = bitmap_rect.height();
86 XImage image; 92 XImage image;
87 memset(&image, 0, sizeof(image)); 93 memset(&image, 0, sizeof(image));
88 94
89 image.width = width; 95 image.width = bitmap_width;
90 image.height = height; 96 image.height = bitmap_height;
91 image.format = ZPixmap; 97 image.format = ZPixmap;
92 image.byte_order = LSBFirst; 98 image.byte_order = LSBFirst;
93 image.bitmap_unit = 8; 99 image.bitmap_unit = 8;
94 image.bitmap_bit_order = LSBFirst; 100 image.bitmap_bit_order = LSBFirst;
95 image.red_mask = 0xff; 101 image.red_mask = 0xff;
96 image.green_mask = 0xff00; 102 image.green_mask = 0xff00;
97 image.blue_mask = 0xff0000; 103 image.blue_mask = 0xff0000;
98 104
105 const int x_offset = paint_rect.x() - bitmap_rect.x();
106 const int y_offset = paint_rect.y() - bitmap_rect.y();
99 if (pixmap_bpp_ == 32) { 107 if (pixmap_bpp_ == 32) {
100 // If the X server depth is already 32-bits, then our job is easy. 108 // If the X server depth is already 32-bits, then our job is easy.
101 image.depth = visual_depth_; 109 image.depth = visual_depth_;
102 image.bits_per_pixel = 32; 110 image.bits_per_pixel = 32;
103 image.bytes_per_line = width * 4; 111 image.bytes_per_line = bitmap_width * 4;
104 image.data = static_cast<char*>(bitmap->memory()); 112 image.data = static_cast<char*>(bitmap->memory());
105 113
106 XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image, 114 XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image,
107 0, 0 /* source x, y */, 0, 0 /* dest x, y */, 115 x_offset, y_offset /* source x, y */, 0, 0 /* dest x, y */,
108 width, height); 116 paint_width, paint_height);
109 } else if (pixmap_bpp_ == 24) { 117 } else if (pixmap_bpp_ == 24) {
110 // In this case we just need to strip the alpha channel out of each 118 // In this case we just need to strip the alpha channel out of each
111 // pixel. This is the case which covers VNC servers since they don't 119 // pixel. This is the case which covers VNC servers since they don't
112 // support Xrender but typically have 24-bit visuals. 120 // support Xrender but typically have 24-bit visuals.
113 // 121 //
114 // It's possible to use some fancy SSE tricks here, but since this is the 122 // It's possible to use some fancy SSE tricks here, but since this is the
115 // slow path anyway, we do it slowly. 123 // slow path anyway, we do it slowly.
116 124
117 uint8_t* bitmap24 = static_cast<uint8_t*>(malloc(3 * width * height)); 125 uint8_t* bitmap24 = static_cast<uint8_t*>(malloc(3 * paint_width *
126 paint_height));
118 const uint32_t* bitmap_in = static_cast<const uint32_t*>(bitmap->memory()); 127 const uint32_t* bitmap_in = static_cast<const uint32_t*>(bitmap->memory());
119 for (int y = 0; y < height; ++y) { 128 const int x_limit = paint_rect.right() - bitmap_rect.x();
120 for (int x = 0; x < width; ++x) { 129 const int y_limit = paint_rect.bottom() - bitmap_rect.y();
130 const int row_length = bitmap_width;
131 bitmap_in += row_length * y_offset;
132 for (int y = y_offset; y < y_limit; ++y) {
133 bitmap_in += x_offset;
134 for (int x = x_offset; x < x_limit; ++x) {
121 const uint32_t pixel = *(bitmap_in++); 135 const uint32_t pixel = *(bitmap_in++);
122 bitmap24[0] = (pixel >> 16) & 0xff; 136 bitmap24[0] = (pixel >> 16) & 0xff;
123 bitmap24[1] = (pixel >> 8) & 0xff; 137 bitmap24[1] = (pixel >> 8) & 0xff;
124 bitmap24[2] = pixel & 0xff; 138 bitmap24[2] = pixel & 0xff;
125 bitmap24 += 3; 139 bitmap24 += 3;
126 } 140 }
141 bitmap_in += row_length - x_limit;
127 } 142 }
128 143
144 image.width = paint_width;
145 image.height = paint_height;
129 image.depth = visual_depth_; 146 image.depth = visual_depth_;
130 image.bits_per_pixel = 24; 147 image.bits_per_pixel = 24;
131 image.bytes_per_line = width * 3; 148 image.bytes_per_line = paint_width * 3;
132 image.data = reinterpret_cast<char*>(bitmap24); 149 image.data = reinterpret_cast<char*>(bitmap24);
133 150
134 XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image, 151 XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image,
135 0, 0 /* source x, y */, 0, 0 /* dest x, y */, 152 0, 0 /* source x, y */, 0, 0 /* dest x, y */,
136 width, height); 153 paint_width, paint_height);
137 154
138 free(bitmap24); 155 free(bitmap24);
139 } else if (pixmap_bpp_ == 16) { 156 } else if (pixmap_bpp_ == 16) {
140 // Some folks have VNC setups which still use 16-bit visuals and VNC 157 // Some folks have VNC setups which still use 16-bit visuals and VNC
141 // doesn't include Xrender. 158 // doesn't include Xrender.
142 159
143 uint16_t* bitmap16 = static_cast<uint16_t*>(malloc(2 * width * height)); 160 uint16_t* bitmap16 = static_cast<uint16_t*>(malloc(2 * paint_width *
161 paint_height));
144 uint16_t* const orig_bitmap16 = bitmap16; 162 uint16_t* const orig_bitmap16 = bitmap16;
145 const uint32_t* bitmap_in = static_cast<const uint32_t*>(bitmap->memory()); 163 const uint32_t* bitmap_in = static_cast<const uint32_t*>(bitmap->memory());
146 for (int y = 0; y < height; ++y) { 164 const int x_limit = paint_rect.right() - bitmap_rect.x();
147 for (int x = 0; x < width; ++x) { 165 const int y_limit = paint_rect.bottom() - bitmap_rect.y();
166 const int row_length = bitmap_width;
167 bitmap_in += row_length * y_offset;
168 for (int y = y_offset; y < y_limit; ++y) {
169 bitmap_in += x_offset;
170 for (int x = x_offset; x < x_limit; ++x) {
148 const uint32_t pixel = *(bitmap_in++); 171 const uint32_t pixel = *(bitmap_in++);
149 uint16_t out_pixel = ((pixel >> 8) & 0xf800) | 172 uint16_t out_pixel = ((pixel >> 8) & 0xf800) |
150 ((pixel >> 5) & 0x07e0) | 173 ((pixel >> 5) & 0x07e0) |
151 ((pixel >> 3) & 0x001f); 174 ((pixel >> 3) & 0x001f);
152 *(bitmap16++) = out_pixel; 175 *(bitmap16++) = out_pixel;
153 } 176 }
177 bitmap_in += row_length - x_limit;
154 } 178 }
155 179
156 image.depth = visual_depth_; 180 image.depth = visual_depth_;
157 image.bits_per_pixel = 16; 181 image.bits_per_pixel = 16;
158 image.bytes_per_line = width * 2; 182 image.bytes_per_line = paint_width * 2;
159 image.data = reinterpret_cast<char*>(orig_bitmap16); 183 image.data = reinterpret_cast<char*>(orig_bitmap16);
160 184
161 image.red_mask = 0xf800; 185 image.red_mask = 0xf800;
162 image.green_mask = 0x07e0; 186 image.green_mask = 0x07e0;
163 image.blue_mask = 0x001f; 187 image.blue_mask = 0x001f;
164 188
165 XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image, 189 XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image,
166 0, 0 /* source x, y */, 0, 0 /* dest x, y */, 190 0, 0 /* source x, y */, 0, 0 /* dest x, y */,
167 width, height); 191 paint_width, paint_height);
168 free(orig_bitmap16); 192 free(orig_bitmap16);
169 } else { 193 } else {
170 CHECK(false) << "Sorry, we don't support your visual depth without " 194 CHECK(false) << "Sorry, we don't support your visual depth without "
171 "Xrender support (depth:" << visual_depth_ 195 "Xrender support (depth:" << visual_depth_
172 << " bpp:" << pixmap_bpp_ << ")"; 196 << " bpp:" << pixmap_bpp_ << ")";
173 } 197 }
174 198
175 XCopyArea(display_, pixmap /* source */, pixmap_ /* target */, 199 XCopyArea(display_, pixmap /* source */, pixmap_ /* target */,
176 static_cast<GC>(pixmap_gc_), 200 static_cast<GC>(pixmap_gc_),
177 0, 0 /* source x, y */, bitmap_rect.width(), bitmap_rect.height(), 201 0, 0 /* source x, y */, paint_width, paint_height,
178 bitmap_rect.x(), bitmap_rect.y() /* dest x, y */); 202 paint_rect.x(), paint_rect.y() /* dest x, y */);
179 203
180 XFreePixmap(display_, pixmap); 204 XFreePixmap(display_, pixmap);
181 } 205 }
182 206
183 void BackingStore::PaintRect(base::ProcessHandle process, 207 void BackingStore::PaintRect(base::ProcessHandle process,
184 TransportDIB* bitmap, 208 TransportDIB* bitmap,
185 const gfx::Rect& bitmap_rect) { 209 const gfx::Rect& bitmap_rect,
210 const gfx::Rect& paint_rect) {
211 DCHECK(bitmap_rect.Contains(paint_rect) &&
212 paint_rect.x() < kMaxBitmapLengthAllowed &&
213 paint_rect.y() < kMaxBitmapLengthAllowed);
186 if (!display_) 214 if (!display_)
187 return; 215 return;
188 216
189 if (bitmap_rect.IsEmpty()) 217 if (bitmap_rect.IsEmpty())
190 return; 218 return;
191 219
192 if (!use_render_) 220 if (!use_render_)
193 return PaintRectWithoutXrender(bitmap, bitmap_rect); 221 return PaintRectWithoutXrender(bitmap, bitmap_rect, paint_rect);
194 222
195 const int width = bitmap_rect.width(); 223 const int paint_width = paint_rect.width();
196 const int height = bitmap_rect.height(); 224 const int paint_height = paint_rect.height();
225
226 // The values for the position of the source rect within the bitmap when
227 // we render the composite depends on the usage of shared memory or not.
228 int src_x = 0;
229 int src_y = 0;
230
197 Picture picture; 231 Picture picture;
198 Pixmap pixmap; 232 Pixmap pixmap;
199 233
200 if (use_shared_memory_) { 234 if (use_shared_memory_) {
201 const XID shmseg = bitmap->MapToX(display_); 235 const XID shmseg = bitmap->MapToX(display_);
202 236
203 XShmSegmentInfo shminfo; 237 XShmSegmentInfo shminfo;
204 memset(&shminfo, 0, sizeof(shminfo)); 238 memset(&shminfo, 0, sizeof(shminfo));
205 shminfo.shmseg = shmseg; 239 shminfo.shmseg = shmseg;
206 240
207 // The NULL in the following is the |data| pointer: this is an artifact of 241 // The NULL in the following is the |data| pointer: this is an artifact of
208 // Xlib trying to be helpful, rather than just exposing the X protocol. It 242 // Xlib trying to be helpful, rather than just exposing the X protocol. It
209 // assumes that we have the shared memory segment mapped into our memory, 243 // assumes that we have the shared memory segment mapped into our memory,
210 // which we don't, and it's trying to calculate an offset by taking the 244 // which we don't, and it's trying to calculate an offset by taking the
211 // difference between the |data| pointer and the address of the mapping in 245 // difference between the |data| pointer and the address of the mapping in
212 // |shminfo|. Since both are NULL, the offset will be calculated to be 0, 246 // |shminfo|. Since both are NULL, the offset will be calculated to be 0,
213 // which is correct for us. 247 // which is correct for us.
214 pixmap = XShmCreatePixmap(display_, root_window_, NULL, &shminfo, width, 248 pixmap = XShmCreatePixmap(display_, root_window_, NULL, &shminfo,
215 height, 32); 249 bitmap_rect.width(), bitmap_rect.height(), 32);
250 // Since we use the whole source bitmap, we must offset the source.
251 src_x = paint_rect.x() - bitmap_rect.x();
252 src_y = paint_rect.y() - bitmap_rect.y();
216 } else { 253 } else {
217 // No shared memory support, we have to copy the bitmap contents to the X 254 // No shared memory support, we have to copy the bitmap contents to the X
218 // server. Xlib wraps the underlying PutImage call behind several layers of 255 // server. Xlib wraps the underlying PutImage call behind several layers of
219 // functions which try to convert the image into the format which the X 256 // functions which try to convert the image into the format which the X
220 // server expects. The following values hopefully disable all conversions. 257 // server expects. The following values hopefully disable all conversions.
221 XImage image; 258 XImage image;
222 memset(&image, 0, sizeof(image)); 259 memset(&image, 0, sizeof(image));
223 260
224 image.width = width; 261 image.width = paint_width;
225 image.height = height; 262 image.height = paint_height;
226 image.depth = 32; 263 image.depth = 32;
227 image.bits_per_pixel = 32; 264 image.bits_per_pixel = 32;
228 image.format = ZPixmap; 265 image.format = ZPixmap;
229 image.byte_order = LSBFirst; 266 image.byte_order = LSBFirst;
230 image.bitmap_unit = 8; 267 image.bitmap_unit = 8;
231 image.bitmap_bit_order = LSBFirst; 268 image.bitmap_bit_order = LSBFirst;
232 image.bytes_per_line = width * 4; 269 image.bytes_per_line = paint_width * 4;
233 image.red_mask = 0xff; 270 image.red_mask = 0xff;
234 image.green_mask = 0xff00; 271 image.green_mask = 0xff00;
235 image.blue_mask = 0xff0000; 272 image.blue_mask = 0xff0000;
273 // TODO(agl): check if we can make this more efficient.
236 image.data = static_cast<char*>(bitmap->memory()); 274 image.data = static_cast<char*>(bitmap->memory());
237 275
238 pixmap = XCreatePixmap(display_, root_window_, width, height, 32); 276 pixmap = XCreatePixmap(display_, root_window_, paint_width, paint_height,
277 32);
239 GC gc = XCreateGC(display_, pixmap, 0, NULL); 278 GC gc = XCreateGC(display_, pixmap, 0, NULL);
240 XPutImage(display_, pixmap, gc, &image, 279 XPutImage(display_, pixmap, gc, &image, paint_rect.x() - bitmap_rect.x(),
241 0, 0 /* source x, y */, 0, 0 /* dest x, y */, 280 paint_rect.y() - bitmap_rect.y() /* source x, y */,
242 width, height); 281 0, 0 /* dest x, y */, paint_width, paint_height);
243 XFreeGC(display_, gc); 282 XFreeGC(display_, gc);
244 } 283 }
245 284
246 picture = x11_util::CreatePictureFromSkiaPixmap(display_, pixmap); 285 picture = x11_util::CreatePictureFromSkiaPixmap(display_, pixmap);
247 XRenderComposite(display_, PictOpSrc, picture /* source */, 0 /* mask */, 286 XRenderComposite(display_, PictOpSrc, picture /* source */, 0 /* mask */,
248 picture_ /* dest */, 0, 0 /* source x, y */, 287 picture_ /* dest */, src_x, src_y /* source x, y */,
249 0, 0 /* mask x, y */, 288 0, 0 /* mask x, y */,
250 bitmap_rect.x(), bitmap_rect.y() /* target x, y */, 289 paint_rect.x(), paint_rect.y() /* target x, y */,
251 width, height); 290 paint_width, paint_height);
252 291
253 // In the case of shared memory, we wait for the composite to complete so that 292 // In the case of shared memory, we wait for the composite to complete so that
254 // we are sure that the X server has finished reading. 293 // we are sure that the X server has finished reading.
255 if (use_shared_memory_) 294 if (use_shared_memory_)
256 XSync(display_, False); 295 XSync(display_, False);
257 296
258 XRenderFreePicture(display_, picture); 297 XRenderFreePicture(display_, picture);
259 XFreePixmap(display_, pixmap); 298 XFreePixmap(display_, pixmap);
260 } 299 }
261 300
(...skipping 26 matching lines...) Expand all
288 XCopyArea(display_, pixmap_, pixmap_, static_cast<GC>(pixmap_gc_), 327 XCopyArea(display_, pixmap_, pixmap_, static_cast<GC>(pixmap_gc_),
289 std::max(clip_rect.x(), clip_rect.x() - dx), 328 std::max(clip_rect.x(), clip_rect.x() - dx),
290 clip_rect.y() /* source y */, 329 clip_rect.y() /* source y */,
291 clip_rect.width() - abs(dx), 330 clip_rect.width() - abs(dx),
292 clip_rect.height(), 331 clip_rect.height(),
293 std::max(clip_rect.x(), clip_rect.x() + dx) /* dest x */, 332 std::max(clip_rect.x(), clip_rect.x() + dx) /* dest x */,
294 clip_rect.y() /* dest x */); 333 clip_rect.y() /* dest x */);
295 } 334 }
296 } 335 }
297 336
298 PaintRect(process, bitmap, bitmap_rect); 337 PaintRect(process, bitmap, bitmap_rect, bitmap_rect);
299 } 338 }
300 339
301 void BackingStore::ShowRect(const gfx::Rect& rect, XID target) { 340 void BackingStore::ShowRect(const gfx::Rect& rect, XID target) {
302 XCopyArea(display_, pixmap_, target, static_cast<GC>(pixmap_gc_), 341 XCopyArea(display_, pixmap_, target, static_cast<GC>(pixmap_gc_),
303 rect.x(), rect.y(), rect.width(), rect.height(), 342 rect.x(), rect.y(), rect.width(), rect.height(),
304 rect.x(), rect.y()); 343 rect.x(), rect.y());
305 } 344 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698