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::DidFinishFrame(const cc::BeginFrameAck& ack) { |
| 238 if (ack.source_id != latest_confirmed_begin_frame_source_id_) { |
| 239 // Source changed, we don't know our freshness anymore. |
| 240 latest_confirmed_begin_frame_sequence_number_ = |
| 241 cc::BeginFrameArgs::kInvalidFrameNumber; |
| 242 } |
| 243 |
| 244 cc::BeginFrameAck modified_ack = ack; |
| 245 if (skipped_frames_) { |
| 246 // If we skipped the last frame(s), we didn't incorporate the last |
| 247 // CompositorFrame's damage, so need to wait for the next one before |
| 248 // confirming newer sequence numbers. |
| 249 modified_ack.has_damage = false; |
| 250 modified_ack.latest_confirmed_sequence_number = |
| 251 latest_confirmed_begin_frame_sequence_number_; |
| 252 } else { |
| 253 latest_confirmed_begin_frame_source_id_ = modified_ack.source_id; |
| 254 latest_confirmed_begin_frame_sequence_number_ = |
| 255 modified_ack.latest_confirmed_sequence_number; |
| 256 } |
| 257 |
| 258 // If there was damage, the unmodified ack was sent with the CompositorFrame. |
| 259 if (!modified_ack.has_damage) |
| 260 support_->BeginFrameDidNotSwap(modified_ack); |
| 261 } |
| 262 |
234 bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const { | 263 bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const { |
235 // Should skip a frame only when another frame from the renderer is guaranteed | 264 // 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 | 265 // 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.) | 266 // the completion of latency infos (such as when taking a Snapshot.) |
238 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || | 267 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || |
239 can_lock_compositor_ == NO_PENDING_COMMIT || !resize_lock_.get()) | 268 can_lock_compositor_ == NO_PENDING_COMMIT || !resize_lock_.get()) |
240 return false; | 269 return false; |
241 | 270 |
242 return size_in_dip != resize_lock_->expected_size(); | 271 return size_in_dip != resize_lock_->expected_size(); |
243 } | 272 } |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 } | 401 } |
373 | 402 |
374 void DelegatedFrameHost::SwapDelegatedFrame( | 403 void DelegatedFrameHost::SwapDelegatedFrame( |
375 uint32_t compositor_frame_sink_id, | 404 uint32_t compositor_frame_sink_id, |
376 const cc::LocalSurfaceId& local_surface_id, | 405 const cc::LocalSurfaceId& local_surface_id, |
377 cc::CompositorFrame frame) { | 406 cc::CompositorFrame frame) { |
378 #if defined(OS_CHROMEOS) | 407 #if defined(OS_CHROMEOS) |
379 DCHECK(!resize_lock_ || !client_->IsAutoResizeEnabled()); | 408 DCHECK(!resize_lock_ || !client_->IsAutoResizeEnabled()); |
380 #endif | 409 #endif |
381 float frame_device_scale_factor = frame.metadata.device_scale_factor; | 410 float frame_device_scale_factor = frame.metadata.device_scale_factor; |
| 411 cc::BeginFrameAck ack(frame.metadata.begin_frame_ack); |
382 | 412 |
383 DCHECK(!frame.render_pass_list.empty()); | 413 DCHECK(!frame.render_pass_list.empty()); |
384 | 414 |
385 cc::RenderPass* root_pass = frame.render_pass_list.back().get(); | 415 cc::RenderPass* root_pass = frame.render_pass_list.back().get(); |
386 | 416 |
387 gfx::Size frame_size = root_pass->output_rect.size(); | 417 gfx::Size frame_size = root_pass->output_rect.size(); |
388 gfx::Size frame_size_in_dip = | 418 gfx::Size frame_size_in_dip = |
389 gfx::ConvertSizeToDIP(frame_device_scale_factor, frame_size); | 419 gfx::ConvertSizeToDIP(frame_device_scale_factor, frame_size); |
390 | 420 |
391 gfx::Rect damage_rect = root_pass->damage_rect; | 421 gfx::Rect damage_rect = root_pass->damage_rect; |
392 damage_rect.Intersect(gfx::Rect(frame_size)); | 422 damage_rect.Intersect(gfx::Rect(frame_size)); |
393 gfx::Rect damage_rect_in_dip = | 423 gfx::Rect damage_rect_in_dip = |
394 gfx::ConvertRectToDIP(frame_device_scale_factor, damage_rect); | 424 gfx::ConvertRectToDIP(frame_device_scale_factor, damage_rect); |
395 | 425 |
396 if (ShouldSkipFrame(frame_size_in_dip)) { | 426 if (ShouldSkipFrame(frame_size_in_dip)) { |
397 cc::ReturnedResourceArray resources; | 427 cc::ReturnedResourceArray resources; |
398 cc::TransferableResource::ReturnResources(frame.resource_list, &resources); | 428 cc::TransferableResource::ReturnResources(frame.resource_list, &resources); |
399 | 429 |
400 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), | 430 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), |
401 frame.metadata.latency_info.begin(), | 431 frame.metadata.latency_info.begin(), |
402 frame.metadata.latency_info.end()); | 432 frame.metadata.latency_info.end()); |
403 | 433 |
404 client_->DelegatedFrameHostSendReclaimCompositorResources( | 434 client_->DelegatedFrameHostSendReclaimCompositorResources( |
405 compositor_frame_sink_id, true /* is_swap_ack*/, resources); | 435 compositor_frame_sink_id, true /* is_swap_ack*/, resources); |
406 skipped_frames_ = true; | 436 skipped_frames_ = true; |
| 437 DidFinishFrame(ack); |
407 return; | 438 return; |
408 } | 439 } |
409 | 440 |
410 if (skipped_frames_) { | 441 if (skipped_frames_) { |
411 skipped_frames_ = false; | 442 skipped_frames_ = false; |
412 damage_rect = gfx::Rect(frame_size); | 443 damage_rect = gfx::Rect(frame_size); |
413 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); | 444 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); |
414 | 445 |
415 // Give the same damage rect to the compositor. | 446 // Give the same damage rect to the compositor. |
416 cc::RenderPass* root_pass = frame.render_pass_list.back().get(); | 447 cc::RenderPass* root_pass = frame.render_pass_list.back().get(); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 } | 506 } |
476 | 507 |
477 if (compositor_) | 508 if (compositor_) |
478 can_lock_compositor_ = NO_PENDING_COMMIT; | 509 can_lock_compositor_ = NO_PENDING_COMMIT; |
479 | 510 |
480 if (has_frame_) { | 511 if (has_frame_) { |
481 delegated_frame_evictor_->SwappedFrame( | 512 delegated_frame_evictor_->SwappedFrame( |
482 client_->DelegatedFrameHostIsVisible()); | 513 client_->DelegatedFrameHostIsVisible()); |
483 } | 514 } |
484 // Note: the frame may have been evicted immediately. | 515 // Note: the frame may have been evicted immediately. |
| 516 |
| 517 DidFinishFrame(ack); |
485 } | 518 } |
486 | 519 |
487 void DelegatedFrameHost::ClearDelegatedFrame() { | 520 void DelegatedFrameHost::ClearDelegatedFrame() { |
488 EvictDelegatedFrame(); | 521 EvictDelegatedFrame(); |
489 } | 522 } |
490 | 523 |
491 void DelegatedFrameHost::DidReceiveCompositorFrameAck() { | 524 void DelegatedFrameHost::DidReceiveCompositorFrameAck() { |
492 client_->DelegatedFrameHostSendReclaimCompositorResources( | 525 client_->DelegatedFrameHostSendReclaimCompositorResources( |
493 last_compositor_frame_sink_id_, true /* is_swap_ack */, | 526 last_compositor_frame_sink_id_, true /* is_swap_ack */, |
494 cc::ReturnedResourceArray()); | 527 cc::ReturnedResourceArray()); |
(...skipping 10 matching lines...) Expand all Loading... |
505 // Frame subscribers are only interested in changes to the target surface, so | 538 // 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 | 539 // 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 | 540 // of parent surfaces from triggering extra frame captures, which can affect |
508 // smoothness. | 541 // smoothness. |
509 if (id != local_surface_id_ || damage_rect.IsEmpty()) | 542 if (id != local_surface_id_ || damage_rect.IsEmpty()) |
510 return; | 543 return; |
511 AttemptFrameSubscriberCapture(damage_rect); | 544 AttemptFrameSubscriberCapture(damage_rect); |
512 } | 545 } |
513 | 546 |
514 void DelegatedFrameHost::OnBeginFrame(const cc::BeginFrameArgs& args) { | 547 void DelegatedFrameHost::OnBeginFrame(const cc::BeginFrameArgs& args) { |
515 begin_frame_source_->OnBeginFrame(args); | 548 client_->OnBeginFrame(args); |
516 } | 549 } |
517 | 550 |
518 void DelegatedFrameHost::EvictDelegatedFrame() { | 551 void DelegatedFrameHost::EvictDelegatedFrame() { |
519 if (!has_frame_) | 552 if (!has_frame_) |
520 return; | 553 return; |
521 client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent(); | 554 client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent(); |
522 support_->EvictFrame(); | 555 support_->EvictFrame(); |
523 has_frame_ = false; | 556 has_frame_ = false; |
524 delegated_frame_evictor_->DiscardedFrame(); | 557 delegated_frame_evictor_->DiscardedFrame(); |
525 UpdateGutters(); | 558 UpdateGutters(); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 } | 782 } |
750 | 783 |
751 //////////////////////////////////////////////////////////////////////////////// | 784 //////////////////////////////////////////////////////////////////////////////// |
752 // DelegatedFrameHost, private: | 785 // DelegatedFrameHost, private: |
753 | 786 |
754 DelegatedFrameHost::~DelegatedFrameHost() { | 787 DelegatedFrameHost::~DelegatedFrameHost() { |
755 DCHECK(!compositor_); | 788 DCHECK(!compositor_); |
756 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 789 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
757 factory->GetContextFactory()->RemoveObserver(this); | 790 factory->GetContextFactory()->RemoveObserver(this); |
758 | 791 |
759 begin_frame_source_.reset(); | |
760 ResetCompositorFrameSinkSupport(); | 792 ResetCompositorFrameSinkSupport(); |
761 | 793 |
762 factory->GetContextFactoryPrivate() | 794 factory->GetContextFactoryPrivate() |
763 ->GetSurfaceManager() | 795 ->GetSurfaceManager() |
764 ->InvalidateFrameSinkId(frame_sink_id_); | 796 ->InvalidateFrameSinkId(frame_sink_id_); |
765 | 797 |
766 DCHECK(!vsync_manager_.get()); | 798 DCHECK(!vsync_manager_.get()); |
767 } | 799 } |
768 | 800 |
769 void DelegatedFrameHost::SetCompositor(ui::Compositor* compositor) { | 801 void DelegatedFrameHost::SetCompositor(ui::Compositor* compositor) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 } else { | 847 } else { |
816 request_copy_of_output_callback_for_testing_.Run(std::move(request)); | 848 request_copy_of_output_callback_for_testing_.Run(std::move(request)); |
817 } | 849 } |
818 } | 850 } |
819 | 851 |
820 void DelegatedFrameHost::UnlockResources() { | 852 void DelegatedFrameHost::UnlockResources() { |
821 DCHECK(local_surface_id_.is_valid()); | 853 DCHECK(local_surface_id_.is_valid()); |
822 delegated_frame_evictor_->UnlockFrame(); | 854 delegated_frame_evictor_->UnlockFrame(); |
823 } | 855 } |
824 | 856 |
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() { | 857 void DelegatedFrameHost::CreateCompositorFrameSinkSupport() { |
857 DCHECK(!support_); | 858 DCHECK(!support_); |
858 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 859 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
859 support_ = base::MakeUnique<cc::CompositorFrameSinkSupport>( | 860 support_ = base::MakeUnique<cc::CompositorFrameSinkSupport>( |
860 this, factory->GetContextFactoryPrivate()->GetSurfaceManager(), | 861 this, factory->GetContextFactoryPrivate()->GetSurfaceManager(), |
861 frame_sink_id_, false /* is_root */, | 862 frame_sink_id_, false /* is_root */, |
862 false /* handles_frame_sink_id_invalidation */, | 863 false /* handles_frame_sink_id_invalidation */, |
863 true /* needs_sync_points */); | 864 true /* needs_sync_points */); |
864 if (compositor_) | 865 if (compositor_) |
865 compositor_->AddFrameSink(frame_sink_id_); | 866 compositor_->AddFrameSink(frame_sink_id_); |
866 if (needs_begin_frame_) | 867 if (needs_begin_frame_) |
867 support_->SetNeedsBeginFrame(true); | 868 support_->SetNeedsBeginFrame(true); |
868 } | 869 } |
869 | 870 |
870 void DelegatedFrameHost::ResetCompositorFrameSinkSupport() { | 871 void DelegatedFrameHost::ResetCompositorFrameSinkSupport() { |
871 if (!support_) | 872 if (!support_) |
872 return; | 873 return; |
873 if (compositor_) | 874 if (compositor_) |
874 compositor_->RemoveFrameSink(frame_sink_id_); | 875 compositor_->RemoveFrameSink(frame_sink_id_); |
875 support_.reset(); | 876 support_.reset(); |
876 } | 877 } |
877 | 878 |
878 } // namespace content | 879 } // namespace content |
OLD | NEW |