diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc new file mode 100644 index 00000000000..b9676a22842 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc @@ -0,0 +1,92 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h" + +#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" +#include "third_party/blink/renderer/core/probe/core_probes.h" + +namespace blink { + +VideoFrameRequestCallbackCollection::VideoFrameRequestCallbackCollection( + ExecutionContext* context) + : context_(context) {} + +VideoFrameRequestCallbackCollection::CallbackId +VideoFrameRequestCallbackCollection::RegisterFrameCallback( + VideoFrameCallback* callback) { + VideoFrameRequestCallbackCollection::CallbackId id = ++next_callback_id_; + callback->SetIsCancelled(false); + callback->SetId(id); + frame_callbacks_.push_back(callback); + + return id; +} + +void VideoFrameRequestCallbackCollection::CancelFrameCallback(CallbackId id) { + for (wtf_size_t i = 0; i < frame_callbacks_.size(); ++i) { + if (frame_callbacks_[i]->Id() == id) { + frame_callbacks_.EraseAt(i); + return; + } + } + for (const auto& callback : callbacks_to_invoke_) { + if (callback->Id() == id) { + callback->SetIsCancelled(true); + // will be removed at the end of ExecuteCallbacks(). + return; + } + } +} + +void VideoFrameRequestCallbackCollection::ExecuteFrameCallbacks( + double high_res_now_ms, + const VideoFrameMetadata* metadata) { + // First, generate a list of callbacks to consider. Callbacks registered from + // this point on are considered only for the "next" frame, not this one. + DCHECK(callbacks_to_invoke_.IsEmpty()); + std::swap(callbacks_to_invoke_, frame_callbacks_); + + for (const auto& callback : callbacks_to_invoke_) { + // When the ExecutionContext is destroyed (e.g. an iframe is detached), + // there is no path to perform wrapper tracing for the callbacks. In such a + // case, the callback functions may already have been collected by V8 GC. + // Since it's possible that a callback function being invoked detaches an + // iframe, we need to check the condition for each callback. + if (context_->IsContextDestroyed()) + break; + + // Another requestAnimationFrame callback already cancelled this one. + if (callback->IsCancelled()) + continue; + + callback->Invoke(high_res_now_ms, metadata); + } + + callbacks_to_invoke_.clear(); +} + +void VideoFrameRequestCallbackCollection::Trace(Visitor* visitor) { + visitor->Trace(frame_callbacks_); + visitor->Trace(callbacks_to_invoke_); + visitor->Trace(context_); +} + +VideoFrameRequestCallbackCollection::V8VideoFrameCallback::V8VideoFrameCallback( + V8VideoFrameRequestCallback* callback) + : callback_(callback) {} + +void VideoFrameRequestCallbackCollection::V8VideoFrameCallback::Trace( + blink::Visitor* visitor) { + visitor->Trace(callback_); + VideoFrameRequestCallbackCollection::VideoFrameCallback::Trace(visitor); +} + +void VideoFrameRequestCallbackCollection::V8VideoFrameCallback::Invoke( + double highResTime, + const VideoFrameMetadata* metadata) { + callback_->InvokeAndReportException(nullptr, highResTime, metadata); +} + +} // namespace blink |