| 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 |