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

Side by Side Diff: ui/accelerated_widget_mac/accelerated_widget_mac.mm

Issue 2018793002: Mac: Move remote layer use to GpuOutputSurfaceMac (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@clean_up_mac
Patch Set: Review feedback Created 4 years, 6 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 "ui/accelerated_widget_mac/accelerated_widget_mac.h" 5 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/mac/mac_util.h" 10 #include "base/mac/mac_util.h"
(...skipping 11 matching lines...) Expand all
22 - (void)setContentsChanged; 22 - (void)setContentsChanged;
23 @end 23 @end
24 24
25 namespace ui { 25 namespace ui {
26 namespace { 26 namespace {
27 27
28 typedef std::map<gfx::AcceleratedWidget,AcceleratedWidgetMac*> 28 typedef std::map<gfx::AcceleratedWidget,AcceleratedWidgetMac*>
29 WidgetToHelperMap; 29 WidgetToHelperMap;
30 base::LazyInstance<WidgetToHelperMap> g_widget_to_helper_map; 30 base::LazyInstance<WidgetToHelperMap> g_widget_to_helper_map;
31 31
32 AcceleratedWidgetMac* GetHelperFromAcceleratedWidget(
33 gfx::AcceleratedWidget widget) {
34 WidgetToHelperMap::const_iterator found =
35 g_widget_to_helper_map.Pointer()->find(widget);
36 // This can end up being accessed after the underlying widget has been
37 // destroyed, but while the ui::Compositor is still being destroyed.
38 // Return NULL in these cases.
39 if (found == g_widget_to_helper_map.Pointer()->end())
40 return NULL;
41 return found->second;
42 }
43 32
44 } // namespace 33 } // namespace
45 34
46 //////////////////////////////////////////////////////////////////////////////// 35 ////////////////////////////////////////////////////////////////////////////////
47 // AcceleratedWidgetMac 36 // AcceleratedWidgetMac
48 37
49 AcceleratedWidgetMac::AcceleratedWidgetMac() : view_(nullptr) { 38 AcceleratedWidgetMac::AcceleratedWidgetMac() : view_(nullptr) {
50 // Disable the fade-in animation as the layers are added. 39 // Disable the fade-in animation as the layers are added.
51 ScopedCAActionDisabler disabler; 40 ScopedCAActionDisabler disabler;
52 41
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 83
95 if (fslp_coordinator_) { 84 if (fslp_coordinator_) {
96 fslp_coordinator_->WillLoseAcceleratedWidget(); 85 fslp_coordinator_->WillLoseAcceleratedWidget();
97 DCHECK(!fslp_coordinator_); 86 DCHECK(!fslp_coordinator_);
98 } 87 }
99 88
100 // Disable the fade-out animation as the view is removed. 89 // Disable the fade-out animation as the view is removed.
101 ScopedCAActionDisabler disabler; 90 ScopedCAActionDisabler disabler;
102 91
103 [flipped_layer_ removeFromSuperlayer]; 92 [flipped_layer_ removeFromSuperlayer];
104 DestroyCAContextLayer(ca_context_layer_); 93 [content_layer_ removeFromSuperlayer];
105 DestroyLocalLayer(); 94 [io_surface_layer_ removeFromSuperlayer];
95 content_layer_.reset();
96 io_surface_layer_.reset();
106 97
107 last_swap_size_dip_ = gfx::Size(); 98 last_swap_size_dip_ = gfx::Size();
108 view_ = NULL; 99 view_ = NULL;
109 } 100 }
110 101
111 void AcceleratedWidgetMac::SetFullscreenLowPowerCoordinator( 102 void AcceleratedWidgetMac::SetFullscreenLowPowerCoordinator(
112 FullscreenLowPowerCoordinator* coordinator) { 103 FullscreenLowPowerCoordinator* coordinator) {
113 DCHECK(coordinator); 104 DCHECK(coordinator);
114 DCHECK(!fslp_coordinator_); 105 DCHECK(!fslp_coordinator_);
115 fslp_coordinator_ = coordinator; 106 fslp_coordinator_ = coordinator;
(...skipping 20 matching lines...) Expand all
136 void AcceleratedWidgetMac::GetVSyncParameters( 127 void AcceleratedWidgetMac::GetVSyncParameters(
137 base::TimeTicks* timebase, base::TimeDelta* interval) const { 128 base::TimeTicks* timebase, base::TimeDelta* interval) const {
138 if (view_) { 129 if (view_) {
139 view_->AcceleratedWidgetGetVSyncParameters(timebase, interval); 130 view_->AcceleratedWidgetGetVSyncParameters(timebase, interval);
140 } else { 131 } else {
141 *timebase = base::TimeTicks(); 132 *timebase = base::TimeTicks();
142 *interval = base::TimeDelta(); 133 *interval = base::TimeDelta();
143 } 134 }
144 } 135 }
145 136
146 void AcceleratedWidgetMac::GotFrame( 137 AcceleratedWidgetMac* AcceleratedWidgetMac::Get(gfx::AcceleratedWidget widget) {
147 CAContextID ca_context_id, 138 WidgetToHelperMap::const_iterator found =
148 bool fullscreen_low_power_ca_context_valid, 139 g_widget_to_helper_map.Pointer()->find(widget);
149 CAContextID fullscreen_low_power_ca_context_id, 140 // This can end up being accessed after the underlying widget has been
150 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, 141 // destroyed, but while the ui::Compositor is still being destroyed.
142 // Return NULL in these cases.
143 if (found == g_widget_to_helper_map.Pointer()->end())
144 return nullptr;
145 return found->second;
146 }
147
148 void AcceleratedWidgetMac::GotCALayerFrame(
149 base::scoped_nsobject<CALayer> content_layer,
150 bool fullscreen_low_power_layer_valid,
151 base::scoped_nsobject<CALayer> fullscreen_low_power_layer,
151 const gfx::Size& pixel_size, 152 const gfx::Size& pixel_size,
152 float scale_factor) { 153 float scale_factor) {
153 TRACE_EVENT0("ui", "AcceleratedWidgetMac::GotFrame"); 154 TRACE_EVENT0("ui", "AcceleratedWidgetMac::GotCAContextFrame");
154
155 // If there is no view and therefore no superview to draw into, early-out.
156 if (!view_) { 155 if (!view_) {
157 TRACE_EVENT0("ui", "No associated NSView"); 156 TRACE_EVENT0("ui", "No associated NSView");
158 return; 157 return;
159 } 158 }
160
161 // Disable the fade-in or fade-out effect if we create or remove layers.
162 ScopedCAActionDisabler disabler; 159 ScopedCAActionDisabler disabler;
163
164 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size); 160 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size);
165 161
166 if (ca_context_id) { 162 // Ensure that the content is in the CALayer hierarchy, and update fullscreen
167 GotCAContextFrame(ca_context_id, fullscreen_low_power_ca_context_valid, 163 // low power state.
168 fullscreen_low_power_ca_context_id, pixel_size, 164 if (content_layer_ != content_layer) {
169 scale_factor); 165 [flipped_layer_ addSublayer:content_layer];
170 } else { 166 [content_layer_ removeFromSuperlayer];
171 GotIOSurfaceFrame(io_surface, pixel_size, scale_factor); 167 content_layer_ = content_layer;
172 } 168 }
173 169 if (fullscreen_low_power_layer_ != fullscreen_low_power_layer) {
174 view_->AcceleratedWidgetSwapCompleted();
175 }
176
177 void AcceleratedWidgetMac::GotCAContextFrame(
178 CAContextID ca_context_id,
179 bool fullscreen_low_power_ca_context_valid,
180 CAContextID fullscreen_low_power_ca_context_id,
181 const gfx::Size& pixel_size,
182 float scale_factor) {
183 TRACE_EVENT0("ui", "AcceleratedWidgetMac::GotCAContextFrame");
184
185 // In the layer is replaced, keep the old one around until after the new one
186 // is installed to avoid flashes.
187 base::scoped_nsobject<CALayerHost> old_ca_context_layer =
188 ca_context_layer_;
189
190 // Create the layer to host the layer exported by the GPU process with this
191 // particular CAContext ID.
192 if ([ca_context_layer_ contextId] != ca_context_id) {
193 TRACE_EVENT0("ui", "Creating a new CALayerHost");
194 ca_context_layer_.reset([[CALayerHost alloc] init]);
195 [ca_context_layer_ setContextId:ca_context_id];
196 [ca_context_layer_
197 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin];
198 [flipped_layer_ addSublayer:ca_context_layer_];
199 }
200 if ([fullscreen_low_power_layer_ contextId] !=
201 fullscreen_low_power_ca_context_id) {
202 TRACE_EVENT0("ui", "Creating a new CALayerHost");
203 if (fslp_coordinator_) { 170 if (fslp_coordinator_) {
204 fslp_coordinator_->WillLoseAcceleratedWidget(); 171 fslp_coordinator_->WillLoseAcceleratedWidget();
205 DCHECK(!fslp_coordinator_); 172 DCHECK(!fslp_coordinator_);
206 } 173 }
207 fullscreen_low_power_layer_.reset([[CALayerHost alloc] init]); 174 fullscreen_low_power_layer_ = fullscreen_low_power_layer;
208 [fullscreen_low_power_layer_
209 setContextId:fullscreen_low_power_ca_context_id];
210 } 175 }
176 if (fslp_coordinator_)
177 fslp_coordinator_->SetLowPowerLayerValid(fullscreen_low_power_layer_valid);
211 178
212 if (fslp_coordinator_) { 179 // Ensure the IOSurface is removed.
213 fslp_coordinator_->SetLowPowerLayerValid( 180 if (io_surface_layer_) {
214 fullscreen_low_power_ca_context_valid); 181 [io_surface_layer_ removeFromSuperlayer];
182 io_surface_layer_.reset();
215 } 183 }
216 184 view_->AcceleratedWidgetSwapCompleted();
217 // If this replacing a same-type layer, remove it now that the new layer is
218 // in the hierarchy.
219 if (old_ca_context_layer != ca_context_layer_)
220 DestroyCAContextLayer(old_ca_context_layer);
221
222 // Remove any different-type layers that this is replacing.
223 DestroyLocalLayer();
224 }
225
226 void AcceleratedWidgetMac::EnsureLocalLayer() {
227 if (!local_layer_) {
228 local_layer_.reset([[CALayer alloc] init]);
229 // Setting contents gravity is necessary to prevent the layer from being
230 // scaled during dyanmic resizes (especially with devtools open).
231 [local_layer_ setContentsGravity:kCAGravityTopLeft];
232 [local_layer_ setAnchorPoint:CGPointMake(0, 0)];
233 [flipped_layer_ addSublayer:local_layer_];
234 }
235 } 185 }
236 186
237 void AcceleratedWidgetMac::GotIOSurfaceFrame( 187 void AcceleratedWidgetMac::GotIOSurfaceFrame(
238 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, 188 base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
239 const gfx::Size& pixel_size, 189 const gfx::Size& pixel_size,
240 float scale_factor) { 190 float scale_factor) {
241 TRACE_EVENT0("ui", "AcceleratedWidgetMac::GotIOSurfaceFrame"); 191 TRACE_EVENT0("ui", "AcceleratedWidgetMac::GotIOSurfaceFrame");
192 if (!view_) {
193 TRACE_EVENT0("ui", "No associated NSView");
194 return;
195 }
196 ScopedCAActionDisabler disabler;
197 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size);
242 198
243 // If there is not a layer for local frames, create one. 199 // Create (if needed) and update the IOSurface layer with new content.
244 EnsureLocalLayer(); 200 if (!io_surface_layer_) {
201 io_surface_layer_.reset([[CALayer alloc] init]);
202 [io_surface_layer_ setContentsGravity:kCAGravityTopLeft];
203 [io_surface_layer_ setAnchorPoint:CGPointMake(0, 0)];
204 [flipped_layer_ addSublayer:io_surface_layer_];
205 }
206 id new_contents = static_cast<id>(io_surface.get());
207 if (new_contents && new_contents == [io_surface_layer_ contents])
208 [io_surface_layer_ setContentsChanged];
209 else
210 [io_surface_layer_ setContents:new_contents];
211 [io_surface_layer_ setBounds:CGRectMake(0, 0, last_swap_size_dip_.width(),
212 last_swap_size_dip_.height())];
213 if ([io_surface_layer_ contentsScale] != scale_factor)
214 [io_surface_layer_ setContentsScale:scale_factor];
245 215
246 id new_contents = static_cast<id>(io_surface.get()); 216 // Ensure that the content layer is removed.
247 217 if (content_layer_) {
248 if (new_contents && new_contents == [local_layer_ contents]) { 218 [content_layer_ removeFromSuperlayer];
249 [local_layer_ setContentsChanged]; 219 content_layer_.reset();
250 } else {
251 [local_layer_ setContents:new_contents];
252 } 220 }
253 221 view_->AcceleratedWidgetSwapCompleted();
254 [local_layer_ setBounds:CGRectMake(0, 0, pixel_size.width() / scale_factor,
255 pixel_size.height() / scale_factor)];
256
257 if ([local_layer_ contentsScale] != scale_factor)
258 [local_layer_ setContentsScale:scale_factor];
259
260 // Remove any different-type layers that this is replacing.
261 DestroyCAContextLayer(ca_context_layer_);
262 }
263
264 void AcceleratedWidgetMac::DestroyCAContextLayer(
265 base::scoped_nsobject<CALayerHost> ca_context_layer) {
266 if (!ca_context_layer)
267 return;
268 [ca_context_layer removeFromSuperlayer];
269 if (ca_context_layer == ca_context_layer_)
270 ca_context_layer_.reset();
271 }
272
273 void AcceleratedWidgetMac::DestroyLocalLayer() {
274 if (!local_layer_)
275 return;
276 [local_layer_ removeFromSuperlayer];
277 local_layer_.reset();
278 }
279
280 void AcceleratedWidgetMacGotFrame(
281 gfx::AcceleratedWidget widget,
282 CAContextID ca_context_id,
283 bool fullscreen_low_power_ca_context_valid,
284 CAContextID fullscreen_low_power_ca_context_id,
285 base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
286 const gfx::Size& pixel_size,
287 float scale_factor,
288 base::TimeTicks* vsync_timebase,
289 base::TimeDelta* vsync_interval) {
290 if (vsync_timebase)
291 *vsync_timebase = base::TimeTicks();
292 if (vsync_interval)
293 *vsync_interval = base::TimeDelta();
294
295 AcceleratedWidgetMac* accelerated_widget_mac =
296 GetHelperFromAcceleratedWidget(widget);
297
298 if (accelerated_widget_mac) {
299 accelerated_widget_mac->GotFrame(ca_context_id,
300 fullscreen_low_power_ca_context_valid,
301 fullscreen_low_power_ca_context_id,
302 io_surface, pixel_size, scale_factor);
303 if (vsync_timebase && vsync_interval) {
304 accelerated_widget_mac->GetVSyncParameters(vsync_timebase,
305 vsync_interval);
306 }
307 }
308 } 222 }
309 223
310 } // namespace ui 224 } // namespace ui
OLDNEW
« no previous file with comments | « ui/accelerated_widget_mac/accelerated_widget_mac.h ('k') | ui/views/widget/native_widget_mac_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698