OLD | NEW |
---|---|
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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) { |
133 DVLOG(2) << __FUNCTION__; | |
133 Document* doc = this->GetDocument(); | 134 Document* doc = this->GetDocument(); |
134 if (!doc) | 135 if (!doc) |
135 return 0; | 136 return 0; |
136 pending_raf_ = true; | 137 pending_vrdisplay_raf_ = true; |
137 if (!vr_v_sync_provider_.is_bound()) { | 138 if (!vr_v_sync_provider_.is_bound()) { |
138 ConnectVSyncProvider(); | 139 ConnectVSyncProvider(); |
139 } else if (!display_blurred_ && !pending_vsync_) { | 140 } else if (!display_blurred_ && !pending_vsync_) { |
140 pending_vsync_ = true; | 141 pending_vsync_ = true; |
141 vr_v_sync_provider_->GetVSync(ConvertToBaseCallback( | 142 vr_v_sync_provider_->GetVSync(ConvertToBaseCallback( |
142 WTF::Bind(&VRDisplay::OnVSync, WrapWeakPersistent(this)))); | 143 WTF::Bind(&VRDisplay::OnVSync, WrapWeakPersistent(this)))); |
143 } | 144 } |
144 callback->use_legacy_time_base_ = false; | 145 callback->use_legacy_time_base_ = false; |
145 return EnsureScriptedAnimationController(doc).RegisterCallback(callback); | 146 return EnsureScriptedAnimationController(doc).RegisterCallback(callback); |
146 } | 147 } |
147 | 148 |
148 void VRDisplay::cancelAnimationFrame(int id) { | 149 void VRDisplay::cancelAnimationFrame(int id) { |
150 DVLOG(2) << __FUNCTION__; | |
149 if (!scripted_animation_controller_) | 151 if (!scripted_animation_controller_) |
150 return; | 152 return; |
151 scripted_animation_controller_->CancelCallback(id); | 153 scripted_animation_controller_->CancelCallback(id); |
152 } | 154 } |
153 | 155 |
154 void VRDisplay::OnBlur() { | 156 void VRDisplay::OnBlur() { |
157 DVLOG(1) << __FUNCTION__; | |
155 display_blurred_ = true; | 158 display_blurred_ = true; |
156 vr_v_sync_provider_.reset(); | 159 vr_v_sync_provider_.reset(); |
157 navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create( | 160 navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create( |
158 EventTypeNames::vrdisplayblur, true, false, this, "")); | 161 EventTypeNames::vrdisplayblur, true, false, this, "")); |
159 } | 162 } |
160 | 163 |
161 void VRDisplay::OnFocus() { | 164 void VRDisplay::OnFocus() { |
165 DVLOG(1) << __FUNCTION__; | |
162 display_blurred_ = false; | 166 display_blurred_ = false; |
163 ConnectVSyncProvider(); | 167 ConnectVSyncProvider(); |
164 navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create( | 168 navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create( |
165 EventTypeNames::vrdisplayfocus, true, false, this, "")); | 169 EventTypeNames::vrdisplayfocus, true, false, this, "")); |
166 } | 170 } |
167 | 171 |
168 void ReportPresentationResult(PresentationResult result) { | 172 void ReportPresentationResult(PresentationResult result) { |
169 // Note that this is called twice for each call to requestPresent - | 173 // Note that this is called twice for each call to requestPresent - |
170 // one to declare that requestPresent was called, and one for the | 174 // one to declare that requestPresent was called, and one for the |
171 // result. | 175 // result. |
172 DEFINE_STATIC_LOCAL( | 176 DEFINE_STATIC_LOCAL( |
173 EnumerationHistogram, vr_presentation_result_histogram, | 177 EnumerationHistogram, vr_presentation_result_histogram, |
174 ("VRDisplayPresentResult", | 178 ("VRDisplayPresentResult", |
175 static_cast<int>(PresentationResult::kPresentationResultMax))); | 179 static_cast<int>(PresentationResult::kPresentationResultMax))); |
176 vr_presentation_result_histogram.Count(static_cast<int>(result)); | 180 vr_presentation_result_histogram.Count(static_cast<int>(result)); |
177 } | 181 } |
178 | 182 |
179 ScriptPromise VRDisplay::requestPresent(ScriptState* script_state, | 183 ScriptPromise VRDisplay::requestPresent(ScriptState* script_state, |
180 const HeapVector<VRLayer>& layers) { | 184 const HeapVector<VRLayer>& layers) { |
185 DVLOG(1) << __FUNCTION__; | |
181 ExecutionContext* execution_context = ExecutionContext::From(script_state); | 186 ExecutionContext* execution_context = ExecutionContext::From(script_state); |
182 UseCounter::Count(execution_context, UseCounter::kVRRequestPresent); | 187 UseCounter::Count(execution_context, UseCounter::kVRRequestPresent); |
183 if (!execution_context->IsSecureContext()) { | 188 if (!execution_context->IsSecureContext()) { |
184 UseCounter::Count(execution_context, | 189 UseCounter::Count(execution_context, |
185 UseCounter::kVRRequestPresentInsecureOrigin); | 190 UseCounter::kVRRequestPresentInsecureOrigin); |
186 } | 191 } |
187 | 192 |
188 ReportPresentationResult(PresentationResult::kRequested); | 193 ReportPresentationResult(PresentationResult::kRequested); |
189 | 194 |
190 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); | 195 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
313 kNotAllowedError, "Presentation request was denied."); | 318 kNotAllowedError, "Presentation request was denied."); |
314 | 319 |
315 while (!pending_present_resolvers_.IsEmpty()) { | 320 while (!pending_present_resolvers_.IsEmpty()) { |
316 ScriptPromiseResolver* resolver = pending_present_resolvers_.TakeFirst(); | 321 ScriptPromiseResolver* resolver = pending_present_resolvers_.TakeFirst(); |
317 resolver->Reject(exception); | 322 resolver->Reject(exception); |
318 } | 323 } |
319 } | 324 } |
320 } | 325 } |
321 | 326 |
322 ScriptPromise VRDisplay::exitPresent(ScriptState* script_state) { | 327 ScriptPromise VRDisplay::exitPresent(ScriptState* script_state) { |
328 DVLOG(1) << __FUNCTION__; | |
323 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); | 329 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); |
324 ScriptPromise promise = resolver->Promise(); | 330 ScriptPromise promise = resolver->Promise(); |
325 | 331 |
326 if (!is_presenting_) { | 332 if (!is_presenting_) { |
327 // Can't stop presenting if we're not presenting. | 333 // Can't stop presenting if we're not presenting. |
328 DOMException* exception = DOMException::Create( | 334 DOMException* exception = DOMException::Create( |
329 kInvalidStateError, "VRDisplay is not presenting."); | 335 kInvalidStateError, "VRDisplay is not presenting."); |
330 resolver->Reject(exception); | 336 resolver->Reject(exception); |
331 return promise; | 337 return promise; |
332 } | 338 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
390 is_presenting_ = true; | 396 is_presenting_ = true; |
391 ReportPresentationResult(PresentationResult::kSuccess); | 397 ReportPresentationResult(PresentationResult::kSuccess); |
392 | 398 |
393 UpdateLayerBounds(); | 399 UpdateLayerBounds(); |
394 | 400 |
395 while (!pending_present_resolvers_.IsEmpty()) { | 401 while (!pending_present_resolvers_.IsEmpty()) { |
396 ScriptPromiseResolver* resolver = pending_present_resolvers_.TakeFirst(); | 402 ScriptPromiseResolver* resolver = pending_present_resolvers_.TakeFirst(); |
397 resolver->Resolve(); | 403 resolver->Resolve(); |
398 } | 404 } |
399 OnPresentChange(); | 405 OnPresentChange(); |
406 | |
407 // TODO(klausw,crbug.com/710863): there appear to be cases where an embedded | |
mthiesse
2017/04/28 19:45:06
If you simply replace all of the code here with:
| |
408 // iframe has started presenting but isn't focused. To fix this, would need | |
409 // to switch focus here. | |
410 | |
411 // Ensure that we get at least one vsync. It's possible that a page may | |
412 // have started presentation but not used vrDisplay.rAF yet, i.e. if it | |
413 // uses window.rAF while not yet presenting. It needs to get a chance | |
mthiesse
2017/04/28 19:13:21
So, why not just fire window.rAF once after presen
klausw
2017/04/28 20:23:01
I'm doing something similar now, and have confirme
| |
414 // to run its animation loop to avoid getting stuck, and to do so we | |
415 // need a vsync where we can run pending window.rAF callbacks. | |
416 if (!vr_v_sync_provider_.is_bound()) { | |
417 ConnectVSyncProvider(); | |
418 } else if (!display_blurred_ && !pending_vsync_) { | |
419 pending_vsync_ = true; | |
420 vr_v_sync_provider_->GetVSync(ConvertToBaseCallback( | |
421 WTF::Bind(&VRDisplay::OnVSync, WrapWeakPersistent(this)))); | |
422 } | |
423 if (!pending_vsync_) { | |
424 DVLOG(1) << __FUNCTION__ << ": scheduling missing vsync"; | |
425 if (vr_v_sync_provider_.is_bound()) { | |
426 pending_vsync_ = true; | |
427 vr_v_sync_provider_->GetVSync(ConvertToBaseCallback( | |
428 WTF::Bind(&VRDisplay::OnVSync, WrapWeakPersistent(this)))); | |
429 } else { | |
430 DVLOG(1) << __FUNCTION__ | |
431 << ": failed to schedule mising vsync, not focused?"; | |
432 } | |
433 } | |
400 } | 434 } |
401 | 435 |
402 // Need to close service if exists and then free rendering context. | 436 // Need to close service if exists and then free rendering context. |
403 void VRDisplay::ForceExitPresent() { | 437 void VRDisplay::ForceExitPresent() { |
404 if (display_) { | 438 if (display_) { |
405 display_->ExitPresent(); | 439 display_->ExitPresent(); |
406 } | 440 } |
407 StopPresenting(); | 441 StopPresenting(); |
408 } | 442 } |
409 | 443 |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
606 | 640 |
607 void VRDisplay::OnSubmitFrameRendered() { | 641 void VRDisplay::OnSubmitFrameRendered() { |
608 pending_previous_frame_render_ = false; | 642 pending_previous_frame_render_ = false; |
609 } | 643 } |
610 | 644 |
611 Document* VRDisplay::GetDocument() { | 645 Document* VRDisplay::GetDocument() { |
612 return navigator_vr_->GetDocument(); | 646 return navigator_vr_->GetDocument(); |
613 } | 647 } |
614 | 648 |
615 void VRDisplay::OnPresentChange() { | 649 void VRDisplay::OnPresentChange() { |
650 DVLOG(1) << __FUNCTION__ << ": is_presenting_=" << is_presenting_; | |
616 if (is_presenting_ && !is_valid_device_for_presenting_) { | 651 if (is_presenting_ && !is_valid_device_for_presenting_) { |
617 DVLOG(1) << __FUNCTION__ << ": device not valid, not sending event"; | 652 DVLOG(1) << __FUNCTION__ << ": device not valid, not sending event"; |
618 return; | 653 return; |
619 } | 654 } |
620 navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create( | 655 navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create( |
621 EventTypeNames::vrdisplaypresentchange, true, false, this, "")); | 656 EventTypeNames::vrdisplaypresentchange, true, false, this, "")); |
622 } | 657 } |
623 | 658 |
624 void VRDisplay::OnChanged(device::mojom::blink::VRDisplayInfoPtr display) { | 659 void VRDisplay::OnChanged(device::mojom::blink::VRDisplayInfoPtr display) { |
625 Update(display); | 660 Update(display); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
674 } | 709 } |
675 | 710 |
676 void VRDisplay::ProcessScheduledWindowAnimations(double timestamp) { | 711 void VRDisplay::ProcessScheduledWindowAnimations(double timestamp) { |
677 TRACE_EVENT1("gpu", "VRDisplay::window.rAF", "frame", vr_frame_id_); | 712 TRACE_EVENT1("gpu", "VRDisplay::window.rAF", "frame", vr_frame_id_); |
678 auto doc = navigator_vr_->GetDocument(); | 713 auto doc = navigator_vr_->GetDocument(); |
679 if (!doc) | 714 if (!doc) |
680 return; | 715 return; |
681 auto page = doc->GetPage(); | 716 auto page = doc->GetPage(); |
682 if (!page) | 717 if (!page) |
683 return; | 718 return; |
719 | |
720 bool had_pending_vrdisplay_raf = pending_vrdisplay_raf_; | |
684 // TODO(klausw): update timestamp based on scheduling delay? | 721 // TODO(klausw): update timestamp based on scheduling delay? |
685 page->Animator().ServiceScriptedAnimations(timestamp); | 722 page->Animator().ServiceScriptedAnimations(timestamp); |
723 | |
724 if (had_pending_vrdisplay_raf != pending_vrdisplay_raf_) { | |
725 DVLOG(1) << __FUNCTION__ | |
726 << ": window.rAF fallback successfully scheduled VRDisplay.rAF"; | |
727 } | |
728 | |
729 if (!pending_vrdisplay_raf_) { | |
730 // There wasn't any call to vrDisplay.rAF, so we will not be getting new | |
731 // frames from now on unless the application schedules one down the road in | |
732 // reaction to a separate event or timeout. TODO(klausw,crbug.com/716087): | |
733 // do something more useful here? | |
734 DVLOG(1) << __FUNCTION__ | |
735 << ": no scheduled VRDisplay.requestAnimationFrame, presentation " | |
736 "broken?"; | |
737 } | |
686 } | 738 } |
687 | 739 |
688 void VRDisplay::ProcessScheduledAnimations(double timestamp) { | 740 void VRDisplay::ProcessScheduledAnimations(double timestamp) { |
741 DVLOG(2) << __FUNCTION__; | |
689 // Check if we still have a valid context, the animation controller | 742 // Check if we still have a valid context, the animation controller |
690 // or document may have disappeared since we scheduled this. | 743 // or document may have disappeared since we scheduled this. |
691 Document* doc = this->GetDocument(); | 744 Document* doc = this->GetDocument(); |
692 if (!doc || display_blurred_ || !scripted_animation_controller_) | 745 if (!doc || display_blurred_) { |
746 DVLOG(2) << __FUNCTION__ << ": early exit, doc=" << doc | |
747 << " display_blurred_=" << display_blurred_; | |
693 return; | 748 return; |
749 } | |
694 | 750 |
695 TRACE_EVENT1("gpu", "VRDisplay::OnVSync", "frame", vr_frame_id_); | 751 TRACE_EVENT1("gpu", "VRDisplay::OnVSync", "frame", vr_frame_id_); |
696 | 752 |
697 AutoReset<bool> animating(&in_animation_frame_, true); | 753 if (pending_vrdisplay_raf_ && scripted_animation_controller_) { |
698 pending_raf_ = false; | 754 // Run the callback, making sure that in_animation_frame_ is only |
699 | 755 // true for the vrDisplay rAF and not for a legacy window rAF |
700 scripted_animation_controller_->ServiceScriptedAnimations(timestamp); | 756 // that may be called later. |
757 AutoReset<bool> animating(&in_animation_frame_, true); | |
758 pending_vrdisplay_raf_ = false; | |
759 scripted_animation_controller_->ServiceScriptedAnimations(timestamp); | |
760 } | |
701 | 761 |
702 // For GVR, we shut down normal vsync processing during VR presentation. | 762 // For GVR, we shut down normal vsync processing during VR presentation. |
703 // Trigger any callbacks on window.rAF manually so that they run after | 763 // Trigger any callbacks on window.rAF manually so that they run after |
704 // completing the vrDisplay.rAF processing. | 764 // completing the vrDisplay.rAF processing. |
705 if (is_presenting_ && !capabilities_->hasExternalDisplay()) { | 765 if (is_presenting_ && !capabilities_->hasExternalDisplay()) { |
706 Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask( | 766 Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask( |
707 BLINK_FROM_HERE, WTF::Bind(&VRDisplay::ProcessScheduledWindowAnimations, | 767 BLINK_FROM_HERE, WTF::Bind(&VRDisplay::ProcessScheduledWindowAnimations, |
708 WrapWeakPersistent(this), timestamp)); | 768 WrapWeakPersistent(this), timestamp)); |
709 } | 769 } |
710 } | 770 } |
711 | 771 |
712 void VRDisplay::OnVSync(device::mojom::blink::VRPosePtr pose, | 772 void VRDisplay::OnVSync(device::mojom::blink::VRPosePtr pose, |
713 mojo::common::mojom::blink::TimeDeltaPtr time, | 773 mojo::common::mojom::blink::TimeDeltaPtr time, |
714 int16_t frame_id, | 774 int16_t frame_id, |
715 device::mojom::blink::VRVSyncProvider::Status error) { | 775 device::mojom::blink::VRVSyncProvider::Status error) { |
776 DVLOG(2) << __FUNCTION__; | |
716 v_sync_connection_failed_ = false; | 777 v_sync_connection_failed_ = false; |
717 switch (error) { | 778 switch (error) { |
718 case device::mojom::blink::VRVSyncProvider::Status::SUCCESS: | 779 case device::mojom::blink::VRVSyncProvider::Status::SUCCESS: |
719 break; | 780 break; |
720 case device::mojom::blink::VRVSyncProvider::Status::CLOSING: | 781 case device::mojom::blink::VRVSyncProvider::Status::CLOSING: |
721 return; | 782 return; |
722 } | 783 } |
723 pending_vsync_ = false; | 784 pending_vsync_ = false; |
724 | 785 |
725 WTF::TimeDelta time_delta = | 786 WTF::TimeDelta time_delta = |
(...skipping 19 matching lines...) Expand all Loading... | |
745 WTF::Bind(&VRDisplay::ProcessScheduledAnimations, | 806 WTF::Bind(&VRDisplay::ProcessScheduledAnimations, |
746 WrapWeakPersistent(this), timebase_ + time_delta.InSecondsF())); | 807 WrapWeakPersistent(this), timebase_ + time_delta.InSecondsF())); |
747 } | 808 } |
748 | 809 |
749 void VRDisplay::ConnectVSyncProvider() { | 810 void VRDisplay::ConnectVSyncProvider() { |
750 if (!navigator_vr_->IsFocused() || vr_v_sync_provider_.is_bound()) | 811 if (!navigator_vr_->IsFocused() || vr_v_sync_provider_.is_bound()) |
751 return; | 812 return; |
752 display_->GetVRVSyncProvider(mojo::MakeRequest(&vr_v_sync_provider_)); | 813 display_->GetVRVSyncProvider(mojo::MakeRequest(&vr_v_sync_provider_)); |
753 vr_v_sync_provider_.set_connection_error_handler(ConvertToBaseCallback( | 814 vr_v_sync_provider_.set_connection_error_handler(ConvertToBaseCallback( |
754 WTF::Bind(&VRDisplay::OnVSyncConnectionError, WrapWeakPersistent(this)))); | 815 WTF::Bind(&VRDisplay::OnVSyncConnectionError, WrapWeakPersistent(this)))); |
755 if (pending_raf_ && !display_blurred_) { | 816 if (pending_vrdisplay_raf_ && !display_blurred_) { |
756 pending_vsync_ = true; | 817 pending_vsync_ = true; |
757 vr_v_sync_provider_->GetVSync(ConvertToBaseCallback( | 818 vr_v_sync_provider_->GetVSync(ConvertToBaseCallback( |
758 WTF::Bind(&VRDisplay::OnVSync, WrapWeakPersistent(this)))); | 819 WTF::Bind(&VRDisplay::OnVSync, WrapWeakPersistent(this)))); |
759 } | 820 } |
760 } | 821 } |
761 | 822 |
762 void VRDisplay::OnVSyncConnectionError() { | 823 void VRDisplay::OnVSyncConnectionError() { |
763 vr_v_sync_provider_.reset(); | 824 vr_v_sync_provider_.reset(); |
764 if (v_sync_connection_failed_) | 825 if (v_sync_connection_failed_) |
765 return; | 826 return; |
(...skipping 28 matching lines...) Expand all Loading... | |
794 } | 855 } |
795 | 856 |
796 bool VRDisplay::HasPendingActivity() const { | 857 bool VRDisplay::HasPendingActivity() const { |
797 // Prevent V8 from garbage collecting the wrapper object if there are | 858 // Prevent V8 from garbage collecting the wrapper object if there are |
798 // event listeners attached to it. | 859 // event listeners attached to it. |
799 return GetExecutionContext() && HasEventListeners(); | 860 return GetExecutionContext() && HasEventListeners(); |
800 } | 861 } |
801 | 862 |
802 void VRDisplay::FocusChanged() { | 863 void VRDisplay::FocusChanged() { |
803 // TODO(mthiesse): Blur/focus the display. | 864 // TODO(mthiesse): Blur/focus the display. |
865 DVLOG(1) << __FUNCTION__; | |
804 vr_v_sync_provider_.reset(); | 866 vr_v_sync_provider_.reset(); |
805 ConnectVSyncProvider(); | 867 ConnectVSyncProvider(); |
806 } | 868 } |
807 | 869 |
808 DEFINE_TRACE(VRDisplay) { | 870 DEFINE_TRACE(VRDisplay) { |
809 EventTargetWithInlineData::Trace(visitor); | 871 EventTargetWithInlineData::Trace(visitor); |
810 ContextLifecycleObserver::Trace(visitor); | 872 ContextLifecycleObserver::Trace(visitor); |
811 visitor->Trace(navigator_vr_); | 873 visitor->Trace(navigator_vr_); |
812 visitor->Trace(capabilities_); | 874 visitor->Trace(capabilities_); |
813 visitor->Trace(stage_parameters_); | 875 visitor->Trace(stage_parameters_); |
814 visitor->Trace(eye_parameters_left_); | 876 visitor->Trace(eye_parameters_left_); |
815 visitor->Trace(eye_parameters_right_); | 877 visitor->Trace(eye_parameters_right_); |
816 visitor->Trace(layer_); | 878 visitor->Trace(layer_); |
817 visitor->Trace(rendering_context_); | 879 visitor->Trace(rendering_context_); |
818 visitor->Trace(scripted_animation_controller_); | 880 visitor->Trace(scripted_animation_controller_); |
819 visitor->Trace(pending_present_resolvers_); | 881 visitor->Trace(pending_present_resolvers_); |
820 } | 882 } |
821 | 883 |
822 } // namespace blink | 884 } // namespace blink |
OLD | NEW |