Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Side by Side Diff: content/browser/renderer_host/delegated_frame_host.cc

Issue 2790623003: ui: Rework CompositorResizeLock interaction with DelegatedFrameHost (Closed)
Patch Set: shouldskip: allowskipafterframe Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 // CompositorFrame's damage, so need to wait for the next one before 226 // CompositorFrame's damage, so need to wait for the next one before
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(const gfx::Size& size_in_dip) {
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 239 // Allow a single renderer frame through even though there's a resize lock
240 // currently in place.
241 if (allow_one_renderer_frame_during_resize_lock_) {
242 allow_one_renderer_frame_during_resize_lock_ = false;
243 return false;
244 }
263 return size_in_dip != resize_lock_->expected_size(); 245 return size_in_dip != resize_lock_->expected_size();
264 } 246 }
265 247
266 void DelegatedFrameHost::WasResized() { 248 void DelegatedFrameHost::WasResized() {
267 if (client_->DelegatedFrameHostDesiredSizeInDIP() != 249 if (client_->DelegatedFrameHostDesiredSizeInDIP() !=
268 current_frame_size_in_dip_ && 250 current_frame_size_in_dip_ &&
269 !client_->DelegatedFrameHostIsVisible()) 251 !client_->DelegatedFrameHostIsVisible())
270 EvictDelegatedFrame(); 252 EvictDelegatedFrame();
271 MaybeCreateResizeLock(); 253 // If |create_resize_lock_after_commit_| is true, we're waiting to recreate
254 // an expired resize lock after the next UI frame is submitted, so don't
255 // make a lock here.
256 if (!resize_lock_ && !create_resize_lock_after_commit_)
257 MaybeCreateResizeLock();
272 UpdateGutters(); 258 UpdateGutters();
273 } 259 }
274 260
275 SkColor DelegatedFrameHost::GetGutterColor() const { 261 SkColor DelegatedFrameHost::GetGutterColor() const {
276 // In fullscreen mode resizing is uncommon, so it makes more sense to 262 // 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 263 // make the initial switch to fullscreen mode look better by using black as
278 // the gutter color. 264 // the gutter color.
279 return client_->DelegatedFrameHostGetGutterColor(background_color_); 265 return client_->DelegatedFrameHostGetGutterColor(background_color_);
280 } 266 }
281 267
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 frame.metadata.latency_info.begin(), 414 frame.metadata.latency_info.begin(),
429 frame.metadata.latency_info.end()); 415 frame.metadata.latency_info.end());
430 416
431 client_->DelegatedFrameHostSendReclaimCompositorResources( 417 client_->DelegatedFrameHostSendReclaimCompositorResources(
432 true /* is_swap_ack*/, resources); 418 true /* is_swap_ack*/, resources);
433 skipped_frames_ = true; 419 skipped_frames_ = true;
434 BeginFrameDidNotSwap(ack); 420 BeginFrameDidNotSwap(ack);
435 return; 421 return;
436 } 422 }
437 423
424 // If we are allowing one renderer frame through, this would ensure the frame
425 // gets through even if we regrab the lock after the UI compositor makes one
426 // frame. If the renderer frame beats the UI compositor, then we don't need to
427 // allow any more, though.
428 allow_one_renderer_frame_during_resize_lock_ = false;
429
438 if (skipped_frames_) { 430 if (skipped_frames_) {
439 skipped_frames_ = false; 431 skipped_frames_ = false;
440 damage_rect = gfx::Rect(frame_size); 432 damage_rect = gfx::Rect(frame_size);
441 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); 433 damage_rect_in_dip = gfx::Rect(frame_size_in_dip);
442 434
443 // Give the same damage rect to the compositor. 435 // Give the same damage rect to the compositor.
444 cc::RenderPass* root_pass = frame.render_pass_list.back().get(); 436 cc::RenderPass* root_pass = frame.render_pass_list.back().get();
445 root_pass->damage_rect = damage_rect; 437 root_pass->damage_rect = damage_rect;
446 } 438 }
447 439
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 current_frame_size_in_dip_ = frame_size_in_dip; 473 current_frame_size_in_dip_ = frame_size_in_dip;
482 CheckResizeLock(); 474 CheckResizeLock();
483 475
484 UpdateGutters(); 476 UpdateGutters();
485 477
486 if (!damage_rect_in_dip.IsEmpty()) { 478 if (!damage_rect_in_dip.IsEmpty()) {
487 client_->DelegatedFrameHostGetLayer()->OnDelegatedFrameDamage( 479 client_->DelegatedFrameHostGetLayer()->OnDelegatedFrameDamage(
488 damage_rect_in_dip); 480 damage_rect_in_dip);
489 } 481 }
490 482
491 if (compositor_)
492 can_lock_compositor_ = NO_PENDING_COMMIT;
493
494 if (has_frame_) { 483 if (has_frame_) {
495 delegated_frame_evictor_->SwappedFrame( 484 delegated_frame_evictor_->SwappedFrame(
496 client_->DelegatedFrameHostIsVisible()); 485 client_->DelegatedFrameHostIsVisible());
497 } 486 }
498 // Note: the frame may have been evicted immediately. 487 // Note: the frame may have been evicted immediately.
499 488
500 DidFinishFrame(ack); 489 DidFinishFrame(ack);
501 } 490 }
502 491
503 void DelegatedFrameHost::ClearDelegatedFrame() { 492 void DelegatedFrameHost::ClearDelegatedFrame() {
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 video_frame->stride(media::VideoFrame::kVPlane), 692 video_frame->stride(media::VideoFrame::kVPlane),
704 video_frame->data(media::VideoFrame::kVPlane), region_in_frame.origin(), 693 video_frame->data(media::VideoFrame::kVPlane), region_in_frame.origin(),
705 finished_callback); 694 finished_callback);
706 media::LetterboxYUV(video_frame.get(), region_in_frame); 695 media::LetterboxYUV(video_frame.get(), region_in_frame);
707 } 696 }
708 697
709 //////////////////////////////////////////////////////////////////////////////// 698 ////////////////////////////////////////////////////////////////////////////////
710 // DelegatedFrameHost, ui::CompositorObserver implementation: 699 // DelegatedFrameHost, ui::CompositorObserver implementation:
711 700
712 void DelegatedFrameHost::OnCompositingDidCommit(ui::Compositor* compositor) { 701 void DelegatedFrameHost::OnCompositingDidCommit(ui::Compositor* compositor) {
713 if (can_lock_compositor_ == NO_PENDING_COMMIT) { 702 // If |create_resize_lock_after_commit_| then we should have popped the old
714 can_lock_compositor_ = YES_CAN_LOCK; 703 // lock already.
715 if (resize_lock_ && resize_lock_->Lock()) 704 DCHECK(!resize_lock_ || !create_resize_lock_after_commit_);
716 can_lock_compositor_ = YES_DID_LOCK; 705
717 }
718 if (resize_lock_ && 706 if (resize_lock_ &&
719 resize_lock_->expected_size() == current_frame_size_in_dip_) { 707 resize_lock_->expected_size() == current_frame_size_in_dip_) {
720 resize_lock_.reset(); 708 resize_lock_.reset();
721 client_->DelegatedFrameHostResizeLockWasReleased(); 709 // 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, 710 create_resize_lock_after_commit_ = true;
723 // or if the UI still gave us some resizes), so make sure we grab a new lock 711 }
724 // if necessary. 712
713 if (create_resize_lock_after_commit_) {
714 create_resize_lock_after_commit_ = false;
725 MaybeCreateResizeLock(); 715 MaybeCreateResizeLock();
726 } 716 }
727 } 717 }
728 718
729 void DelegatedFrameHost::OnCompositingStarted(ui::Compositor* compositor, 719 void DelegatedFrameHost::OnCompositingStarted(ui::Compositor* compositor,
730 base::TimeTicks start_time) { 720 base::TimeTicks start_time) {
731 last_draw_ended_ = start_time; 721 last_draw_ended_ = start_time;
732 } 722 }
733 723
734 void DelegatedFrameHost::OnCompositingLockStateChanged( 724 void DelegatedFrameHost::OnCompositingLockStateChanged(
735 ui::Compositor* compositor) { 725 ui::Compositor* compositor) {
736 // A compositor lock that is part of a resize lock timed out. We 726 if (resize_lock_ && resize_lock_->timed_out()) {
737 // should display a renderer frame. 727 // A compositor lock that is part of a resize lock timed out. We allow
738 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { 728 // the UI to produce a frame before locking it again, so we don't lock here.
739 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; 729 // We release the |resize_lock_| though to allow any other resizes that are
730 // desired at the same time since we're allowing the UI to make a frame
731 // which will gutter anyways.
732 resize_lock_.reset();
733 create_resize_lock_after_commit_ = true;
734 // Because this timed out, we're going to allow the UI to update and lock
735 // again. We would allow renderer frames through during this time if they
736 // came late, but would stop them again once the UI finished its frame. We
737 // want to allow the slow renderer to show us one frame even if its wrong
738 // since we're guttering anyways, but not unlimited number of frames as that
739 // would be a waste of power.
740 allow_one_renderer_frame_during_resize_lock_ = true;
740 } 741 }
741 } 742 }
742 743
743 void DelegatedFrameHost::OnCompositingShuttingDown(ui::Compositor* compositor) { 744 void DelegatedFrameHost::OnCompositingShuttingDown(ui::Compositor* compositor) {
744 DCHECK_EQ(compositor, compositor_); 745 DCHECK_EQ(compositor, compositor_);
745 ResetCompositor(); 746 ResetCompositor();
746 DCHECK(!compositor_); 747 DCHECK(!compositor_);
747 } 748 }
748 749
749 void DelegatedFrameHost::OnUpdateVSyncParameters(base::TimeTicks timebase, 750 void DelegatedFrameHost::OnUpdateVSyncParameters(base::TimeTicks timebase,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 DCHECK(!vsync_manager_.get()); 788 DCHECK(!vsync_manager_.get());
788 vsync_manager_ = compositor_->vsync_manager(); 789 vsync_manager_ = compositor_->vsync_manager();
789 vsync_manager_->AddObserver(this); 790 vsync_manager_->AddObserver(this);
790 791
791 compositor_->AddFrameSink(frame_sink_id_); 792 compositor_->AddFrameSink(frame_sink_id_);
792 } 793 }
793 794
794 void DelegatedFrameHost::ResetCompositor() { 795 void DelegatedFrameHost::ResetCompositor() {
795 if (!compositor_) 796 if (!compositor_)
796 return; 797 return;
797 if (resize_lock_) { 798 resize_lock_.reset();
798 resize_lock_.reset();
799 client_->DelegatedFrameHostResizeLockWasReleased();
800 }
801 if (compositor_->HasObserver(this)) 799 if (compositor_->HasObserver(this))
802 compositor_->RemoveObserver(this); 800 compositor_->RemoveObserver(this);
803 if (vsync_manager_) { 801 if (vsync_manager_) {
804 vsync_manager_->RemoveObserver(this); 802 vsync_manager_->RemoveObserver(this);
805 vsync_manager_ = nullptr; 803 vsync_manager_ = nullptr;
806 } 804 }
807 805
808 compositor_->RemoveFrameSink(frame_sink_id_); 806 compositor_->RemoveFrameSink(frame_sink_id_);
809 compositor_ = nullptr; 807 compositor_ = nullptr;
810 } 808 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 } 862 }
865 863
866 if (!skipped_frames_) { 864 if (!skipped_frames_) {
867 latest_confirmed_begin_frame_source_id_ = ack.source_id; 865 latest_confirmed_begin_frame_source_id_ = ack.source_id;
868 latest_confirmed_begin_frame_sequence_number_ = 866 latest_confirmed_begin_frame_sequence_number_ =
869 ack.latest_confirmed_sequence_number; 867 ack.latest_confirmed_sequence_number;
870 } 868 }
871 } 869 }
872 870
873 } // namespace content 871 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/delegated_frame_host.h ('k') | content/browser/renderer_host/delegated_frame_host_client_aura.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698