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

Side by Side Diff: content/browser/compositor/browser_compositor_view_private_mac.mm

Issue 394883007: Mac: Shift more code into C++ classes from ObjC classes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@flip_fix
Patch Set: Touch-ups Created 6 years, 5 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/browser/compositor/browser_compositor_view_private_mac.h" 5 #include "content/browser/compositor/browser_compositor_view_private_mac.h"
6 6
7 #include "base/debug/trace_event.h" 7 #include "base/debug/trace_event.h"
8 #include "content/browser/compositor/gpu_process_transport_factory.h" 8 #include "content/browser/compositor/gpu_process_transport_factory.h"
9 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" 9 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
10 #include "content/browser/renderer_host/compositing_iosurface_mac.h" 10 #include "content/browser/renderer_host/compositing_iosurface_mac.h"
11 #include "content/browser/renderer_host/software_layer_mac.h" 11 #include "content/browser/renderer_host/software_layer_mac.h"
12 #include "content/public/browser/context_factory.h" 12 #include "content/public/browser/context_factory.h"
13 #include "ui/base/cocoa/animation_utils.h" 13 #include "ui/base/cocoa/animation_utils.h"
14 #include "ui/gl/scoped_cgl.h" 14 #include "ui/gl/scoped_cgl.h"
15 15
16 //////////////////////////////////////////////////////////////////////////////// 16 ////////////////////////////////////////////////////////////////////////////////
17 // BrowserCompositorViewCocoa 17 // BrowserCompositorViewMacInternal
18 18
19 @implementation BrowserCompositorViewCocoa : NSView 19 namespace content {
20 20
21 - (id)init { 21 BrowserCompositorViewMacInternal::BrowserCompositorViewMacInternal()
22 if (self = [super init]) { 22 : client_(NULL),
23 accelerated_layer_output_surface_id_ = 0; 23 accelerated_layer_output_surface_id_(0) {
24 client_ = NULL; 24 // Disable the fade-in animation as the layers are added.
25 helper_.reset(new content::BrowserCompositorViewCocoaHelper(self)); 25 ScopedCAActionDisabler disabler;
26 [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
27 26
28 // Disable the fade-in animation as the layer and view are added. 27 // Make this view host a transparent layer.
29 ScopedCAActionDisabler disabler; 28 background_layer_.reset([[CALayer alloc] init]);
30 29
31 // Make this view host a transparent layer. 30 // Add a flipped transparent layer as a child, so that we don't need to
32 background_layer_.reset([[CALayer alloc] init]); 31 // fiddle with the position of sub-layers -- they will always be at the
33 [self setLayer:background_layer_]; 32 // origin.
34 [self setWantsLayer:YES]; 33 flipped_layer_.reset([[CALayer alloc] init]);
34 [flipped_layer_ setGeometryFlipped:YES];
35 [flipped_layer_
36 setAutoresizingMask:kCALayerWidthSizable|kCALayerHeightSizable];
37 [background_layer_ addSublayer:flipped_layer_];
35 38
36 // Add a flipped transparent layer as a child, so that we don't need to 39 // Set the Cocoa view to be hosting the un-flipped background layer (hosting
37 // fiddle with the position of sub-layers -- they will always be at the 40 // a flipped layer results in unpredictable behavior).
38 // origin. 41 cocoa_view_.reset([[BrowserCompositorViewCocoa alloc] initWithClient:this]);
39 flipped_layer_.reset([[CALayer alloc] init]); 42 [cocoa_view_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
40 [flipped_layer_ setGeometryFlipped:YES]; 43 [cocoa_view_ setLayer:background_layer_];
41 [flipped_layer_ 44 [cocoa_view_ setWantsLayer:YES];
42 setAutoresizingMask:kCALayerWidthSizable|kCALayerHeightSizable];
43 [background_layer_ addSublayer:flipped_layer_];
44 45
45 compositor_.reset(new ui::Compositor(self, content::GetContextFactory())); 46 // Create a compositor to draw the contents of |cocoa_view_|.
46 } 47 compositor_.reset(new ui::Compositor(
47 return self; 48 cocoa_view_, content::GetContextFactory()));
48 } 49 }
49 50
50 - (void)setClient:(content::BrowserCompositorViewMacClient*)client { 51 BrowserCompositorViewMacInternal::~BrowserCompositorViewMacInternal() {
51 // Disable the fade-out as layers are removed. 52 DCHECK(!client_);
53 [cocoa_view_ resetClient];
54 // Ensure that the compositor be destroyed before the NSView that it is
55 // using.
56 compositor_.reset();
miu 2014/07/16 22:31:55 nit: Your choice, but you could let C++ destructio
ccameron 2014/07/17 02:30:02 Moved this to the header variable ordering.
57 }
58
59 void BrowserCompositorViewMacInternal::SetClient(
60 BrowserCompositorViewMacClient* client) {
61 // Disable the fade-in animation as the view is added.
52 ScopedCAActionDisabler disabler; 62 ScopedCAActionDisabler disabler;
53 [self removeFromSuperview];
54 63
55 // Reset all state. 64 DCHECK(client && !client_);
65 client_ = client;
66 compositor_->SetRootLayer(client_->BrowserCompositorRootLayer());
67 [cocoa_view_ setFrame:[client_->BrowserCompositorSuperview() frame]];
68 [client_->BrowserCompositorSuperview() addSubview:cocoa_view_];
69 }
70
71 void BrowserCompositorViewMacInternal::ResetClient() {
72 if (!client_)
73 return;
74
75 // Disable the fade-out animation as the view is removed.
76 ScopedCAActionDisabler disabler;
77
78 [cocoa_view_ removeFromSuperview];
79
56 [accelerated_layer_ removeFromSuperlayer]; 80 [accelerated_layer_ removeFromSuperlayer];
57 [accelerated_layer_ resetClient]; 81 [accelerated_layer_ resetClient];
58 accelerated_layer_.reset(); 82 accelerated_layer_.reset();
59 accelerated_layer_output_surface_id_ = 0; 83 accelerated_layer_output_surface_id_ = 0;
84
60 [software_layer_ removeFromSuperlayer]; 85 [software_layer_ removeFromSuperlayer];
61 software_layer_.reset(); 86 software_layer_.reset();
87
62 compositor_->SetScaleAndSize(1.0, gfx::Size(0, 0)); 88 compositor_->SetScaleAndSize(1.0, gfx::Size(0, 0));
63 89 compositor_->SetRootLayer(NULL);
64 client_ = client; 90 client_ = NULL;
65 if (client_) {
66 DCHECK(compositor_);
67 compositor_->SetRootLayer(client_->BrowserCompositorRootLayer());
68 [self setFrame:[client_->BrowserCompositorSuperview() frame]];
69 [client_->BrowserCompositorSuperview() addSubview:self];
70 } else {
71 compositor_->SetRootLayer(NULL);
72 }
73 } 91 }
74 92
75 - (void)destroyCompositor { 93 void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame(
76 DCHECK(!client_); 94 IOSurfaceID io_surface_id,
77 compositor_.reset(); 95 int output_surface_id,
78 } 96 const std::vector<ui::LatencyInfo>& latency_info,
79 97 gfx::Size pixel_size,
80 - (void)gotAcceleratedLayerError { 98 float scale_factor) {
81 if (!accelerated_layer_)
82 return;
83
84 [accelerated_layer_ context]->PoisonContextAndSharegroup();
85 compositor_->ScheduleFullRedraw();
86 }
87
88 - (ui::Compositor*)compositor {
89 return compositor_.get();
90 }
91
92 - (void)gotAcceleratedIOSurfaceFrame:(IOSurfaceID)surface_handle
93 withOutputSurfaceID:(int)surface_id
94 withLatencyInfo:(std::vector<ui::LatencyInfo>) latency_info
95 withPixelSize:(gfx::Size)pixel_size
96 withScaleFactor:(float)scale_factor {
97 DCHECK(!accelerated_layer_output_surface_id_); 99 DCHECK(!accelerated_layer_output_surface_id_);
98 accelerated_layer_output_surface_id_ = surface_id; 100 accelerated_layer_output_surface_id_ = output_surface_id;
99 accelerated_latency_info_.insert(accelerated_latency_info_.end(), 101 accelerated_latency_info_.insert(accelerated_latency_info_.end(),
100 latency_info.begin(), latency_info.end()); 102 latency_info.begin(), latency_info.end());
101 103
104 // If there is no client and therefore no superview to draw into, early-out.
105 if (!client_) {
106 AcceleratedLayerDidDrawFrame(true);
107 return;
108 }
109
110 // Disable the fade-in or fade-out effect if we create or remove layers.
102 ScopedCAActionDisabler disabler; 111 ScopedCAActionDisabler disabler;
103 112
104 // If there is already an accelerated layer, but it has the wrong scale 113 // If there is already an accelerated layer, but it has the wrong scale
105 // factor or it was poisoned, remove the old layer and replace it. 114 // factor or it was poisoned, remove the old layer and replace it.
106 base::scoped_nsobject<CompositingIOSurfaceLayer> old_accelerated_layer; 115 base::scoped_nsobject<CompositingIOSurfaceLayer> old_accelerated_layer;
107 if (accelerated_layer_ && ( 116 if (accelerated_layer_ && (
108 [accelerated_layer_ context]->HasBeenPoisoned() || 117 [accelerated_layer_ context]->HasBeenPoisoned() ||
109 [accelerated_layer_ iosurface]->scale_factor() != scale_factor)) { 118 [accelerated_layer_ iosurface]->scale_factor() != scale_factor)) {
110 old_accelerated_layer = accelerated_layer_; 119 old_accelerated_layer = accelerated_layer_;
111 accelerated_layer_.reset(); 120 accelerated_layer_.reset();
112 } 121 }
113 122
114 // If there is not a layer for accelerated frames, create one. 123 // If there is not a layer for accelerated frames, create one.
115 if (!accelerated_layer_) { 124 if (!accelerated_layer_) {
116 // Disable the fade-in animation as the layer is added.
117 ScopedCAActionDisabler disabler;
118 scoped_refptr<content::CompositingIOSurfaceMac> iosurface = 125 scoped_refptr<content::CompositingIOSurfaceMac> iosurface =
119 content::CompositingIOSurfaceMac::Create(); 126 content::CompositingIOSurfaceMac::Create();
120 accelerated_layer_.reset([[CompositingIOSurfaceLayer alloc] 127 accelerated_layer_.reset([[CompositingIOSurfaceLayer alloc]
121 initWithIOSurface:iosurface 128 initWithIOSurface:iosurface
122 withScaleFactor:scale_factor 129 withScaleFactor:scale_factor
123 withClient:helper_.get()]); 130 withClient:this]);
124 [flipped_layer_ addSublayer:accelerated_layer_]; 131 [flipped_layer_ addSublayer:accelerated_layer_];
125 } 132 }
126 133
134 // Open the provided IOSurface.
127 { 135 {
128 bool result = true; 136 bool result = true;
129 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( 137 gfx::ScopedCGLSetCurrentContext scoped_set_current_context(
130 [accelerated_layer_ context]->cgl_context()); 138 [accelerated_layer_ context]->cgl_context());
131 result = [accelerated_layer_ iosurface]->SetIOSurfaceWithContextCurrent( 139 result = [accelerated_layer_ iosurface]->SetIOSurfaceWithContextCurrent(
132 [accelerated_layer_ context], surface_handle, pixel_size, scale_factor); 140 [accelerated_layer_ context], io_surface_id, pixel_size, scale_factor);
133 if (!result) 141 if (!result)
134 LOG(ERROR) << "Failed SetIOSurface on CompositingIOSurfaceMac"; 142 LOG(ERROR) << "Failed SetIOSurface on CompositingIOSurfaceMac";
135 } 143 }
136 [accelerated_layer_ gotNewFrame]; 144 [accelerated_layer_ gotNewFrame];
137 145
138 // Set the bounds of the accelerated layer to match the size of the frame. 146 // Set the bounds of the accelerated layer to match the size of the frame.
139 // If the bounds changed, force the content to be displayed immediately. 147 // If the bounds changed, force the content to be displayed immediately.
140 CGRect new_layer_bounds = CGRectMake( 148 CGRect new_layer_bounds = CGRectMake(
141 0, 149 0,
142 0, 150 0,
143 [accelerated_layer_ iosurface]->dip_io_surface_size().width(), 151 [accelerated_layer_ iosurface]->dip_io_surface_size().width(),
144 [accelerated_layer_ iosurface]->dip_io_surface_size().height()); 152 [accelerated_layer_ iosurface]->dip_io_surface_size().height());
145 bool bounds_changed = !CGRectEqualToRect( 153 bool bounds_changed = !CGRectEqualToRect(
146 new_layer_bounds, [accelerated_layer_ bounds]); 154 new_layer_bounds, [accelerated_layer_ bounds]);
147 [accelerated_layer_ setBounds:new_layer_bounds]; 155 [accelerated_layer_ setBounds:new_layer_bounds];
148 if (bounds_changed) { 156 if (bounds_changed) {
149 [accelerated_layer_ setNeedsDisplay]; 157 [accelerated_layer_ setNeedsDisplay];
150 [accelerated_layer_ displayIfNeeded]; 158 [accelerated_layer_ displayIfNeeded];
151 } 159 }
152 160
153 // If there was a software layer or an old accelerated layer, remove it. 161 // If there was a software layer or an old accelerated layer, remove it.
154 // Disable the fade-out animation as the layer is removed. 162 // Disable the fade-out animation as the layer is removed.
155 { 163 {
156 ScopedCAActionDisabler disabler;
157 [software_layer_ removeFromSuperlayer]; 164 [software_layer_ removeFromSuperlayer];
158 software_layer_.reset(); 165 software_layer_.reset();
159 [old_accelerated_layer resetClient]; 166 [old_accelerated_layer resetClient];
160 [old_accelerated_layer removeFromSuperlayer]; 167 [old_accelerated_layer removeFromSuperlayer];
161 old_accelerated_layer.reset(); 168 old_accelerated_layer.reset();
162 } 169 }
163 } 170 }
164 171
165 - (void)gotSoftwareFrame:(cc::SoftwareFrameData*)frame_data 172 void BrowserCompositorViewMacInternal::GotSoftwareFrame(
166 withScaleFactor:(float)scale_factor 173 cc::SoftwareFrameData* frame_data,
167 withCanvas:(SkCanvas*)canvas { 174 float scale_factor,
168 if (!frame_data || !canvas) 175 SkCanvas* canvas) {
176 if (!frame_data || !canvas || !client_)
169 return; 177 return;
170 178
179 // Disable the fade-in or fade-out effect if we create or remove layers.
180 ScopedCAActionDisabler disabler;
181
171 // If there is not a layer for software frames, create one. 182 // If there is not a layer for software frames, create one.
172 if (!software_layer_) { 183 if (!software_layer_) {
173 // Disable the fade-in animation as the layer is added.
174 ScopedCAActionDisabler disabler;
175 software_layer_.reset([[SoftwareLayer alloc] init]); 184 software_layer_.reset([[SoftwareLayer alloc] init]);
176 [flipped_layer_ addSublayer:software_layer_]; 185 [flipped_layer_ addSublayer:software_layer_];
177 } 186 }
178 187
188 // Set the software layer to draw the provided canvas.
179 SkImageInfo info; 189 SkImageInfo info;
180 size_t row_bytes; 190 size_t row_bytes;
181 const void* pixels = canvas->peekPixels(&info, &row_bytes); 191 const void* pixels = canvas->peekPixels(&info, &row_bytes);
182 [software_layer_ setContentsToData:pixels 192 [software_layer_ setContentsToData:pixels
183 withRowBytes:row_bytes 193 withRowBytes:row_bytes
184 withPixelSize:gfx::Size(info.fWidth, info.fHeight) 194 withPixelSize:gfx::Size(info.fWidth, info.fHeight)
185 withScaleFactor:scale_factor]; 195 withScaleFactor:scale_factor];
186 196
187 // If there was an accelerated layer, remove it. 197 // If there was an accelerated layer, remove it.
188 // Disable the fade-out animation as the layer is removed.
189 { 198 {
190 ScopedCAActionDisabler disabler;
191 [accelerated_layer_ resetClient]; 199 [accelerated_layer_ resetClient];
192 [accelerated_layer_ removeFromSuperlayer]; 200 [accelerated_layer_ removeFromSuperlayer];
193 accelerated_layer_.reset(); 201 accelerated_layer_.reset();
194 } 202 }
195
196 // This call can be nested insider ui::Compositor commit calls, and can also
197 // make additional ui::Compositor commit calls. Avoid the potential recursion
198 // by acknowledging the frame asynchronously.
199 [self performSelector:@selector(layerDidDrawFrame)
200 withObject:nil
201 afterDelay:0];
202 } 203 }
203 204
204 - (void)layerDidDrawFrame { 205 void BrowserCompositorViewMacInternal::AcceleratedLayerDidDrawFrame(
206 bool succeeded) {
205 if (accelerated_layer_output_surface_id_) { 207 if (accelerated_layer_output_surface_id_) {
206 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed( 208 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed(
207 accelerated_layer_output_surface_id_); 209 accelerated_layer_output_surface_id_);
208 accelerated_layer_output_surface_id_ = 0; 210 accelerated_layer_output_surface_id_ = 0;
209 } 211 }
210 212
211 if (client_) 213 if (client_)
212 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_); 214 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_);
215
213 accelerated_latency_info_.clear(); 216 accelerated_latency_info_.clear();
217
218 if (!succeeded) {
219 if (accelerated_layer_)
220 [accelerated_layer_ context]->PoisonContextAndSharegroup();
221 compositor_->ScheduleFullRedraw();
222 }
223 }
224
225 } // namespace content
226
227 ////////////////////////////////////////////////////////////////////////////////
228 // BrowserCompositorViewCocoa
229
230 @implementation BrowserCompositorViewCocoa
231
232 - (id)initWithClient:(content::BrowserCompositorViewCocoaClient*)client {
233 if (self = [super init]) {
234 client_ = client;
235 }
236 return self;
237 }
238
239 - (void)dealloc {
240 DCHECK(!client_);
241 [super dealloc];
242 }
243
244 - (void)resetClient {
245 client_ = NULL;
246 }
247
248 - (void)gotAcceleratedIOSurfaceFrame:(IOSurfaceID)surface_handle
249 withOutputSurfaceID:(int)surface_id
250 withLatencyInfo:(std::vector<ui::LatencyInfo>)latency_info
251 withPixelSize:(gfx::Size)pixel_size
252 withScaleFactor:(float)scale_factor {
253 if (!client_)
254 return;
255 client_->GotAcceleratedIOSurfaceFrame(
256 surface_handle, surface_id, latency_info, pixel_size, scale_factor);
257 }
258
259 - (void)gotSoftwareFrame:(cc::SoftwareFrameData*)frame_data
260 withScaleFactor:(float)scale_factor
261 withCanvas:(SkCanvas*)canvas {
262 if (!client_)
263 return;
264 client_->GotSoftwareFrame(frame_data, scale_factor, canvas);
214 } 265 }
215 266
216 @end // BrowserCompositorViewCocoa 267 @end // BrowserCompositorViewCocoa
217 268
218 ////////////////////////////////////////////////////////////////////////////////
219 // BrowserCompositorViewCocoaHelper
220
221 namespace content {
222
223 void BrowserCompositorViewCocoaHelper::AcceleratedLayerDidDrawFrame(
224 bool succeeded) {
225 [view_ layerDidDrawFrame];
226 if (!succeeded)
227 [view_ gotAcceleratedLayerError];
228 }
229
230 }
231
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698