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

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

Issue 441743003: Make remote CALayers work with browser compositor on Mac (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ... and don't use local renames of includes Created 6 years, 4 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
« no previous file with comments | « content/browser/compositor/browser_compositor_view_private_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/renderer_host/compositing_iosurface_context_mac.h"
14 #include "content/browser/renderer_host/compositing_iosurface_mac.h" 14 #include "content/browser/renderer_host/compositing_iosurface_mac.h"
15 #include "content/browser/renderer_host/dip_util.h" 15 #include "content/browser/renderer_host/dip_util.h"
16 #include "content/browser/renderer_host/render_widget_resize_helper.h" 16 #include "content/browser/renderer_host/render_widget_resize_helper.h"
17 #include "content/browser/renderer_host/software_layer_mac.h" 17 #include "content/browser/renderer_host/software_layer_mac.h"
18 #include "content/common/gpu/surface_handle_types_mac.h"
18 #include "content/public/browser/context_factory.h" 19 #include "content/public/browser/context_factory.h"
19 #include "ui/base/cocoa/animation_utils.h" 20 #include "ui/base/cocoa/animation_utils.h"
20 #include "ui/gl/scoped_cgl.h" 21 #include "ui/gl/scoped_cgl.h"
21 22
22 namespace content { 23 namespace content {
23 namespace { 24 namespace {
24 25
25 typedef std::map<gfx::AcceleratedWidget,BrowserCompositorViewMacInternal*> 26 typedef std::map<gfx::AcceleratedWidget,BrowserCompositorViewMacInternal*>
26 WidgetToInternalsMap; 27 WidgetToInternalsMap;
27 base::LazyInstance<WidgetToInternalsMap> g_widget_to_internals_map; 28 base::LazyInstance<WidgetToInternalsMap> g_widget_to_internals_map;
28 29
29 } 30 }
30 31
31 //////////////////////////////////////////////////////////////////////////////// 32 ////////////////////////////////////////////////////////////////////////////////
32 // BrowserCompositorViewMacInternal 33 // BrowserCompositorViewMacInternal
33 34
34 BrowserCompositorViewMacInternal::BrowserCompositorViewMacInternal() 35 BrowserCompositorViewMacInternal::BrowserCompositorViewMacInternal()
35 : client_(NULL), 36 : client_(NULL),
36 accelerated_layer_output_surface_id_(0) { 37 accelerated_output_surface_id_(0) {
37 // Disable the fade-in animation as the layers are added. 38 // Disable the fade-in animation as the layers are added.
38 ScopedCAActionDisabler disabler; 39 ScopedCAActionDisabler disabler;
39 40
40 // Add a flipped transparent layer as a child, so that we don't need to 41 // Add a flipped transparent layer as a child, so that we don't need to
41 // fiddle with the position of sub-layers -- they will always be at the 42 // fiddle with the position of sub-layers -- they will always be at the
42 // origin. 43 // origin.
43 flipped_layer_.reset([[CALayer alloc] init]); 44 flipped_layer_.reset([[CALayer alloc] init]);
44 [flipped_layer_ setGeometryFlipped:YES]; 45 [flipped_layer_ setGeometryFlipped:YES];
45 [flipped_layer_ setAnchorPoint:CGPointMake(0, 0)]; 46 [flipped_layer_ setAnchorPoint:CGPointMake(0, 0)];
46 [flipped_layer_ 47 [flipped_layer_
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 85
85 void BrowserCompositorViewMacInternal::ResetClient() { 86 void BrowserCompositorViewMacInternal::ResetClient() {
86 if (!client_) 87 if (!client_)
87 return; 88 return;
88 89
89 // Disable the fade-out animation as the view is removed. 90 // Disable the fade-out animation as the view is removed.
90 ScopedCAActionDisabler disabler; 91 ScopedCAActionDisabler disabler;
91 92
92 [flipped_layer_ removeFromSuperlayer]; 93 [flipped_layer_ removeFromSuperlayer];
93 94
94 [accelerated_layer_ removeFromSuperlayer]; 95 [io_surface_layer_ removeFromSuperlayer];
95 [accelerated_layer_ resetClient]; 96 [io_surface_layer_ resetClient];
96 accelerated_layer_.reset(); 97 io_surface_layer_.reset();
97 accelerated_layer_output_surface_id_ = 0; 98 accelerated_output_surface_id_ = 0;
98 99
99 [software_layer_ removeFromSuperlayer]; 100 [software_layer_ removeFromSuperlayer];
100 software_layer_.reset(); 101 software_layer_.reset();
101 102
102 last_swap_size_dip_ = gfx::Size(); 103 last_swap_size_dip_ = gfx::Size();
103 104
104 compositor_->SetScaleAndSize(1.0, gfx::Size(0, 0)); 105 compositor_->SetScaleAndSize(1.0, gfx::Size(0, 0));
105 compositor_->SetRootLayer(NULL); 106 compositor_->SetRootLayer(NULL);
106 client_ = NULL; 107 client_ = NULL;
107 } 108 }
108 109
109 bool BrowserCompositorViewMacInternal::HasFrameOfSize( 110 bool BrowserCompositorViewMacInternal::HasFrameOfSize(
110 const gfx::Size& dip_size) const { 111 const gfx::Size& dip_size) const {
111 return last_swap_size_dip_ == dip_size; 112 return last_swap_size_dip_ == dip_size;
112 } 113 }
113 114
114 void BrowserCompositorViewMacInternal::BeginPumpingFrames() { 115 void BrowserCompositorViewMacInternal::BeginPumpingFrames() {
115 [accelerated_layer_ beginPumpingFrames]; 116 [io_surface_layer_ beginPumpingFrames];
116 } 117 }
117 118
118 void BrowserCompositorViewMacInternal::EndPumpingFrames() { 119 void BrowserCompositorViewMacInternal::EndPumpingFrames() {
119 [accelerated_layer_ endPumpingFrames]; 120 [io_surface_layer_ endPumpingFrames];
120 } 121 }
121 122
122 void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame( 123 void BrowserCompositorViewMacInternal::GotAcceleratedFrame(
123 IOSurfaceID io_surface_id, 124 uint64 surface_handle, int output_surface_id,
124 int output_surface_id,
125 const std::vector<ui::LatencyInfo>& latency_info, 125 const std::vector<ui::LatencyInfo>& latency_info,
126 gfx::Size pixel_size, 126 gfx::Size pixel_size, float scale_factor) {
127 float scale_factor) { 127 // Record the surface and latency info to use when acknowledging this frame.
128 DCHECK(!accelerated_layer_output_surface_id_); 128 DCHECK(!accelerated_output_surface_id_);
129 accelerated_layer_output_surface_id_ = output_surface_id; 129 accelerated_output_surface_id_ = output_surface_id;
130 accelerated_latency_info_.insert(accelerated_latency_info_.end(), 130 accelerated_latency_info_.insert(accelerated_latency_info_.end(),
131 latency_info.begin(), latency_info.end()); 131 latency_info.begin(), latency_info.end());
132 132
133 // If there is no client and therefore no superview to draw into, early-out. 133 // If there is no client and therefore no superview to draw into, early-out.
134 if (!client_) { 134 if (!client_) {
135 AcceleratedLayerDidDrawFrame(true); 135 AcceleratedLayerDidDrawFrame(true);
136 return; 136 return;
137 } 137 }
138 138
139 // Disable the fade-in or fade-out effect if we create or remove layers. 139 // Disable the fade-in or fade-out effect if we create or remove layers.
140 ScopedCAActionDisabler disabler; 140 ScopedCAActionDisabler disabler;
141 141
142 // If there is already an accelerated layer, but it has the wrong scale 142 last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size);
143 // factor or it was poisoned, remove the old layer and replace it. 143 switch (GetSurfaceHandleType(surface_handle)) {
144 base::scoped_nsobject<CompositingIOSurfaceLayer> old_accelerated_layer; 144 case kSurfaceHandleTypeIOSurface: {
145 if (accelerated_layer_ && ( 145 IOSurfaceID io_surface_id = IOSurfaceIDFromSurfaceHandle(surface_handle);
146 [accelerated_layer_ context]->HasBeenPoisoned() || 146 GotAcceleratedIOSurfaceFrame(io_surface_id, pixel_size, scale_factor);
147 [accelerated_layer_ iosurface]->scale_factor() != scale_factor)) { 147 break;
148 old_accelerated_layer = accelerated_layer_; 148 }
149 accelerated_layer_.reset(); 149 case kSurfaceHandleTypeCAContext: {
150 CAContextID ca_context_id = CAContextIDFromSurfaceHandle(surface_handle);
151 GotAcceleratedCAContextFrame(ca_context_id, pixel_size, scale_factor);
152 break;
153 }
154 default:
155 LOG(ERROR) << "Unrecognized accelerated frame type.";
156 return;
157 }
158 }
159
160 void BrowserCompositorViewMacInternal::GotAcceleratedCAContextFrame(
161 CAContextID ca_context_id,
162 gfx::Size pixel_size,
163 float scale_factor) {
164 // In the layer is replaced, keep the old one around until after the new one
165 // is installed to avoid flashes.
166 base::scoped_nsobject<CALayerHost> old_ca_context_layer =
167 ca_context_layer_;
168
169 // Create the layer to host the layer exported by the GPU process with this
170 // particular CAContext ID.
171 if ([ca_context_layer_ contextId] != ca_context_id) {
172 ca_context_layer_.reset([[CALayerHost alloc] init]);
173 [ca_context_layer_ setContextId:ca_context_id];
174 [ca_context_layer_
175 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin];
176 [flipped_layer_ addSublayer:ca_context_layer_];
150 } 177 }
151 178
152 // If there is not a layer for accelerated frames, create one. 179 // Acknowledge the frame to unblock the compositor immediately (the GPU
153 if (!accelerated_layer_) { 180 // process will do any required throttling).
181 AcceleratedLayerDidDrawFrame(true);
182
183 // If this replacing a same-type layer, remove it now that the new layer is
184 // in the hierarchy.
185 if (old_ca_context_layer != ca_context_layer_)
186 [old_ca_context_layer removeFromSuperlayer];
187
188 // Remove any different-type layers that this is replacing.
189 if (io_surface_layer_) {
190 [io_surface_layer_ resetClient];
191 [io_surface_layer_ removeFromSuperlayer];
192 io_surface_layer_.reset();
193 }
194 if (software_layer_) {
195 [software_layer_ removeFromSuperlayer];
196 software_layer_.reset();
197 }
198 }
199
200 void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame(
201 IOSurfaceID io_surface_id,
202 gfx::Size pixel_size,
203 float scale_factor) {
204 // In the layer is replaced, keep the old one around until after the new one
205 // is installed to avoid flashes.
206 base::scoped_nsobject<CompositingIOSurfaceLayer> old_io_surface_layer =
207 io_surface_layer_;
208
209 // Create or re-create an IOSurface layer if needed. If there already exists
210 // a layer but it has the wrong scale factor or it was poisoned, re-create the
211 // layer.
212 bool needs_new_layer =
213 !io_surface_layer_ ||
214 [io_surface_layer_ context]->HasBeenPoisoned() ||
215 [io_surface_layer_ iosurface]->scale_factor() != scale_factor;
216 if (needs_new_layer) {
154 scoped_refptr<content::CompositingIOSurfaceMac> iosurface = 217 scoped_refptr<content::CompositingIOSurfaceMac> iosurface =
155 content::CompositingIOSurfaceMac::Create(); 218 content::CompositingIOSurfaceMac::Create();
156 accelerated_layer_.reset([[CompositingIOSurfaceLayer alloc] 219 io_surface_layer_.reset([[CompositingIOSurfaceLayer alloc]
157 initWithIOSurface:iosurface 220 initWithIOSurface:iosurface
158 withScaleFactor:scale_factor 221 withScaleFactor:scale_factor
159 withClient:this]); 222 withClient:this]);
160 [flipped_layer_ addSublayer:accelerated_layer_]; 223 [flipped_layer_ addSublayer:io_surface_layer_];
161 } 224 }
162 225
163 // Open the provided IOSurface. 226 // Open the provided IOSurface.
164 { 227 {
165 bool result = true; 228 bool result = true;
166 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( 229 gfx::ScopedCGLSetCurrentContext scoped_set_current_context(
167 [accelerated_layer_ context]->cgl_context()); 230 [io_surface_layer_ context]->cgl_context());
168 result = [accelerated_layer_ iosurface]->SetIOSurfaceWithContextCurrent( 231 result = [io_surface_layer_ iosurface]->SetIOSurfaceWithContextCurrent(
169 [accelerated_layer_ context], io_surface_id, pixel_size, scale_factor); 232 [io_surface_layer_ context], io_surface_id, pixel_size, scale_factor);
170 if (!result) 233 if (!result)
171 LOG(ERROR) << "Failed SetIOSurface on CompositingIOSurfaceMac"; 234 LOG(ERROR) << "Failed SetIOSurface on CompositingIOSurfaceMac";
172 } 235 }
173 [accelerated_layer_ gotNewFrame]; 236 [io_surface_layer_ gotNewFrame];
174 237
175 // Set the bounds of the accelerated layer to match the size of the frame. 238 // Set the bounds of the accelerated layer to match the size of the frame.
176 // If the bounds changed, force the content to be displayed immediately. 239 // If the bounds changed, force the content to be displayed immediately.
177 last_swap_size_dip_ = [accelerated_layer_ iosurface]->dip_io_surface_size();
178 CGRect new_layer_bounds = CGRectMake( 240 CGRect new_layer_bounds = CGRectMake(
179 0, 0, last_swap_size_dip_.width(), last_swap_size_dip_.height()); 241 0, 0, last_swap_size_dip_.width(), last_swap_size_dip_.height());
180 bool bounds_changed = !CGRectEqualToRect( 242 bool bounds_changed = !CGRectEqualToRect(
181 new_layer_bounds, [accelerated_layer_ bounds]); 243 new_layer_bounds, [io_surface_layer_ bounds]);
182 [accelerated_layer_ setBounds:new_layer_bounds]; 244 [io_surface_layer_ setBounds:new_layer_bounds];
183 if (bounds_changed) 245 if (bounds_changed)
184 [accelerated_layer_ setNeedsDisplayAndDisplayAndAck]; 246 [io_surface_layer_ setNeedsDisplayAndDisplayAndAck];
185 247
186 // If there was a software layer or an old accelerated layer, remove it. 248 // If this replacing a same-type layer, remove it now that the new layer is
187 // Disable the fade-out animation as the layer is removed. 249 // in the hierarchy.
188 { 250 if (old_io_surface_layer != io_surface_layer_) {
251 [old_io_surface_layer resetClient];
252 [old_io_surface_layer removeFromSuperlayer];
253 }
254
255 // Remove any different-type layers that this is replacing.
256 if (ca_context_layer_) {
257 [ca_context_layer_ removeFromSuperlayer];
258 ca_context_layer_.reset();
259 }
260 if (software_layer_) {
189 [software_layer_ removeFromSuperlayer]; 261 [software_layer_ removeFromSuperlayer];
190 software_layer_.reset(); 262 software_layer_.reset();
191 [old_accelerated_layer resetClient];
192 [old_accelerated_layer removeFromSuperlayer];
193 old_accelerated_layer.reset();
194 } 263 }
195 } 264 }
196 265
197 void BrowserCompositorViewMacInternal::GotSoftwareFrame( 266 void BrowserCompositorViewMacInternal::GotSoftwareFrame(
198 cc::SoftwareFrameData* frame_data, 267 cc::SoftwareFrameData* frame_data,
199 float scale_factor, 268 float scale_factor,
200 SkCanvas* canvas) { 269 SkCanvas* canvas) {
201 if (!frame_data || !canvas || !client_) 270 if (!frame_data || !canvas || !client_)
202 return; 271 return;
203 272
(...skipping 10 matching lines...) Expand all
214 SkImageInfo info; 283 SkImageInfo info;
215 size_t row_bytes; 284 size_t row_bytes;
216 const void* pixels = canvas->peekPixels(&info, &row_bytes); 285 const void* pixels = canvas->peekPixels(&info, &row_bytes);
217 gfx::Size pixel_size(info.fWidth, info.fHeight); 286 gfx::Size pixel_size(info.fWidth, info.fHeight);
218 [software_layer_ setContentsToData:pixels 287 [software_layer_ setContentsToData:pixels
219 withRowBytes:row_bytes 288 withRowBytes:row_bytes
220 withPixelSize:pixel_size 289 withPixelSize:pixel_size
221 withScaleFactor:scale_factor]; 290 withScaleFactor:scale_factor];
222 last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size); 291 last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size);
223 292
224 // If there was an accelerated layer, remove it. 293 // Remove any different-type layers that this is replacing.
225 { 294 if (ca_context_layer_) {
226 [accelerated_layer_ resetClient]; 295 [ca_context_layer_ removeFromSuperlayer];
227 [accelerated_layer_ removeFromSuperlayer]; 296 ca_context_layer_.reset();
228 accelerated_layer_.reset(); 297 }
298 if (io_surface_layer_) {
299 [io_surface_layer_ resetClient];
300 [io_surface_layer_ removeFromSuperlayer];
301 io_surface_layer_.reset();
229 } 302 }
230 } 303 }
231 304
232 bool BrowserCompositorViewMacInternal::AcceleratedLayerShouldAckImmediately() 305 bool BrowserCompositorViewMacInternal::AcceleratedLayerShouldAckImmediately()
233 const { 306 const {
234 // If there is no client then the accelerated layer is not in the hierarchy 307 // If there is no client then the accelerated layer is not in the hierarchy
235 // and will never draw. 308 // and will never draw.
236 if (!client_) 309 if (!client_)
237 return true; 310 return true;
238 return client_->BrowserCompositorViewShouldAckImmediately(); 311 return client_->BrowserCompositorViewShouldAckImmediately();
239 } 312 }
240 313
241 void BrowserCompositorViewMacInternal::AcceleratedLayerDidDrawFrame( 314 void BrowserCompositorViewMacInternal::AcceleratedLayerDidDrawFrame(
242 bool succeeded) { 315 bool succeeded) {
243 if (accelerated_layer_output_surface_id_) { 316 if (accelerated_output_surface_id_) {
244 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed( 317 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed(
245 accelerated_layer_output_surface_id_); 318 accelerated_output_surface_id_);
246 accelerated_layer_output_surface_id_ = 0; 319 accelerated_output_surface_id_ = 0;
247 } 320 }
248 321
249 if (client_) 322 if (client_)
250 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_); 323 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_);
251 324
252 accelerated_latency_info_.clear(); 325 accelerated_latency_info_.clear();
253 326
254 if (!succeeded) { 327 if (!succeeded) {
255 if (accelerated_layer_) 328 if (io_surface_layer_)
256 [accelerated_layer_ context]->PoisonContextAndSharegroup(); 329 [io_surface_layer_ context]->PoisonContextAndSharegroup();
257 compositor_->ScheduleFullRedraw(); 330 compositor_->ScheduleFullRedraw();
258 } 331 }
259 } 332 }
260 333
261 // static 334 // static
262 BrowserCompositorViewMacInternal* BrowserCompositorViewMacInternal:: 335 BrowserCompositorViewMacInternal* BrowserCompositorViewMacInternal::
263 FromAcceleratedWidget(gfx::AcceleratedWidget widget) { 336 FromAcceleratedWidget(gfx::AcceleratedWidget widget) {
264 WidgetToInternalsMap::const_iterator found = 337 WidgetToInternalsMap::const_iterator found =
265 g_widget_to_internals_map.Pointer()->find(widget); 338 g_widget_to_internals_map.Pointer()->find(widget);
266 // This can end up being accessed after the underlying widget has been 339 // This can end up being accessed after the underlying widget has been
267 // destroyed, but while the ui::Compositor is still being destroyed. 340 // destroyed, but while the ui::Compositor is still being destroyed.
268 // Return NULL in these cases. 341 // Return NULL in these cases.
269 if (found == g_widget_to_internals_map.Pointer()->end()) 342 if (found == g_widget_to_internals_map.Pointer()->end())
270 return NULL; 343 return NULL;
271 return found->second; 344 return found->second;
272 } 345 }
273 346
274
275 } // namespace content 347 } // namespace content
276
OLDNEW
« no previous file with comments | « content/browser/compositor/browser_compositor_view_private_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698