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/delegated_frame_host.h" | 5 #include "content/browser/renderer_host/delegated_frame_host.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
15 #include "base/time/default_tick_clock.h" | 15 #include "base/time/default_tick_clock.h" |
16 #include "cc/base/switches.h" | 16 #include "cc/base/switches.h" |
17 #include "cc/output/compositor_frame.h" | 17 #include "cc/output/compositor_frame.h" |
18 #include "cc/output/copy_output_request.h" | 18 #include "cc/output/copy_output_request.h" |
19 #include "cc/resources/single_release_callback.h" | 19 #include "cc/resources/single_release_callback.h" |
20 #include "cc/resources/texture_mailbox.h" | 20 #include "cc/resources/texture_mailbox.h" |
| 21 #include "cc/surfaces/compositor_frame_sink_support.h" |
21 #include "cc/surfaces/local_surface_id_allocator.h" | 22 #include "cc/surfaces/local_surface_id_allocator.h" |
22 #include "cc/surfaces/surface.h" | 23 #include "cc/surfaces/surface.h" |
23 #include "cc/surfaces/surface_factory.h" | 24 #include "cc/surfaces/surface_factory.h" |
24 #include "cc/surfaces/surface_hittest.h" | 25 #include "cc/surfaces/surface_hittest.h" |
25 #include "cc/surfaces/surface_manager.h" | 26 #include "cc/surfaces/surface_manager.h" |
26 #include "components/display_compositor/gl_helper.h" | 27 #include "components/display_compositor/gl_helper.h" |
27 #include "content/browser/compositor/surface_utils.h" | 28 #include "content/browser/compositor/surface_utils.h" |
28 #include "content/browser/gpu/compositor_util.h" | 29 #include "content/browser/gpu/compositor_util.h" |
29 #include "content/browser/renderer_host/render_widget_host_view_frame_subscriber
.h" | 30 #include "content/browser/renderer_host/render_widget_host_view_frame_subscriber
.h" |
30 #include "content/browser/renderer_host/resize_lock.h" | 31 #include "content/browser/renderer_host/resize_lock.h" |
(...skipping 11 matching lines...) Expand all Loading... |
42 //////////////////////////////////////////////////////////////////////////////// | 43 //////////////////////////////////////////////////////////////////////////////// |
43 // DelegatedFrameHost | 44 // DelegatedFrameHost |
44 | 45 |
45 DelegatedFrameHost::DelegatedFrameHost(const cc::FrameSinkId& frame_sink_id, | 46 DelegatedFrameHost::DelegatedFrameHost(const cc::FrameSinkId& frame_sink_id, |
46 DelegatedFrameHostClient* client) | 47 DelegatedFrameHostClient* client) |
47 : frame_sink_id_(frame_sink_id), | 48 : frame_sink_id_(frame_sink_id), |
48 client_(client), | 49 client_(client), |
49 compositor_(nullptr), | 50 compositor_(nullptr), |
50 tick_clock_(new base::DefaultTickClock()), | 51 tick_clock_(new base::DefaultTickClock()), |
51 last_compositor_frame_sink_id_(0), | 52 last_compositor_frame_sink_id_(0), |
52 pending_delegated_ack_count_(0), | |
53 skipped_frames_(false), | 53 skipped_frames_(false), |
54 background_color_(SK_ColorRED), | 54 background_color_(SK_ColorRED), |
55 current_scale_factor_(1.f), | 55 current_scale_factor_(1.f), |
56 can_lock_compositor_(YES_CAN_LOCK), | 56 can_lock_compositor_(YES_CAN_LOCK), |
57 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { | 57 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { |
58 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 58 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
59 factory->GetContextFactory()->AddObserver(this); | 59 factory->GetContextFactory()->AddObserver(this); |
60 id_allocator_.reset(new cc::LocalSurfaceIdAllocator()); | 60 id_allocator_.reset(new cc::LocalSurfaceIdAllocator()); |
61 factory->GetContextFactoryPrivate()->GetSurfaceManager()->RegisterFrameSinkId( | 61 factory->GetContextFactoryPrivate()->GetSurfaceManager()->RegisterFrameSinkId( |
62 frame_sink_id_); | 62 frame_sink_id_); |
63 factory->GetContextFactoryPrivate() | 63 CreateCompositorFrameSinkSupport(); |
64 ->GetSurfaceManager() | 64 begin_frame_source_ = base::MakeUnique<cc::ExternalBeginFrameSource>(this); |
65 ->RegisterSurfaceFactoryClient(frame_sink_id_, this); | 65 client_->SetBeginFrameSource(begin_frame_source_.get()); |
66 surface_factory_ = base::MakeUnique<cc::SurfaceFactory>( | |
67 frame_sink_id_, factory->GetContextFactoryPrivate()->GetSurfaceManager(), | |
68 this); | |
69 } | 66 } |
70 | 67 |
71 void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) { | 68 void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) { |
72 delegated_frame_evictor_->SetVisible(true); | 69 delegated_frame_evictor_->SetVisible(true); |
73 | 70 |
74 if (!local_surface_id_.is_valid() && !released_front_lock_.get()) { | 71 if (!local_surface_id_.is_valid() && !released_front_lock_.get()) { |
75 if (compositor_) | 72 if (compositor_) |
76 released_front_lock_ = compositor_->GetCompositorLock(); | 73 released_front_lock_ = compositor_->GetCompositorLock(); |
77 } | 74 } |
78 | 75 |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 subscriber_texture->target())); | 369 subscriber_texture->target())); |
373 } | 370 } |
374 | 371 |
375 if (local_surface_id_.is_valid()) { | 372 if (local_surface_id_.is_valid()) { |
376 // To avoid unnecessary composites, go directly to the Surface rather than | 373 // To avoid unnecessary composites, go directly to the Surface rather than |
377 // through RequestCopyOfOutput (which goes through the browser | 374 // through RequestCopyOfOutput (which goes through the browser |
378 // compositor). | 375 // compositor). |
379 if (!request_copy_of_output_callback_for_testing_.is_null()) | 376 if (!request_copy_of_output_callback_for_testing_.is_null()) |
380 request_copy_of_output_callback_for_testing_.Run(std::move(request)); | 377 request_copy_of_output_callback_for_testing_.Run(std::move(request)); |
381 else | 378 else |
382 surface_factory_->RequestCopyOfSurface(std::move(request)); | 379 support_->RequestCopyOfSurface(std::move(request)); |
383 } else { | 380 } else { |
384 request->set_area(gfx::Rect(current_frame_size_in_dip_)); | 381 request->set_area(gfx::Rect(current_frame_size_in_dip_)); |
385 RequestCopyOfOutput(std::move(request)); | 382 RequestCopyOfOutput(std::move(request)); |
386 } | 383 } |
387 } | 384 } |
388 | 385 |
389 void DelegatedFrameHost::SwapDelegatedFrame(uint32_t compositor_frame_sink_id, | 386 void DelegatedFrameHost::SwapDelegatedFrame(uint32_t compositor_frame_sink_id, |
390 cc::CompositorFrame frame) { | 387 cc::CompositorFrame frame) { |
391 #if defined(OS_CHROMEOS) | 388 #if defined(OS_CHROMEOS) |
392 DCHECK(!resize_lock_ || !client_->IsAutoResizeEnabled()); | 389 DCHECK(!resize_lock_ || !client_->IsAutoResizeEnabled()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 | 429 |
433 if (compositor_frame_sink_id != last_compositor_frame_sink_id_) { | 430 if (compositor_frame_sink_id != last_compositor_frame_sink_id_) { |
434 // Resource ids are scoped by the output surface. | 431 // Resource ids are scoped by the output surface. |
435 // If the originating output surface doesn't match the last one, it | 432 // If the originating output surface doesn't match the last one, it |
436 // indicates the renderer's output surface may have been recreated, in which | 433 // indicates the renderer's output surface may have been recreated, in which |
437 // case we should recreate the DelegatedRendererLayer, to avoid matching | 434 // case we should recreate the DelegatedRendererLayer, to avoid matching |
438 // resources from the old one with resources from the new one which would | 435 // resources from the old one with resources from the new one which would |
439 // have the same id. Changing the layer to showing painted content destroys | 436 // have the same id. Changing the layer to showing painted content destroys |
440 // the DelegatedRendererLayer. | 437 // the DelegatedRendererLayer. |
441 EvictDelegatedFrame(); | 438 EvictDelegatedFrame(); |
442 surface_factory_->Reset(); | 439 ResetCompositorFrameSinkSupport(); |
443 surface_returned_resources_.clear(); | 440 CreateCompositorFrameSinkSupport(); |
444 last_compositor_frame_sink_id_ = compositor_frame_sink_id; | 441 last_compositor_frame_sink_id_ = compositor_frame_sink_id; |
445 } | 442 } |
446 pending_delegated_ack_count_++; | |
447 | 443 |
448 background_color_ = frame.metadata.root_background_color; | 444 background_color_ = frame.metadata.root_background_color; |
449 | 445 |
450 if (frame_size.IsEmpty()) { | 446 if (frame_size.IsEmpty()) { |
451 DCHECK(frame.resource_list.empty()); | 447 DCHECK(frame.resource_list.empty()); |
452 EvictDelegatedFrame(); | 448 EvictDelegatedFrame(); |
453 } else { | 449 } else { |
454 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 450 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
455 cc::SurfaceManager* manager = | 451 cc::SurfaceManager* manager = |
456 factory->GetContextFactoryPrivate()->GetSurfaceManager(); | 452 factory->GetContextFactoryPrivate()->GetSurfaceManager(); |
457 bool allocated_new_local_surface_id = false; | 453 bool allocated_new_local_surface_id = false; |
458 if (!local_surface_id_.is_valid() || frame_size != current_surface_size_ || | 454 if (!local_surface_id_.is_valid() || frame_size != current_surface_size_ || |
459 frame_size_in_dip != current_frame_size_in_dip_) { | 455 frame_size_in_dip != current_frame_size_in_dip_) { |
460 local_surface_id_ = id_allocator_->GenerateId(); | 456 local_surface_id_ = id_allocator_->GenerateId(); |
461 allocated_new_local_surface_id = true; | 457 allocated_new_local_surface_id = true; |
462 } | 458 } |
463 | 459 |
464 frame.metadata.latency_info.insert(frame.metadata.latency_info.end(), | 460 frame.metadata.latency_info.insert(frame.metadata.latency_info.end(), |
465 skipped_latency_info_list_.begin(), | 461 skipped_latency_info_list_.begin(), |
466 skipped_latency_info_list_.end()); | 462 skipped_latency_info_list_.end()); |
467 skipped_latency_info_list_.clear(); | 463 skipped_latency_info_list_.clear(); |
468 | 464 |
469 auto ack_callback = base::Bind(&DelegatedFrameHost::SurfaceDrawn, | 465 support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)); |
470 AsWeakPtr(), compositor_frame_sink_id); | 466 |
471 surface_factory_->SubmitCompositorFrame(local_surface_id_, std::move(frame), | |
472 ack_callback); | |
473 if (allocated_new_local_surface_id) { | 467 if (allocated_new_local_surface_id) { |
474 // manager must outlive compositors using it. | 468 // manager must outlive compositors using it. |
475 cc::SurfaceId surface_id(frame_sink_id_, local_surface_id_); | 469 cc::SurfaceId surface_id(frame_sink_id_, local_surface_id_); |
476 cc::SurfaceInfo surface_info(surface_id, frame_device_scale_factor, | 470 cc::SurfaceInfo surface_info(surface_id, frame_device_scale_factor, |
477 frame_size); | 471 frame_size); |
478 client_->DelegatedFrameHostGetLayer()->SetShowSurface( | 472 client_->DelegatedFrameHostGetLayer()->SetShowSurface( |
479 surface_info, manager->reference_factory()); | 473 surface_info, manager->reference_factory()); |
480 current_surface_size_ = frame_size; | 474 current_surface_size_ = frame_size; |
481 current_scale_factor_ = frame_device_scale_factor; | 475 current_scale_factor_ = frame_device_scale_factor; |
482 } | 476 } |
(...skipping 17 matching lines...) Expand all Loading... |
500 client_->DelegatedFrameHostIsVisible()); | 494 client_->DelegatedFrameHostIsVisible()); |
501 } | 495 } |
502 // Note: the frame may have been evicted immediately. | 496 // Note: the frame may have been evicted immediately. |
503 } | 497 } |
504 | 498 |
505 void DelegatedFrameHost::ClearDelegatedFrame() { | 499 void DelegatedFrameHost::ClearDelegatedFrame() { |
506 if (local_surface_id_.is_valid()) | 500 if (local_surface_id_.is_valid()) |
507 EvictDelegatedFrame(); | 501 EvictDelegatedFrame(); |
508 } | 502 } |
509 | 503 |
510 void DelegatedFrameHost::SendReclaimCompositorResources( | 504 void DelegatedFrameHost::DidReceiveCompositorFrameAck() { |
511 uint32_t compositor_frame_sink_id, | |
512 bool is_swap_ack) { | |
513 client_->DelegatedFrameHostSendReclaimCompositorResources( | 505 client_->DelegatedFrameHostSendReclaimCompositorResources( |
514 compositor_frame_sink_id, is_swap_ack, surface_returned_resources_); | 506 last_compositor_frame_sink_id_, true /* is_swap_ack */, |
515 surface_returned_resources_.clear(); | 507 cc::ReturnedResourceArray()); |
516 if (is_swap_ack) { | |
517 DCHECK_GT(pending_delegated_ack_count_, 0); | |
518 pending_delegated_ack_count_--; | |
519 } | |
520 } | 508 } |
521 | 509 |
522 void DelegatedFrameHost::SurfaceDrawn(uint32_t compositor_frame_sink_id) { | 510 void DelegatedFrameHost::ReclaimResources( |
523 SendReclaimCompositorResources(compositor_frame_sink_id, | |
524 true /* is_swap_ack */); | |
525 } | |
526 | |
527 void DelegatedFrameHost::ReturnResources( | |
528 const cc::ReturnedResourceArray& resources) { | 511 const cc::ReturnedResourceArray& resources) { |
529 if (resources.empty()) | 512 client_->DelegatedFrameHostSendReclaimCompositorResources( |
530 return; | 513 last_compositor_frame_sink_id_, false /* is_swap_ack */, resources); |
531 std::copy(resources.begin(), resources.end(), | |
532 std::back_inserter(surface_returned_resources_)); | |
533 if (!pending_delegated_ack_count_) { | |
534 SendReclaimCompositorResources(last_compositor_frame_sink_id_, | |
535 false /* is_swap_ack */); | |
536 } | |
537 } | 514 } |
538 | 515 |
539 void DelegatedFrameHost::WillDrawSurface(const cc::LocalSurfaceId& id, | 516 void DelegatedFrameHost::WillDrawSurface(const cc::LocalSurfaceId& id, |
540 const gfx::Rect& damage_rect) { | 517 const gfx::Rect& damage_rect) { |
541 // Frame subscribers are only interested in changes to the target surface, so | 518 // Frame subscribers are only interested in changes to the target surface, so |
542 // do not attempt capture if |damage_rect| is empty. This prevents the draws | 519 // do not attempt capture if |damage_rect| is empty. This prevents the draws |
543 // of parent surfaces from triggering extra frame captures, which can affect | 520 // of parent surfaces from triggering extra frame captures, which can affect |
544 // smoothness. | 521 // smoothness. |
545 if (id != local_surface_id_ || damage_rect.IsEmpty()) | 522 if (id != local_surface_id_ || damage_rect.IsEmpty()) |
546 return; | 523 return; |
547 AttemptFrameSubscriberCapture(damage_rect); | 524 AttemptFrameSubscriberCapture(damage_rect); |
548 } | 525 } |
549 | 526 |
550 void DelegatedFrameHost::SetBeginFrameSource( | 527 void DelegatedFrameHost::OnBeginFrame(const cc::BeginFrameArgs& args) { |
551 cc::BeginFrameSource* begin_frame_source) { | 528 begin_frame_source_->OnBeginFrame(args); |
552 client_->SetBeginFrameSource(begin_frame_source); | |
553 } | 529 } |
554 | 530 |
555 void DelegatedFrameHost::EvictDelegatedFrame() { | 531 void DelegatedFrameHost::EvictDelegatedFrame() { |
556 client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent(); | 532 client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent(); |
557 if (local_surface_id_.is_valid()) { | 533 if (local_surface_id_.is_valid()) { |
558 surface_factory_->EvictSurface(); | 534 support_->EvictFrame(); |
559 local_surface_id_ = cc::LocalSurfaceId(); | 535 local_surface_id_ = cc::LocalSurfaceId(); |
560 } | 536 } |
561 delegated_frame_evictor_->DiscardedFrame(); | 537 delegated_frame_evictor_->DiscardedFrame(); |
562 UpdateGutters(); | 538 UpdateGutters(); |
563 } | 539 } |
564 | 540 |
565 // static | 541 // static |
566 void DelegatedFrameHost::ReturnSubscriberTexture( | 542 void DelegatedFrameHost::ReturnSubscriberTexture( |
567 base::WeakPtr<DelegatedFrameHost> dfh, | 543 base::WeakPtr<DelegatedFrameHost> dfh, |
568 scoped_refptr<OwnedMailbox> subscriber_texture, | 544 scoped_refptr<OwnedMailbox> subscriber_texture, |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 yuv_readback_pipeline_.reset(); | 758 yuv_readback_pipeline_.reset(); |
783 } | 759 } |
784 | 760 |
785 //////////////////////////////////////////////////////////////////////////////// | 761 //////////////////////////////////////////////////////////////////////////////// |
786 // DelegatedFrameHost, private: | 762 // DelegatedFrameHost, private: |
787 | 763 |
788 DelegatedFrameHost::~DelegatedFrameHost() { | 764 DelegatedFrameHost::~DelegatedFrameHost() { |
789 DCHECK(!compositor_); | 765 DCHECK(!compositor_); |
790 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 766 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
791 factory->GetContextFactory()->RemoveObserver(this); | 767 factory->GetContextFactory()->RemoveObserver(this); |
792 surface_factory_->EvictSurface(); | 768 |
793 factory->GetContextFactoryPrivate() | 769 begin_frame_source_.reset(); |
794 ->GetSurfaceManager() | 770 ResetCompositorFrameSinkSupport(); |
795 ->UnregisterSurfaceFactoryClient(frame_sink_id_); | 771 |
796 factory->GetContextFactoryPrivate() | 772 factory->GetContextFactoryPrivate() |
797 ->GetSurfaceManager() | 773 ->GetSurfaceManager() |
798 ->InvalidateFrameSinkId(frame_sink_id_); | 774 ->InvalidateFrameSinkId(frame_sink_id_); |
799 | 775 |
800 DCHECK(!vsync_manager_.get()); | 776 DCHECK(!vsync_manager_.get()); |
801 } | 777 } |
802 | 778 |
803 void DelegatedFrameHost::SetCompositor(ui::Compositor* compositor) { | 779 void DelegatedFrameHost::SetCompositor(ui::Compositor* compositor) { |
804 DCHECK(!compositor_); | 780 DCHECK(!compositor_); |
805 if (!compositor) | 781 if (!compositor) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
844 client_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput( | 820 client_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput( |
845 std::move(request)); | 821 std::move(request)); |
846 } | 822 } |
847 } | 823 } |
848 | 824 |
849 void DelegatedFrameHost::UnlockResources() { | 825 void DelegatedFrameHost::UnlockResources() { |
850 DCHECK(local_surface_id_.is_valid()); | 826 DCHECK(local_surface_id_.is_valid()); |
851 delegated_frame_evictor_->UnlockFrame(); | 827 delegated_frame_evictor_->UnlockFrame(); |
852 } | 828 } |
853 | 829 |
| 830 void DelegatedFrameHost::OnNeedsBeginFrames(bool needs_begin_frames) { |
| 831 needs_begin_frame_ = needs_begin_frames; |
| 832 support_->SetNeedsBeginFrame(needs_begin_frames); |
| 833 } |
| 834 |
| 835 void DelegatedFrameHost::OnDidFinishFrame(const cc::BeginFrameAck& ack) {} |
| 836 |
| 837 void DelegatedFrameHost::CreateCompositorFrameSinkSupport() { |
| 838 DCHECK(!support_); |
| 839 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
| 840 support_ = base::MakeUnique<cc::CompositorFrameSinkSupport>( |
| 841 this, factory->GetContextFactoryPrivate()->GetSurfaceManager(), |
| 842 frame_sink_id_, false /* is_root */, |
| 843 false /* handles_frame_sink_id_invalidation */, |
| 844 true /* needs_sync_points */); |
| 845 if (compositor_) |
| 846 compositor_->AddFrameSink(frame_sink_id_); |
| 847 if (needs_begin_frame_) |
| 848 support_->SetNeedsBeginFrame(true); |
| 849 } |
| 850 |
| 851 void DelegatedFrameHost::ResetCompositorFrameSinkSupport() { |
| 852 if (!support_) |
| 853 return; |
| 854 if (compositor_) |
| 855 compositor_->RemoveFrameSink(frame_sink_id_); |
| 856 support_.reset(); |
| 857 } |
| 858 |
854 } // namespace content | 859 } // namespace content |
OLD | NEW |