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

Side by Side Diff: third_party/WebKit/Source/modules/vr/VRDisplay.cpp

Issue 2888313002: WebVR: Defer GetVSync calls until the current frame is submitted. (Closed)
Patch Set: Tweak test to run a few frames in magic window mode Created 3 years, 7 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "modules/vr/VRDisplay.h" 5 #include "modules/vr/VRDisplay.h"
6 6
7 #include "core/css/StylePropertySet.h" 7 #include "core/css/StylePropertySet.h"
8 #include "core/dom/DOMException.h" 8 #include "core/dom/DOMException.h"
9 #include "core/dom/FrameRequestCallback.h" 9 #include "core/dom/FrameRequestCallback.h"
10 #include "core/dom/ScriptedAnimationController.h" 10 #include "core/dom/ScriptedAnimationController.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 switch (StringToVREye(which_eye)) { 122 switch (StringToVREye(which_eye)) {
123 case kVREyeLeft: 123 case kVREyeLeft:
124 return eye_parameters_left_; 124 return eye_parameters_left_;
125 case kVREyeRight: 125 case kVREyeRight:
126 return eye_parameters_right_; 126 return eye_parameters_right_;
127 default: 127 default:
128 return nullptr; 128 return nullptr;
129 } 129 }
130 } 130 }
131 131
132 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) { 132 void VRDisplay::RequestVSync() {
133 DVLOG(2) << __FUNCTION__; 133 DVLOG(2) << __FUNCTION__
134 Document* doc = this->GetDocument(); 134 << " start: pending_vrdisplay_raf_=" << pending_vrdisplay_raf_
135 if (!doc) 135 << " in_animation_frame_=" << in_animation_frame_
136 return 0; 136 << " did_submit_this_frame_=" << did_submit_this_frame_;
137 pending_vrdisplay_raf_ = true; 137
138 // The logic here is a bit subtle. We get called from one of the following
139 // four contexts:
140 //
141 // (a) from requestAnimationFrame if outside an animating context (i.e. the
142 // first rAF call from inside a getVRDisplays() promise)
143 //
144 // (b) from requestAnimationFrame in an animating context if the JS code
145 // calls rAF after submitFrame.
146 //
147 // (c) from submitFrame if that is called after rAF.
148 //
149 // (d) from ProcessScheduledAnimations if a rAF callback finishes without
150 // submitting a frame.
151 //
152 // These cases are mutually exclusive which prevents duplicate RequestVSync
153 // calls. Case (a) only applies outside an animating context
154 // (in_animation_frame_ is false), and (b,c,d) all require an animating
155 // context. While in an animating context, submitFrame is called either
156 // before rAF (b), after rAF (c), or not at all (d). If rAF isn't called at
157 // all, there won't be future frames.
158
138 if (!vr_v_sync_provider_.is_bound()) { 159 if (!vr_v_sync_provider_.is_bound()) {
139 ConnectVSyncProvider(); 160 ConnectVSyncProvider();
140 } else if (!display_blurred_ && !pending_vsync_) { 161 } else if (!display_blurred_ && !pending_vsync_) {
141 pending_vsync_ = true; 162 pending_vsync_ = true;
142 vr_v_sync_provider_->GetVSync(ConvertToBaseCallback( 163 vr_v_sync_provider_->GetVSync(ConvertToBaseCallback(
143 WTF::Bind(&VRDisplay::OnVSync, WrapWeakPersistent(this)))); 164 WTF::Bind(&VRDisplay::OnVSync, WrapWeakPersistent(this))));
144 } 165 }
166
167 DVLOG(2) << __FUNCTION__ << " done:"
168 << " vr_v_sync_provider_.is_bound()="
169 << vr_v_sync_provider_.is_bound()
170 << " pending_vsync_=" << pending_vsync_;
171 }
172
173 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) {
174 DVLOG(2) << __FUNCTION__;
175 Document* doc = this->GetDocument();
176 if (!doc)
177 return 0;
178 pending_vrdisplay_raf_ = true;
179
180 // We want to delay the GetVSync call while presenting to ensure it doesn't
181 // arrive earlier than frame submission, but other than that we want to call
182 // it as early as possible. See comments inside RequestVSync() for more
183 // details on the applicable cases.
184 if (!in_animation_frame_ || did_submit_this_frame_) {
185 RequestVSync();
186 }
145 callback->use_legacy_time_base_ = false; 187 callback->use_legacy_time_base_ = false;
146 return EnsureScriptedAnimationController(doc).RegisterCallback(callback); 188 return EnsureScriptedAnimationController(doc).RegisterCallback(callback);
147 } 189 }
148 190
149 void VRDisplay::cancelAnimationFrame(int id) { 191 void VRDisplay::cancelAnimationFrame(int id) {
150 DVLOG(2) << __FUNCTION__; 192 DVLOG(2) << __FUNCTION__;
151 if (!scripted_animation_controller_) 193 if (!scripted_animation_controller_)
152 return; 194 return;
153 scripted_animation_controller_->CancelCallback(id); 195 scripted_animation_controller_->CancelCallback(id);
154 } 196 }
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 HeapVector<VRLayer> layers; 522 HeapVector<VRLayer> layers;
481 523
482 if (is_presenting_) { 524 if (is_presenting_) {
483 layers.push_back(layer_); 525 layers.push_back(layer_);
484 } 526 }
485 527
486 return layers; 528 return layers;
487 } 529 }
488 530
489 void VRDisplay::submitFrame() { 531 void VRDisplay::submitFrame() {
532 DVLOG(2) << __FUNCTION__;
533
490 if (!display_) 534 if (!display_)
491 return; 535 return;
492 TRACE_EVENT1("gpu", "submitFrame", "frame", vr_frame_id_); 536 TRACE_EVENT1("gpu", "submitFrame", "frame", vr_frame_id_);
493 537
494 Document* doc = this->GetDocument(); 538 Document* doc = this->GetDocument();
495 if (!is_presenting_) { 539 if (!is_presenting_) {
496 if (doc) { 540 if (doc) {
497 doc->AddConsoleMessage(ConsoleMessage::Create( 541 doc->AddConsoleMessage(ConsoleMessage::Create(
498 kRenderingMessageSource, kWarningMessageLevel, 542 kRenderingMessageSource, kWarningMessageLevel,
499 "submitFrame has no effect when the VRDisplay is not presenting.")); 543 "submitFrame has no effect when the VRDisplay is not presenting."));
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 } 664 }
621 665
622 pending_previous_frame_render_ = true; 666 pending_previous_frame_render_ = true;
623 pending_submit_frame_ = true; 667 pending_submit_frame_ = true;
624 668
625 TRACE_EVENT_BEGIN0("gpu", "VRDisplay::SubmitFrame"); 669 TRACE_EVENT_BEGIN0("gpu", "VRDisplay::SubmitFrame");
626 display_->SubmitFrame(vr_frame_id_, 670 display_->SubmitFrame(vr_frame_id_,
627 gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D)); 671 gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D));
628 TRACE_EVENT_END0("gpu", "VRDisplay::SubmitFrame"); 672 TRACE_EVENT_END0("gpu", "VRDisplay::SubmitFrame");
629 673
674 did_submit_this_frame_ = true;
675 // If we were deferring a rAF-triggered vsync request, do this now.
676 if (pending_vrdisplay_raf_)
677 RequestVSync();
678
630 // If preserveDrawingBuffer is false, must clear now. Normally this 679 // If preserveDrawingBuffer is false, must clear now. Normally this
631 // happens as part of compositing, but that's not active while 680 // happens as part of compositing, but that's not active while
632 // presenting, so run the responsible code directly. 681 // presenting, so run the responsible code directly.
633 rendering_context_->MarkCompositedAndClearBackbufferIfNeeded(); 682 rendering_context_->MarkCompositedAndClearBackbufferIfNeeded();
634 683
635 // If we're not deferring the wait for transferring the mailbox, 684 // If we're not deferring the wait for transferring the mailbox,
636 // we need to wait for it now to prevent the image going out of 685 // we need to wait for it now to prevent the image going out of
637 // scope before its mailbox is retrieved. 686 // scope before its mailbox is retrieved.
638 if (!wait_for_previous_transfer_to_finish) { 687 if (!wait_for_previous_transfer_to_finish) {
639 TRACE_EVENT0("gpu", "waitForCurrentTransferToFinish"); 688 TRACE_EVENT0("gpu", "waitForCurrentTransferToFinish");
640 while (pending_submit_frame_) { 689 while (pending_submit_frame_) {
641 if (!submit_frame_client_binding_.WaitForIncomingMethodCall()) { 690 if (!submit_frame_client_binding_.WaitForIncomingMethodCall()) {
642 DLOG(ERROR) << "Failed to receive SubmitFrame response"; 691 DLOG(ERROR) << "Failed to receive SubmitFrame response";
643 break; 692 break;
644 } 693 }
645 } 694 }
646 } 695 }
647 } 696 }
648 697
649 void VRDisplay::OnSubmitFrameTransferred() { 698 void VRDisplay::OnSubmitFrameTransferred() {
699 DVLOG(3) << __FUNCTION__;
650 pending_submit_frame_ = false; 700 pending_submit_frame_ = false;
651 } 701 }
652 702
653 void VRDisplay::OnSubmitFrameRendered() { 703 void VRDisplay::OnSubmitFrameRendered() {
704 DVLOG(3) << __FUNCTION__;
654 pending_previous_frame_render_ = false; 705 pending_previous_frame_render_ = false;
655 } 706 }
656 707
657 Document* VRDisplay::GetDocument() { 708 Document* VRDisplay::GetDocument() {
658 return navigator_vr_->GetDocument(); 709 return navigator_vr_->GetDocument();
659 } 710 }
660 711
661 void VRDisplay::OnPresentChange() { 712 void VRDisplay::OnPresentChange() {
662 DVLOG(1) << __FUNCTION__ << ": is_presenting_=" << is_presenting_; 713 DVLOG(1) << __FUNCTION__ << ": is_presenting_=" << is_presenting_;
663 if (is_presenting_ && !is_valid_device_for_presenting_) { 714 if (is_presenting_ && !is_valid_device_for_presenting_) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 // Record user action for stop presenting. Note that this could be 756 // Record user action for stop presenting. Note that this could be
706 // user-triggered or not. 757 // user-triggered or not.
707 Platform::Current()->RecordAction( 758 Platform::Current()->RecordAction(
708 UserMetricsAction("VR.WebVR.StopPresenting")); 759 UserMetricsAction("VR.WebVR.StopPresenting"));
709 } 760 }
710 761
711 rendering_context_ = nullptr; 762 rendering_context_ = nullptr;
712 context_gl_ = nullptr; 763 context_gl_ = nullptr;
713 pending_submit_frame_ = false; 764 pending_submit_frame_ = false;
714 pending_previous_frame_render_ = false; 765 pending_previous_frame_render_ = false;
766 did_submit_this_frame_ = false;
715 } 767 }
716 768
717 void VRDisplay::OnActivate(device::mojom::blink::VRDisplayEventReason reason, 769 void VRDisplay::OnActivate(device::mojom::blink::VRDisplayEventReason reason,
718 const OnActivateCallback& on_handled) { 770 const OnActivateCallback& on_handled) {
719 AutoReset<bool> activating(&in_display_activate_, true); 771 AutoReset<bool> activating(&in_display_activate_, true);
720 navigator_vr_->DispatchVREvent(VRDisplayEvent::Create( 772 navigator_vr_->DispatchVREvent(VRDisplayEvent::Create(
721 EventTypeNames::vrdisplayactivate, true, false, this, reason)); 773 EventTypeNames::vrdisplayactivate, true, false, this, reason));
722 on_handled.Run(pending_present_request_); 774 on_handled.Run(pending_present_request_);
723 } 775 }
724 776
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 } 821 }
770 822
771 TRACE_EVENT1("gpu", "VRDisplay::OnVSync", "frame", vr_frame_id_); 823 TRACE_EVENT1("gpu", "VRDisplay::OnVSync", "frame", vr_frame_id_);
772 824
773 if (pending_vrdisplay_raf_ && scripted_animation_controller_) { 825 if (pending_vrdisplay_raf_ && scripted_animation_controller_) {
774 // Run the callback, making sure that in_animation_frame_ is only 826 // Run the callback, making sure that in_animation_frame_ is only
775 // true for the vrDisplay rAF and not for a legacy window rAF 827 // true for the vrDisplay rAF and not for a legacy window rAF
776 // that may be called later. 828 // that may be called later.
777 AutoReset<bool> animating(&in_animation_frame_, true); 829 AutoReset<bool> animating(&in_animation_frame_, true);
778 pending_vrdisplay_raf_ = false; 830 pending_vrdisplay_raf_ = false;
831 did_submit_this_frame_ = false;
779 scripted_animation_controller_->ServiceScriptedAnimations(timestamp); 832 scripted_animation_controller_->ServiceScriptedAnimations(timestamp);
833 if (pending_vrdisplay_raf_ && !did_submit_this_frame_) {
834 DVLOG(2) << __FUNCTION__ << ": vrDisplay.rAF did not submit a frame";
835 RequestVSync();
836 }
780 } 837 }
781 838
839 // Sanity check: If pending_vrdisplay_raf_ is true and the vsync provider
840 // is connected, we must now have a pending vsync.
841 DCHECK(!pending_vrdisplay_raf_ || !vr_v_sync_provider_.is_bound() ||
842 pending_vsync_);
843
782 // For GVR, we shut down normal vsync processing during VR presentation. 844 // For GVR, we shut down normal vsync processing during VR presentation.
783 // Trigger any callbacks on window.rAF manually so that they run after 845 // Trigger any callbacks on window.rAF manually so that they run after
784 // completing the vrDisplay.rAF processing. 846 // completing the vrDisplay.rAF processing.
785 if (is_presenting_ && !capabilities_->hasExternalDisplay()) { 847 if (is_presenting_ && !capabilities_->hasExternalDisplay()) {
786 Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask( 848 Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
787 BLINK_FROM_HERE, WTF::Bind(&VRDisplay::ProcessScheduledWindowAnimations, 849 BLINK_FROM_HERE, WTF::Bind(&VRDisplay::ProcessScheduledWindowAnimations,
788 WrapWeakPersistent(this), timestamp)); 850 WrapWeakPersistent(this), timestamp));
789 } 851 }
790 } 852 }
791 853
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 visitor->Trace(stage_parameters_); 963 visitor->Trace(stage_parameters_);
902 visitor->Trace(eye_parameters_left_); 964 visitor->Trace(eye_parameters_left_);
903 visitor->Trace(eye_parameters_right_); 965 visitor->Trace(eye_parameters_right_);
904 visitor->Trace(layer_); 966 visitor->Trace(layer_);
905 visitor->Trace(rendering_context_); 967 visitor->Trace(rendering_context_);
906 visitor->Trace(scripted_animation_controller_); 968 visitor->Trace(scripted_animation_controller_);
907 visitor->Trace(pending_present_resolvers_); 969 visitor->Trace(pending_present_resolvers_);
908 } 970 }
909 971
910 } // namespace blink 972 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/vr/VRDisplay.h ('k') | third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698