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

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

Issue 490393002: Simplify IOSurface CoreAnimation code: Part 2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Missed colon Created 6 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
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 <map> 7 #include <map>
8 8
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "content/browser/compositor/gpu_process_transport_factory.h" 12 #include "content/browser/compositor/gpu_process_transport_factory.h"
13 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" 13 #include "content/browser/compositor/software_layer_mac.h"
14 #include "content/browser/renderer_host/compositing_iosurface_mac.h"
15 #include "content/browser/renderer_host/dip_util.h" 14 #include "content/browser/renderer_host/dip_util.h"
16 #include "content/browser/renderer_host/render_widget_resize_helper.h" 15 #include "content/browser/renderer_host/render_widget_resize_helper.h"
17 #include "content/browser/renderer_host/software_layer_mac.h"
18 #include "content/common/gpu/surface_handle_types_mac.h" 16 #include "content/common/gpu/surface_handle_types_mac.h"
19 #include "content/public/browser/context_factory.h" 17 #include "content/public/browser/context_factory.h"
20 #include "ui/base/cocoa/animation_utils.h" 18 #include "ui/base/cocoa/animation_utils.h"
21 #include "ui/gl/scoped_cgl.h" 19 #include "ui/gl/scoped_cgl.h"
22 20
23 namespace content { 21 namespace content {
24 namespace { 22 namespace {
25 23
26 typedef std::map<gfx::AcceleratedWidget,BrowserCompositorViewMacInternal*> 24 typedef std::map<gfx::AcceleratedWidget,BrowserCompositorViewMacInternal*>
27 WidgetToInternalsMap; 25 WidgetToInternalsMap;
28 base::LazyInstance<WidgetToInternalsMap> g_widget_to_internals_map; 26 base::LazyInstance<WidgetToInternalsMap> g_widget_to_internals_map;
29 27
30 } 28 }
31 29
32 //////////////////////////////////////////////////////////////////////////////// 30 ////////////////////////////////////////////////////////////////////////////////
33 // BrowserCompositorViewMacInternal 31 // BrowserCompositorViewMacInternal
34 32
35 BrowserCompositorViewMacInternal::BrowserCompositorViewMacInternal() 33 BrowserCompositorViewMacInternal::BrowserCompositorViewMacInternal()
36 : client_(NULL), 34 : client_(NULL),
37 accelerated_output_surface_id_(0) { 35 accelerated_output_surface_id_(0),
36 weak_factory_(this) {
38 // Disable the fade-in animation as the layers are added. 37 // Disable the fade-in animation as the layers are added.
39 ScopedCAActionDisabler disabler; 38 ScopedCAActionDisabler disabler;
40 39
41 // Add a flipped transparent layer as a child, so that we don't need to 40 // Add a flipped transparent layer as a child, so that we don't need to
42 // fiddle with the position of sub-layers -- they will always be at the 41 // fiddle with the position of sub-layers -- they will always be at the
43 // origin. 42 // origin.
44 flipped_layer_.reset([[CALayer alloc] init]); 43 flipped_layer_.reset([[CALayer alloc] init]);
45 [flipped_layer_ setGeometryFlipped:YES]; 44 [flipped_layer_ setGeometryFlipped:YES];
46 [flipped_layer_ setAnchorPoint:CGPointMake(0, 0)]; 45 [flipped_layer_ setAnchorPoint:CGPointMake(0, 0)];
47 [flipped_layer_ 46 [flipped_layer_
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 client_ = NULL; 102 client_ = NULL;
104 } 103 }
105 104
106 bool BrowserCompositorViewMacInternal::HasFrameOfSize( 105 bool BrowserCompositorViewMacInternal::HasFrameOfSize(
107 const gfx::Size& dip_size) const { 106 const gfx::Size& dip_size) const {
108 return last_swap_size_dip_ == dip_size; 107 return last_swap_size_dip_ == dip_size;
109 } 108 }
110 109
111 int BrowserCompositorViewMacInternal::GetRendererID() const { 110 int BrowserCompositorViewMacInternal::GetRendererID() const {
112 if (io_surface_layer_) 111 if (io_surface_layer_)
113 return [io_surface_layer_ iosurface]->GetRendererID(); 112 return [io_surface_layer_ rendererID];
114 return 0; 113 return 0;
115 } 114 }
116 115
117 void BrowserCompositorViewMacInternal::BeginPumpingFrames() { 116 void BrowserCompositorViewMacInternal::BeginPumpingFrames() {
118 [io_surface_layer_ beginPumpingFrames]; 117 [io_surface_layer_ beginPumpingFrames];
119 } 118 }
120 119
121 void BrowserCompositorViewMacInternal::EndPumpingFrames() { 120 void BrowserCompositorViewMacInternal::EndPumpingFrames() {
122 [io_surface_layer_ endPumpingFrames]; 121 [io_surface_layer_ endPumpingFrames];
123 } 122 }
124 123
125 void BrowserCompositorViewMacInternal::GotAcceleratedFrame( 124 void BrowserCompositorViewMacInternal::GotAcceleratedFrame(
126 uint64 surface_handle, int output_surface_id, 125 uint64 surface_handle, int output_surface_id,
127 const std::vector<ui::LatencyInfo>& latency_info, 126 const std::vector<ui::LatencyInfo>& latency_info,
128 gfx::Size pixel_size, float scale_factor) { 127 gfx::Size pixel_size, float scale_factor) {
129 // Record the surface and latency info to use when acknowledging this frame. 128 // Record the surface and latency info to use when acknowledging this frame.
130 DCHECK(!accelerated_output_surface_id_); 129 DCHECK(!accelerated_output_surface_id_);
131 accelerated_output_surface_id_ = output_surface_id; 130 accelerated_output_surface_id_ = output_surface_id;
132 accelerated_latency_info_.insert(accelerated_latency_info_.end(), 131 accelerated_latency_info_.insert(accelerated_latency_info_.end(),
133 latency_info.begin(), latency_info.end()); 132 latency_info.begin(), latency_info.end());
134 133
135 // If there is no client and therefore no superview to draw into, early-out. 134 // If there is no client and therefore no superview to draw into, early-out.
136 if (!client_) { 135 if (!client_) {
137 AcceleratedLayerDidDrawFrame(); 136 IOSurfaceLayerDidDrawFrame();
138 return; 137 return;
139 } 138 }
140 139
141 // Disable the fade-in or fade-out effect if we create or remove layers. 140 // Disable the fade-in or fade-out effect if we create or remove layers.
142 ScopedCAActionDisabler disabler; 141 ScopedCAActionDisabler disabler;
143 142
144 last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size); 143 last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size);
145 switch (GetSurfaceHandleType(surface_handle)) { 144 switch (GetSurfaceHandleType(surface_handle)) {
146 case kSurfaceHandleTypeIOSurface: { 145 case kSurfaceHandleTypeIOSurface: {
147 IOSurfaceID io_surface_id = IOSurfaceIDFromSurfaceHandle(surface_handle); 146 IOSurfaceID io_surface_id = IOSurfaceIDFromSurfaceHandle(surface_handle);
(...skipping 25 matching lines...) Expand all
173 if ([ca_context_layer_ contextId] != ca_context_id) { 172 if ([ca_context_layer_ contextId] != ca_context_id) {
174 ca_context_layer_.reset([[CALayerHost alloc] init]); 173 ca_context_layer_.reset([[CALayerHost alloc] init]);
175 [ca_context_layer_ setContextId:ca_context_id]; 174 [ca_context_layer_ setContextId:ca_context_id];
176 [ca_context_layer_ 175 [ca_context_layer_
177 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin]; 176 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin];
178 [flipped_layer_ addSublayer:ca_context_layer_]; 177 [flipped_layer_ addSublayer:ca_context_layer_];
179 } 178 }
180 179
181 // Acknowledge the frame to unblock the compositor immediately (the GPU 180 // Acknowledge the frame to unblock the compositor immediately (the GPU
182 // process will do any required throttling). 181 // process will do any required throttling).
183 AcceleratedLayerDidDrawFrame(); 182 IOSurfaceLayerDidDrawFrame();
184 183
185 // If this replacing a same-type layer, remove it now that the new layer is 184 // If this replacing a same-type layer, remove it now that the new layer is
186 // in the hierarchy. 185 // in the hierarchy.
187 if (old_ca_context_layer != ca_context_layer_) 186 if (old_ca_context_layer != ca_context_layer_)
188 DestroyCAContextLayer(old_ca_context_layer); 187 DestroyCAContextLayer(old_ca_context_layer);
189 188
190 // Remove any different-type layers that this is replacing. 189 // Remove any different-type layers that this is replacing.
191 DestroyIOSurfaceLayer(io_surface_layer_); 190 DestroyIOSurfaceLayer(io_surface_layer_);
192 DestroySoftwareLayer(); 191 DestroySoftwareLayer();
193 } 192 }
194 193
195 void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame( 194 void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame(
196 IOSurfaceID io_surface_id, 195 IOSurfaceID io_surface_id,
197 gfx::Size pixel_size, 196 gfx::Size pixel_size,
198 float scale_factor) { 197 float scale_factor) {
199 // In the layer is replaced, keep the old one around until after the new one 198 // In the layer is replaced, keep the old one around until after the new one
200 // is installed to avoid flashes. 199 // is installed to avoid flashes.
201 base::scoped_nsobject<CompositingIOSurfaceLayer> old_io_surface_layer = 200 base::scoped_nsobject<IOSurfaceLayer> old_io_surface_layer =
202 io_surface_layer_; 201 io_surface_layer_;
203 202
204 // Create or re-create an IOSurface layer if needed. If there already exists 203 // Create or re-create an IOSurface layer if needed. If there already exists
205 // a layer but it has the wrong scale factor or it was poisoned, re-create the 204 // a layer but it has the wrong scale factor re-create the layer.
206 // layer. 205 bool needs_new_layer = !io_surface_layer_ ||
207 bool needs_new_layer = 206 [io_surface_layer_ scaleFactor] != scale_factor;
208 !io_surface_layer_ ||
209 [io_surface_layer_ context]->HasBeenPoisoned() ||
210 [io_surface_layer_ iosurface]->scale_factor() != scale_factor;
211 if (needs_new_layer) { 207 if (needs_new_layer) {
212 scoped_refptr<content::CompositingIOSurfaceMac> iosurface = 208 io_surface_layer_.reset([[IOSurfaceLayer alloc]
213 content::CompositingIOSurfaceMac::Create(); 209 initWithClient:this withScaleFactor:scale_factor]);
214 if (!iosurface) { 210 DCHECK(io_surface_layer_);
215 LOG(ERROR) << "Failed to create CompositingIOSurfaceMac"; 211 [flipped_layer_ addSublayer:io_surface_layer_];
216 } else {
217 io_surface_layer_.reset([[CompositingIOSurfaceLayer alloc]
218 initWithIOSurface:iosurface
219 withScaleFactor:scale_factor
220 withClient:this]);
221 if (io_surface_layer_)
222 [flipped_layer_ addSublayer:io_surface_layer_];
223 else
224 LOG(ERROR) << "Failed to create CompositingIOSurfaceLayer";
225 }
226 } 212 }
227 213
228 // Open the provided IOSurface. 214 [io_surface_layer_ gotFrameWithIOSurface:io_surface_id
229 if (io_surface_layer_) { 215 withPixelSize:pixel_size
230 bool result = true; 216 withScaleFactor:scale_factor];
231 gfx::ScopedCGLSetCurrentContext scoped_set_current_context(
232 [io_surface_layer_ context]->cgl_context());
233 result = [io_surface_layer_ iosurface]->SetIOSurfaceWithContextCurrent(
234 [io_surface_layer_ context], io_surface_id, pixel_size, scale_factor);
235 if (!result) {
236 DestroyIOSurfaceLayer(io_surface_layer_);
237 LOG(ERROR) << "Failed open IOSurface in CompositingIOSurfaceLayer";
238 }
239 }
240 217
241 // Give a final complaint if anything with the layer's creation went wrong. 218 // Set the bounds of the accelerated layer to match the size of the frame.
242 // This frame will appear blank, the compositor will try to create another, 219 // If the bounds changed, force the content to be displayed immediately.
243 // and maybe that will go better. 220 CGRect new_layer_bounds = CGRectMake(
244 if (!io_surface_layer_) { 221 0, 0, last_swap_size_dip_.width(), last_swap_size_dip_.height());
245 LOG(ERROR) << "CompositingIOSurfaceLayer is nil, tab will be blank"; 222 bool bounds_changed = !CGRectEqualToRect(
246 AcceleratedLayerHitError(); 223 new_layer_bounds, [io_surface_layer_ bounds]);
247 } 224 [io_surface_layer_ setBounds:new_layer_bounds];
248 225 if (bounds_changed)
249 // Make the CALayer draw and set its size appropriately. 226 [io_surface_layer_ setNeedsDisplayAndDisplayAndAck];
250 if (io_surface_layer_) {
251 [io_surface_layer_ gotNewFrame];
252
253 // Set the bounds of the accelerated layer to match the size of the frame.
254 // If the bounds changed, force the content to be displayed immediately.
255 CGRect new_layer_bounds = CGRectMake(
256 0, 0, last_swap_size_dip_.width(), last_swap_size_dip_.height());
257 bool bounds_changed = !CGRectEqualToRect(
258 new_layer_bounds, [io_surface_layer_ bounds]);
259 [io_surface_layer_ setBounds:new_layer_bounds];
260 if (bounds_changed)
261 [io_surface_layer_ setNeedsDisplayAndDisplayAndAck];
262 }
263 227
264 // If this replacing a same-type layer, remove it now that the new layer is 228 // If this replacing a same-type layer, remove it now that the new layer is
265 // in the hierarchy. 229 // in the hierarchy.
266 if (old_io_surface_layer != io_surface_layer_) 230 if (old_io_surface_layer != io_surface_layer_)
267 DestroyIOSurfaceLayer(old_io_surface_layer); 231 DestroyIOSurfaceLayer(old_io_surface_layer);
268 232
269 // Remove any different-type layers that this is replacing. 233 // Remove any different-type layers that this is replacing.
270 DestroyCAContextLayer(ca_context_layer_); 234 DestroyCAContextLayer(ca_context_layer_);
271 DestroySoftwareLayer(); 235 DestroySoftwareLayer();
272 } 236 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 void BrowserCompositorViewMacInternal::DestroyCAContextLayer( 270 void BrowserCompositorViewMacInternal::DestroyCAContextLayer(
307 base::scoped_nsobject<CALayerHost> ca_context_layer) { 271 base::scoped_nsobject<CALayerHost> ca_context_layer) {
308 if (!ca_context_layer) 272 if (!ca_context_layer)
309 return; 273 return;
310 [ca_context_layer removeFromSuperlayer]; 274 [ca_context_layer removeFromSuperlayer];
311 if (ca_context_layer == ca_context_layer_) 275 if (ca_context_layer == ca_context_layer_)
312 ca_context_layer_.reset(); 276 ca_context_layer_.reset();
313 } 277 }
314 278
315 void BrowserCompositorViewMacInternal::DestroyIOSurfaceLayer( 279 void BrowserCompositorViewMacInternal::DestroyIOSurfaceLayer(
316 base::scoped_nsobject<CompositingIOSurfaceLayer> io_surface_layer) { 280 base::scoped_nsobject<IOSurfaceLayer> io_surface_layer) {
317 if (!io_surface_layer) 281 if (!io_surface_layer)
318 return; 282 return;
319 [io_surface_layer resetClient]; 283 [io_surface_layer resetClient];
320 [io_surface_layer removeFromSuperlayer]; 284 [io_surface_layer removeFromSuperlayer];
321 if (io_surface_layer == io_surface_layer_) 285 if (io_surface_layer == io_surface_layer_)
322 io_surface_layer_.reset(); 286 io_surface_layer_.reset();
323 } 287 }
324 288
325 void BrowserCompositorViewMacInternal::DestroySoftwareLayer() { 289 void BrowserCompositorViewMacInternal::DestroySoftwareLayer() {
326 if (!software_layer_) 290 if (!software_layer_)
327 return; 291 return;
328 [software_layer_ removeFromSuperlayer]; 292 [software_layer_ removeFromSuperlayer];
329 software_layer_.reset(); 293 software_layer_.reset();
330 } 294 }
331 295
332 bool BrowserCompositorViewMacInternal::AcceleratedLayerShouldAckImmediately() 296 bool BrowserCompositorViewMacInternal::IOSurfaceLayerShouldAckImmediately()
333 const { 297 const {
334 // If there is no client then the accelerated layer is not in the hierarchy 298 // If there is no client then the accelerated layer is not in the hierarchy
335 // and will never draw. 299 // and will never draw.
336 if (!client_) 300 if (!client_)
337 return true; 301 return true;
338 return client_->BrowserCompositorViewShouldAckImmediately(); 302 return client_->BrowserCompositorViewShouldAckImmediately();
339 } 303 }
340 304
341 void BrowserCompositorViewMacInternal::AcceleratedLayerDidDrawFrame() { 305 void BrowserCompositorViewMacInternal::IOSurfaceLayerDidDrawFrame() {
342 if (accelerated_output_surface_id_) { 306 if (accelerated_output_surface_id_) {
343 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed( 307 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed(
344 accelerated_output_surface_id_); 308 accelerated_output_surface_id_);
345 accelerated_output_surface_id_ = 0; 309 accelerated_output_surface_id_ = 0;
346 } 310 }
347 311
348 if (client_) 312 if (client_)
349 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_); 313 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_);
350 314
351 accelerated_latency_info_.clear(); 315 accelerated_latency_info_.clear();
352 } 316 }
353 317
354 void BrowserCompositorViewMacInternal::AcceleratedLayerHitError() { 318 void BrowserCompositorViewMacInternal::IOSurfaceLayerHitError() {
355 // Perform all acks that would have been done if the frame had succeeded, to 319 base::MessageLoop::current()->PostTask(FROM_HERE,
356 // un-block the compositor and renderer. 320 base::Bind(&BrowserCompositorViewMacInternal::HandleIOSurfaceLayerError,
357 AcceleratedLayerDidDrawFrame(); 321 weak_factory_.GetWeakPtr()));
322 }
358 323
359 // Poison the context being used and request a mulligan. 324 void BrowserCompositorViewMacInternal::HandleIOSurfaceLayerError() {
360 if (io_surface_layer_) 325 // Destroy the layer that caused the error.
361 [io_surface_layer_ context]->PoisonContextAndSharegroup(); 326 DestroyIOSurfaceLayer(io_surface_layer_);
327
328 // Request a mulligan.
362 compositor_->ScheduleFullRedraw(); 329 compositor_->ScheduleFullRedraw();
363 } 330 }
364 331
365 // static 332 // static
366 BrowserCompositorViewMacInternal* BrowserCompositorViewMacInternal:: 333 BrowserCompositorViewMacInternal* BrowserCompositorViewMacInternal::
367 FromAcceleratedWidget(gfx::AcceleratedWidget widget) { 334 FromAcceleratedWidget(gfx::AcceleratedWidget widget) {
368 WidgetToInternalsMap::const_iterator found = 335 WidgetToInternalsMap::const_iterator found =
369 g_widget_to_internals_map.Pointer()->find(widget); 336 g_widget_to_internals_map.Pointer()->find(widget);
370 // This can end up being accessed after the underlying widget has been 337 // This can end up being accessed after the underlying widget has been
371 // destroyed, but while the ui::Compositor is still being destroyed. 338 // destroyed, but while the ui::Compositor is still being destroyed.
372 // Return NULL in these cases. 339 // Return NULL in these cases.
373 if (found == g_widget_to_internals_map.Pointer()->end()) 340 if (found == g_widget_to_internals_map.Pointer()->end())
374 return NULL; 341 return NULL;
375 return found->second; 342 return found->second;
376 } 343 }
377 344
378 } // namespace content 345 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698