1 // Copyright 2019 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 #include "android_webview/browser/gfx/root_frame_sink_proxy.h"
6
7 #include <utility>
8
9 #include "android_webview/browser/gfx/root_frame_sink.h"
10 #include "android_webview/browser/gfx/viz_compositor_thread_runner_webview.h"
11
12 namespace android_webview {
13
14 class RootFrameSinkProxy::RootFrameSinkClientImpl : public RootFrameSinkClient {
15 public:
RootFrameSinkClientImpl(RootFrameSinkProxy * owner)16 RootFrameSinkClientImpl(RootFrameSinkProxy* owner) : owner_(owner) {}
17 ~RootFrameSinkClientImpl() override = default;
18
19 // RootFrameSinkClient implementation
SetNeedsBeginFrames(bool needs_begin_frame)20 void SetNeedsBeginFrames(bool needs_begin_frame) override {
21 owner_->SetNeedsBeginFramesOnViz(needs_begin_frame);
22 }
Invalidate()23 void Invalidate() override { owner_->InvalidateOnViz(); }
ReturnResources(viz::FrameSinkId frame_sink_id,uint32_t layer_tree_frame_sink_id,std::vector<viz::ReturnedResource> resources)24 void ReturnResources(viz::FrameSinkId frame_sink_id,
25 uint32_t layer_tree_frame_sink_id,
26 std::vector<viz::ReturnedResource> resources) override {
27 owner_->ReturnResourcesOnViz(frame_sink_id, layer_tree_frame_sink_id,
28 std::move(resources));
29 }
30
31 private:
32 RootFrameSinkProxy* const owner_;
33 };
34
35 // static
GetRootFrameSinkHelper(base::WeakPtr<RootFrameSinkProxy> proxy)36 scoped_refptr<RootFrameSink> RootFrameSinkProxy::GetRootFrameSinkHelper(
37 base::WeakPtr<RootFrameSinkProxy> proxy) {
38 DCHECK(VizCompositorThreadRunnerWebView::GetInstance()
39 ->task_runner()
40 ->BelongsToCurrentThread());
41 if (proxy)
42 return proxy->without_gpu_;
43 return nullptr;
44 }
45
RootFrameSinkProxy(const scoped_refptr<base::SingleThreadTaskRunner> & ui_task_runner,RootFrameSinkProxyClient * client,viz::BeginFrameSource * begin_frame_source)46 RootFrameSinkProxy::RootFrameSinkProxy(
47 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
48 RootFrameSinkProxyClient* client,
49 viz::BeginFrameSource* begin_frame_source)
50 : ui_task_runner_(ui_task_runner),
51 viz_task_runner_(
52 VizCompositorThreadRunnerWebView::GetInstance()->task_runner()),
53 client_(client),
54 begin_frame_source_(begin_frame_source) {
55 DETACH_FROM_THREAD(viz_thread_checker_);
56 viz_task_runner_->PostTask(
57 FROM_HERE, base::BindOnce(&RootFrameSinkProxy::InitializeOnViz,
58 base::Unretained(this)));
59 }
60
InitializeOnViz()61 void RootFrameSinkProxy::InitializeOnViz() {
62 DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_);
63 root_frame_sink_client_ = std::make_unique<RootFrameSinkClientImpl>(this);
64 without_gpu_ =
65 base::MakeRefCounted<RootFrameSink>(root_frame_sink_client_.get());
66 }
67
~RootFrameSinkProxy()68 RootFrameSinkProxy::~RootFrameSinkProxy() {
69 DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_);
70 VizCompositorThreadRunnerWebView::GetInstance()->PostTaskAndBlock(
71 FROM_HERE, base::BindOnce(&RootFrameSinkProxy::DestroyOnViz,
72 base::Unretained(this)));
73 if (observing_bfs_)
74 begin_frame_source_->RemoveObserver(this);
75 }
76
DestroyOnViz()77 void RootFrameSinkProxy::DestroyOnViz() {
78 DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_);
79 without_gpu_->DettachClient();
80 without_gpu_.reset();
81 weak_ptr_factory_on_viz_.InvalidateWeakPtrs();
82 root_frame_sink_client_.reset();
83 }
84
SetNeedsBeginFramesOnViz(bool needs_begin_frames)85 void RootFrameSinkProxy::SetNeedsBeginFramesOnViz(bool needs_begin_frames) {
86 DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_);
87 ui_task_runner_->PostTask(
88 FROM_HERE,
89 base::BindOnce(&RootFrameSinkProxy::SetNeedsBeginFramesOnUI,
90 weak_ptr_factory_.GetWeakPtr(), needs_begin_frames));
91 }
92
SetNeedsBeginFramesOnUI(bool needs_begin_frames)93 void RootFrameSinkProxy::SetNeedsBeginFramesOnUI(bool needs_begin_frames) {
94 DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_);
95 if (observing_bfs_ == needs_begin_frames)
96 return;
97
98 observing_bfs_ = needs_begin_frames;
99
100 if (needs_begin_frames)
101 begin_frame_source_->AddObserver(this);
102 else
103 begin_frame_source_->RemoveObserver(this);
104 }
105
InvalidateOnViz()106 void RootFrameSinkProxy::InvalidateOnViz() {
107 DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_);
108 ui_task_runner_->PostTask(FROM_HERE,
109 base::BindOnce(&RootFrameSinkProxy::InvalidateOnUI,
110 weak_ptr_factory_.GetWeakPtr()));
111 }
112
InvalidateOnUI()113 void RootFrameSinkProxy::InvalidateOnUI() {
114 DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_);
115 client_->Invalidate();
116 }
117
AddChildFrameSinkId(const viz::FrameSinkId & frame_sink_id)118 void RootFrameSinkProxy::AddChildFrameSinkId(
119 const viz::FrameSinkId& frame_sink_id) {
120 DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_);
121 viz_task_runner_->PostTask(
122 FROM_HERE,
123 base::BindOnce(&RootFrameSinkProxy::AddChildFrameSinkIdOnViz,
124 weak_ptr_factory_on_viz_.GetWeakPtr(), frame_sink_id));
125 }
126
AddChildFrameSinkIdOnViz(const viz::FrameSinkId & frame_sink_id)127 void RootFrameSinkProxy::AddChildFrameSinkIdOnViz(
128 const viz::FrameSinkId& frame_sink_id) {
129 DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_);
130 without_gpu_->AddChildFrameSinkId(frame_sink_id);
131 }
132
RemoveChildFrameSinkId(const viz::FrameSinkId & frame_sink_id)133 void RootFrameSinkProxy::RemoveChildFrameSinkId(
134 const viz::FrameSinkId& frame_sink_id) {
135 DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_);
136 viz_task_runner_->PostTask(
137 FROM_HERE,
138 base::BindOnce(&RootFrameSinkProxy::RemoveChildFrameSinkIdOnViz,
139 weak_ptr_factory_on_viz_.GetWeakPtr(), frame_sink_id));
140 }
141
RemoveChildFrameSinkIdOnViz(const viz::FrameSinkId & frame_sink_id)142 void RootFrameSinkProxy::RemoveChildFrameSinkIdOnViz(
143 const viz::FrameSinkId& frame_sink_id) {
144 DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_);
145 without_gpu_->RemoveChildFrameSinkId(frame_sink_id);
146 }
147
OnInputEvent()148 void RootFrameSinkProxy::OnInputEvent() {
149 DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_);
150 had_input_event_ = true;
151 }
152
BeginFrame(const viz::BeginFrameArgs & args)153 bool RootFrameSinkProxy::BeginFrame(const viz::BeginFrameArgs& args) {
154 DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_);
155 bool invalidate = false;
156 VizCompositorThreadRunnerWebView::GetInstance()->PostTaskAndBlock(
157 FROM_HERE, base::BindOnce(&RootFrameSinkProxy::BeginFrameOnViz,
158 base::Unretained(this), args, had_input_event_,
159 &invalidate));
160 had_input_event_ = false;
161 return invalidate;
162 }
163
BeginFrameOnViz(const viz::BeginFrameArgs & args,bool had_input_event,bool * invalidate)164 void RootFrameSinkProxy::BeginFrameOnViz(const viz::BeginFrameArgs& args,
165 bool had_input_event,
166 bool* invalidate) {
167 DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_);
168 *invalidate = without_gpu_->BeginFrame(args, had_input_event);
169 }
170
SetBeginFrameSourcePausedOnViz(bool paused)171 void RootFrameSinkProxy::SetBeginFrameSourcePausedOnViz(bool paused) {
172 DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_);
173 without_gpu_->SetBeginFrameSourcePaused(paused);
174 }
175
GetRootFrameSinkCallback()176 RootFrameSinkGetter RootFrameSinkProxy::GetRootFrameSinkCallback() {
177 return base::BindRepeating(&RootFrameSinkProxy::GetRootFrameSinkHelper,
178 weak_ptr_factory_on_viz_.GetWeakPtr());
179 }
180
OnBeginFrameSourcePausedChanged(bool paused)181 void RootFrameSinkProxy::OnBeginFrameSourcePausedChanged(bool paused) {
182 DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_);
183 viz_task_runner_->PostTask(
184 FROM_HERE,
185 base::BindOnce(&RootFrameSinkProxy::SetBeginFrameSourcePausedOnViz,
186 weak_ptr_factory_on_viz_.GetWeakPtr(), paused));
187 }
188
OnBeginFrameDerivedImpl(const viz::BeginFrameArgs & args)189 bool RootFrameSinkProxy::OnBeginFrameDerivedImpl(
190 const viz::BeginFrameArgs& args) {
191 DCHECK(client_);
192 if (BeginFrame(args))
193 client_->Invalidate();
194
195 return true;
196 }
197
ReturnResourcesOnUI(viz::FrameSinkId frame_sink_id,uint32_t layer_tree_frame_sink_id,std::vector<viz::ReturnedResource> resources)198 void RootFrameSinkProxy::ReturnResourcesOnUI(
199 viz::FrameSinkId frame_sink_id,
200 uint32_t layer_tree_frame_sink_id,
201 std::vector<viz::ReturnedResource> resources) {
202 DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_);
203 client_->ReturnResourcesFromViz(frame_sink_id, layer_tree_frame_sink_id,
204 std::move(resources));
205 }
ReturnResourcesOnViz(viz::FrameSinkId frame_sink_id,uint32_t layer_tree_frame_sink_id,std::vector<viz::ReturnedResource> resources)206 void RootFrameSinkProxy::ReturnResourcesOnViz(
207 viz::FrameSinkId frame_sink_id,
208 uint32_t layer_tree_frame_sink_id,
209 std::vector<viz::ReturnedResource> resources) {
210 DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_);
211 ui_task_runner_->PostTask(
212 FROM_HERE,
213 base::BindOnce(&RootFrameSinkProxy::ReturnResourcesOnUI,
214 weak_ptr_factory_.GetWeakPtr(), frame_sink_id,
215 layer_tree_frame_sink_id, std::move(resources)));
216 }
217
218 } // namespace android_webview
219