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