Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: content/browser/android/in_process/synchronous_compositor_impl.cc

Issue 1838853005: android: Remove in-process sync compositor code path (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@remove_in_proc_video
Patch Set: rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 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 "content/browser/android/in_process/synchronous_compositor_impl.h"
6
7 #include <utility>
8
9 #include "base/auto_reset.h"
10 #include "base/bind.h"
11 #include "base/lazy_instance.h"
12 #include "base/message_loop/message_loop.h"
13 #include "content/browser/android/in_process/synchronous_compositor_factory_impl .h"
14 #include "content/browser/android/in_process/synchronous_compositor_registry_in_ proc.h"
15 #include "content/browser/android/in_process/synchronous_input_event_filter.h"
16 #include "content/browser/gpu/gpu_process_host.h"
17 #include "content/browser/renderer_host/render_widget_host_view_android.h"
18 #include "content/common/input/did_overscroll_params.h"
19 #include "content/common/input_messages.h"
20 #include "content/public/browser/android/synchronous_compositor_client.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/render_process_host.h"
23 #include "content/public/browser/render_view_host.h"
24 #include "content/public/browser/render_widget_host.h"
25 #include "content/public/common/child_process_host.h"
26 #include "ui/gfx/geometry/scroll_offset.h"
27 #include "ui/gl/gl_surface.h"
28
29 namespace content {
30
31 namespace {
32
33 int g_process_id = ChildProcessHost::kInvalidUniqueID;
34
35 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
36 LAZY_INSTANCE_INITIALIZER;
37
38 } // namespace
39
40 SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID(
41 int routing_id) {
42 if (g_factory == nullptr)
43 return nullptr;
44 if (g_process_id == ChildProcessHost::kInvalidUniqueID)
45 return nullptr;
46 RenderViewHost* rvh = RenderViewHost::FromID(g_process_id, routing_id);
47 if (!rvh)
48 return nullptr;
49 RenderWidgetHostViewAndroid* rwhva =
50 static_cast<RenderWidgetHostViewAndroid*>(rvh->GetWidget()->GetView());
51 if (!rwhva)
52 return nullptr;
53 return static_cast<SynchronousCompositorImpl*>(
54 rwhva->GetSynchronousCompositor());
55 }
56
57 SynchronousCompositorImpl::SynchronousCompositorImpl(
58 RenderWidgetHostViewAndroid* rwhva,
59 SynchronousCompositorClient* client)
60 : rwhva_(rwhva),
61 routing_id_(rwhva_->GetRenderWidgetHost()->GetRoutingID()),
62 compositor_client_(client),
63 output_surface_(nullptr),
64 begin_frame_source_(nullptr),
65 synchronous_input_handler_proxy_(nullptr),
66 registered_with_client_(false),
67 is_active_(true),
68 renderer_needs_begin_frames_(false),
69 need_animate_input_(false),
70 weak_ptr_factory_(this) {
71 DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
72 g_factory.Get(); // Ensure it's initialized.
73
74 int process_id = rwhva_->GetRenderWidgetHost()->GetProcess()->GetID();
75 if (g_process_id == ChildProcessHost::kInvalidUniqueID) {
76 g_process_id = process_id;
77 } else {
78 DCHECK_EQ(g_process_id, process_id); // Not multiprocess compatible.
79 }
80
81 SynchronousCompositorRegistryInProc::GetInstance()->RegisterCompositor(
82 routing_id_, this);
83 }
84
85 SynchronousCompositorImpl::~SynchronousCompositorImpl() {
86 SynchronousCompositorRegistryInProc::GetInstance()->UnregisterCompositor(
87 routing_id_, this);
88 }
89
90 void SynchronousCompositorImpl::RegisterWithClient() {
91 DCHECK(CalledOnValidThread());
92 DCHECK(output_surface_);
93 DCHECK(synchronous_input_handler_proxy_);
94 DCHECK(!registered_with_client_);
95 registered_with_client_ = true;
96
97 compositor_client_->DidInitializeCompositor(this);
98 compositor_client_->DidBecomeCurrent(this);
99
100 output_surface_->SetTreeActivationCallback(
101 base::Bind(&SynchronousCompositorImpl::DidActivatePendingTree,
102 weak_ptr_factory_.GetWeakPtr()));
103
104 // This disables the input system from animating inputs autonomously, instead
105 // routing all input animations through the SynchronousInputHandler, which is
106 // |this| class. Calling this causes an UpdateRootLayerState() immediately so,
107 // do it after setting the client.
108 synchronous_input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(this);
109 }
110
111 void SynchronousCompositorImpl::DidInitializeRendererObjects(
112 SynchronousCompositorOutputSurface* output_surface,
113 SynchronousCompositorExternalBeginFrameSource* begin_frame_source,
114 ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
115 DCHECK(!output_surface_);
116 DCHECK(!begin_frame_source_);
117 DCHECK(output_surface);
118 DCHECK(begin_frame_source);
119 DCHECK(synchronous_input_handler_proxy);
120
121 output_surface_ = output_surface;
122 begin_frame_source_ = begin_frame_source;
123 synchronous_input_handler_proxy_ = synchronous_input_handler_proxy;
124
125 output_surface_->SetSyncClient(this);
126 begin_frame_source_->SetClient(this);
127 begin_frame_source_->SetBeginFrameSourcePaused(!is_active_);
128 }
129
130 void SynchronousCompositorImpl::DidDestroyRendererObjects() {
131 DCHECK(output_surface_);
132 DCHECK(begin_frame_source_);
133
134 if (registered_with_client_) {
135 output_surface_->SetTreeActivationCallback(base::Closure());
136 compositor_client_->DidDestroyCompositor(this);
137 registered_with_client_ = false;
138 }
139
140 // This object is being destroyed, so remove pointers to it.
141 begin_frame_source_->SetClient(nullptr);
142 output_surface_->SetSyncClient(nullptr);
143 synchronous_input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(
144 nullptr);
145
146 synchronous_input_handler_proxy_ = nullptr;
147 begin_frame_source_ = nullptr;
148 output_surface_ = nullptr;
149 // Don't propogate this signal from one renderer to the next.
150 need_animate_input_ = false;
151 }
152
153 SynchronousCompositor::Frame SynchronousCompositorImpl::DemandDrawHw(
154 const gfx::Size& surface_size,
155 const gfx::Transform& transform,
156 const gfx::Rect& viewport,
157 const gfx::Rect& clip,
158 const gfx::Rect& viewport_rect_for_tile_priority,
159 const gfx::Transform& transform_for_tile_priority) {
160 DCHECK(CalledOnValidThread());
161 DCHECK(output_surface_);
162 DCHECK(begin_frame_source_);
163 DCHECK(!frame_holder_.frame);
164
165 output_surface_->DemandDrawHw(surface_size, transform, viewport, clip,
166 viewport_rect_for_tile_priority,
167 transform_for_tile_priority);
168
169 if (frame_holder_.frame)
170 UpdateFrameMetaData(frame_holder_.frame->metadata);
171
172 return std::move(frame_holder_);
173 }
174
175 void SynchronousCompositorImpl::ReturnResources(
176 uint32_t output_surface_id,
177 const cc::CompositorFrameAck& frame_ack) {
178 DCHECK(CalledOnValidThread());
179 output_surface_->ReturnResources(output_surface_id, frame_ack);
180 }
181
182 bool SynchronousCompositorImpl::DemandDrawSw(SkCanvas* canvas) {
183 DCHECK(CalledOnValidThread());
184 DCHECK(output_surface_);
185 DCHECK(begin_frame_source_);
186 DCHECK(!frame_holder_.frame);
187
188 output_surface_->DemandDrawSw(canvas);
189
190 bool success = !!frame_holder_.frame;
191 if (frame_holder_.frame) {
192 UpdateFrameMetaData(frame_holder_.frame->metadata);
193 frame_holder_.frame.reset();
194 }
195
196 return success;
197 }
198
199 void SynchronousCompositorImpl::SwapBuffers(uint32_t output_surface_id,
200 cc::CompositorFrame* frame) {
201 DCHECK(!frame_holder_.frame);
202 frame_holder_.output_surface_id = output_surface_id;
203 frame_holder_.frame.reset(new cc::CompositorFrame);
204 frame->AssignTo(frame_holder_.frame.get());
205 }
206
207 void SynchronousCompositorImpl::UpdateFrameMetaData(
208 const cc::CompositorFrameMetadata& frame_metadata) {
209 rwhva_->SynchronousFrameMetadata(frame_metadata);
210 DeliverMessages();
211 }
212
213 void SynchronousCompositorImpl::SetMemoryPolicy(size_t bytes_limit) {
214 DCHECK(CalledOnValidThread());
215 DCHECK(output_surface_);
216 output_surface_->SetMemoryPolicy(bytes_limit);
217 }
218
219 void SynchronousCompositorImpl::Invalidate() {
220 DCHECK(CalledOnValidThread());
221 if (registered_with_client_)
222 compositor_client_->PostInvalidate();
223 }
224
225 void SynchronousCompositorImpl::DidChangeRootLayerScrollOffset(
226 const gfx::ScrollOffset& root_offset) {
227 DCHECK(CalledOnValidThread());
228 if (!synchronous_input_handler_proxy_)
229 return;
230 synchronous_input_handler_proxy_->SynchronouslySetRootScrollOffset(
231 root_offset);
232 }
233
234 void SynchronousCompositorImpl::SynchronouslyZoomBy(float zoom_delta,
235 const gfx::Point& anchor) {
236 DCHECK(CalledOnValidThread());
237 if (!synchronous_input_handler_proxy_)
238 return;
239 synchronous_input_handler_proxy_->SynchronouslyZoomBy(zoom_delta, anchor);
240 }
241
242 void SynchronousCompositorImpl::SetIsActive(bool is_active) {
243 TRACE_EVENT1("cc", "SynchronousCompositorImpl::SetIsActive", "is_active",
244 is_active);
245 if (is_active_ == is_active)
246 return;
247
248 is_active_ = is_active;
249 UpdateNeedsBeginFrames();
250 if (begin_frame_source_)
251 begin_frame_source_->SetBeginFrameSourcePaused(!is_active_);
252 }
253
254 void SynchronousCompositorImpl::OnComputeScroll(
255 base::TimeTicks animation_time) {
256 if (need_animate_input_) {
257 need_animate_input_ = false;
258 synchronous_input_handler_proxy_->SynchronouslyAnimate(animation_time);
259 }
260 }
261
262 void SynchronousCompositorImpl::OnNeedsBeginFramesChange(
263 bool needs_begin_frames) {
264 renderer_needs_begin_frames_ = needs_begin_frames;
265 UpdateNeedsBeginFrames();
266 }
267
268 void SynchronousCompositorImpl::BeginFrame(const cc::BeginFrameArgs& args) {
269 if (!registered_with_client_ && is_active_ && renderer_needs_begin_frames_) {
270 // Make sure this is a BeginFrame that renderer side explicitly requested.
271 // Otherwise it is possible renderer objects not initialized.
272 RegisterWithClient();
273 DCHECK(registered_with_client_);
274 }
275 if (begin_frame_source_)
276 begin_frame_source_->BeginFrame(args);
277 }
278
279 void SynchronousCompositorImpl::UpdateNeedsBeginFrames() {
280 rwhva_->OnSetNeedsBeginFrames(is_active_ && renderer_needs_begin_frames_);
281 }
282
283 void SynchronousCompositorImpl::DidOverscrollInProcess(
284 const DidOverscrollParams& params) {
285 if (registered_with_client_) {
286 compositor_client_->DidOverscroll(params.accumulated_overscroll,
287 params.latest_overscroll_delta,
288 params.current_fling_velocity);
289 }
290 }
291
292 void SynchronousCompositorImpl::DidStopFlinging() {
293 // It's important that the fling-end notification follow the same path as it
294 // takes on other platforms (using an IPC). This ensures consistent
295 // bookkeeping at all stages of the input pipeline.
296 rwhva_->GetRenderWidgetHost()->GetProcess()->OnMessageReceived(
297 InputHostMsg_DidStopFlinging(routing_id_));
298 }
299
300 InputEventAckState SynchronousCompositorImpl::HandleInputEvent(
301 const blink::WebInputEvent& input_event) {
302 DCHECK(CalledOnValidThread());
303 return g_factory.Get().synchronous_input_event_filter()->HandleInputEvent(
304 routing_id_, input_event);
305 }
306
307 void SynchronousCompositorImpl::DidOverscroll(
308 const DidOverscrollParams& params) {
309 // SynchronousCompositorImpl uses synchronous DidOverscrollInProcess for
310 // overscroll instead of this async path.
311 NOTREACHED();
312 }
313
314 bool SynchronousCompositorImpl::OnMessageReceived(const IPC::Message& message) {
315 NOTREACHED();
316 return false;
317 }
318
319 void SynchronousCompositorImpl::DidBecomeCurrent() {
320 // This is single process synchronous compositor. There is only one
321 // RenderViewHost. DidBecomeCurrent could be called before the renderer
322 // objects are initialized. So hold off calling DidBecomeCurrent until
323 // RegisterWithClient. Intentional no-op here.
324 }
325
326 void SynchronousCompositorImpl::DeliverMessages() {
327 std::vector<std::unique_ptr<IPC::Message>> messages;
328 output_surface_->GetMessagesToDeliver(&messages);
329 RenderProcessHost* rph = rwhva_->GetRenderWidgetHost()->GetProcess();
330 for (const auto& msg : messages) {
331 rph->OnMessageReceived(*msg);
332 }
333 }
334
335 void SynchronousCompositorImpl::DidActivatePendingTree() {
336 if (registered_with_client_)
337 compositor_client_->DidUpdateContent();
338 DeliverMessages();
339 }
340
341 void SynchronousCompositorImpl::SetNeedsSynchronousAnimateInput() {
342 DCHECK(CalledOnValidThread());
343 if (!registered_with_client_)
344 return;
345 need_animate_input_ = true;
346 compositor_client_->PostInvalidate();
347 }
348
349 void SynchronousCompositorImpl::UpdateRootLayerState(
350 const gfx::ScrollOffset& total_scroll_offset,
351 const gfx::ScrollOffset& max_scroll_offset,
352 const gfx::SizeF& scrollable_size,
353 float page_scale_factor,
354 float min_page_scale_factor,
355 float max_page_scale_factor) {
356 DCHECK(CalledOnValidThread());
357
358 if (registered_with_client_) {
359 // TODO(miletus): Pass in ScrollOffset. crbug.com/414283.
360 compositor_client_->UpdateRootLayerState(
361 gfx::ScrollOffsetToVector2dF(total_scroll_offset),
362 gfx::ScrollOffsetToVector2dF(max_scroll_offset),
363 scrollable_size,
364 page_scale_factor,
365 min_page_scale_factor,
366 max_page_scale_factor);
367 }
368 }
369
370 // Not using base::NonThreadSafe as we want to enforce a more exacting threading
371 // requirement: SynchronousCompositorImpl() must only be used on the UI thread.
372 bool SynchronousCompositorImpl::CalledOnValidThread() const {
373 return BrowserThread::CurrentlyOn(BrowserThread::UI);
374 }
375
376 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698