| 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 "content/browser/renderer_host/browser_compositor_view_mac.h" | 5 #include "content/browser/renderer_host/browser_compositor_view_mac.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 12 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
| 13 #include "content/browser/compositor/image_transport_factory.h" | 13 #include "content/browser/compositor/image_transport_factory.h" |
| 14 #include "content/browser/renderer_host/resize_lock.h" |
| 14 #include "content/public/browser/context_factory.h" | 15 #include "content/public/browser/context_factory.h" |
| 15 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" | 16 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" |
| 16 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" | 17 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" |
| 17 #include "ui/base/layout.h" | 18 #include "ui/base/layout.h" |
| 18 #include "ui/gfx/geometry/dip_util.h" | 19 #include "ui/gfx/geometry/dip_util.h" |
| 19 | 20 |
| 20 namespace content { | 21 namespace content { |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 // RecyclableCompositorMac that we just populated. | 143 // RecyclableCompositorMac that we just populated. |
| 143 if (!g_browser_compositor_count) | 144 if (!g_browser_compositor_count) |
| 144 g_spare_recyclable_compositor.Get().reset(); | 145 g_spare_recyclable_compositor.Get().reset(); |
| 145 } | 146 } |
| 146 | 147 |
| 147 //////////////////////////////////////////////////////////////////////////////// | 148 //////////////////////////////////////////////////////////////////////////////// |
| 148 // BrowserCompositorMac | 149 // BrowserCompositorMac |
| 149 | 150 |
| 150 BrowserCompositorMac::BrowserCompositorMac( | 151 BrowserCompositorMac::BrowserCompositorMac( |
| 151 ui::AcceleratedWidgetMacNSView* accelerated_widget_mac_ns_view, | 152 ui::AcceleratedWidgetMacNSView* accelerated_widget_mac_ns_view, |
| 152 DelegatedFrameHostClient* delegated_frame_host_client, | 153 BrowserCompositorMacClient* client, |
| 153 bool render_widget_host_is_hidden, | 154 bool render_widget_host_is_hidden, |
| 154 bool ns_view_attached_to_window) | 155 bool ns_view_attached_to_window) |
| 155 : accelerated_widget_mac_ns_view_(accelerated_widget_mac_ns_view), | 156 : client_(client), |
| 157 accelerated_widget_mac_ns_view_(accelerated_widget_mac_ns_view), |
| 156 weak_factory_(this) { | 158 weak_factory_(this) { |
| 157 g_browser_compositor_count += 1; | 159 g_browser_compositor_count += 1; |
| 158 | 160 |
| 159 root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); | 161 root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); |
| 160 delegated_frame_host_.reset( | 162 delegated_frame_host_.reset(new DelegatedFrameHost(this)); |
| 161 new DelegatedFrameHost(delegated_frame_host_client)); | |
| 162 | 163 |
| 163 SetRenderWidgetHostIsHidden(render_widget_host_is_hidden); | 164 SetRenderWidgetHostIsHidden(render_widget_host_is_hidden); |
| 164 SetNSViewAttachedToWindow(ns_view_attached_to_window); | 165 SetNSViewAttachedToWindow(ns_view_attached_to_window); |
| 165 } | 166 } |
| 166 | 167 |
| 167 BrowserCompositorMac::~BrowserCompositorMac() { | 168 BrowserCompositorMac::~BrowserCompositorMac() { |
| 168 DCHECK(has_been_destroyed_); | 169 // Ensure that copy callbacks completed or cancelled during further tear-down |
| 169 } | 170 // do not call back into this. |
| 170 | 171 weak_factory_.InvalidateWeakPtrs(); |
| 171 void BrowserCompositorMac::Destroy() { | |
| 172 if (has_been_destroyed_) | |
| 173 return; | |
| 174 | 172 |
| 175 TransitionToState(HasNoCompositor); | 173 TransitionToState(HasNoCompositor); |
| 176 delegated_frame_host_.reset(); | 174 delegated_frame_host_.reset(); |
| 177 root_layer_.reset(); | 175 root_layer_.reset(); |
| 178 has_been_destroyed_ = true; | |
| 179 | 176 |
| 180 DCHECK_GT(g_browser_compositor_count, 0u); | 177 DCHECK_GT(g_browser_compositor_count, 0u); |
| 181 g_browser_compositor_count -= 1; | 178 g_browser_compositor_count -= 1; |
| 182 | 179 |
| 183 // If there are no compositors allocated, destroy the recyclable | 180 // If there are no compositors allocated, destroy the recyclable |
| 184 // RecyclableCompositorMac. | 181 // RecyclableCompositorMac. |
| 185 if (!g_browser_compositor_count) | 182 if (!g_browser_compositor_count) |
| 186 g_spare_recyclable_compositor.Get().reset(); | 183 g_spare_recyclable_compositor.Get().reset(); |
| 187 } | 184 } |
| 188 | 185 |
| 189 ui::AcceleratedWidgetMac* BrowserCompositorMac::GetAcceleratedWidgetMac() { | 186 ui::AcceleratedWidgetMac* BrowserCompositorMac::GetAcceleratedWidgetMac() { |
| 190 if (recyclable_compositor_) | 187 if (recyclable_compositor_) |
| 191 return recyclable_compositor_->accelerated_widget_mac(); | 188 return recyclable_compositor_->accelerated_widget_mac(); |
| 192 return nullptr; | 189 return nullptr; |
| 193 } | 190 } |
| 194 | 191 |
| 195 ui::Layer* BrowserCompositorMac::GetRootLayer() { | |
| 196 return root_layer_.get(); | |
| 197 } | |
| 198 | |
| 199 DelegatedFrameHost* BrowserCompositorMac::GetDelegatedFrameHost() { | 192 DelegatedFrameHost* BrowserCompositorMac::GetDelegatedFrameHost() { |
| 200 DCHECK(delegated_frame_host_); | 193 DCHECK(delegated_frame_host_); |
| 201 return delegated_frame_host_.get(); | 194 return delegated_frame_host_.get(); |
| 202 } | 195 } |
| 203 | 196 |
| 204 void BrowserCompositorMac::CopyCompleted( | 197 void BrowserCompositorMac::CopyCompleted( |
| 205 base::WeakPtr<BrowserCompositorMac> browser_compositor, | 198 base::WeakPtr<BrowserCompositorMac> browser_compositor, |
| 206 const ReadbackRequestCallback& callback, | 199 const ReadbackRequestCallback& callback, |
| 207 const SkBitmap& bitmap, | 200 const SkBitmap& bitmap, |
| 208 ReadbackResponse response) { | 201 ReadbackResponse response) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 auto callback_with_decrement = | 245 auto callback_with_decrement = |
| 253 base::Bind(&BrowserCompositorMac::CopyToVideoFrameCompleted, | 246 base::Bind(&BrowserCompositorMac::CopyToVideoFrameCompleted, |
| 254 weak_factory_.GetWeakPtr(), callback); | 247 weak_factory_.GetWeakPtr(), callback); |
| 255 | 248 |
| 256 delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame( | 249 delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame( |
| 257 src_subrect, target, callback_with_decrement); | 250 src_subrect, target, callback_with_decrement); |
| 258 } | 251 } |
| 259 | 252 |
| 260 void BrowserCompositorMac::SwapCompositorFrame(uint32_t output_surface_id, | 253 void BrowserCompositorMac::SwapCompositorFrame(uint32_t output_surface_id, |
| 261 cc::CompositorFrame frame) { | 254 cc::CompositorFrame frame) { |
| 262 DCHECK(!has_been_destroyed_); | |
| 263 | |
| 264 // Compute the frame size based on the root render pass rect size. | 255 // Compute the frame size based on the root render pass rect size. |
| 265 cc::RenderPass* root_pass = | 256 cc::RenderPass* root_pass = |
| 266 frame.delegated_frame_data->render_pass_list.back().get(); | 257 frame.delegated_frame_data->render_pass_list.back().get(); |
| 267 float scale_factor = frame.metadata.device_scale_factor; | 258 float scale_factor = frame.metadata.device_scale_factor; |
| 268 gfx::Size pixel_size = root_pass->output_rect.size(); | 259 gfx::Size pixel_size = root_pass->output_rect.size(); |
| 269 gfx::Size dip_size = gfx::ConvertSizeToDIP(scale_factor, pixel_size); | 260 gfx::Size dip_size = gfx::ConvertSizeToDIP(scale_factor, pixel_size); |
| 270 root_layer_->SetBounds(gfx::Rect(dip_size)); | 261 root_layer_->SetBounds(gfx::Rect(dip_size)); |
| 271 if (recyclable_compositor_) { | 262 if (recyclable_compositor_) { |
| 272 recyclable_compositor_->compositor()->SetScaleAndSize(scale_factor, | 263 recyclable_compositor_->compositor()->SetScaleAndSize(scale_factor, |
| 273 pixel_size); | 264 pixel_size); |
| 274 } | 265 } |
| 275 delegated_frame_host_->SwapDelegatedFrame(output_surface_id, | 266 delegated_frame_host_->SwapDelegatedFrame(output_surface_id, |
| 276 std::move(frame)); | 267 std::move(frame)); |
| 277 } | 268 } |
| 278 | 269 |
| 279 void BrowserCompositorMac::SetHasTransparentBackground(bool transparent) { | 270 void BrowserCompositorMac::SetHasTransparentBackground(bool transparent) { |
| 280 DCHECK(!has_been_destroyed_); | |
| 281 has_transparent_background_ = transparent; | 271 has_transparent_background_ = transparent; |
| 282 if (recyclable_compositor_) { | 272 if (recyclable_compositor_) { |
| 283 recyclable_compositor_->compositor()->SetHostHasTransparentBackground( | 273 recyclable_compositor_->compositor()->SetHostHasTransparentBackground( |
| 284 has_transparent_background_); | 274 has_transparent_background_); |
| 285 } | 275 } |
| 286 } | 276 } |
| 287 | 277 |
| 288 void BrowserCompositorMac::UpdateVSyncParameters( | 278 void BrowserCompositorMac::UpdateVSyncParameters( |
| 289 const base::TimeTicks& timebase, | 279 const base::TimeTicks& timebase, |
| 290 const base::TimeDelta& interval) { | 280 const base::TimeDelta& interval) { |
| 291 DCHECK(!has_been_destroyed_); | |
| 292 if (recyclable_compositor_) { | 281 if (recyclable_compositor_) { |
| 293 recyclable_compositor_->compositor() | 282 recyclable_compositor_->compositor() |
| 294 ->vsync_manager() | 283 ->vsync_manager() |
| 295 ->UpdateVSyncParameters(timebase, interval); | 284 ->UpdateVSyncParameters(timebase, interval); |
| 296 } | 285 } |
| 297 } | 286 } |
| 298 | 287 |
| 299 void BrowserCompositorMac::SetRenderWidgetHostIsHidden(bool hidden) { | 288 void BrowserCompositorMac::SetRenderWidgetHostIsHidden(bool hidden) { |
| 300 render_widget_host_is_hidden_ = hidden; | 289 render_widget_host_is_hidden_ = hidden; |
| 301 UpdateState(); | 290 UpdateState(); |
| 302 } | 291 } |
| 303 | 292 |
| 304 void BrowserCompositorMac::SetNSViewAttachedToWindow(bool attached) { | 293 void BrowserCompositorMac::SetNSViewAttachedToWindow(bool attached) { |
| 305 ns_view_attached_to_window_ = attached; | 294 ns_view_attached_to_window_ = attached; |
| 306 UpdateState(); | 295 UpdateState(); |
| 307 } | 296 } |
| 308 | 297 |
| 309 void BrowserCompositorMac::UpdateState() { | 298 void BrowserCompositorMac::UpdateState() { |
| 310 if (has_been_destroyed_) { | |
| 311 DCHECK(state_ == HasNoCompositor); | |
| 312 return; | |
| 313 } | |
| 314 | |
| 315 if (!render_widget_host_is_hidden_ || outstanding_copy_count_ > 0) | 299 if (!render_widget_host_is_hidden_ || outstanding_copy_count_ > 0) |
| 316 TransitionToState(HasAttachedCompositor); | 300 TransitionToState(HasAttachedCompositor); |
| 317 else if (ns_view_attached_to_window_) | 301 else if (ns_view_attached_to_window_) |
| 318 TransitionToState(HasDetachedCompositor); | 302 TransitionToState(HasDetachedCompositor); |
| 319 else | 303 else |
| 320 TransitionToState(HasNoCompositor); | 304 TransitionToState(HasNoCompositor); |
| 321 } | 305 } |
| 322 | 306 |
| 323 void BrowserCompositorMac::TransitionToState(State new_state) { | 307 void BrowserCompositorMac::TransitionToState(State new_state) { |
| 324 // Transition HasNoCompositor -> HasDetachedCompositor. | 308 // Transition HasNoCompositor -> HasDetachedCompositor. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 state_ = HasNoCompositor; | 357 state_ = HasNoCompositor; |
| 374 } | 358 } |
| 375 } | 359 } |
| 376 | 360 |
| 377 // static | 361 // static |
| 378 void BrowserCompositorMac::DisableRecyclingForShutdown() { | 362 void BrowserCompositorMac::DisableRecyclingForShutdown() { |
| 379 g_has_shut_down = true; | 363 g_has_shut_down = true; |
| 380 g_spare_recyclable_compositor.Get().reset(); | 364 g_spare_recyclable_compositor.Get().reset(); |
| 381 } | 365 } |
| 382 | 366 |
| 367 void BrowserCompositorMac::SetNeedsBeginFrames(bool needs_begin_frames) { |
| 368 if (needs_begin_frames_ == needs_begin_frames) |
| 369 return; |
| 370 |
| 371 needs_begin_frames_ = needs_begin_frames; |
| 372 if (begin_frame_source_) { |
| 373 if (needs_begin_frames_) |
| 374 begin_frame_source_->AddObserver(this); |
| 375 else |
| 376 begin_frame_source_->RemoveObserver(this); |
| 377 } |
| 378 } |
| 379 |
| 380 //////////////////////////////////////////////////////////////////////////////// |
| 381 // DelegatedFrameHost, public: |
| 382 |
| 383 ui::Layer* BrowserCompositorMac::DelegatedFrameHostGetLayer() const { |
| 384 return root_layer_.get(); |
| 385 } |
| 386 |
| 387 bool BrowserCompositorMac::DelegatedFrameHostIsVisible() const { |
| 388 return state_ == HasAttachedCompositor; |
| 389 } |
| 390 |
| 391 SkColor BrowserCompositorMac::DelegatedFrameHostGetGutterColor( |
| 392 SkColor color) const { |
| 393 return client_->BrowserCompositorMacGetGutterColor(color); |
| 394 } |
| 395 |
| 396 gfx::Size BrowserCompositorMac::DelegatedFrameHostDesiredSizeInDIP() const { |
| 397 NSRect bounds = [client_->BrowserCompositorMacGetNSView() bounds]; |
| 398 return gfx::Size(bounds.size.width, bounds.size.height); |
| 399 } |
| 400 |
| 401 bool BrowserCompositorMac::DelegatedFrameCanCreateResizeLock() const { |
| 402 // Mac uses the RenderWidgetResizeHelper instead of a resize lock. |
| 403 return false; |
| 404 } |
| 405 |
| 406 std::unique_ptr<ResizeLock> |
| 407 BrowserCompositorMac::DelegatedFrameHostCreateResizeLock( |
| 408 bool defer_compositor_lock) { |
| 409 NOTREACHED(); |
| 410 return std::unique_ptr<ResizeLock>(); |
| 411 } |
| 412 |
| 413 void BrowserCompositorMac::DelegatedFrameHostResizeLockWasReleased() { |
| 414 NOTREACHED(); |
| 415 } |
| 416 |
| 417 void BrowserCompositorMac::DelegatedFrameHostSendCompositorSwapAck( |
| 418 int output_surface_id, |
| 419 const cc::CompositorFrameAck& ack) { |
| 420 client_->BrowserCompositorMacSendCompositorSwapAck(output_surface_id, ack); |
| 421 } |
| 422 |
| 423 void BrowserCompositorMac::DelegatedFrameHostSendReclaimCompositorResources( |
| 424 int output_surface_id, |
| 425 const cc::CompositorFrameAck& ack) { |
| 426 client_->BrowserCompositorMacSendReclaimCompositorResources(output_surface_id, |
| 427 ack); |
| 428 } |
| 429 |
| 430 void BrowserCompositorMac::DelegatedFrameHostOnLostCompositorResources() { |
| 431 client_->BrowserCompositorMacOnLostCompositorResources(); |
| 432 } |
| 433 |
| 434 void BrowserCompositorMac::DelegatedFrameHostUpdateVSyncParameters( |
| 435 const base::TimeTicks& timebase, |
| 436 const base::TimeDelta& interval) { |
| 437 client_->BrowserCompositorMacUpdateVSyncParameters(timebase, interval); |
| 438 } |
| 439 |
| 440 void BrowserCompositorMac::SetBeginFrameSource(cc::BeginFrameSource* source) { |
| 441 if (begin_frame_source_ && needs_begin_frames_) |
| 442 begin_frame_source_->RemoveObserver(this); |
| 443 begin_frame_source_ = source; |
| 444 if (begin_frame_source_ && needs_begin_frames_) |
| 445 begin_frame_source_->AddObserver(this); |
| 446 } |
| 447 |
| 448 //////////////////////////////////////////////////////////////////////////////// |
| 449 // cc::BeginFrameSourceBase, public: |
| 450 |
| 451 void BrowserCompositorMac::OnBeginFrame(const cc::BeginFrameArgs& args) { |
| 452 delegated_frame_host_->SetVSyncParameters(args.frame_time, args.interval); |
| 453 client_->BrowserCompositorMacSendBeginFrame(args); |
| 454 last_begin_frame_args_ = args; |
| 455 } |
| 456 |
| 457 const cc::BeginFrameArgs& BrowserCompositorMac::LastUsedBeginFrameArgs() const { |
| 458 return last_begin_frame_args_; |
| 459 } |
| 460 |
| 461 void BrowserCompositorMac::OnBeginFrameSourcePausedChanged(bool paused) { |
| 462 // Only used on Android WebView. |
| 463 } |
| 464 |
| 383 } // namespace content | 465 } // namespace content |
| OLD | NEW |