|  | // Copyright 2020 The Chromium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef ANDROID_WEBVIEW_BROWSER_GFX_BEGIN_FRAME_SOURCE_WEBVIEW_H_ | 
|  | #define ANDROID_WEBVIEW_BROWSER_GFX_BEGIN_FRAME_SOURCE_WEBVIEW_H_ | 
|  |  | 
|  | #include <memory> | 
|  |  | 
|  | #include "base/android/scoped_java_ref.h" | 
|  | #include "base/functional/callback.h" | 
|  | #include "base/functional/callback_helpers.h" | 
|  | #include "base/memory/raw_ptr.h" | 
|  | #include "base/no_destructor.h" | 
|  | #include "components/viz/common/frame_sinks/begin_frame_source.h" | 
|  | #include "components/viz/service/frame_sinks/external_begin_frame_source_android.h" | 
|  |  | 
|  | namespace android_webview { | 
|  |  | 
|  | // The BeginFrameSourceWebView implements ExternalBeginFrameSource by observing | 
|  | // another begin_frame_source and provides AfterBeginFrame callback that called | 
|  | // after BeginFrame is sent out to all observers. It supports hierarchy | 
|  | // BeginFrameSourceWebView to provide AddBeginFrameCompletionCallback which will | 
|  | // be forwarded to root begin frame source to ensure that callbacks called after | 
|  | // all BeginFrames are sent. | 
|  | // | 
|  | // Lifetime: WebView | 
|  | class BeginFrameSourceWebView : public viz::ExternalBeginFrameSource { | 
|  | public: | 
|  | BeginFrameSourceWebView(); | 
|  | ~BeginFrameSourceWebView() override; | 
|  |  | 
|  | // Sets parent of this BeginFrameSource | 
|  | void SetParentSource(BeginFrameSourceWebView* parent); | 
|  | bool inside_begin_frame() { return inside_begin_frame_; } | 
|  |  | 
|  | // Schedules BeginFrame completion callback on root begin frame source. | 
|  | virtual void AddBeginFrameCompletionCallback(base::OnceClosure callback); | 
|  |  | 
|  | // Returns last dispatched begin frame args. | 
|  | const viz::BeginFrameArgs& LastDispatchedBeginFrameArgs(); | 
|  |  | 
|  | protected: | 
|  | void ObserveBeginFrameSource(viz::BeginFrameSource* begin_frame_source); | 
|  |  | 
|  | virtual void AfterBeginFrame() {} | 
|  |  | 
|  | private: | 
|  | class BeginFrameObserver; | 
|  | class BeginFrameSourceClient : public viz::ExternalBeginFrameSourceClient { | 
|  | public: | 
|  | BeginFrameSourceClient(BeginFrameSourceWebView* owner); | 
|  | ~BeginFrameSourceClient(); | 
|  |  | 
|  | // ExternalBeginFrameSourceClient implementation. | 
|  | void OnNeedsBeginFrames(bool needs_begin_frames) override; | 
|  |  | 
|  | private: | 
|  | const raw_ptr<BeginFrameSourceWebView> owner_; | 
|  | }; | 
|  |  | 
|  | void SendBeginFrame(const viz::BeginFrameArgs& args); | 
|  | void OnNeedsBeginFrames(bool needs_begin_frames); | 
|  |  | 
|  | BeginFrameSourceClient bfs_client_; | 
|  | raw_ptr<viz::BeginFrameSource> observed_begin_frame_source_ = nullptr; | 
|  | raw_ptr<BeginFrameSourceWebView> parent_ = nullptr; | 
|  | std::unique_ptr<BeginFrameObserver> parent_observer_; | 
|  | bool inside_begin_frame_ = false; | 
|  | }; | 
|  |  | 
|  | // RootBeginFrameSourceWebView is subclass of BeginFrameSourceWebView that | 
|  | // observes ExternalBeginFrameSourceAndroid to provide actual BeginFrames from | 
|  | // Android Choreographer and implements the logic of | 
|  | // AddBeginFrameCompletionCallback. | 
|  | // | 
|  | // Lifetime: Singleton | 
|  | // | 
|  | // There is only one RootBeginFrameSourceWebView, even if there are multiple | 
|  | // displays with different VSync timings attached. Choreographer only uses the | 
|  | // built-in display for frame timing. | 
|  | class RootBeginFrameSourceWebView : public BeginFrameSourceWebView { | 
|  | public: | 
|  | static RootBeginFrameSourceWebView* GetInstance(); | 
|  |  | 
|  | void OnUpdateRefreshRate(JNIEnv* env, | 
|  | float refresh_rate); | 
|  |  | 
|  | // As this is implementation of root BeginFrameSourceWebView this is actual | 
|  | // implementation of scheduling callbacks. | 
|  | void AddBeginFrameCompletionCallback(base::OnceClosure callback) override; | 
|  |  | 
|  | private: | 
|  | friend class base::NoDestructor<RootBeginFrameSourceWebView>; | 
|  | friend class BeginFrameSourceWebViewTest; | 
|  |  | 
|  | RootBeginFrameSourceWebView(); | 
|  | ~RootBeginFrameSourceWebView() override; | 
|  |  | 
|  | void AfterBeginFrame() override; | 
|  |  | 
|  | viz::ExternalBeginFrameSourceAndroid begin_frame_source_; | 
|  | std::vector<base::ScopedClosureRunner> after_begin_frame_callbacks_; | 
|  | base::android::ScopedJavaGlobalRef<jobject> j_object_; | 
|  | }; | 
|  |  | 
|  | }  // namespace android_webview | 
|  |  | 
|  | #endif  // ANDROID_WEBVIEW_BROWSER_GFX_BEGIN_FRAME_SOURCE_WEBVIEW_H_ |