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> |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 skipped_frames_(false), | 52 skipped_frames_(false), |
53 background_color_(SK_ColorRED), | 53 background_color_(SK_ColorRED), |
54 current_scale_factor_(1.f), | 54 current_scale_factor_(1.f), |
55 can_lock_compositor_(YES_CAN_LOCK), | 55 can_lock_compositor_(YES_CAN_LOCK), |
56 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { | 56 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { |
57 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 57 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
58 factory->GetContextFactory()->AddObserver(this); | 58 factory->GetContextFactory()->AddObserver(this); |
59 factory->GetContextFactoryPrivate()->GetSurfaceManager()->RegisterFrameSinkId( | 59 factory->GetContextFactoryPrivate()->GetSurfaceManager()->RegisterFrameSinkId( |
60 frame_sink_id_); | 60 frame_sink_id_); |
61 CreateCompositorFrameSinkSupport(); | 61 CreateCompositorFrameSinkSupport(); |
62 begin_frame_source_ = base::MakeUnique<cc::ExternalBeginFrameSource>(this); | |
63 client_->SetBeginFrameSource(begin_frame_source_.get()); | |
64 } | 62 } |
65 | 63 |
66 void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) { | 64 void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) { |
67 delegated_frame_evictor_->SetVisible(true); | 65 delegated_frame_evictor_->SetVisible(true); |
68 | 66 |
69 if (!has_frame_ && !released_front_lock_.get()) { | 67 if (!has_frame_ && !released_front_lock_.get()) { |
70 if (compositor_) | 68 if (compositor_) |
71 released_front_lock_ = compositor_->GetCompositorLock(); | 69 released_front_lock_ = compositor_->GetCompositorLock(); |
72 } | 70 } |
73 | 71 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 RenderWidgetHostViewBase* target_view, | 222 RenderWidgetHostViewBase* target_view, |
225 gfx::Point* transformed_point) { | 223 gfx::Point* transformed_point) { |
226 if (!has_frame_) | 224 if (!has_frame_) |
227 return false; | 225 return false; |
228 | 226 |
229 return target_view->TransformPointToLocalCoordSpace( | 227 return target_view->TransformPointToLocalCoordSpace( |
230 point, cc::SurfaceId(frame_sink_id_, local_surface_id_), | 228 point, cc::SurfaceId(frame_sink_id_, local_surface_id_), |
231 transformed_point); | 229 transformed_point); |
232 } | 230 } |
233 | 231 |
| 232 void DelegatedFrameHost::SetNeedsBeginFrames(bool needs_begin_frames) { |
| 233 needs_begin_frame_ = needs_begin_frames; |
| 234 support_->SetNeedsBeginFrame(needs_begin_frames); |
| 235 } |
| 236 |
| 237 void DelegatedFrameHost::BeginFrameDidNotSwap(const cc::BeginFrameAck& ack) { |
| 238 DidFinishFrame(ack); |
| 239 |
| 240 cc::BeginFrameAck modified_ack = ack; |
| 241 if (skipped_frames_) { |
| 242 // If we skipped the last frame(s), we didn't incorporate the last |
| 243 // CompositorFrame's damage, so need to wait for the next one before |
| 244 // confirming newer sequence numbers. |
| 245 modified_ack.has_damage = false; |
| 246 modified_ack.latest_confirmed_sequence_number = |
| 247 latest_confirmed_begin_frame_sequence_number_; |
| 248 } |
| 249 |
| 250 support_->BeginFrameDidNotSwap(modified_ack); |
| 251 } |
| 252 |
234 bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const { | 253 bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const { |
235 // Should skip a frame only when another frame from the renderer is guaranteed | 254 // Should skip a frame only when another frame from the renderer is guaranteed |
236 // to replace it. Otherwise may cause hangs when the renderer is waiting for | 255 // to replace it. Otherwise may cause hangs when the renderer is waiting for |
237 // the completion of latency infos (such as when taking a Snapshot.) | 256 // the completion of latency infos (such as when taking a Snapshot.) |
238 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || | 257 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || |
239 can_lock_compositor_ == NO_PENDING_COMMIT || !resize_lock_.get()) | 258 can_lock_compositor_ == NO_PENDING_COMMIT || !resize_lock_.get()) |
240 return false; | 259 return false; |
241 | 260 |
242 return size_in_dip != resize_lock_->expected_size(); | 261 return size_in_dip != resize_lock_->expected_size(); |
243 } | 262 } |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 } | 391 } |
373 | 392 |
374 void DelegatedFrameHost::SwapDelegatedFrame( | 393 void DelegatedFrameHost::SwapDelegatedFrame( |
375 uint32_t compositor_frame_sink_id, | 394 uint32_t compositor_frame_sink_id, |
376 const cc::LocalSurfaceId& local_surface_id, | 395 const cc::LocalSurfaceId& local_surface_id, |
377 cc::CompositorFrame frame) { | 396 cc::CompositorFrame frame) { |
378 #if defined(OS_CHROMEOS) | 397 #if defined(OS_CHROMEOS) |
379 DCHECK(!resize_lock_ || !client_->IsAutoResizeEnabled()); | 398 DCHECK(!resize_lock_ || !client_->IsAutoResizeEnabled()); |
380 #endif | 399 #endif |
381 float frame_device_scale_factor = frame.metadata.device_scale_factor; | 400 float frame_device_scale_factor = frame.metadata.device_scale_factor; |
| 401 cc::BeginFrameAck ack(frame.metadata.begin_frame_ack); |
382 | 402 |
383 DCHECK(!frame.render_pass_list.empty()); | 403 DCHECK(!frame.render_pass_list.empty()); |
384 | 404 |
385 cc::RenderPass* root_pass = frame.render_pass_list.back().get(); | 405 cc::RenderPass* root_pass = frame.render_pass_list.back().get(); |
386 | 406 |
387 gfx::Size frame_size = root_pass->output_rect.size(); | 407 gfx::Size frame_size = root_pass->output_rect.size(); |
388 gfx::Size frame_size_in_dip = | 408 gfx::Size frame_size_in_dip = |
389 gfx::ConvertSizeToDIP(frame_device_scale_factor, frame_size); | 409 gfx::ConvertSizeToDIP(frame_device_scale_factor, frame_size); |
390 | 410 |
391 gfx::Rect damage_rect = root_pass->damage_rect; | 411 gfx::Rect damage_rect = root_pass->damage_rect; |
392 damage_rect.Intersect(gfx::Rect(frame_size)); | 412 damage_rect.Intersect(gfx::Rect(frame_size)); |
393 gfx::Rect damage_rect_in_dip = | 413 gfx::Rect damage_rect_in_dip = |
394 gfx::ConvertRectToDIP(frame_device_scale_factor, damage_rect); | 414 gfx::ConvertRectToDIP(frame_device_scale_factor, damage_rect); |
395 | 415 |
396 if (ShouldSkipFrame(frame_size_in_dip)) { | 416 if (ShouldSkipFrame(frame_size_in_dip)) { |
397 cc::ReturnedResourceArray resources; | 417 cc::ReturnedResourceArray resources; |
398 cc::TransferableResource::ReturnResources(frame.resource_list, &resources); | 418 cc::TransferableResource::ReturnResources(frame.resource_list, &resources); |
399 | 419 |
400 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), | 420 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), |
401 frame.metadata.latency_info.begin(), | 421 frame.metadata.latency_info.begin(), |
402 frame.metadata.latency_info.end()); | 422 frame.metadata.latency_info.end()); |
403 | 423 |
404 client_->DelegatedFrameHostSendReclaimCompositorResources( | 424 client_->DelegatedFrameHostSendReclaimCompositorResources( |
405 compositor_frame_sink_id, true /* is_swap_ack*/, resources); | 425 compositor_frame_sink_id, true /* is_swap_ack*/, resources); |
406 skipped_frames_ = true; | 426 skipped_frames_ = true; |
| 427 BeginFrameDidNotSwap(ack); |
407 return; | 428 return; |
408 } | 429 } |
409 | 430 |
410 if (skipped_frames_) { | 431 if (skipped_frames_) { |
411 skipped_frames_ = false; | 432 skipped_frames_ = false; |
412 damage_rect = gfx::Rect(frame_size); | 433 damage_rect = gfx::Rect(frame_size); |
413 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); | 434 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); |
414 | 435 |
415 // Give the same damage rect to the compositor. | 436 // Give the same damage rect to the compositor. |
416 cc::RenderPass* root_pass = frame.render_pass_list.back().get(); | 437 cc::RenderPass* root_pass = frame.render_pass_list.back().get(); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 } | 496 } |
476 | 497 |
477 if (compositor_) | 498 if (compositor_) |
478 can_lock_compositor_ = NO_PENDING_COMMIT; | 499 can_lock_compositor_ = NO_PENDING_COMMIT; |
479 | 500 |
480 if (has_frame_) { | 501 if (has_frame_) { |
481 delegated_frame_evictor_->SwappedFrame( | 502 delegated_frame_evictor_->SwappedFrame( |
482 client_->DelegatedFrameHostIsVisible()); | 503 client_->DelegatedFrameHostIsVisible()); |
483 } | 504 } |
484 // Note: the frame may have been evicted immediately. | 505 // Note: the frame may have been evicted immediately. |
| 506 |
| 507 DidFinishFrame(ack); |
485 } | 508 } |
486 | 509 |
487 void DelegatedFrameHost::ClearDelegatedFrame() { | 510 void DelegatedFrameHost::ClearDelegatedFrame() { |
488 EvictDelegatedFrame(); | 511 EvictDelegatedFrame(); |
489 } | 512 } |
490 | 513 |
491 void DelegatedFrameHost::DidReceiveCompositorFrameAck() { | 514 void DelegatedFrameHost::DidReceiveCompositorFrameAck() { |
492 client_->DelegatedFrameHostSendReclaimCompositorResources( | 515 client_->DelegatedFrameHostSendReclaimCompositorResources( |
493 last_compositor_frame_sink_id_, true /* is_swap_ack */, | 516 last_compositor_frame_sink_id_, true /* is_swap_ack */, |
494 cc::ReturnedResourceArray()); | 517 cc::ReturnedResourceArray()); |
(...skipping 10 matching lines...) Expand all Loading... |
505 // Frame subscribers are only interested in changes to the target surface, so | 528 // Frame subscribers are only interested in changes to the target surface, so |
506 // do not attempt capture if |damage_rect| is empty. This prevents the draws | 529 // do not attempt capture if |damage_rect| is empty. This prevents the draws |
507 // of parent surfaces from triggering extra frame captures, which can affect | 530 // of parent surfaces from triggering extra frame captures, which can affect |
508 // smoothness. | 531 // smoothness. |
509 if (id != local_surface_id_ || damage_rect.IsEmpty()) | 532 if (id != local_surface_id_ || damage_rect.IsEmpty()) |
510 return; | 533 return; |
511 AttemptFrameSubscriberCapture(damage_rect); | 534 AttemptFrameSubscriberCapture(damage_rect); |
512 } | 535 } |
513 | 536 |
514 void DelegatedFrameHost::OnBeginFrame(const cc::BeginFrameArgs& args) { | 537 void DelegatedFrameHost::OnBeginFrame(const cc::BeginFrameArgs& args) { |
515 begin_frame_source_->OnBeginFrame(args); | 538 client_->OnBeginFrame(args); |
516 } | 539 } |
517 | 540 |
518 void DelegatedFrameHost::EvictDelegatedFrame() { | 541 void DelegatedFrameHost::EvictDelegatedFrame() { |
519 if (!has_frame_) | 542 if (!has_frame_) |
520 return; | 543 return; |
521 client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent(); | 544 client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent(); |
522 support_->EvictFrame(); | 545 support_->EvictFrame(); |
523 has_frame_ = false; | 546 has_frame_ = false; |
524 delegated_frame_evictor_->DiscardedFrame(); | 547 delegated_frame_evictor_->DiscardedFrame(); |
525 UpdateGutters(); | 548 UpdateGutters(); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 } | 772 } |
750 | 773 |
751 //////////////////////////////////////////////////////////////////////////////// | 774 //////////////////////////////////////////////////////////////////////////////// |
752 // DelegatedFrameHost, private: | 775 // DelegatedFrameHost, private: |
753 | 776 |
754 DelegatedFrameHost::~DelegatedFrameHost() { | 777 DelegatedFrameHost::~DelegatedFrameHost() { |
755 DCHECK(!compositor_); | 778 DCHECK(!compositor_); |
756 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 779 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
757 factory->GetContextFactory()->RemoveObserver(this); | 780 factory->GetContextFactory()->RemoveObserver(this); |
758 | 781 |
759 begin_frame_source_.reset(); | |
760 ResetCompositorFrameSinkSupport(); | 782 ResetCompositorFrameSinkSupport(); |
761 | 783 |
762 factory->GetContextFactoryPrivate() | 784 factory->GetContextFactoryPrivate() |
763 ->GetSurfaceManager() | 785 ->GetSurfaceManager() |
764 ->InvalidateFrameSinkId(frame_sink_id_); | 786 ->InvalidateFrameSinkId(frame_sink_id_); |
765 | 787 |
766 DCHECK(!vsync_manager_.get()); | 788 DCHECK(!vsync_manager_.get()); |
767 } | 789 } |
768 | 790 |
769 void DelegatedFrameHost::SetCompositor(ui::Compositor* compositor) { | 791 void DelegatedFrameHost::SetCompositor(ui::Compositor* compositor) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 } else { | 837 } else { |
816 request_copy_of_output_callback_for_testing_.Run(std::move(request)); | 838 request_copy_of_output_callback_for_testing_.Run(std::move(request)); |
817 } | 839 } |
818 } | 840 } |
819 | 841 |
820 void DelegatedFrameHost::UnlockResources() { | 842 void DelegatedFrameHost::UnlockResources() { |
821 DCHECK(local_surface_id_.is_valid()); | 843 DCHECK(local_surface_id_.is_valid()); |
822 delegated_frame_evictor_->UnlockFrame(); | 844 delegated_frame_evictor_->UnlockFrame(); |
823 } | 845 } |
824 | 846 |
825 void DelegatedFrameHost::OnNeedsBeginFrames(bool needs_begin_frames) { | |
826 needs_begin_frame_ = needs_begin_frames; | |
827 support_->SetNeedsBeginFrame(needs_begin_frames); | |
828 } | |
829 | |
830 void DelegatedFrameHost::OnDidFinishFrame(const cc::BeginFrameAck& ack) { | |
831 if (ack.source_id != latest_confirmed_begin_frame_source_id_) { | |
832 // Source changed, we don't know our freshness anymore. | |
833 latest_confirmed_begin_frame_sequence_number_ = | |
834 cc::BeginFrameArgs::kInvalidFrameNumber; | |
835 } | |
836 | |
837 cc::BeginFrameAck modified_ack = ack; | |
838 if (skipped_frames_) { | |
839 // If we skipped the last frame(s), we didn't incorporate the last | |
840 // CompositorFrame's damage, so need to wait for the next one before | |
841 // confirming newer sequence numbers. | |
842 modified_ack.has_damage = false; | |
843 modified_ack.latest_confirmed_sequence_number = | |
844 latest_confirmed_begin_frame_sequence_number_; | |
845 } else { | |
846 latest_confirmed_begin_frame_source_id_ = modified_ack.source_id; | |
847 latest_confirmed_begin_frame_sequence_number_ = | |
848 modified_ack.latest_confirmed_sequence_number; | |
849 } | |
850 | |
851 // If there was damage, the unmodified ack was sent with the CompositorFrame. | |
852 if (!modified_ack.has_damage) | |
853 support_->BeginFrameDidNotSwap(modified_ack); | |
854 } | |
855 | |
856 void DelegatedFrameHost::CreateCompositorFrameSinkSupport() { | 847 void DelegatedFrameHost::CreateCompositorFrameSinkSupport() { |
857 DCHECK(!support_); | 848 DCHECK(!support_); |
858 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 849 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
859 support_ = base::MakeUnique<cc::CompositorFrameSinkSupport>( | 850 support_ = base::MakeUnique<cc::CompositorFrameSinkSupport>( |
860 this, factory->GetContextFactoryPrivate()->GetSurfaceManager(), | 851 this, factory->GetContextFactoryPrivate()->GetSurfaceManager(), |
861 frame_sink_id_, false /* is_root */, | 852 frame_sink_id_, false /* is_root */, |
862 false /* handles_frame_sink_id_invalidation */, | 853 false /* handles_frame_sink_id_invalidation */, |
863 true /* needs_sync_points */); | 854 true /* needs_sync_points */); |
864 if (compositor_) | 855 if (compositor_) |
865 compositor_->AddFrameSink(frame_sink_id_); | 856 compositor_->AddFrameSink(frame_sink_id_); |
866 if (needs_begin_frame_) | 857 if (needs_begin_frame_) |
867 support_->SetNeedsBeginFrame(true); | 858 support_->SetNeedsBeginFrame(true); |
868 } | 859 } |
869 | 860 |
870 void DelegatedFrameHost::ResetCompositorFrameSinkSupport() { | 861 void DelegatedFrameHost::ResetCompositorFrameSinkSupport() { |
871 if (!support_) | 862 if (!support_) |
872 return; | 863 return; |
873 if (compositor_) | 864 if (compositor_) |
874 compositor_->RemoveFrameSink(frame_sink_id_); | 865 compositor_->RemoveFrameSink(frame_sink_id_); |
875 support_.reset(); | 866 support_.reset(); |
876 } | 867 } |
877 | 868 |
| 869 void DelegatedFrameHost::DidFinishFrame(const cc::BeginFrameAck& ack) { |
| 870 if (ack.source_id != latest_confirmed_begin_frame_source_id_) { |
| 871 // Source changed, we don't know our freshness anymore. |
| 872 latest_confirmed_begin_frame_sequence_number_ = |
| 873 cc::BeginFrameArgs::kInvalidFrameNumber; |
| 874 } |
| 875 |
| 876 if (!skipped_frames_) { |
| 877 latest_confirmed_begin_frame_source_id_ = ack.source_id; |
| 878 latest_confirmed_begin_frame_sequence_number_ = |
| 879 ack.latest_confirmed_sequence_number; |
| 880 } |
| 881 } |
| 882 |
878 } // namespace content | 883 } // namespace content |
OLD | NEW |