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

Side by Side Diff: chrome/browser/renderer_host/backing_store_mac.mm

Issue 175027: Update BackingStore to handle the case where our Cocoa view has... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 3 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 #import <Cocoa/Cocoa.h> 5 #import <Cocoa/Cocoa.h>
6 6
7 #include "chrome/browser/renderer_host/backing_store.h" 7 #include "chrome/browser/renderer_host/backing_store.h"
8 #include "chrome/browser/renderer_host/render_widget_host.h" 8 #include "chrome/browser/renderer_host/render_widget_host.h"
9 #include "chrome/browser/renderer_host/render_widget_host_view.h" 9 #include "chrome/browser/renderer_host/render_widget_host_view.h"
10 10
(...skipping 11 matching lines...) Expand all
22 // all or mostly on the GPU, which is good for performance. 22 // all or mostly on the GPU, which is good for performance.
23 23
24 BackingStore::BackingStore(RenderWidgetHost* widget, const gfx::Size& size) 24 BackingStore::BackingStore(RenderWidgetHost* widget, const gfx::Size& size)
25 : render_widget_host_(widget), 25 : render_widget_host_(widget),
26 size_(size), 26 size_(size),
27 cg_layer_(NULL) { 27 cg_layer_(NULL) {
28 // We want our CGLayer to be optimized for drawing into our containing 28 // We want our CGLayer to be optimized for drawing into our containing
29 // window, so extract a CGContext corresponding to that window that we can 29 // window, so extract a CGContext corresponding to that window that we can
30 // pass to CGLayerCreateWithContext. 30 // pass to CGLayerCreateWithContext.
31 NSWindow* containing_window = [widget->view()->GetNativeView() window]; 31 NSWindow* containing_window = [widget->view()->GetNativeView() window];
32 if (!containing_window) // possible in unit tests 32 if (!containing_window) {
33 return; 33 // If we are not in a containing window yet, create a CGBitmapContext
34 CGContextRef context = static_cast<CGContextRef>([[containing_window graphicsC ontext] graphicsPort]); 34 // to use as a stand-in for the layer.
35 CGLayerRef layer = CGLayerCreateWithContext(context, size.ToCGSize(), NULL); 35 scoped_cftyperef<CGColorSpaceRef>
36 cg_layer_.reset(layer); 36 color_space(CGColorSpaceCreateDeviceRGB());
37 cg_bitmap_.reset(CGBitmapContextCreate(NULL, size.width(), size.height(),
38 8, size.width() * 8, color_space,
39 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
40 } else {
41 CGContextRef context = static_cast<CGContextRef>(
42 [[containing_window graphicsContext] graphicsPort]);
43 CGLayerRef layer = CGLayerCreateWithContext(context, size.ToCGSize(), NULL);
44 cg_layer_.reset(layer);
45 }
37 } 46 }
38 47
39 BackingStore::~BackingStore() { 48 BackingStore::~BackingStore() {
40 } 49 }
41 50
42 size_t BackingStore::MemorySize() { 51 size_t BackingStore::MemorySize() {
43 // Estimate memory usage as 4 bytes per pixel. 52 // Estimate memory usage as 4 bytes per pixel.
44 return size_.GetArea() * 4; 53 return size_.GetArea() * 4;
45 } 54 }
46 55
47 // Paint the contents of a TransportDIB into a rectangle of our CGLayer 56 // Paint the contents of a TransportDIB into a rectangle of our CGLayer
48 void BackingStore::PaintRect(base::ProcessHandle process, 57 void BackingStore::PaintRect(base::ProcessHandle process,
49 TransportDIB* bitmap, 58 TransportDIB* bitmap,
50 const gfx::Rect& bitmap_rect) { 59 const gfx::Rect& bitmap_rect) {
51 if (!cg_layer()) return;
52
53 scoped_cftyperef<CGColorSpaceRef> color_space(CGColorSpaceCreateDeviceRGB()); 60 scoped_cftyperef<CGColorSpaceRef> color_space(CGColorSpaceCreateDeviceRGB());
54 scoped_cftyperef<CGDataProviderRef> data_provider( 61 scoped_cftyperef<CGDataProviderRef> data_provider(
55 CGDataProviderCreateWithData(NULL, bitmap->memory(), 62 CGDataProviderCreateWithData(NULL, bitmap->memory(),
56 bitmap_rect.width() * bitmap_rect.height() * 4, NULL)); 63 bitmap_rect.width() * bitmap_rect.height() * 4, NULL));
57 scoped_cftyperef<CGImageRef> image(CGImageCreate(bitmap_rect.width(), 64 scoped_cftyperef<CGImageRef> image(
58 bitmap_rect.height(), 8, 32, 4 * bitmap_rect.width(), color_space, 65 CGImageCreate(bitmap_rect.width(), bitmap_rect.height(), 8, 32,
59 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, data_provider, 66 4 * bitmap_rect.width(), color_space,
60 NULL, false, kCGRenderingIntentDefault)); 67 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
68 data_provider, NULL, false, kCGRenderingIntentDefault));
61 69
62 // The CGLayer's origin is in the lower left, but flipping the CTM would 70 if (!cg_layer()) {
63 // cause the image to get drawn upside down. So we move the rectangle 71 // we don't have a CGLayer yet, so see if we can create one.
64 // to the right position before drawing the image. 72 NSWindow* containing_window =
65 CGContextRef layer = CGLayerGetContext(cg_layer()); 73 [render_widget_host()->view()->GetNativeView() window];
66 gfx::Rect paint_rect = bitmap_rect; 74 if (containing_window) {
67 paint_rect.set_y(size_.height() - bitmap_rect.bottom()); 75 CGContextRef context = static_cast<CGContextRef>(
68 CGContextDrawImage(layer, paint_rect.ToCGRect(), image); 76 [[containing_window graphicsContext] graphicsPort]);
77 CGLayerRef layer =
78 CGLayerCreateWithContext(context, size().ToCGSize(), NULL);
79 cg_layer_.reset(layer);
80 // now that we have a layer, copy the cached image into it
81 scoped_cftyperef<CGImageRef> bitmap_image(
82 CGBitmapContextCreateImage(cg_bitmap_));
83 CGContextDrawImage(CGLayerGetContext(layer),
84 CGRectMake(0, 0, size().width(), size().height()),
85 bitmap_image);
86 // Discard the cache bitmap, since we no longer need it.
87 cg_bitmap_.reset(NULL);
88 }
89 }
90
91 if (cg_layer()) {
92 // The CGLayer's origin is in the lower left, but flipping the CTM would
93 // cause the image to get drawn upside down. So we move the rectangle
94 // to the right position before drawing the image.
95 CGContextRef layer = CGLayerGetContext(cg_layer());
96 gfx::Rect paint_rect = bitmap_rect;
97 paint_rect.set_y(size_.height() - bitmap_rect.bottom());
98 CGContextDrawImage(layer, paint_rect.ToCGRect(), image);
99 } else {
100 // The layer hasn't been created yet, so draw into the cache bitmap.
101 gfx::Rect paint_rect = bitmap_rect;
102 paint_rect.set_y(size_.height() - bitmap_rect.bottom());
103 CGContextDrawImage(cg_bitmap_, paint_rect.ToCGRect(), image);
104 }
69 } 105 }
70 106
71 // Scroll the contents of our CGLayer 107 // Scroll the contents of our CGLayer
72 void BackingStore::ScrollRect(base::ProcessHandle process, 108 void BackingStore::ScrollRect(base::ProcessHandle process,
73 TransportDIB* bitmap, 109 TransportDIB* bitmap,
74 const gfx::Rect& bitmap_rect, 110 const gfx::Rect& bitmap_rect,
75 int dx, int dy, 111 int dx, int dy,
76 const gfx::Rect& clip_rect, 112 const gfx::Rect& clip_rect,
77 const gfx::Size& view_size) { 113 const gfx::Size& view_size) {
78 if (!cg_layer()) return; 114 if (!cg_layer()) return;
79 115
80 // "Scroll" the contents of the layer by creating a new CGLayer, 116 // "Scroll" the contents of the layer by creating a new CGLayer,
81 // copying the contents of the old one into the new one offset by the scroll 117 // copying the contents of the old one into the new one offset by the scroll
82 // amount, swapping in the new CGLayer, and then painting in the new data. 118 // amount, swapping in the new CGLayer, and then painting in the new data.
83 // 119 //
84 // The Windows code always sets the whole backing store as the source of the 120 // The Windows code always sets the whole backing store as the source of the
85 // scroll. Thus, we only have to worry about pixels which will end up inside 121 // scroll. Thus, we only have to worry about pixels which will end up inside
86 // the clipping rectangle. (Note that the clipping rectangle is not 122 // the clipping rectangle. (Note that the clipping rectangle is not
87 // translated by the scroll.) 123 // translated by the scroll.)
88 124
89 // We assume |clip_rect| is contained within the backing store. 125 // We assume |clip_rect| is contained within the backing store.
90 CGSize layer_size = CGLayerGetSize(cg_layer()); 126 CGSize layer_size = CGLayerGetSize(cg_layer());
91 DCHECK(clip_rect.bottom() <= layer_size.height); 127 DCHECK(clip_rect.bottom() <= layer_size.height);
92 DCHECK(clip_rect.right() <= layer_size.width); 128 DCHECK(clip_rect.right() <= layer_size.width);
93 129
94 if ((dx && abs(dx) < layer_size.width) || 130 if ((dx && abs(dx) < layer_size.width) ||
95 (dy && abs(dy) < layer_size.height)) { 131 (dy && abs(dy) < layer_size.height)) {
96 // 132 if (cg_layer()) {
97 scoped_cftyperef<CGLayerRef> new_layer(CGLayerCreateWithContext( 133 CGContextRef context = CGLayerGetContext(cg_layer());
98 CGLayerGetContext(cg_layer()), layer_size, NULL)); 134 scoped_cftyperef<CGLayerRef> new_layer(
99 CGContextRef layer = CGLayerGetContext(new_layer); 135 CGLayerCreateWithContext(context, layer_size, NULL));
100 CGContextDrawLayerAtPoint(layer, CGPointMake(0, 0), cg_layer()); 136 CGContextRef layer = CGLayerGetContext(new_layer);
101 CGContextSaveGState(layer); 137 CGContextDrawLayerAtPoint(layer, CGPointMake(0, 0), cg_layer());
102 CGContextClipToRect(layer, CGRectMake(clip_rect.x(), 138 CGContextSaveGState(layer);
103 size_.height() - clip_rect.bottom(), 139 CGContextClipToRect(layer, CGRectMake(clip_rect.x(),
104 clip_rect.width(), 140 size_.height() - clip_rect.bottom(),
105 clip_rect.height())); 141 clip_rect.width(),
106 CGContextDrawLayerAtPoint(layer, CGPointMake(dx, -dy), cg_layer()); 142 clip_rect.height()));
107 CGContextRestoreGState(layer); 143 CGContextDrawLayerAtPoint(layer, CGPointMake(dx, -dy), cg_layer());
108 cg_layer_.swap(new_layer); 144 CGContextRestoreGState(layer);
145 cg_layer_.swap(new_layer);
146 } else {
147 // We don't have a layer, so scroll the contents of the CGBitmapContext.
148 scoped_cftyperef<CGColorSpaceRef>
149 color_space(CGColorSpaceCreateDeviceRGB());
150 scoped_cftyperef<CGContextRef> new_bitmap(
151 CGBitmapContextCreate(NULL, size_.width(), size_.height(), 8,
152 size_.width() * 8, color_space,
153 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
154 scoped_cftyperef<CGImageRef> bitmap_image(
155 CGBitmapContextCreateImage(cg_bitmap_));
156 CGContextDrawImage(new_bitmap,
157 CGRectMake(0, 0, size_.width(), size_.height()),
158 bitmap_image);
159 CGContextSaveGState(new_bitmap);
160 CGContextClipToRect(new_bitmap,
161 CGRectMake(clip_rect.x(),
162 size_.height() - clip_rect.bottom(),
163 clip_rect.width(),
164 clip_rect.height()));
165 CGContextDrawImage(new_bitmap,
166 CGRectMake(dx, -dy, size_.width(), size_.height()),
167 bitmap_image);
168 CGContextRestoreGState(new_bitmap);
169 cg_bitmap_.swap(new_bitmap);
170 }
109 } 171 }
110 // Now paint the new bitmap data into the CGLayer 172 // Now paint the new bitmap data
111 PaintRect(process, bitmap, bitmap_rect); 173 PaintRect(process, bitmap, bitmap_rect);
112 return; 174 return;
113 } 175 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698