1 // Copyright 2020 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef ANDROID_WEBVIEW_BROWSER_GFX_BEGIN_FRAME_SOURCE_WEBVIEW_H_ 6 #define ANDROID_WEBVIEW_BROWSER_GFX_BEGIN_FRAME_SOURCE_WEBVIEW_H_ 7 8 #include <memory> 9 #include "base/android/scoped_java_ref.h" 10 #include "base/callback.h" 11 #include "base/callback_helpers.h" 12 #include "components/viz/common/frame_sinks/begin_frame_source.h" 13 #include "components/viz/service/frame_sinks/external_begin_frame_source_android.h" 14 15 namespace android_webview { 16 17 // The BeginFrameSourceWebView implements ExternalBeginFrameSource by observing 18 // another begin_frame_source and provides AfterBeginFrame callback that called 19 // after BeginFrame is sent out to all observers. It supports hierarchy 20 // BeginFrameSourceWebView to provide AddBeginFrameCompletionCallback which will 21 // be forwarded to root begin frame source to ensure that callbacks called after 22 // all BeginFrames are sent. 23 class BeginFrameSourceWebView : public viz::ExternalBeginFrameSource { 24 public: 25 BeginFrameSourceWebView(); 26 ~BeginFrameSourceWebView() override; 27 28 // Sets parent of this BeginFrameSource 29 void SetParentSource(BeginFrameSourceWebView* parent); 30 31 // Schedules BeginFrame completion callback on root begin frame source. 32 virtual void AddBeginFrameCompletionCallback(base::OnceClosure callback); 33 34 protected: 35 void ObserveBeginFrameSource(viz::BeginFrameSource* begin_frame_source); 36 AfterBeginFrame()37 virtual void AfterBeginFrame() {} inside_begin_frame()38 bool inside_begin_frame() { return inside_begin_frame_; } 39 40 private: 41 class BeginFrameObserver; 42 class BeginFrameSourceClient : public viz::ExternalBeginFrameSourceClient { 43 public: 44 BeginFrameSourceClient(BeginFrameSourceWebView* owner); 45 ~BeginFrameSourceClient(); 46 47 // ExternalBeginFrameSourceClient implementation. 48 void OnNeedsBeginFrames(bool needs_begin_frames) override; 49 50 private: 51 BeginFrameSourceWebView* const owner_; 52 }; 53 54 void SendBeginFrame(const viz::BeginFrameArgs& args); 55 void OnNeedsBeginFrames(bool needs_begin_frames); 56 57 BeginFrameSourceClient bfs_client_; 58 viz::BeginFrameSource* observed_begin_frame_source_ = nullptr; 59 BeginFrameSourceWebView* parent_ = nullptr; 60 std::unique_ptr<BeginFrameObserver> parent_observer_; 61 bool inside_begin_frame_ = false; 62 }; 63 64 // RootBeginFrameSourceWebView is subclass of BeginFrameSourceWebView that 65 // observes ExternalBeginFrameSourceAndroid to provide actual BeginFrames from 66 // Android Choreographer and implements the logic of 67 // AddBeginFrameCompletionCallback. 68 class RootBeginFrameSourceWebView : public BeginFrameSourceWebView { 69 public: 70 static RootBeginFrameSourceWebView* GetInstance(); 71 72 void OnUpdateRefreshRate(JNIEnv* env, 73 const base::android::JavaParamRef<jobject>& obj, 74 float refresh_rate); 75 76 // As this is implementation of root BeginFrameSourceWebView this is actual 77 // implementation of scheduling callbacks. 78 void AddBeginFrameCompletionCallback(base::OnceClosure callback) override; 79 80 private: 81 friend class base::NoDestructor<RootBeginFrameSourceWebView>; 82 friend class BeginFrameSourceWebViewTest; 83 84 RootBeginFrameSourceWebView(); 85 ~RootBeginFrameSourceWebView() override; 86 87 void AfterBeginFrame() override; 88 89 viz::ExternalBeginFrameSourceAndroid begin_frame_source_; 90 std::vector<base::ScopedClosureRunner> after_begin_frame_callbacks_; 91 base::android::ScopedJavaGlobalRef<jobject> j_object_; 92 }; 93 94 } // namespace android_webview 95 96 #endif // ANDROID_WEBVIEW_BROWSER_GFX_BEGIN_FRAME_SOURCE_WEBVIEW_H_ 97