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