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

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

Issue 6257006: Move a bunch of random other files to src/ui/base... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 11 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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_x.h" 5 #include "chrome/browser/renderer_host/backing_store_x.h"
6 6
7 #include <cairo-xlib.h> 7 #include <cairo-xlib.h>
8 #include <gtk/gtk.h> 8 #include <gtk/gtk.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <sys/ipc.h> 10 #include <sys/ipc.h>
11 #include <sys/shm.h> 11 #include <sys/shm.h>
12 12
13 #if defined(OS_OPENBSD) || defined(OS_FREEBSD) 13 #if defined(OS_OPENBSD) || defined(OS_FREEBSD)
14 #include <sys/endian.h> 14 #include <sys/endian.h>
15 #endif 15 #endif
16 16
17 #include <algorithm> 17 #include <algorithm>
18 #include <utility> 18 #include <utility>
19 #include <limits> 19 #include <limits>
20 20
21 #include "app/surface/transport_dib.h" 21 #include "app/surface/transport_dib.h"
22 #include "app/x11_util.h"
23 #include "app/x11_util_internal.h"
24 #include "base/compiler_specific.h" 22 #include "base/compiler_specific.h"
25 #include "base/logging.h" 23 #include "base/logging.h"
26 #include "base/metrics/histogram.h" 24 #include "base/metrics/histogram.h"
27 #include "base/time.h" 25 #include "base/time.h"
28 #include "chrome/browser/renderer_host/render_process_host.h" 26 #include "chrome/browser/renderer_host/render_process_host.h"
29 #include "gfx/rect.h" 27 #include "gfx/rect.h"
30 #include "skia/ext/platform_canvas.h" 28 #include "skia/ext/platform_canvas.h"
31 #include "third_party/skia/include/core/SkBitmap.h" 29 #include "third_party/skia/include/core/SkBitmap.h"
30 #include "ui/base/x/x11_util.h"
31 #include "ui/base/x/x11_util_internal.h"
32 32
33 // Assume that somewhere along the line, someone will do width * height * 4 33 // Assume that somewhere along the line, someone will do width * height * 4
34 // with signed numbers. If the maximum value is 2**31, then 2**31 / 4 = 34 // with signed numbers. If the maximum value is 2**31, then 2**31 / 4 =
35 // 2**29 and floor(sqrt(2**29)) = 23170. 35 // 2**29 and floor(sqrt(2**29)) = 23170.
36 36
37 // Max height and width for layers 37 // Max height and width for layers
38 static const int kMaxVideoLayerSize = 23170; 38 static const int kMaxVideoLayerSize = 23170;
39 39
40 40
41 // X Backing Stores: 41 // X Backing Stores:
(...skipping 15 matching lines...) Expand all
57 XShmDetach(display, shminfo); 57 XShmDetach(display, shminfo);
58 XDestroyImage(image); 58 XDestroyImage(image);
59 shmdt(shminfo->shmaddr); 59 shmdt(shminfo->shmaddr);
60 } 60 }
61 61
62 BackingStoreX::BackingStoreX(RenderWidgetHost* widget, 62 BackingStoreX::BackingStoreX(RenderWidgetHost* widget,
63 const gfx::Size& size, 63 const gfx::Size& size,
64 void* visual, 64 void* visual,
65 int depth) 65 int depth)
66 : BackingStore(widget, size), 66 : BackingStore(widget, size),
67 display_(x11_util::GetXDisplay()), 67 display_(ui::GetXDisplay()),
68 shared_memory_support_(x11_util::QuerySharedMemorySupport(display_)), 68 shared_memory_support_(ui::QuerySharedMemorySupport(display_)),
69 use_render_(x11_util::QueryRenderSupport(display_)), 69 use_render_(ui::QueryRenderSupport(display_)),
70 visual_(visual), 70 visual_(visual),
71 visual_depth_(depth), 71 visual_depth_(depth),
72 root_window_(x11_util::GetX11RootWindow()) { 72 root_window_(ui::GetX11RootWindow()) {
73 #if defined(OS_OPENBSD) || defined(OS_FREEBSD) 73 #if defined(OS_OPENBSD) || defined(OS_FREEBSD)
74 COMPILE_ASSERT(_BYTE_ORDER == _LITTLE_ENDIAN, assumes_little_endian); 74 COMPILE_ASSERT(_BYTE_ORDER == _LITTLE_ENDIAN, assumes_little_endian);
75 #else 75 #else
76 COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian); 76 COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian);
77 #endif 77 #endif
78 78
79 pixmap_ = XCreatePixmap(display_, root_window_, 79 pixmap_ = XCreatePixmap(display_, root_window_,
80 size.width(), size.height(), depth); 80 size.width(), size.height(), depth);
81 81
82 if (use_render_) { 82 if (use_render_) {
83 picture_ = XRenderCreatePicture( 83 picture_ = XRenderCreatePicture(
84 display_, pixmap_, 84 display_, pixmap_,
85 x11_util::GetRenderVisualFormat(display_, 85 ui::GetRenderVisualFormat(display_,
86 static_cast<Visual*>(visual)), 86 static_cast<Visual*>(visual)),
87 0, NULL); 87 0, NULL);
88 pixmap_bpp_ = 0; 88 pixmap_bpp_ = 0;
89 } else { 89 } else {
90 picture_ = 0; 90 picture_ = 0;
91 pixmap_bpp_ = x11_util::BitsPerPixelForPixmapDepth(display_, depth); 91 pixmap_bpp_ = ui::BitsPerPixelForPixmapDepth(display_, depth);
92 } 92 }
93 93
94 pixmap_gc_ = XCreateGC(display_, pixmap_, 0, NULL); 94 pixmap_gc_ = XCreateGC(display_, pixmap_, 0, NULL);
95 } 95 }
96 96
97 BackingStoreX::BackingStoreX(RenderWidgetHost* widget, const gfx::Size& size) 97 BackingStoreX::BackingStoreX(RenderWidgetHost* widget, const gfx::Size& size)
98 : BackingStore(widget, size), 98 : BackingStore(widget, size),
99 display_(NULL), 99 display_(NULL),
100 shared_memory_support_(x11_util::SHARED_MEMORY_NONE), 100 shared_memory_support_(ui::SHARED_MEMORY_NONE),
101 use_render_(false), 101 use_render_(false),
102 pixmap_bpp_(0), 102 pixmap_bpp_(0),
103 visual_(NULL), 103 visual_(NULL),
104 visual_depth_(-1), 104 visual_depth_(-1),
105 root_window_(0), 105 root_window_(0),
106 pixmap_(0), 106 pixmap_(0),
107 picture_(0), 107 picture_(0),
108 pixmap_gc_(NULL) { 108 pixmap_gc_(NULL) {
109 } 109 }
110 110
(...skipping 17 matching lines...) Expand all
128 void BackingStoreX::PaintRectWithoutXrender( 128 void BackingStoreX::PaintRectWithoutXrender(
129 TransportDIB* bitmap, 129 TransportDIB* bitmap,
130 const gfx::Rect& bitmap_rect, 130 const gfx::Rect& bitmap_rect,
131 const std::vector<gfx::Rect>& copy_rects) { 131 const std::vector<gfx::Rect>& copy_rects) {
132 const int width = bitmap_rect.width(); 132 const int width = bitmap_rect.width();
133 const int height = bitmap_rect.height(); 133 const int height = bitmap_rect.height();
134 Pixmap pixmap = XCreatePixmap(display_, root_window_, width, height, 134 Pixmap pixmap = XCreatePixmap(display_, root_window_, width, height,
135 visual_depth_); 135 visual_depth_);
136 136
137 // Draw ARGB transport DIB onto our pixmap. 137 // Draw ARGB transport DIB onto our pixmap.
138 x11_util::PutARGBImage(display_, visual_, visual_depth_, pixmap, 138 ui::PutARGBImage(display_, visual_, visual_depth_, pixmap,
139 pixmap_gc_, static_cast<uint8*>(bitmap->memory()), 139 pixmap_gc_, static_cast<uint8*>(bitmap->memory()),
140 width, height); 140 width, height);
141 141
142 for (size_t i = 0; i < copy_rects.size(); i++) { 142 for (size_t i = 0; i < copy_rects.size(); i++) {
143 const gfx::Rect& copy_rect = copy_rects[i]; 143 const gfx::Rect& copy_rect = copy_rects[i];
144 XCopyArea(display_, 144 XCopyArea(display_,
145 pixmap, // src 145 pixmap, // src
146 pixmap_, // dest 146 pixmap_, // dest
147 static_cast<GC>(pixmap_gc_), // gc 147 static_cast<GC>(pixmap_gc_), // gc
148 copy_rect.x() - bitmap_rect.x(), // src_x 148 copy_rect.x() - bitmap_rect.x(), // src_x
149 copy_rect.y() - bitmap_rect.y(), // src_y 149 copy_rect.y() - bitmap_rect.y(), // src_y
150 copy_rect.width(), // width 150 copy_rect.width(), // width
(...skipping 26 matching lines...) Expand all
177 TransportDIB* dib = process->GetTransportDIB(bitmap); 177 TransportDIB* dib = process->GetTransportDIB(bitmap);
178 if (!dib) 178 if (!dib)
179 return; 179 return;
180 180
181 if (!use_render_) 181 if (!use_render_)
182 return PaintRectWithoutXrender(dib, bitmap_rect, copy_rects); 182 return PaintRectWithoutXrender(dib, bitmap_rect, copy_rects);
183 183
184 Picture picture; 184 Picture picture;
185 Pixmap pixmap; 185 Pixmap pixmap;
186 186
187 if (shared_memory_support_ == x11_util::SHARED_MEMORY_PIXMAP) { 187 if (shared_memory_support_ == ui::SHARED_MEMORY_PIXMAP) {
188 XShmSegmentInfo shminfo = {0}; 188 XShmSegmentInfo shminfo = {0};
189 shminfo.shmseg = dib->MapToX(display_); 189 shminfo.shmseg = dib->MapToX(display_);
190 190
191 // The NULL in the following is the |data| pointer: this is an artifact of 191 // The NULL in the following is the |data| pointer: this is an artifact of
192 // Xlib trying to be helpful, rather than just exposing the X protocol. It 192 // Xlib trying to be helpful, rather than just exposing the X protocol. It
193 // assumes that we have the shared memory segment mapped into our memory, 193 // assumes that we have the shared memory segment mapped into our memory,
194 // which we don't, and it's trying to calculate an offset by taking the 194 // which we don't, and it's trying to calculate an offset by taking the
195 // difference between the |data| pointer and the address of the mapping in 195 // difference between the |data| pointer and the address of the mapping in
196 // |shminfo|. Since both are NULL, the offset will be calculated to be 0, 196 // |shminfo|. Since both are NULL, the offset will be calculated to be 0,
197 // which is correct for us. 197 // which is correct for us.
198 pixmap = XShmCreatePixmap(display_, root_window_, NULL, &shminfo, 198 pixmap = XShmCreatePixmap(display_, root_window_, NULL, &shminfo,
199 width, height, 32); 199 width, height, 32);
200 } else { 200 } else {
201 // We don't have shared memory pixmaps. Fall back to creating a pixmap 201 // We don't have shared memory pixmaps. Fall back to creating a pixmap
202 // ourselves and putting an image on it. 202 // ourselves and putting an image on it.
203 pixmap = XCreatePixmap(display_, root_window_, width, height, 32); 203 pixmap = XCreatePixmap(display_, root_window_, width, height, 32);
204 GC gc = XCreateGC(display_, pixmap, 0, NULL); 204 GC gc = XCreateGC(display_, pixmap, 0, NULL);
205 205
206 if (shared_memory_support_ == x11_util::SHARED_MEMORY_PUTIMAGE) { 206 if (shared_memory_support_ == ui::SHARED_MEMORY_PUTIMAGE) {
207 const XID shmseg = dib->MapToX(display_); 207 const XID shmseg = dib->MapToX(display_);
208 208
209 XShmSegmentInfo shminfo; 209 XShmSegmentInfo shminfo;
210 memset(&shminfo, 0, sizeof(shminfo)); 210 memset(&shminfo, 0, sizeof(shminfo));
211 shminfo.shmseg = shmseg; 211 shminfo.shmseg = shmseg;
212 shminfo.shmaddr = static_cast<char*>(dib->memory()); 212 shminfo.shmaddr = static_cast<char*>(dib->memory());
213 213
214 XImage* image = XShmCreateImage(display_, static_cast<Visual*>(visual_), 214 XImage* image = XShmCreateImage(display_, static_cast<Visual*>(visual_),
215 32, ZPixmap, 215 32, ZPixmap,
216 shminfo.shmaddr, &shminfo, 216 shminfo.shmaddr, &shminfo,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 image.blue_mask = 0xff0000; 262 image.blue_mask = 0xff0000;
263 image.data = static_cast<char*>(dib->memory()); 263 image.data = static_cast<char*>(dib->memory());
264 264
265 XPutImage(display_, pixmap, gc, &image, 265 XPutImage(display_, pixmap, gc, &image,
266 0, 0 /* source x, y */, 0, 0 /* dest x, y */, 266 0, 0 /* source x, y */, 0, 0 /* dest x, y */,
267 width, height); 267 width, height);
268 } 268 }
269 XFreeGC(display_, gc); 269 XFreeGC(display_, gc);
270 } 270 }
271 271
272 picture = x11_util::CreatePictureFromSkiaPixmap(display_, pixmap); 272 picture = ui::CreatePictureFromSkiaPixmap(display_, pixmap);
273 273
274 for (size_t i = 0; i < copy_rects.size(); i++) { 274 for (size_t i = 0; i < copy_rects.size(); i++) {
275 const gfx::Rect& copy_rect = copy_rects[i]; 275 const gfx::Rect& copy_rect = copy_rects[i];
276 XRenderComposite(display_, 276 XRenderComposite(display_,
277 PictOpSrc, // op 277 PictOpSrc, // op
278 picture, // src 278 picture, // src
279 0, // mask 279 0, // mask
280 picture_, // dest 280 picture_, // dest
281 copy_rect.x() - bitmap_rect.x(), // src_x 281 copy_rect.x() - bitmap_rect.x(), // src_x
282 copy_rect.y() - bitmap_rect.y(), // src_y 282 copy_rect.y() - bitmap_rect.y(), // src_y
283 0, // mask_x 283 0, // mask_x
284 0, // mask_y 284 0, // mask_y
285 copy_rect.x(), // dest_x 285 copy_rect.x(), // dest_x
286 copy_rect.y(), // dest_y 286 copy_rect.y(), // dest_y
287 copy_rect.width(), // width 287 copy_rect.width(), // width
288 copy_rect.height()); // height 288 copy_rect.height()); // height
289 } 289 }
290 290
291 // In the case of shared memory, we wait for the composite to complete so that 291 // In the case of shared memory, we wait for the composite to complete so that
292 // we are sure that the X server has finished reading from the shared memory 292 // we are sure that the X server has finished reading from the shared memory
293 // segment. 293 // segment.
294 if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE) 294 if (shared_memory_support_ != ui::SHARED_MEMORY_NONE)
295 XSync(display_, False); 295 XSync(display_, False);
296 296
297 XRenderFreePicture(display_, picture); 297 XRenderFreePicture(display_, picture);
298 XFreePixmap(display_, pixmap); 298 XFreePixmap(display_, pixmap);
299 } 299 }
300 300
301 bool BackingStoreX::CopyFromBackingStore(const gfx::Rect& rect, 301 bool BackingStoreX::CopyFromBackingStore(const gfx::Rect& rect,
302 skia::PlatformCanvas* output) { 302 skia::PlatformCanvas* output) {
303 base::TimeTicks begin_time = base::TimeTicks::Now(); 303 base::TimeTicks begin_time = base::TimeTicks::Now();
304 304
305 if (visual_depth_ < 24) { 305 if (visual_depth_ < 24) {
306 // CopyFromBackingStore() copies pixels out of the XImage 306 // CopyFromBackingStore() copies pixels out of the XImage
307 // in a way that assumes that each component (red, green, 307 // in a way that assumes that each component (red, green,
308 // blue) is a byte. This doesn't work on visuals which 308 // blue) is a byte. This doesn't work on visuals which
309 // encode a pixel color with less than a byte per color. 309 // encode a pixel color with less than a byte per color.
310 return false; 310 return false;
311 } 311 }
312 312
313 const int width = std::min(size().width(), rect.width()); 313 const int width = std::min(size().width(), rect.width());
314 const int height = std::min(size().height(), rect.height()); 314 const int height = std::min(size().height(), rect.height());
315 315
316 XImage* image; 316 XImage* image;
317 XShmSegmentInfo shminfo; // Used only when shared memory is enabled. 317 XShmSegmentInfo shminfo; // Used only when shared memory is enabled.
318 if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE) { 318 if (shared_memory_support_ != ui::SHARED_MEMORY_NONE) {
319 // Use shared memory for faster copies when it's available. 319 // Use shared memory for faster copies when it's available.
320 Visual* visual = static_cast<Visual*>(visual_); 320 Visual* visual = static_cast<Visual*>(visual_);
321 memset(&shminfo, 0, sizeof(shminfo)); 321 memset(&shminfo, 0, sizeof(shminfo));
322 image = XShmCreateImage(display_, visual, 32, 322 image = XShmCreateImage(display_, visual, 32,
323 ZPixmap, NULL, &shminfo, width, height); 323 ZPixmap, NULL, &shminfo, width, height);
324 if (!image) { 324 if (!image) {
325 return false; 325 return false;
326 } 326 }
327 // Create the shared memory segment for the image and map it. 327 // Create the shared memory segment for the image and map it.
328 if (image->bytes_per_line == 0 || image->height == 0 || 328 if (image->bytes_per_line == 0 || image->height == 0 ||
(...skipping 28 matching lines...) Expand all
357 image = XGetImage(display_, pixmap_, 357 image = XGetImage(display_, pixmap_,
358 rect.x(), rect.y(), width, height, 358 rect.x(), rect.y(), width, height,
359 AllPlanes, ZPixmap); 359 AllPlanes, ZPixmap);
360 } 360 }
361 361
362 // TODO(jhawkins): Need to convert the image data if the image bits per pixel 362 // TODO(jhawkins): Need to convert the image data if the image bits per pixel
363 // is not 32. 363 // is not 32.
364 // Note that this also initializes the output bitmap as opaque. 364 // Note that this also initializes the output bitmap as opaque.
365 if (!output->initialize(width, height, true) || 365 if (!output->initialize(width, height, true) ||
366 image->bits_per_pixel != 32) { 366 image->bits_per_pixel != 32) {
367 if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE) 367 if (shared_memory_support_ != ui::SHARED_MEMORY_NONE)
368 DestroySharedImage(display_, image, &shminfo); 368 DestroySharedImage(display_, image, &shminfo);
369 else 369 else
370 XDestroyImage(image); 370 XDestroyImage(image);
371 return false; 371 return false;
372 } 372 }
373 373
374 // The X image might have a different row stride, so iterate through 374 // The X image might have a different row stride, so iterate through
375 // it and copy each row out, only up to the pixels we're actually 375 // it and copy each row out, only up to the pixels we're actually
376 // using. This code assumes a visual mode where a pixel is 376 // using. This code assumes a visual mode where a pixel is
377 // represented using a 32-bit unsigned int, with a byte per component. 377 // represented using a 32-bit unsigned int, with a byte per component.
378 SkBitmap bitmap = output->getTopPlatformDevice().accessBitmap(true); 378 SkBitmap bitmap = output->getTopPlatformDevice().accessBitmap(true);
379 for (int y = 0; y < height; y++) { 379 for (int y = 0; y < height; y++) {
380 const uint32* src_row = reinterpret_cast<uint32*>( 380 const uint32* src_row = reinterpret_cast<uint32*>(
381 &image->data[image->bytes_per_line * y]); 381 &image->data[image->bytes_per_line * y]);
382 uint32* dest_row = bitmap.getAddr32(0, y); 382 uint32* dest_row = bitmap.getAddr32(0, y);
383 for (int x = 0; x < width; ++x, ++dest_row) { 383 for (int x = 0; x < width; ++x, ++dest_row) {
384 // Force alpha to be 0xff, because otherwise it causes rendering problems. 384 // Force alpha to be 0xff, because otherwise it causes rendering problems.
385 *dest_row = src_row[x] | 0xff000000; 385 *dest_row = src_row[x] | 0xff000000;
386 } 386 }
387 } 387 }
388 388
389 if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE) 389 if (shared_memory_support_ != ui::SHARED_MEMORY_NONE)
390 DestroySharedImage(display_, image, &shminfo); 390 DestroySharedImage(display_, image, &shminfo);
391 else 391 else
392 XDestroyImage(image); 392 XDestroyImage(image);
393 393
394 HISTOGRAM_TIMES("BackingStore.RetrievalFromX", 394 HISTOGRAM_TIMES("BackingStore.RetrievalFromX",
395 base::TimeTicks::Now() - begin_time); 395 base::TimeTicks::Now() - begin_time);
396 return true; 396 return true;
397 } 397 }
398 398
399 void BackingStoreX::ScrollBackingStore(int dx, int dy, 399 void BackingStoreX::ScrollBackingStore(int dx, int dy,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 cairo_set_source(cr, pattern); 468 cairo_set_source(cr, pattern);
469 cairo_pattern_destroy(pattern); 469 cairo_pattern_destroy(pattern);
470 470
471 cairo_identity_matrix(cr); 471 cairo_identity_matrix(cr);
472 472
473 cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height()); 473 cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
474 cairo_fill(cr); 474 cairo_fill(cr);
475 cairo_destroy(cr); 475 cairo_destroy(cr);
476 } 476 }
477 #endif 477 #endif
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/backing_store_x.h ('k') | chrome/browser/renderer_host/render_message_filter_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698