| // 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_ |