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 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
6 | 6 |
7 #include "chrome/browser/renderer_host/backing_store_mac.h" | 7 #include "chrome/browser/renderer_host/backing_store_mac.h" |
8 | 8 |
9 #include "app/surface/transport_dib.h" | 9 #include "app/surface/transport_dib.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/mac_util.h" | 11 #include "base/mac_util.h" |
| 12 #include "base/mac/scoped_cftyperef.h" |
12 #include "base/sys_info.h" | 13 #include "base/sys_info.h" |
13 #include "chrome/browser/renderer_host/render_process_host.h" | 14 #include "chrome/browser/renderer_host/render_process_host.h" |
14 #include "chrome/browser/renderer_host/render_widget_host.h" | 15 #include "chrome/browser/renderer_host/render_widget_host.h" |
15 #include "chrome/browser/renderer_host/render_widget_host_view.h" | 16 #include "chrome/browser/renderer_host/render_widget_host_view.h" |
16 #include "gfx/rect.h" | 17 #include "gfx/rect.h" |
17 #include "skia/ext/platform_canvas.h" | 18 #include "skia/ext/platform_canvas.h" |
18 #include "third_party/skia/include/core/SkBitmap.h" | 19 #include "third_party/skia/include/core/SkBitmap.h" |
19 #include "third_party/skia/include/core/SkCanvas.h" | 20 #include "third_party/skia/include/core/SkCanvas.h" |
20 | 21 |
21 // Mac Backing Stores: | 22 // Mac Backing Stores: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 // Our paints are always synchronous and the caller can free the TransportDIB, | 61 // Our paints are always synchronous and the caller can free the TransportDIB, |
61 // even on failure. | 62 // even on failure. |
62 *painted_synchronously = true; | 63 *painted_synchronously = true; |
63 | 64 |
64 DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap())); | 65 DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap())); |
65 | 66 |
66 TransportDIB* dib = process->GetTransportDIB(bitmap); | 67 TransportDIB* dib = process->GetTransportDIB(bitmap); |
67 if (!dib) | 68 if (!dib) |
68 return; | 69 return; |
69 | 70 |
70 scoped_cftyperef<CGDataProviderRef> data_provider( | 71 base::mac::ScopedCFTypeRef<CGDataProviderRef> data_provider( |
71 CGDataProviderCreateWithData(NULL, dib->memory(), | 72 CGDataProviderCreateWithData(NULL, dib->memory(), |
72 bitmap_rect.width() * bitmap_rect.height() * 4, NULL)); | 73 bitmap_rect.width() * bitmap_rect.height() * 4, NULL)); |
73 | 74 |
74 scoped_cftyperef<CGImageRef> bitmap_image( | 75 base::mac::ScopedCFTypeRef<CGImageRef> bitmap_image( |
75 CGImageCreate(bitmap_rect.width(), bitmap_rect.height(), 8, 32, | 76 CGImageCreate(bitmap_rect.width(), bitmap_rect.height(), 8, 32, |
76 4 * bitmap_rect.width(), mac_util::GetSystemColorSpace(), | 77 4 * bitmap_rect.width(), mac_util::GetSystemColorSpace(), |
77 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, | 78 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, |
78 data_provider, NULL, false, kCGRenderingIntentDefault)); | 79 data_provider, NULL, false, kCGRenderingIntentDefault)); |
79 | 80 |
80 for (size_t i = 0; i < copy_rects.size(); i++) { | 81 for (size_t i = 0; i < copy_rects.size(); i++) { |
81 const gfx::Rect& copy_rect = copy_rects[i]; | 82 const gfx::Rect& copy_rect = copy_rects[i]; |
82 | 83 |
83 // Only the subpixels given by copy_rect have pixels to copy. | 84 // Only the subpixels given by copy_rect have pixels to copy. |
84 scoped_cftyperef<CGImageRef> image( | 85 base::mac::ScopedCFTypeRef<CGImageRef> image( |
85 CGImageCreateWithImageInRect(bitmap_image, CGRectMake( | 86 CGImageCreateWithImageInRect(bitmap_image, CGRectMake( |
86 copy_rect.x() - bitmap_rect.x(), | 87 copy_rect.x() - bitmap_rect.x(), |
87 copy_rect.y() - bitmap_rect.y(), | 88 copy_rect.y() - bitmap_rect.y(), |
88 copy_rect.width(), | 89 copy_rect.width(), |
89 copy_rect.height()))); | 90 copy_rect.height()))); |
90 | 91 |
91 if (!cg_layer()) { | 92 if (!cg_layer()) { |
92 // The view may have moved to a window. Try to get a CGLayer. | 93 // The view may have moved to a window. Try to get a CGLayer. |
93 cg_layer_.reset(CreateCGLayer()); | 94 cg_layer_.reset(CreateCGLayer()); |
94 if (cg_layer()) { | 95 if (cg_layer()) { |
95 // now that we have a layer, copy the cached image into it | 96 // now that we have a layer, copy the cached image into it |
96 scoped_cftyperef<CGImageRef> bitmap_image( | 97 base::mac::ScopedCFTypeRef<CGImageRef> bitmap_image( |
97 CGBitmapContextCreateImage(cg_bitmap_)); | 98 CGBitmapContextCreateImage(cg_bitmap_)); |
98 CGContextDrawImage(CGLayerGetContext(cg_layer()), | 99 CGContextDrawImage(CGLayerGetContext(cg_layer()), |
99 CGRectMake(0, 0, size().width(), size().height()), | 100 CGRectMake(0, 0, size().width(), size().height()), |
100 bitmap_image); | 101 bitmap_image); |
101 // Discard the cache bitmap, since we no longer need it. | 102 // Discard the cache bitmap, since we no longer need it. |
102 cg_bitmap_.reset(NULL); | 103 cg_bitmap_.reset(NULL); |
103 } | 104 } |
104 } | 105 } |
105 | 106 |
106 DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap())); | 107 DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap())); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 156 |
156 // We assume |clip_rect| is contained within the backing store. | 157 // We assume |clip_rect| is contained within the backing store. |
157 DCHECK(clip_rect.bottom() <= size().height()); | 158 DCHECK(clip_rect.bottom() <= size().height()); |
158 DCHECK(clip_rect.right() <= size().width()); | 159 DCHECK(clip_rect.right() <= size().width()); |
159 | 160 |
160 if ((dx || dy) && abs(dx) < size().width() && abs(dy) < size().height()) { | 161 if ((dx || dy) && abs(dx) < size().width() && abs(dy) < size().height()) { |
161 if (cg_layer()) { | 162 if (cg_layer()) { |
162 // See http://crbug.com/45553 , comments 5 and 6. | 163 // See http://crbug.com/45553 , comments 5 and 6. |
163 static bool needs_layer_workaround = NeedsLayerWorkaround(); | 164 static bool needs_layer_workaround = NeedsLayerWorkaround(); |
164 | 165 |
165 scoped_cftyperef<CGLayerRef> new_layer; | 166 base::mac::ScopedCFTypeRef<CGLayerRef> new_layer; |
166 CGContextRef layer; | 167 CGContextRef layer; |
167 | 168 |
168 if (needs_layer_workaround) { | 169 if (needs_layer_workaround) { |
169 new_layer.reset(CreateCGLayer()); | 170 new_layer.reset(CreateCGLayer()); |
170 // If the current view is in a window, the replacement must be too. | 171 // If the current view is in a window, the replacement must be too. |
171 DCHECK(new_layer); | 172 DCHECK(new_layer); |
172 | 173 |
173 layer = CGLayerGetContext(new_layer); | 174 layer = CGLayerGetContext(new_layer); |
174 CGContextDrawLayerAtPoint(layer, CGPointMake(0, 0), cg_layer()); | 175 CGContextDrawLayerAtPoint(layer, CGPointMake(0, 0), cg_layer()); |
175 } else { | 176 } else { |
176 layer = CGLayerGetContext(cg_layer()); | 177 layer = CGLayerGetContext(cg_layer()); |
177 } | 178 } |
178 | 179 |
179 CGContextSaveGState(layer); | 180 CGContextSaveGState(layer); |
180 CGContextClipToRect(layer, | 181 CGContextClipToRect(layer, |
181 CGRectMake(clip_rect.x(), | 182 CGRectMake(clip_rect.x(), |
182 size().height() - clip_rect.bottom(), | 183 size().height() - clip_rect.bottom(), |
183 clip_rect.width(), | 184 clip_rect.width(), |
184 clip_rect.height())); | 185 clip_rect.height())); |
185 CGContextDrawLayerAtPoint(layer, CGPointMake(dx, -dy), cg_layer()); | 186 CGContextDrawLayerAtPoint(layer, CGPointMake(dx, -dy), cg_layer()); |
186 CGContextRestoreGState(layer); | 187 CGContextRestoreGState(layer); |
187 | 188 |
188 if (needs_layer_workaround) | 189 if (needs_layer_workaround) |
189 cg_layer_.swap(new_layer); | 190 cg_layer_.swap(new_layer); |
190 } else { | 191 } else { |
191 // We don't have a layer, so scroll the contents of the CGBitmapContext. | 192 // We don't have a layer, so scroll the contents of the CGBitmapContext. |
192 scoped_cftyperef<CGImageRef> bitmap_image( | 193 base::mac::ScopedCFTypeRef<CGImageRef> bitmap_image( |
193 CGBitmapContextCreateImage(cg_bitmap_)); | 194 CGBitmapContextCreateImage(cg_bitmap_)); |
194 CGContextSaveGState(cg_bitmap_); | 195 CGContextSaveGState(cg_bitmap_); |
195 CGContextClipToRect(cg_bitmap_, | 196 CGContextClipToRect(cg_bitmap_, |
196 CGRectMake(clip_rect.x(), | 197 CGRectMake(clip_rect.x(), |
197 size().height() - clip_rect.bottom(), | 198 size().height() - clip_rect.bottom(), |
198 clip_rect.width(), | 199 clip_rect.width(), |
199 clip_rect.height())); | 200 clip_rect.height())); |
200 CGContextDrawImage(cg_bitmap_, | 201 CGContextDrawImage(cg_bitmap_, |
201 CGRectMake(dx, -dy, size().width(), size().height()), | 202 CGRectMake(dx, -dy, size().width(), size().height()), |
202 bitmap_image); | 203 bitmap_image); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 CGContextRef context = CGBitmapContextCreate(NULL, | 238 CGContextRef context = CGBitmapContextCreate(NULL, |
238 size().width(), size().height(), | 239 size().width(), size().height(), |
239 8, size().width() * 4, | 240 8, size().width() * 4, |
240 mac_util::GetSystemColorSpace(), | 241 mac_util::GetSystemColorSpace(), |
241 kCGImageAlphaPremultipliedFirst | | 242 kCGImageAlphaPremultipliedFirst | |
242 kCGBitmapByteOrder32Host); | 243 kCGBitmapByteOrder32Host); |
243 DCHECK(context); | 244 DCHECK(context); |
244 | 245 |
245 return context; | 246 return context; |
246 } | 247 } |
OLD | NEW |