Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / browser / android / in_process / synchronous_compositor_impl.cc
blob6fe045a9c97668cb5c0dafce7d3394526fca32e9
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/lazy_instance.h"
8 #include "base/message_loop/message_loop.h"
9 #include "cc/input/input_handler.h"
10 #include "content/browser/android/in_process/synchronous_compositor_factory_impl.h"
11 #include "content/browser/android/in_process/synchronous_input_event_filter.h"
12 #include "content/browser/renderer_host/render_widget_host_view_android.h"
13 #include "content/common/input/did_overscroll_params.h"
14 #include "content/public/browser/android/synchronous_compositor_client.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "ui/gl/gl_surface.h"
20 namespace content {
22 namespace {
24 int GetInProcessRendererId() {
25 content::RenderProcessHost::iterator it =
26 content::RenderProcessHost::AllHostsIterator();
27 if (it.IsAtEnd()) {
28 // There should always be one RPH in single process mode.
29 NOTREACHED();
30 return 0;
33 int id = it.GetCurrentValue()->GetID();
34 it.Advance();
35 DCHECK(it.IsAtEnd()); // Not multiprocess compatible.
36 return id;
39 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
40 LAZY_INSTANCE_INITIALIZER;
42 } // namespace
44 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl);
46 // static
47 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id,
48 int routing_id) {
49 if (g_factory == NULL)
50 return NULL;
51 RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id);
52 if (!rvh)
53 return NULL;
54 WebContents* contents = WebContents::FromRenderViewHost(rvh);
55 if (!contents)
56 return NULL;
57 return FromWebContents(contents);
60 SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID(
61 int routing_id) {
62 return FromID(GetInProcessRendererId(), routing_id);
65 SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents)
66 : compositor_client_(NULL),
67 output_surface_(NULL),
68 contents_(contents),
69 input_handler_(NULL),
70 weak_ptr_factory_(this) {
71 DCHECK(contents);
74 SynchronousCompositorImpl::~SynchronousCompositorImpl() {
75 if (compositor_client_)
76 compositor_client_->DidDestroyCompositor(this);
77 SetInputHandler(NULL);
80 void SynchronousCompositorImpl::SetClient(
81 SynchronousCompositorClient* compositor_client) {
82 DCHECK(CalledOnValidThread());
83 compositor_client_ = compositor_client;
86 // static
87 void SynchronousCompositor::SetGpuService(
88 scoped_refptr<gpu::InProcessCommandBuffer::Service> service) {
89 g_factory.Get().SetDeferredGpuService(service);
92 // static
93 void SynchronousCompositor::SetRecordFullDocument(bool record_full_document) {
94 g_factory.Get().SetRecordFullDocument(record_full_document);
97 bool SynchronousCompositorImpl::InitializeHwDraw() {
98 DCHECK(CalledOnValidThread());
99 DCHECK(output_surface_);
101 scoped_refptr<cc::ContextProvider> onscreen_context =
102 g_factory.Get().CreateOnscreenContextProviderForCompositorThread();
104 bool success = output_surface_->InitializeHwDraw(onscreen_context);
106 if (success)
107 g_factory.Get().CompositorInitializedHardwareDraw();
108 return success;
111 void SynchronousCompositorImpl::ReleaseHwDraw() {
112 DCHECK(CalledOnValidThread());
113 DCHECK(output_surface_);
114 output_surface_->ReleaseHwDraw();
115 g_factory.Get().CompositorReleasedHardwareDraw();
118 gpu::GLInProcessContext* SynchronousCompositorImpl::GetShareContext() {
119 DCHECK(CalledOnValidThread());
120 return g_factory.Get().GetShareContext();
123 scoped_ptr<cc::CompositorFrame> SynchronousCompositorImpl::DemandDrawHw(
124 gfx::Size surface_size,
125 const gfx::Transform& transform,
126 gfx::Rect viewport,
127 gfx::Rect clip,
128 gfx::Rect viewport_rect_for_tile_priority,
129 const gfx::Transform& transform_for_tile_priority) {
130 DCHECK(CalledOnValidThread());
131 DCHECK(output_surface_);
133 scoped_ptr<cc::CompositorFrame> frame =
134 output_surface_->DemandDrawHw(surface_size,
135 transform,
136 viewport,
137 clip,
138 viewport_rect_for_tile_priority,
139 transform_for_tile_priority);
140 if (frame.get())
141 UpdateFrameMetaData(frame->metadata);
143 return frame.Pass();
146 void SynchronousCompositorImpl::ReturnResources(
147 const cc::CompositorFrameAck& frame_ack) {
148 DCHECK(CalledOnValidThread());
149 output_surface_->ReturnResources(frame_ack);
152 bool SynchronousCompositorImpl::DemandDrawSw(SkCanvas* canvas) {
153 DCHECK(CalledOnValidThread());
154 DCHECK(output_surface_);
156 scoped_ptr<cc::CompositorFrame> frame = output_surface_->DemandDrawSw(canvas);
157 if (frame.get())
158 UpdateFrameMetaData(frame->metadata);
159 return !!frame.get();
162 void SynchronousCompositorImpl::UpdateFrameMetaData(
163 const cc::CompositorFrameMetadata& frame_metadata) {
164 RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>(
165 contents_->GetRenderWidgetHostView());
166 if (rwhv)
167 rwhv->SynchronousFrameMetadata(frame_metadata);
168 DeliverMessages();
171 void SynchronousCompositorImpl::SetMemoryPolicy(
172 const SynchronousCompositorMemoryPolicy& policy) {
173 DCHECK(CalledOnValidThread());
174 DCHECK(output_surface_);
176 output_surface_->SetMemoryPolicy(policy);
179 void SynchronousCompositorImpl::DidChangeRootLayerScrollOffset() {
180 if (input_handler_)
181 input_handler_->OnRootLayerDelegatedScrollOffsetChanged();
184 void SynchronousCompositorImpl::DidBindOutputSurface(
185 SynchronousCompositorOutputSurface* output_surface) {
186 DCHECK(CalledOnValidThread());
187 output_surface_ = output_surface;
188 if (compositor_client_)
189 compositor_client_->DidInitializeCompositor(this);
192 void SynchronousCompositorImpl::DidDestroySynchronousOutputSurface(
193 SynchronousCompositorOutputSurface* output_surface) {
194 DCHECK(CalledOnValidThread());
196 // Allow for transient hand-over when two output surfaces may refer to
197 // a single delegate.
198 if (output_surface_ == output_surface) {
199 output_surface_ = NULL;
200 if (compositor_client_)
201 compositor_client_->DidDestroyCompositor(this);
202 compositor_client_ = NULL;
206 void SynchronousCompositorImpl::SetInputHandler(
207 cc::InputHandler* input_handler) {
208 DCHECK(CalledOnValidThread());
210 if (input_handler_)
211 input_handler_->SetRootLayerScrollOffsetDelegate(NULL);
213 input_handler_ = input_handler;
215 if (input_handler_)
216 input_handler_->SetRootLayerScrollOffsetDelegate(this);
219 void SynchronousCompositorImpl::DidOverscroll(
220 const DidOverscrollParams& params) {
221 if (compositor_client_) {
222 compositor_client_->DidOverscroll(params.accumulated_overscroll,
223 params.latest_overscroll_delta,
224 params.current_fling_velocity);
228 void SynchronousCompositorImpl::DidStopFlinging() {
229 RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>(
230 contents_->GetRenderWidgetHostView());
231 if (rwhv)
232 rwhv->DidStopFlinging();
235 void SynchronousCompositorImpl::SetContinuousInvalidate(bool enable) {
236 DCHECK(CalledOnValidThread());
237 if (compositor_client_)
238 compositor_client_->SetContinuousInvalidate(enable);
241 InputEventAckState SynchronousCompositorImpl::HandleInputEvent(
242 const blink::WebInputEvent& input_event) {
243 DCHECK(CalledOnValidThread());
244 return g_factory.Get().synchronous_input_event_filter()->HandleInputEvent(
245 contents_->GetRoutingID(), input_event);
248 void SynchronousCompositorImpl::DeliverMessages() {
249 ScopedVector<IPC::Message> messages;
250 output_surface_->GetMessagesToDeliver(&messages);
251 RenderProcessHost* rph = contents_->GetRenderProcessHost();
252 for (ScopedVector<IPC::Message>::const_iterator i = messages.begin();
253 i != messages.end();
254 ++i) {
255 rph->OnMessageReceived(**i);
259 void SynchronousCompositorImpl::DidActivatePendingTree() {
260 if (compositor_client_)
261 compositor_client_->DidUpdateContent();
264 gfx::Vector2dF SynchronousCompositorImpl::GetTotalScrollOffset() {
265 DCHECK(CalledOnValidThread());
266 if (compositor_client_)
267 return compositor_client_->GetTotalRootLayerScrollOffset();
268 return gfx::Vector2dF();
271 bool SynchronousCompositorImpl::IsExternalFlingActive() const {
272 DCHECK(CalledOnValidThread());
273 if (compositor_client_)
274 return compositor_client_->IsExternalFlingActive();
275 return false;
278 void SynchronousCompositorImpl::UpdateRootLayerState(
279 const gfx::Vector2dF& total_scroll_offset,
280 const gfx::Vector2dF& max_scroll_offset,
281 const gfx::SizeF& scrollable_size,
282 float page_scale_factor,
283 float min_page_scale_factor,
284 float max_page_scale_factor) {
285 DCHECK(CalledOnValidThread());
286 if (!compositor_client_)
287 return;
289 compositor_client_->UpdateRootLayerState(total_scroll_offset,
290 max_scroll_offset,
291 scrollable_size,
292 page_scale_factor,
293 min_page_scale_factor,
294 max_page_scale_factor);
297 // Not using base::NonThreadSafe as we want to enforce a more exacting threading
298 // requirement: SynchronousCompositorImpl() must only be used on the UI thread.
299 bool SynchronousCompositorImpl::CalledOnValidThread() const {
300 return BrowserThread::CurrentlyOn(BrowserThread::UI);
303 // static
304 void SynchronousCompositor::SetClientForWebContents(
305 WebContents* contents,
306 SynchronousCompositorClient* client) {
307 DCHECK(contents);
308 if (client) {
309 g_factory.Get(); // Ensure it's initialized.
310 SynchronousCompositorImpl::CreateForWebContents(contents);
312 if (SynchronousCompositorImpl* instance =
313 SynchronousCompositorImpl::FromWebContents(contents)) {
314 instance->SetClient(client);
318 } // namespace content