Chromium Code Reviews| 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 | 44 |
| 45 DelegatedFrameHost::DelegatedFrameHost(const cc::FrameSinkId& frame_sink_id, | 45 DelegatedFrameHost::DelegatedFrameHost(const cc::FrameSinkId& frame_sink_id, |
| 46 DelegatedFrameHostClient* client) | 46 DelegatedFrameHostClient* client) |
| 47 : frame_sink_id_(frame_sink_id), | 47 : frame_sink_id_(frame_sink_id), |
| 48 client_(client), | 48 client_(client), |
| 49 compositor_(nullptr), | 49 compositor_(nullptr), |
| 50 tick_clock_(new base::DefaultTickClock()), | 50 tick_clock_(new base::DefaultTickClock()), |
| 51 skipped_frames_(false), | 51 skipped_frames_(false), |
| 52 background_color_(SK_ColorRED), | 52 background_color_(SK_ColorRED), |
| 53 current_scale_factor_(1.f), | 53 current_scale_factor_(1.f), |
| 54 can_lock_compositor_(YES_CAN_LOCK), | |
| 55 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { | 54 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { |
| 56 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 55 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
| 57 factory->GetContextFactory()->AddObserver(this); | 56 factory->GetContextFactory()->AddObserver(this); |
| 58 factory->GetContextFactoryPrivate()->GetSurfaceManager()->RegisterFrameSinkId( | 57 factory->GetContextFactoryPrivate()->GetSurfaceManager()->RegisterFrameSinkId( |
| 59 frame_sink_id_); | 58 frame_sink_id_); |
| 60 CreateCompositorFrameSinkSupport(); | 59 CreateCompositorFrameSinkSupport(); |
| 61 } | 60 } |
| 62 | 61 |
| 63 void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) { | 62 void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) { |
| 64 delegated_frame_evictor_->SetVisible(true); | 63 delegated_frame_evictor_->SetVisible(true); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 76 bool DelegatedFrameHost::HasSavedFrame() { | 75 bool DelegatedFrameHost::HasSavedFrame() { |
| 77 return delegated_frame_evictor_->HasFrame(); | 76 return delegated_frame_evictor_->HasFrame(); |
| 78 } | 77 } |
| 79 | 78 |
| 80 void DelegatedFrameHost::WasHidden() { | 79 void DelegatedFrameHost::WasHidden() { |
| 81 delegated_frame_evictor_->SetVisible(false); | 80 delegated_frame_evictor_->SetVisible(false); |
| 82 released_front_lock_ = NULL; | 81 released_front_lock_ = NULL; |
| 83 } | 82 } |
| 84 | 83 |
| 85 void DelegatedFrameHost::MaybeCreateResizeLock() { | 84 void DelegatedFrameHost::MaybeCreateResizeLock() { |
| 86 if (!ShouldCreateResizeLock()) | 85 DCHECK(!resize_lock_); |
| 86 | |
| 87 if (!compositor_) | |
| 87 return; | 88 return; |
| 88 DCHECK(compositor_); | |
| 89 | 89 |
| 90 bool defer_compositor_lock = | 90 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 91 can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || | 91 switches::kDisableResizeLock)) |
| 92 can_lock_compositor_ == NO_PENDING_COMMIT; | 92 return; |
| 93 | 93 |
| 94 if (can_lock_compositor_ == YES_CAN_LOCK) | 94 if (!client_->DelegatedFrameCanCreateResizeLock()) |
| 95 can_lock_compositor_ = YES_DID_LOCK; | 95 return; |
| 96 | |
| 97 gfx::Size desired_size = client_->DelegatedFrameHostDesiredSizeInDIP(); | |
| 98 if (desired_size.IsEmpty()) | |
| 99 return; | |
| 100 if (desired_size == current_frame_size_in_dip_) | |
| 101 return; | |
| 96 | 102 |
| 97 resize_lock_ = client_->DelegatedFrameHostCreateResizeLock(); | 103 resize_lock_ = client_->DelegatedFrameHostCreateResizeLock(); |
| 98 if (!defer_compositor_lock) { | 104 bool locked = resize_lock_->Lock(); |
| 99 bool locked = resize_lock_->Lock(); | 105 DCHECK(locked); |
| 100 DCHECK(locked); | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 bool DelegatedFrameHost::ShouldCreateResizeLock() { | |
| 105 static const bool is_disabled = | |
| 106 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 107 switches::kDisableResizeLock); | |
| 108 if (is_disabled) | |
| 109 return false; | |
| 110 | |
| 111 if (!client_->DelegatedFrameCanCreateResizeLock()) | |
| 112 return false; | |
| 113 | |
| 114 if (resize_lock_) | |
| 115 return false; | |
| 116 | |
| 117 gfx::Size desired_size = client_->DelegatedFrameHostDesiredSizeInDIP(); | |
| 118 if (desired_size == current_frame_size_in_dip_ || desired_size.IsEmpty()) | |
| 119 return false; | |
| 120 | |
| 121 if (!compositor_) | |
| 122 return false; | |
| 123 | |
| 124 return true; | |
| 125 } | 106 } |
| 126 | 107 |
| 127 void DelegatedFrameHost::CopyFromCompositingSurface( | 108 void DelegatedFrameHost::CopyFromCompositingSurface( |
| 128 const gfx::Rect& src_subrect, | 109 const gfx::Rect& src_subrect, |
| 129 const gfx::Size& output_size, | 110 const gfx::Size& output_size, |
| 130 const ReadbackRequestCallback& callback, | 111 const ReadbackRequestCallback& callback, |
| 131 const SkColorType preferred_color_type) { | 112 const SkColorType preferred_color_type) { |
| 132 // Only ARGB888 and RGB565 supported as of now. | 113 // Only ARGB888 and RGB565 supported as of now. |
| 133 bool format_support = ((preferred_color_type == kAlpha_8_SkColorType) || | 114 bool format_support = ((preferred_color_type == kAlpha_8_SkColorType) || |
| 134 (preferred_color_type == kRGB_565_SkColorType) || | 115 (preferred_color_type == kRGB_565_SkColorType) || |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 // confirming newer sequence numbers. | 227 // confirming newer sequence numbers. |
| 247 modified_ack.has_damage = false; | 228 modified_ack.has_damage = false; |
| 248 modified_ack.latest_confirmed_sequence_number = | 229 modified_ack.latest_confirmed_sequence_number = |
| 249 latest_confirmed_begin_frame_sequence_number_; | 230 latest_confirmed_begin_frame_sequence_number_; |
| 250 } | 231 } |
| 251 | 232 |
| 252 support_->BeginFrameDidNotSwap(modified_ack); | 233 support_->BeginFrameDidNotSwap(modified_ack); |
| 253 } | 234 } |
| 254 | 235 |
| 255 bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const { | 236 bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const { |
| 256 // Should skip a frame only when another frame from the renderer is guaranteed | 237 if (!resize_lock_) |
| 257 // to replace it. Otherwise may cause hangs when the renderer is waiting for | |
| 258 // the completion of latency infos (such as when taking a Snapshot.) | |
| 259 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || | |
| 260 can_lock_compositor_ == NO_PENDING_COMMIT || !resize_lock_.get()) | |
| 261 return false; | 238 return false; |
| 262 | |
| 263 return size_in_dip != resize_lock_->expected_size(); | 239 return size_in_dip != resize_lock_->expected_size(); |
| 264 } | 240 } |
| 265 | 241 |
| 266 void DelegatedFrameHost::WasResized() { | 242 void DelegatedFrameHost::WasResized() { |
| 267 if (client_->DelegatedFrameHostDesiredSizeInDIP() != | 243 if (client_->DelegatedFrameHostDesiredSizeInDIP() != |
| 268 current_frame_size_in_dip_ && | 244 current_frame_size_in_dip_ && |
| 269 !client_->DelegatedFrameHostIsVisible()) | 245 !client_->DelegatedFrameHostIsVisible()) |
| 270 EvictDelegatedFrame(); | 246 EvictDelegatedFrame(); |
| 271 MaybeCreateResizeLock(); | 247 if (!resize_lock_) |
| 248 MaybeCreateResizeLock(); | |
| 272 UpdateGutters(); | 249 UpdateGutters(); |
| 273 } | 250 } |
| 274 | 251 |
| 275 SkColor DelegatedFrameHost::GetGutterColor() const { | 252 SkColor DelegatedFrameHost::GetGutterColor() const { |
| 276 // In fullscreen mode resizing is uncommon, so it makes more sense to | 253 // In fullscreen mode resizing is uncommon, so it makes more sense to |
| 277 // make the initial switch to fullscreen mode look better by using black as | 254 // make the initial switch to fullscreen mode look better by using black as |
| 278 // the gutter color. | 255 // the gutter color. |
| 279 return client_->DelegatedFrameHostGetGutterColor(background_color_); | 256 return client_->DelegatedFrameHostGetGutterColor(background_color_); |
| 280 } | 257 } |
| 281 | 258 |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 481 current_frame_size_in_dip_ = frame_size_in_dip; | 458 current_frame_size_in_dip_ = frame_size_in_dip; |
| 482 CheckResizeLock(); | 459 CheckResizeLock(); |
| 483 | 460 |
| 484 UpdateGutters(); | 461 UpdateGutters(); |
| 485 | 462 |
| 486 if (!damage_rect_in_dip.IsEmpty()) { | 463 if (!damage_rect_in_dip.IsEmpty()) { |
| 487 client_->DelegatedFrameHostGetLayer()->OnDelegatedFrameDamage( | 464 client_->DelegatedFrameHostGetLayer()->OnDelegatedFrameDamage( |
| 488 damage_rect_in_dip); | 465 damage_rect_in_dip); |
| 489 } | 466 } |
| 490 | 467 |
| 491 if (compositor_) | |
| 492 can_lock_compositor_ = NO_PENDING_COMMIT; | |
| 493 | |
| 494 if (has_frame_) { | 468 if (has_frame_) { |
| 495 delegated_frame_evictor_->SwappedFrame( | 469 delegated_frame_evictor_->SwappedFrame( |
| 496 client_->DelegatedFrameHostIsVisible()); | 470 client_->DelegatedFrameHostIsVisible()); |
| 497 } | 471 } |
| 498 // Note: the frame may have been evicted immediately. | 472 // Note: the frame may have been evicted immediately. |
| 499 | 473 |
| 500 DidFinishFrame(ack); | 474 DidFinishFrame(ack); |
| 501 } | 475 } |
| 502 | 476 |
| 503 void DelegatedFrameHost::ClearDelegatedFrame() { | 477 void DelegatedFrameHost::ClearDelegatedFrame() { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 703 video_frame->stride(media::VideoFrame::kVPlane), | 677 video_frame->stride(media::VideoFrame::kVPlane), |
| 704 video_frame->data(media::VideoFrame::kVPlane), region_in_frame.origin(), | 678 video_frame->data(media::VideoFrame::kVPlane), region_in_frame.origin(), |
| 705 finished_callback); | 679 finished_callback); |
| 706 media::LetterboxYUV(video_frame.get(), region_in_frame); | 680 media::LetterboxYUV(video_frame.get(), region_in_frame); |
| 707 } | 681 } |
| 708 | 682 |
| 709 //////////////////////////////////////////////////////////////////////////////// | 683 //////////////////////////////////////////////////////////////////////////////// |
| 710 // DelegatedFrameHost, ui::CompositorObserver implementation: | 684 // DelegatedFrameHost, ui::CompositorObserver implementation: |
| 711 | 685 |
| 712 void DelegatedFrameHost::OnCompositingDidCommit(ui::Compositor* compositor) { | 686 void DelegatedFrameHost::OnCompositingDidCommit(ui::Compositor* compositor) { |
| 713 if (can_lock_compositor_ == NO_PENDING_COMMIT) { | 687 // If |create_resize_lock_after_commit_| then we should have popped the old |
| 714 can_lock_compositor_ = YES_CAN_LOCK; | 688 // lock already. |
| 715 if (resize_lock_ && resize_lock_->Lock()) | 689 DCHECK(!resize_lock_ || !create_resize_lock_after_commit_); |
| 716 can_lock_compositor_ = YES_DID_LOCK; | 690 |
| 717 } | |
| 718 if (resize_lock_ && | 691 if (resize_lock_ && |
| 719 resize_lock_->expected_size() == current_frame_size_in_dip_) { | 692 resize_lock_->expected_size() == current_frame_size_in_dip_) { |
| 720 resize_lock_.reset(); | 693 resize_lock_.reset(); |
| 721 client_->DelegatedFrameHostResizeLockWasReleased(); | 694 // We had a lock but the UI may have resized in the meantime. |
| 722 // We may have had a resize while we had the lock (e.g. if the lock expired, | 695 create_resize_lock_after_commit_ = true; |
| 723 // or if the UI still gave us some resizes), so make sure we grab a new lock | 696 } |
| 724 // if necessary. | 697 |
| 698 if (create_resize_lock_after_commit_) { | |
| 699 create_resize_lock_after_commit_ = false; | |
| 725 MaybeCreateResizeLock(); | 700 MaybeCreateResizeLock(); |
| 726 } | 701 } |
| 727 } | 702 } |
| 728 | 703 |
| 729 void DelegatedFrameHost::OnCompositingStarted(ui::Compositor* compositor, | 704 void DelegatedFrameHost::OnCompositingStarted(ui::Compositor* compositor, |
| 730 base::TimeTicks start_time) { | 705 base::TimeTicks start_time) { |
| 731 last_draw_ended_ = start_time; | 706 last_draw_ended_ = start_time; |
| 732 } | 707 } |
| 733 | 708 |
| 734 void DelegatedFrameHost::OnCompositingLockStateChanged( | 709 void DelegatedFrameHost::OnCompositingLockStateChanged( |
| 735 ui::Compositor* compositor) { | 710 ui::Compositor* compositor) { |
| 736 // A compositor lock that is part of a resize lock timed out. We | 711 if (resize_lock_ && resize_lock_->timed_out()) { |
| 737 // should display a renderer frame. | 712 // A compositor lock that is part of a resize lock timed out. We allow |
| 738 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { | 713 // the UI to produce a frame before locking it again, so we don't lock here. |
| 739 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; | 714 // We release the |resize_lock_| though to allow any other resizes that are |
| 715 // desired at the same time since we're allowing the UI to make a frame | |
| 716 // which will gutter anyways. | |
|
piman
2017/03/31 00:31:55
Ok, here I think I know why we wanted the NO_PENDI
danakj
2017/03/31 19:34:42
Ah okay, so maybe allow_one_renderer_frame_ = true
| |
| 717 resize_lock_.reset(); | |
| 718 create_resize_lock_after_commit_ = true; | |
| 740 } | 719 } |
| 741 } | 720 } |
| 742 | 721 |
| 743 void DelegatedFrameHost::OnCompositingShuttingDown(ui::Compositor* compositor) { | 722 void DelegatedFrameHost::OnCompositingShuttingDown(ui::Compositor* compositor) { |
| 744 DCHECK_EQ(compositor, compositor_); | 723 DCHECK_EQ(compositor, compositor_); |
| 745 ResetCompositor(); | 724 ResetCompositor(); |
| 746 DCHECK(!compositor_); | 725 DCHECK(!compositor_); |
| 747 } | 726 } |
| 748 | 727 |
| 749 void DelegatedFrameHost::OnUpdateVSyncParameters(base::TimeTicks timebase, | 728 void DelegatedFrameHost::OnUpdateVSyncParameters(base::TimeTicks timebase, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 787 DCHECK(!vsync_manager_.get()); | 766 DCHECK(!vsync_manager_.get()); |
| 788 vsync_manager_ = compositor_->vsync_manager(); | 767 vsync_manager_ = compositor_->vsync_manager(); |
| 789 vsync_manager_->AddObserver(this); | 768 vsync_manager_->AddObserver(this); |
| 790 | 769 |
| 791 compositor_->AddFrameSink(frame_sink_id_); | 770 compositor_->AddFrameSink(frame_sink_id_); |
| 792 } | 771 } |
| 793 | 772 |
| 794 void DelegatedFrameHost::ResetCompositor() { | 773 void DelegatedFrameHost::ResetCompositor() { |
| 795 if (!compositor_) | 774 if (!compositor_) |
| 796 return; | 775 return; |
| 797 if (resize_lock_) { | 776 resize_lock_.reset(); |
| 798 resize_lock_.reset(); | |
| 799 client_->DelegatedFrameHostResizeLockWasReleased(); | |
| 800 } | |
| 801 if (compositor_->HasObserver(this)) | 777 if (compositor_->HasObserver(this)) |
| 802 compositor_->RemoveObserver(this); | 778 compositor_->RemoveObserver(this); |
| 803 if (vsync_manager_) { | 779 if (vsync_manager_) { |
| 804 vsync_manager_->RemoveObserver(this); | 780 vsync_manager_->RemoveObserver(this); |
| 805 vsync_manager_ = nullptr; | 781 vsync_manager_ = nullptr; |
| 806 } | 782 } |
| 807 | 783 |
| 808 compositor_->RemoveFrameSink(frame_sink_id_); | 784 compositor_->RemoveFrameSink(frame_sink_id_); |
| 809 compositor_ = nullptr; | 785 compositor_ = nullptr; |
| 810 } | 786 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 864 } | 840 } |
| 865 | 841 |
| 866 if (!skipped_frames_) { | 842 if (!skipped_frames_) { |
| 867 latest_confirmed_begin_frame_source_id_ = ack.source_id; | 843 latest_confirmed_begin_frame_source_id_ = ack.source_id; |
| 868 latest_confirmed_begin_frame_sequence_number_ = | 844 latest_confirmed_begin_frame_sequence_number_ = |
| 869 ack.latest_confirmed_sequence_number; | 845 ack.latest_confirmed_sequence_number; |
| 870 } | 846 } |
| 871 } | 847 } |
| 872 | 848 |
| 873 } // namespace content | 849 } // namespace content |
| OLD | NEW |