| 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 |