Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / content / browser / android / in_process / synchronous_compositor_impl.cc
blobf8701c1a00af71945d2af9cb96164ffda94dc0ef
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.
5 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
7 #include "base/auto_reset.h"
8 #include "base/bind.h"
9 #include "base/lazy_instance.h"
10 #include "base/message_loop/message_loop.h"
11 #include "cc/input/input_handler.h"
12 #include "content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h"
13 #include "content/browser/android/in_process/synchronous_compositor_factory_impl.h"
14 #include "content/browser/android/in_process/synchronous_compositor_registry.h"
15 #include "content/browser/android/in_process/synchronous_input_event_filter.h"
16 #include "content/browser/renderer_host/render_widget_host_view_android.h"
17 #include "content/common/input/did_overscroll_params.h"
18 #include "content/public/browser/android/synchronous_compositor_client.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/render_process_host.h"
21 #include "content/public/browser/render_view_host.h"
22 #include "ui/gl/gl_surface.h"
24 namespace content {
26 namespace {
28 int GetInProcessRendererId() {
29 content::RenderProcessHost::iterator it =
30 content::RenderProcessHost::AllHostsIterator();
31 if (it.IsAtEnd()) {
32 // There should always be one RPH in single process mode.
33 NOTREACHED();
34 return 0;
37 int id = it.GetCurrentValue()->GetID();
38 it.Advance();
39 DCHECK(it.IsAtEnd()); // Not multiprocess compatible.
40 return id;
43 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
44 LAZY_INSTANCE_INITIALIZER;
46 } // namespace
48 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl);
50 // static
51 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id,
52 int routing_id) {
53 if (g_factory == NULL)
54 return NULL;
55 RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id);
56 if (!rvh)
57 return NULL;
58 WebContents* contents = WebContents::FromRenderViewHost(rvh);
59 if (!contents)
60 return NULL;
61 return FromWebContents(contents);
64 SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID(
65 int routing_id) {
66 return FromID(GetInProcessRendererId(), routing_id);
69 SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents)
70 : compositor_client_(NULL),
71 output_surface_(NULL),
72 begin_frame_source_(nullptr),
73 contents_(contents),
74 routing_id_(contents->GetRoutingID()),
75 input_handler_(NULL),
76 is_active_(false),
77 renderer_needs_begin_frames_(false),
78 weak_ptr_factory_(this) {
79 DCHECK(contents);
80 DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
81 SynchronousCompositorRegistry::GetInstance()->RegisterCompositor(routing_id_,
82 this);
85 SynchronousCompositorImpl::~SynchronousCompositorImpl() {
86 SynchronousCompositorRegistry::GetInstance()->UnregisterCompositor(
87 routing_id_, this);
89 DCHECK(!output_surface_);
90 DCHECK(!begin_frame_source_);
91 DCHECK(!input_handler_);
94 void SynchronousCompositorImpl::SetClient(
95 SynchronousCompositorClient* compositor_client) {
96 DCHECK(CalledOnValidThread());
97 compositor_client_ = compositor_client;
100 // static
101 void SynchronousCompositor::SetGpuService(
102 scoped_refptr<gpu::InProcessCommandBuffer::Service> service) {
103 g_factory.Get().SetDeferredGpuService(service);
106 // static
107 void SynchronousCompositor::SetRecordFullDocument(bool record_full_document) {
108 g_factory.Get().SetRecordFullDocument(record_full_document);
111 void SynchronousCompositorImpl::DidInitializeRendererObjects(
112 SynchronousCompositorOutputSurface* output_surface,
113 SynchronousCompositorExternalBeginFrameSource* begin_frame_source,
114 cc::InputHandler* input_handler) {
115 DCHECK(!output_surface_);
116 DCHECK(!begin_frame_source_);
117 DCHECK(output_surface);
118 DCHECK(begin_frame_source);
119 DCHECK(compositor_client_);
120 DCHECK(input_handler);
122 output_surface_ = output_surface;
123 begin_frame_source_ = begin_frame_source;
125 begin_frame_source_->SetCompositor(this);
126 output_surface_->SetCompositor(this);
128 output_surface_->SetTreeActivationCallback(
129 base::Bind(&SynchronousCompositorImpl::DidActivatePendingTree,
130 weak_ptr_factory_.GetWeakPtr()));
132 OnNeedsBeginFramesChange(begin_frame_source_->NeedsBeginFrames());
134 compositor_client_->DidInitializeCompositor(this);
136 SetInputHandler(input_handler);
139 void SynchronousCompositorImpl::DidDestroyRendererObjects() {
140 DCHECK(output_surface_);
141 DCHECK(begin_frame_source_);
143 begin_frame_source_->SetCompositor(nullptr);
144 output_surface_->SetCompositor(nullptr);
145 if (compositor_client_)
146 compositor_client_->DidDestroyCompositor(this);
147 compositor_client_ = nullptr;
148 output_surface_ = nullptr;
149 begin_frame_source_ = nullptr;
150 SetInputHandler(nullptr);
153 void SynchronousCompositorImpl::NotifyDidDestroyCompositorToClient() {
154 if (compositor_client_)
155 compositor_client_->DidDestroyCompositor(this);
156 compositor_client_ = nullptr;
159 scoped_ptr<cc::CompositorFrame> SynchronousCompositorImpl::DemandDrawHw(
160 gfx::Size surface_size,
161 const gfx::Transform& transform,
162 gfx::Rect viewport,
163 gfx::Rect clip,
164 gfx::Rect viewport_rect_for_tile_priority,
165 const gfx::Transform& transform_for_tile_priority) {
166 DCHECK(CalledOnValidThread());
167 DCHECK(output_surface_);
168 DCHECK(compositor_client_);
169 DCHECK(begin_frame_source_);
171 scoped_ptr<cc::CompositorFrame> frame =
172 output_surface_->DemandDrawHw(surface_size,
173 transform,
174 viewport,
175 clip,
176 viewport_rect_for_tile_priority,
177 transform_for_tile_priority);
179 if (frame.get())
180 UpdateFrameMetaData(frame->metadata);
182 return frame.Pass();
185 void SynchronousCompositorImpl::ReturnResources(
186 const cc::CompositorFrameAck& frame_ack) {
187 DCHECK(CalledOnValidThread());
188 output_surface_->ReturnResources(frame_ack);
191 bool SynchronousCompositorImpl::DemandDrawSw(SkCanvas* canvas) {
192 DCHECK(CalledOnValidThread());
193 DCHECK(output_surface_);
194 DCHECK(compositor_client_);
195 DCHECK(begin_frame_source_);
197 scoped_ptr<cc::CompositorFrame> frame =
198 output_surface_->DemandDrawSw(canvas);
200 if (frame.get())
201 UpdateFrameMetaData(frame->metadata);
203 return !!frame.get();
206 void SynchronousCompositorImpl::UpdateFrameMetaData(
207 const cc::CompositorFrameMetadata& frame_metadata) {
208 RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>(
209 contents_->GetRenderWidgetHostView());
210 if (rwhv)
211 rwhv->SynchronousFrameMetadata(frame_metadata);
212 DeliverMessages();
215 void SynchronousCompositorImpl::SetMemoryPolicy(size_t bytes_limit) {
216 DCHECK(CalledOnValidThread());
217 DCHECK(output_surface_);
219 size_t current_bytes_limit = output_surface_->GetMemoryPolicy();
220 output_surface_->SetMemoryPolicy(bytes_limit);
222 if (bytes_limit && !current_bytes_limit) {
223 g_factory.Get().CompositorInitializedHardwareDraw();
224 } else if (!bytes_limit && current_bytes_limit) {
225 g_factory.Get().CompositorReleasedHardwareDraw();
229 void SynchronousCompositorImpl::PostInvalidate() {
230 DCHECK(CalledOnValidThread());
231 DCHECK(compositor_client_);
232 compositor_client_->PostInvalidate();
235 void SynchronousCompositorImpl::DidChangeRootLayerScrollOffset() {
236 if (input_handler_)
237 input_handler_->OnRootLayerDelegatedScrollOffsetChanged();
240 void SynchronousCompositorImpl::SetIsActive(bool is_active) {
241 TRACE_EVENT1("cc", "SynchronousCompositorImpl::SetIsActive", "is_active",
242 is_active);
243 is_active_ = is_active;
244 UpdateNeedsBeginFrames();
247 void SynchronousCompositorImpl::OnNeedsBeginFramesChange(
248 bool needs_begin_frames) {
249 renderer_needs_begin_frames_ = needs_begin_frames;
250 UpdateNeedsBeginFrames();
253 void SynchronousCompositorImpl::BeginFrame(const cc::BeginFrameArgs& args) {
254 if (begin_frame_source_)
255 begin_frame_source_->BeginFrame(args);
258 void SynchronousCompositorImpl::UpdateNeedsBeginFrames() {
259 RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>(
260 contents_->GetRenderWidgetHostView());
261 if (rwhv)
262 rwhv->OnSetNeedsBeginFrames(is_active_ && renderer_needs_begin_frames_);
265 void SynchronousCompositorImpl::SetInputHandler(
266 cc::InputHandler* input_handler) {
267 DCHECK(CalledOnValidThread());
269 if (input_handler_)
270 input_handler_->SetRootLayerScrollOffsetDelegate(NULL);
272 input_handler_ = input_handler;
274 if (input_handler_)
275 input_handler_->SetRootLayerScrollOffsetDelegate(this);
278 void SynchronousCompositorImpl::DidOverscroll(
279 const DidOverscrollParams& params) {
280 if (compositor_client_) {
281 compositor_client_->DidOverscroll(params.accumulated_overscroll,
282 params.latest_overscroll_delta,
283 params.current_fling_velocity);
287 void SynchronousCompositorImpl::DidStopFlinging() {
288 RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>(
289 contents_->GetRenderWidgetHostView());
290 if (rwhv)
291 rwhv->DidStopFlinging();
294 InputEventAckState SynchronousCompositorImpl::HandleInputEvent(
295 const blink::WebInputEvent& input_event) {
296 DCHECK(CalledOnValidThread());
297 return g_factory.Get().synchronous_input_event_filter()->HandleInputEvent(
298 contents_->GetRoutingID(), input_event);
301 void SynchronousCompositorImpl::DeliverMessages() {
302 ScopedVector<IPC::Message> messages;
303 output_surface_->GetMessagesToDeliver(&messages);
304 RenderProcessHost* rph = contents_->GetRenderProcessHost();
305 for (ScopedVector<IPC::Message>::const_iterator i = messages.begin();
306 i != messages.end();
307 ++i) {
308 rph->OnMessageReceived(**i);
312 void SynchronousCompositorImpl::DidActivatePendingTree() {
313 if (compositor_client_)
314 compositor_client_->DidUpdateContent();
317 gfx::ScrollOffset SynchronousCompositorImpl::GetTotalScrollOffset() {
318 DCHECK(CalledOnValidThread());
319 if (compositor_client_) {
320 // TODO(miletus): Make GetTotalRootLayerScrollOffset return
321 // ScrollOffset. crbug.com/414283.
322 return gfx::ScrollOffset(
323 compositor_client_->GetTotalRootLayerScrollOffset());
325 return gfx::ScrollOffset();
328 bool SynchronousCompositorImpl::IsExternalFlingActive() const {
329 DCHECK(CalledOnValidThread());
330 if (compositor_client_)
331 return compositor_client_->IsExternalFlingActive();
332 return false;
335 void SynchronousCompositorImpl::UpdateRootLayerState(
336 const gfx::ScrollOffset& total_scroll_offset,
337 const gfx::ScrollOffset& max_scroll_offset,
338 const gfx::SizeF& scrollable_size,
339 float page_scale_factor,
340 float min_page_scale_factor,
341 float max_page_scale_factor) {
342 DCHECK(CalledOnValidThread());
343 if (!compositor_client_)
344 return;
346 // TODO(miletus): Pass in ScrollOffset. crbug.com/414283.
347 compositor_client_->UpdateRootLayerState(
348 gfx::ScrollOffsetToVector2dF(total_scroll_offset),
349 gfx::ScrollOffsetToVector2dF(max_scroll_offset),
350 scrollable_size,
351 page_scale_factor,
352 min_page_scale_factor,
353 max_page_scale_factor);
356 // Not using base::NonThreadSafe as we want to enforce a more exacting threading
357 // requirement: SynchronousCompositorImpl() must only be used on the UI thread.
358 bool SynchronousCompositorImpl::CalledOnValidThread() const {
359 return BrowserThread::CurrentlyOn(BrowserThread::UI);
362 // static
363 void SynchronousCompositor::SetClientForWebContents(
364 WebContents* contents,
365 SynchronousCompositorClient* client) {
366 DCHECK(contents);
367 if (client) {
368 g_factory.Get(); // Ensure it's initialized.
369 SynchronousCompositorImpl::CreateForWebContents(contents);
371 SynchronousCompositorImpl* instance =
372 SynchronousCompositorImpl::FromWebContents(contents);
373 DCHECK(instance);
374 instance->SetClient(client);
377 } // namespace content