OLD | NEW |
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 | 20 |
20 #include "app/surface/transport_dib.h" | 21 #include "app/surface/transport_dib.h" |
21 #include "app/x11_util.h" | 22 #include "app/x11_util.h" |
22 #include "app/x11_util_internal.h" | 23 #include "app/x11_util_internal.h" |
23 #include "base/compiler_specific.h" | 24 #include "base/compiler_specific.h" |
24 #include "base/histogram.h" | 25 #include "base/histogram.h" |
25 #include "base/logging.h" | 26 #include "base/logging.h" |
26 #include "base/time.h" | 27 #include "base/time.h" |
27 #include "chrome/browser/renderer_host/render_process_host.h" | 28 #include "chrome/browser/renderer_host/render_process_host.h" |
28 #include "gfx/rect.h" | 29 #include "gfx/rect.h" |
29 #include "skia/ext/platform_canvas.h" | 30 #include "skia/ext/platform_canvas.h" |
30 #include "third_party/skia/include/core/SkBitmap.h" | 31 #include "third_party/skia/include/core/SkBitmap.h" |
31 | 32 |
| 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 = |
| 35 // 2**29 and floor(sqrt(2**29)) = 23170. |
| 36 |
| 37 // Max height and width for layers |
| 38 static const int kMaxVideoLayerSize = 23170; |
| 39 |
| 40 |
32 // X Backing Stores: | 41 // X Backing Stores: |
33 // | 42 // |
34 // Unlike Windows, where the backing store is kept in heap memory, we keep our | 43 // Unlike Windows, where the backing store is kept in heap memory, we keep our |
35 // backing store in the X server, as a pixmap. Thus expose events just require | 44 // backing store in the X server, as a pixmap. Thus expose events just require |
36 // instructing the X server to copy from the backing store to the window. | 45 // instructing the X server to copy from the backing store to the window. |
37 // | 46 // |
38 // The backing store is in the same format as the visual which our main window | 47 // The backing store is in the same format as the visual which our main window |
39 // is using. Bitmaps from the renderer are uploaded to the X server, either via | 48 // is using. Bitmaps from the renderer are uploaded to the X server, either via |
40 // shared memory or over the wire, and XRENDER is used to convert them to the | 49 // shared memory or over the wire, and XRENDER is used to convert them to the |
41 // correct format for the backing store. | 50 // correct format for the backing store. |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 *painted_synchronously = true; | 162 *painted_synchronously = true; |
154 | 163 |
155 if (!display_) | 164 if (!display_) |
156 return; | 165 return; |
157 | 166 |
158 if (bitmap_rect.IsEmpty()) | 167 if (bitmap_rect.IsEmpty()) |
159 return; | 168 return; |
160 | 169 |
161 const int width = bitmap_rect.width(); | 170 const int width = bitmap_rect.width(); |
162 const int height = bitmap_rect.height(); | 171 const int height = bitmap_rect.height(); |
163 // Assume that somewhere along the line, someone will do width * height * 4 | 172 |
164 // with signed numbers. If the maximum value is 2**31, then 2**31 / 4 = | 173 if (width <= 0 || width > kMaxVideoLayerSize || |
165 // 2**29 and floor(sqrt(2**29)) = 23170. | 174 height <= 0 || height > kMaxVideoLayerSize) |
166 if (width > 23170 || height > 23170) | |
167 return; | 175 return; |
168 | 176 |
169 TransportDIB* dib = process->GetTransportDIB(bitmap); | 177 TransportDIB* dib = process->GetTransportDIB(bitmap); |
170 if (!dib) | 178 if (!dib) |
171 return; | 179 return; |
172 | 180 |
173 if (!use_render_) | 181 if (!use_render_) |
174 return PaintRectWithoutXrender(dib, bitmap_rect, copy_rects); | 182 return PaintRectWithoutXrender(dib, bitmap_rect, copy_rects); |
175 | 183 |
176 Picture picture; | 184 Picture picture; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 const int height = std::min(size().height(), rect.height()); | 295 const int height = std::min(size().height(), rect.height()); |
288 | 296 |
289 XImage* image; | 297 XImage* image; |
290 XShmSegmentInfo shminfo; // Used only when shared memory is enabled. | 298 XShmSegmentInfo shminfo; // Used only when shared memory is enabled. |
291 if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE) { | 299 if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE) { |
292 // Use shared memory for faster copies when it's available. | 300 // Use shared memory for faster copies when it's available. |
293 Visual* visual = static_cast<Visual*>(visual_); | 301 Visual* visual = static_cast<Visual*>(visual_); |
294 memset(&shminfo, 0, sizeof(shminfo)); | 302 memset(&shminfo, 0, sizeof(shminfo)); |
295 image = XShmCreateImage(display_, visual, 32, | 303 image = XShmCreateImage(display_, visual, 32, |
296 ZPixmap, NULL, &shminfo, width, height); | 304 ZPixmap, NULL, &shminfo, width, height); |
297 | 305 if (!image) { |
| 306 return false; |
| 307 } |
298 // Create the shared memory segment for the image and map it. | 308 // Create the shared memory segment for the image and map it. |
| 309 if (image->bytes_per_line == 0 || image->height == 0 || |
| 310 (std::numeric_limits<size_t>::max() / image->bytes_per_line) > |
| 311 static_cast<size_t>(image->height)) { |
| 312 XDestroyImage(image); |
| 313 return false; |
| 314 } |
299 shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, | 315 shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, |
300 IPC_CREAT|0666); | 316 IPC_CREAT|0666); |
301 if (shminfo.shmid == -1) { | 317 if (shminfo.shmid == -1) { |
302 XDestroyImage(image); | 318 XDestroyImage(image); |
303 return false; | 319 return false; |
304 } | 320 } |
305 | 321 |
306 void* mapped_memory = shmat(shminfo.shmid, NULL, SHM_RDONLY); | 322 void* mapped_memory = shmat(shminfo.shmid, NULL, SHM_RDONLY); |
307 shmctl(shminfo.shmid, IPC_RMID, 0); | 323 shmctl(shminfo.shmid, IPC_RMID, 0); |
308 if (mapped_memory == (void*)-1) { | 324 if (mapped_memory == (void*)-1) { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 cairo_set_source(cr, pattern); | 443 cairo_set_source(cr, pattern); |
428 cairo_pattern_destroy(pattern); | 444 cairo_pattern_destroy(pattern); |
429 | 445 |
430 cairo_identity_matrix(cr); | 446 cairo_identity_matrix(cr); |
431 | 447 |
432 cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height()); | 448 cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height()); |
433 cairo_fill(cr); | 449 cairo_fill(cr); |
434 cairo_destroy(cr); | 450 cairo_destroy(cr); |
435 } | 451 } |
436 #endif | 452 #endif |
OLD | NEW |