OLD | NEW |
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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 | 100 |
101 last_swap_size_dip_ = gfx::Size(); | 101 last_swap_size_dip_ = gfx::Size(); |
102 view_ = NULL; | 102 view_ = NULL; |
103 } | 103 } |
104 | 104 |
105 bool AcceleratedWidgetMac::HasFrameOfSize( | 105 bool AcceleratedWidgetMac::HasFrameOfSize( |
106 const gfx::Size& dip_size) const { | 106 const gfx::Size& dip_size) const { |
107 return last_swap_size_dip_ == dip_size; | 107 return last_swap_size_dip_ == dip_size; |
108 } | 108 } |
109 | 109 |
110 int AcceleratedWidgetMac::GetRendererID() const { | |
111 return 0; | |
112 } | |
113 | |
114 void AcceleratedWidgetMac::GetVSyncParameters( | 110 void AcceleratedWidgetMac::GetVSyncParameters( |
115 base::TimeTicks* timebase, base::TimeDelta* interval) const { | 111 base::TimeTicks* timebase, base::TimeDelta* interval) const { |
116 if (view_) { | 112 if (view_) { |
117 view_->AcceleratedWidgetGetVSyncParameters(timebase, interval); | 113 view_->AcceleratedWidgetGetVSyncParameters(timebase, interval); |
118 } else { | 114 } else { |
119 *timebase = base::TimeTicks(); | 115 *timebase = base::TimeTicks(); |
120 *interval = base::TimeDelta(); | 116 *interval = base::TimeDelta(); |
121 } | 117 } |
122 } | 118 } |
123 | 119 |
124 bool AcceleratedWidgetMac::IsRendererThrottlingDisabled() const { | 120 void AcceleratedWidgetMac::GotFrame( |
125 if (view_) | |
126 return view_->AcceleratedWidgetShouldIgnoreBackpressure(); | |
127 return false; | |
128 } | |
129 | |
130 void AcceleratedWidgetMac::BeginPumpingFrames() { | |
131 } | |
132 | |
133 void AcceleratedWidgetMac::EndPumpingFrames() { | |
134 } | |
135 | |
136 void AcceleratedWidgetMac::GotAcceleratedFrame( | |
137 CAContextID ca_context_id, | 121 CAContextID ca_context_id, |
138 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 122 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
139 const std::vector<ui::LatencyInfo>& latency_info, | |
140 const gfx::Size& pixel_size, | 123 const gfx::Size& pixel_size, |
141 float scale_factor, | 124 float scale_factor) { |
142 const gfx::Rect& pixel_damage_rect, | |
143 const base::Closure& drawn_callback) { | |
144 // Record the surface and latency info to use when acknowledging this frame. | |
145 DCHECK(accelerated_frame_drawn_callback_.is_null()); | |
146 accelerated_frame_drawn_callback_ = drawn_callback; | |
147 accelerated_latency_info_.insert(accelerated_latency_info_.end(), | |
148 latency_info.begin(), latency_info.end()); | |
149 | |
150 // If there is no view and therefore no superview to draw into, early-out. | 125 // If there is no view and therefore no superview to draw into, early-out. |
151 if (!view_) { | 126 if (!view_) |
152 AcknowledgeAcceleratedFrame(); | |
153 return; | 127 return; |
154 } | |
155 | 128 |
156 // Disable the fade-in or fade-out effect if we create or remove layers. | 129 // Disable the fade-in or fade-out effect if we create or remove layers. |
157 ScopedCAActionDisabler disabler; | 130 ScopedCAActionDisabler disabler; |
158 | 131 |
| 132 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size); |
| 133 |
159 if (ca_context_id) | 134 if (ca_context_id) |
160 GotAcceleratedCAContextFrame(ca_context_id, pixel_size, scale_factor); | 135 GotCAContextFrame(ca_context_id, pixel_size, scale_factor); |
161 else | 136 else |
162 GotAcceleratedIOSurfaceFrame(io_surface, pixel_size, scale_factor); | 137 GotIOSurfaceFrame(io_surface, pixel_size, scale_factor); |
163 | |
164 AcknowledgeAcceleratedFrame(); | |
165 } | 138 } |
166 | 139 |
167 void AcceleratedWidgetMac::GotAcceleratedCAContextFrame( | 140 void AcceleratedWidgetMac::GotCAContextFrame(CAContextID ca_context_id, |
168 CAContextID ca_context_id, | 141 const gfx::Size& pixel_size, |
169 const gfx::Size& pixel_size, | 142 float scale_factor) { |
170 float scale_factor) { | |
171 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size); | |
172 | |
173 // In the layer is replaced, keep the old one around until after the new one | 143 // In the layer is replaced, keep the old one around until after the new one |
174 // is installed to avoid flashes. | 144 // is installed to avoid flashes. |
175 base::scoped_nsobject<CALayerHost> old_ca_context_layer = | 145 base::scoped_nsobject<CALayerHost> old_ca_context_layer = |
176 ca_context_layer_; | 146 ca_context_layer_; |
177 | 147 |
178 // Create the layer to host the layer exported by the GPU process with this | 148 // Create the layer to host the layer exported by the GPU process with this |
179 // particular CAContext ID. | 149 // particular CAContext ID. |
180 if ([ca_context_layer_ contextId] != ca_context_id) { | 150 if ([ca_context_layer_ contextId] != ca_context_id) { |
181 ca_context_layer_.reset([[CALayerHost alloc] init]); | 151 ca_context_layer_.reset([[CALayerHost alloc] init]); |
182 [ca_context_layer_ setContextId:ca_context_id]; | 152 [ca_context_layer_ setContextId:ca_context_id]; |
183 [ca_context_layer_ | 153 [ca_context_layer_ |
184 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin]; | 154 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin]; |
185 [flipped_layer_ addSublayer:ca_context_layer_]; | 155 [flipped_layer_ addSublayer:ca_context_layer_]; |
186 } | 156 } |
187 | 157 |
188 // If this replacing a same-type layer, remove it now that the new layer is | 158 // If this replacing a same-type layer, remove it now that the new layer is |
189 // in the hierarchy. | 159 // in the hierarchy. |
190 if (old_ca_context_layer != ca_context_layer_) | 160 if (old_ca_context_layer != ca_context_layer_) |
191 DestroyCAContextLayer(old_ca_context_layer); | 161 DestroyCAContextLayer(old_ca_context_layer); |
192 | 162 |
193 // Remove any different-type layers that this is replacing. | 163 // Remove any different-type layers that this is replacing. |
194 DestroyLocalLayer(); | 164 DestroyLocalLayer(); |
195 } | 165 } |
196 | 166 |
197 void AcceleratedWidgetMac::GotAcceleratedIOSurfaceFrame( | |
198 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | |
199 const gfx::Size& pixel_size, | |
200 float scale_factor) { | |
201 GotIOSurfaceFrame(io_surface, pixel_size, scale_factor, false); | |
202 } | |
203 | |
204 void AcceleratedWidgetMac::EnsureLocalLayer() { | 167 void AcceleratedWidgetMac::EnsureLocalLayer() { |
205 if (!local_layer_) { | 168 if (!local_layer_) { |
206 local_layer_.reset([[CALayer alloc] init]); | 169 local_layer_.reset([[CALayer alloc] init]); |
207 // Setting contents gravity is necessary to prevent the layer from being | 170 // Setting contents gravity is necessary to prevent the layer from being |
208 // scaled during dyanmic resizes (especially with devtools open). | 171 // scaled during dyanmic resizes (especially with devtools open). |
209 [local_layer_ setContentsGravity:kCAGravityTopLeft]; | 172 [local_layer_ setContentsGravity:kCAGravityTopLeft]; |
| 173 [local_layer_ setAnchorPoint:CGPointMake(0, 0)]; |
210 [flipped_layer_ addSublayer:local_layer_]; | 174 [flipped_layer_ addSublayer:local_layer_]; |
211 } | 175 } |
212 } | 176 } |
213 | 177 |
214 void AcceleratedWidgetMac::GotIOSurfaceFrame( | 178 void AcceleratedWidgetMac::GotIOSurfaceFrame( |
215 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 179 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
216 const gfx::Size& pixel_size, | 180 const gfx::Size& pixel_size, |
217 float scale_factor, | 181 float scale_factor) { |
218 bool flip_y) { | |
219 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size); | |
220 | |
221 // Disable the fade-in or fade-out effect if we create or remove layers. | |
222 ScopedCAActionDisabler disabler; | |
223 | |
224 // If there is not a layer for local frames, create one. | 182 // If there is not a layer for local frames, create one. |
225 EnsureLocalLayer(); | 183 EnsureLocalLayer(); |
226 | 184 |
227 id new_contents = static_cast<id>(io_surface.get()); | 185 id new_contents = static_cast<id>(io_surface.get()); |
228 | 186 |
229 if (new_contents && new_contents == [local_layer_ contents]) { | 187 if (new_contents && new_contents == [local_layer_ contents]) { |
230 [local_layer_ setContentsChanged]; | 188 [local_layer_ setContentsChanged]; |
231 } else { | 189 } else { |
232 [local_layer_ setContents:new_contents]; | 190 [local_layer_ setContents:new_contents]; |
233 } | 191 } |
234 | 192 |
235 [local_layer_ setBounds:CGRectMake(0, 0, pixel_size.width() / scale_factor, | 193 [local_layer_ setBounds:CGRectMake(0, 0, pixel_size.width() / scale_factor, |
236 pixel_size.height() / scale_factor)]; | 194 pixel_size.height() / scale_factor)]; |
237 | 195 |
238 if ([local_layer_ respondsToSelector:(@selector(contentsScale))] && | 196 if ([local_layer_ respondsToSelector:(@selector(contentsScale))] && |
239 [local_layer_ respondsToSelector:(@selector(setContentsScale:))] && | 197 [local_layer_ respondsToSelector:(@selector(setContentsScale:))] && |
240 [local_layer_ contentsScale] != scale_factor) { | 198 [local_layer_ contentsScale] != scale_factor) { |
241 DCHECK(base::mac::IsOSLionOrLater()); | 199 DCHECK(base::mac::IsOSLionOrLater()); |
242 [local_layer_ setContentsScale:scale_factor]; | 200 [local_layer_ setContentsScale:scale_factor]; |
243 } | 201 } |
244 | 202 |
245 if (flip_y) { | |
246 [local_layer_ setAnchorPoint:CGPointMake(0, 1)]; | |
247 [local_layer_ setAffineTransform:CGAffineTransformMakeScale(1.0, -1.0)]; | |
248 } else { | |
249 [local_layer_ setAnchorPoint:CGPointMake(0, 0)]; | |
250 [local_layer_ setAffineTransform:CGAffineTransformMakeScale(1.0, 1.0)]; | |
251 } | |
252 | |
253 // Remove any different-type layers that this is replacing. | 203 // Remove any different-type layers that this is replacing. |
254 DestroyCAContextLayer(ca_context_layer_); | 204 DestroyCAContextLayer(ca_context_layer_); |
255 } | 205 } |
256 | 206 |
257 void AcceleratedWidgetMac::DestroyCAContextLayer( | 207 void AcceleratedWidgetMac::DestroyCAContextLayer( |
258 base::scoped_nsobject<CALayerHost> ca_context_layer) { | 208 base::scoped_nsobject<CALayerHost> ca_context_layer) { |
259 if (!ca_context_layer) | 209 if (!ca_context_layer) |
260 return; | 210 return; |
261 [ca_context_layer removeFromSuperlayer]; | 211 [ca_context_layer removeFromSuperlayer]; |
262 if (ca_context_layer == ca_context_layer_) | 212 if (ca_context_layer == ca_context_layer_) |
263 ca_context_layer_.reset(); | 213 ca_context_layer_.reset(); |
264 } | 214 } |
265 | 215 |
266 void AcceleratedWidgetMac::DestroyLocalLayer() { | 216 void AcceleratedWidgetMac::DestroyLocalLayer() { |
267 if (!local_layer_) | 217 if (!local_layer_) |
268 return; | 218 return; |
269 [local_layer_ removeFromSuperlayer]; | 219 [local_layer_ removeFromSuperlayer]; |
270 local_layer_.reset(); | 220 local_layer_.reset(); |
271 } | 221 } |
272 | 222 |
273 void AcceleratedWidgetMac::AcknowledgeAcceleratedFrame() { | 223 void AcceleratedWidgetMacGotFrame( |
274 if (accelerated_frame_drawn_callback_.is_null()) | |
275 return; | |
276 accelerated_frame_drawn_callback_.Run(); | |
277 accelerated_frame_drawn_callback_.Reset(); | |
278 if (view_) | |
279 view_->AcceleratedWidgetSwapCompleted(accelerated_latency_info_); | |
280 accelerated_latency_info_.clear(); | |
281 } | |
282 | |
283 void AcceleratedWidgetMacGotAcceleratedFrame( | |
284 gfx::AcceleratedWidget widget, | 224 gfx::AcceleratedWidget widget, |
285 CAContextID ca_context_id, | 225 CAContextID ca_context_id, |
286 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 226 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
287 const std::vector<ui::LatencyInfo>& latency_info, | |
288 const gfx::Size& pixel_size, | 227 const gfx::Size& pixel_size, |
289 float scale_factor, | 228 float scale_factor, |
290 const gfx::Rect& pixel_damage_rect, | |
291 const base::Closure& drawn_callback, | |
292 bool* disable_throttling, | |
293 int* renderer_id, | |
294 base::TimeTicks* vsync_timebase, | 229 base::TimeTicks* vsync_timebase, |
295 base::TimeDelta* vsync_interval) { | 230 base::TimeDelta* vsync_interval) { |
| 231 if (vsync_timebase) |
| 232 *vsync_timebase = base::TimeTicks(); |
| 233 if (vsync_interval) |
| 234 *vsync_interval = base::TimeDelta(); |
| 235 |
296 AcceleratedWidgetMac* accelerated_widget_mac = | 236 AcceleratedWidgetMac* accelerated_widget_mac = |
297 GetHelperFromAcceleratedWidget(widget); | 237 GetHelperFromAcceleratedWidget(widget); |
| 238 |
298 if (accelerated_widget_mac) { | 239 if (accelerated_widget_mac) { |
299 accelerated_widget_mac->GotAcceleratedFrame( | 240 accelerated_widget_mac->GotFrame(ca_context_id, io_surface, pixel_size, |
300 ca_context_id, io_surface, latency_info, pixel_size, scale_factor, | 241 scale_factor); |
301 pixel_damage_rect, drawn_callback); | 242 if (vsync_timebase && vsync_interval) { |
302 *disable_throttling = | 243 accelerated_widget_mac->GetVSyncParameters(vsync_timebase, |
303 accelerated_widget_mac->IsRendererThrottlingDisabled(); | 244 vsync_interval); |
304 *renderer_id = accelerated_widget_mac->GetRendererID(); | 245 } |
305 accelerated_widget_mac->GetVSyncParameters(vsync_timebase, vsync_interval); | |
306 } else { | |
307 *disable_throttling = false; | |
308 *renderer_id = 0; | |
309 *vsync_timebase = base::TimeTicks(); | |
310 *vsync_interval = base::TimeDelta(); | |
311 } | 246 } |
312 } | 247 } |
313 | 248 |
314 void AcceleratedWidgetMacGotIOSurfaceFrame( | |
315 gfx::AcceleratedWidget widget, | |
316 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | |
317 const gfx::Size& pixel_size, | |
318 float scale_factor, | |
319 bool flip_y) { | |
320 AcceleratedWidgetMac* accelerated_widget_mac = | |
321 GetHelperFromAcceleratedWidget(widget); | |
322 if (accelerated_widget_mac) { | |
323 accelerated_widget_mac->GotIOSurfaceFrame(io_surface, pixel_size, | |
324 scale_factor, flip_y); | |
325 } | |
326 } | |
327 | |
328 } // namespace ui | 249 } // namespace ui |
OLD | NEW |