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

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

Issue 1150423003: webview: Initialize synchronous compositor after first activation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix broken tests Created 5 years, 6 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
« no previous file with comments | « content/browser/android/in_process/synchronous_compositor_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/android/in_process/synchronous_compositor_impl.h" 5 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory = 44 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
45 LAZY_INSTANCE_INITIALIZER; 45 LAZY_INSTANCE_INITIALIZER;
46 46
47 } // namespace 47 } // namespace
48 48
49 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl); 49 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl);
50 50
51 // static 51 // static
52 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id, 52 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id,
53 int routing_id) { 53 int routing_id) {
54 if (g_factory == NULL) 54 if (g_factory == nullptr)
55 return NULL; 55 return nullptr;
56 RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id); 56 RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id);
57 if (!rvh) 57 if (!rvh)
58 return NULL; 58 return nullptr;
59 WebContents* contents = WebContents::FromRenderViewHost(rvh); 59 WebContents* contents = WebContents::FromRenderViewHost(rvh);
60 if (!contents) 60 if (!contents)
61 return NULL; 61 return nullptr;
62 return FromWebContents(contents); 62 return FromWebContents(contents);
63 } 63 }
64 64
65 SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID( 65 SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID(
66 int routing_id) { 66 int routing_id) {
67 return FromID(GetInProcessRendererId(), routing_id); 67 return FromID(GetInProcessRendererId(), routing_id);
68 } 68 }
69 69
70 SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents) 70 SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents)
71 : compositor_client_(NULL), 71 : compositor_client_(nullptr),
72 output_surface_(NULL), 72 output_surface_(nullptr),
73 begin_frame_source_(nullptr), 73 begin_frame_source_(nullptr),
74 contents_(contents), 74 contents_(contents),
75 routing_id_(contents->GetRoutingID()), 75 routing_id_(contents->GetRoutingID()),
76 input_handler_(NULL), 76 input_handler_(nullptr),
77 is_active_(false), 77 registered_with_client_(false),
78 is_active_(true),
78 renderer_needs_begin_frames_(false), 79 renderer_needs_begin_frames_(false),
79 weak_ptr_factory_(this) { 80 weak_ptr_factory_(this) {
80 DCHECK(contents); 81 DCHECK(contents);
81 DCHECK_NE(routing_id_, MSG_ROUTING_NONE); 82 DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
82 } 83 }
83 84
84 SynchronousCompositorImpl::~SynchronousCompositorImpl() { 85 SynchronousCompositorImpl::~SynchronousCompositorImpl() {
85 DCHECK(!output_surface_); 86 DCHECK(!output_surface_);
86 DCHECK(!begin_frame_source_); 87 DCHECK(!begin_frame_source_);
87 DCHECK(!input_handler_); 88 DCHECK(!input_handler_);
(...skipping 13 matching lines...) Expand all
101 compositor_client_ = compositor_client; 102 compositor_client_ = compositor_client;
102 103
103 // SetClient is essentially the constructor and destructor of 104 // SetClient is essentially the constructor and destructor of
104 // SynchronousCompositorImpl. 105 // SynchronousCompositorImpl.
105 if (compositor_client_) { 106 if (compositor_client_) {
106 SynchronousCompositorRegistry::GetInstance()->RegisterCompositor( 107 SynchronousCompositorRegistry::GetInstance()->RegisterCompositor(
107 routing_id_, this); 108 routing_id_, this);
108 } 109 }
109 } 110 }
110 111
112 void SynchronousCompositorImpl::RegisterWithClient() {
113 DCHECK(CalledOnValidThread());
114 DCHECK(compositor_client_);
115 DCHECK(output_surface_);
116 DCHECK(input_handler_);
117 DCHECK(!registered_with_client_);
118 registered_with_client_ = true;
119
120 compositor_client_->DidInitializeCompositor(this);
121
122 output_surface_->SetTreeActivationCallback(
123 base::Bind(&SynchronousCompositorImpl::DidActivatePendingTree,
124 weak_ptr_factory_.GetWeakPtr()));
125
126 // Setting the delegate causes UpdateRootLayerState immediately so do it
127 // after setting the client.
128 input_handler_->SetRootLayerScrollOffsetDelegate(this);
129 }
130
111 // static 131 // static
112 void SynchronousCompositor::SetGpuService( 132 void SynchronousCompositor::SetGpuService(
113 scoped_refptr<gpu::InProcessCommandBuffer::Service> service) { 133 scoped_refptr<gpu::InProcessCommandBuffer::Service> service) {
114 g_factory.Get().SetDeferredGpuService(service); 134 g_factory.Get().SetDeferredGpuService(service);
115 } 135 }
116 136
117 // static 137 // static
118 void SynchronousCompositor::SetRecordFullDocument(bool record_full_document) { 138 void SynchronousCompositor::SetRecordFullDocument(bool record_full_document) {
119 g_factory.Get().SetRecordFullDocument(record_full_document); 139 g_factory.Get().SetRecordFullDocument(record_full_document);
120 } 140 }
121 141
122 void SynchronousCompositorImpl::DidInitializeRendererObjects( 142 void SynchronousCompositorImpl::DidInitializeRendererObjects(
123 SynchronousCompositorOutputSurface* output_surface, 143 SynchronousCompositorOutputSurface* output_surface,
124 SynchronousCompositorExternalBeginFrameSource* begin_frame_source, 144 SynchronousCompositorExternalBeginFrameSource* begin_frame_source,
125 cc::InputHandler* input_handler) { 145 cc::InputHandler* input_handler) {
126 DCHECK(!output_surface_); 146 DCHECK(!output_surface_);
127 DCHECK(!begin_frame_source_); 147 DCHECK(!begin_frame_source_);
128 DCHECK(output_surface); 148 DCHECK(output_surface);
129 DCHECK(begin_frame_source); 149 DCHECK(begin_frame_source);
130 DCHECK(compositor_client_); 150 DCHECK(compositor_client_);
131 DCHECK(input_handler); 151 DCHECK(input_handler);
132 152
133 output_surface_ = output_surface; 153 output_surface_ = output_surface;
134 begin_frame_source_ = begin_frame_source; 154 begin_frame_source_ = begin_frame_source;
155 input_handler_ = input_handler;
135 156
157 output_surface_->SetCompositor(this);
136 begin_frame_source_->SetCompositor(this); 158 begin_frame_source_->SetCompositor(this);
137 output_surface_->SetCompositor(this);
138
139 output_surface_->SetTreeActivationCallback(
140 base::Bind(&SynchronousCompositorImpl::DidActivatePendingTree,
141 weak_ptr_factory_.GetWeakPtr()));
142
143 OnNeedsBeginFramesChange(begin_frame_source_->NeedsBeginFrames());
144
145 compositor_client_->DidInitializeCompositor(this);
146
147 SetInputHandler(input_handler);
148 } 159 }
149 160
150 void SynchronousCompositorImpl::DidDestroyRendererObjects() { 161 void SynchronousCompositorImpl::DidDestroyRendererObjects() {
151 DCHECK(output_surface_); 162 DCHECK(output_surface_);
152 DCHECK(begin_frame_source_); 163 DCHECK(begin_frame_source_);
153 DCHECK(compositor_client_); 164 DCHECK(compositor_client_);
154 165
166 if (registered_with_client_) {
167 input_handler_->SetRootLayerScrollOffsetDelegate(nullptr);
168 output_surface_->SetTreeActivationCallback(base::Closure());
169 compositor_client_->DidDestroyCompositor(this);
170 registered_with_client_ = false;
171 }
172
155 begin_frame_source_->SetCompositor(nullptr); 173 begin_frame_source_->SetCompositor(nullptr);
156 output_surface_->SetCompositor(nullptr); 174 output_surface_->SetCompositor(nullptr);
157 SetInputHandler(nullptr); 175
158 compositor_client_->DidDestroyCompositor(this); 176 input_handler_ = nullptr;
177 begin_frame_source_ = nullptr;
159 output_surface_ = nullptr; 178 output_surface_ = nullptr;
160 begin_frame_source_ = nullptr;
161 } 179 }
162 180
163 scoped_ptr<cc::CompositorFrame> SynchronousCompositorImpl::DemandDrawHw( 181 scoped_ptr<cc::CompositorFrame> SynchronousCompositorImpl::DemandDrawHw(
164 gfx::Size surface_size, 182 gfx::Size surface_size,
165 const gfx::Transform& transform, 183 const gfx::Transform& transform,
166 gfx::Rect viewport, 184 gfx::Rect viewport,
167 gfx::Rect clip, 185 gfx::Rect clip,
168 gfx::Rect viewport_rect_for_tile_priority, 186 gfx::Rect viewport_rect_for_tile_priority,
169 const gfx::Transform& transform_for_tile_priority) { 187 const gfx::Transform& transform_for_tile_priority) {
170 DCHECK(CalledOnValidThread()); 188 DCHECK(CalledOnValidThread());
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 if (bytes_limit && !current_bytes_limit) { 244 if (bytes_limit && !current_bytes_limit) {
227 g_factory.Get().CompositorInitializedHardwareDraw(); 245 g_factory.Get().CompositorInitializedHardwareDraw();
228 } else if (!bytes_limit && current_bytes_limit) { 246 } else if (!bytes_limit && current_bytes_limit) {
229 g_factory.Get().CompositorReleasedHardwareDraw(); 247 g_factory.Get().CompositorReleasedHardwareDraw();
230 } 248 }
231 } 249 }
232 250
233 void SynchronousCompositorImpl::PostInvalidate() { 251 void SynchronousCompositorImpl::PostInvalidate() {
234 DCHECK(CalledOnValidThread()); 252 DCHECK(CalledOnValidThread());
235 DCHECK(compositor_client_); 253 DCHECK(compositor_client_);
236 compositor_client_->PostInvalidate(); 254 if (registered_with_client_)
255 compositor_client_->PostInvalidate();
237 } 256 }
238 257
239 void SynchronousCompositorImpl::DidChangeRootLayerScrollOffset() { 258 void SynchronousCompositorImpl::DidChangeRootLayerScrollOffset() {
240 if (input_handler_) 259 if (input_handler_)
241 input_handler_->OnRootLayerDelegatedScrollOffsetChanged(); 260 input_handler_->OnRootLayerDelegatedScrollOffsetChanged();
242 } 261 }
243 262
244 void SynchronousCompositorImpl::SetIsActive(bool is_active) { 263 void SynchronousCompositorImpl::SetIsActive(bool is_active) {
245 TRACE_EVENT1("cc", "SynchronousCompositorImpl::SetIsActive", "is_active", 264 TRACE_EVENT1("cc", "SynchronousCompositorImpl::SetIsActive", "is_active",
246 is_active); 265 is_active);
247 is_active_ = is_active; 266 is_active_ = is_active;
248 UpdateNeedsBeginFrames(); 267 UpdateNeedsBeginFrames();
249 } 268 }
250 269
251 void SynchronousCompositorImpl::OnNeedsBeginFramesChange( 270 void SynchronousCompositorImpl::OnNeedsBeginFramesChange(
252 bool needs_begin_frames) { 271 bool needs_begin_frames) {
253 renderer_needs_begin_frames_ = needs_begin_frames; 272 renderer_needs_begin_frames_ = needs_begin_frames;
254 UpdateNeedsBeginFrames(); 273 UpdateNeedsBeginFrames();
255 } 274 }
256 275
257 void SynchronousCompositorImpl::BeginFrame(const cc::BeginFrameArgs& args) { 276 void SynchronousCompositorImpl::BeginFrame(const cc::BeginFrameArgs& args) {
277 if (!registered_with_client_) {
278 RegisterWithClient();
279 DCHECK(registered_with_client_);
280 }
258 if (begin_frame_source_) 281 if (begin_frame_source_)
259 begin_frame_source_->BeginFrame(args); 282 begin_frame_source_->BeginFrame(args);
260 } 283 }
261 284
262 void SynchronousCompositorImpl::UpdateNeedsBeginFrames() { 285 void SynchronousCompositorImpl::UpdateNeedsBeginFrames() {
263 RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>( 286 RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>(
264 contents_->GetRenderWidgetHostView()); 287 contents_->GetRenderWidgetHostView());
265 if (rwhv) 288 if (rwhv)
266 rwhv->OnSetNeedsBeginFrames(is_active_ && renderer_needs_begin_frames_); 289 rwhv->OnSetNeedsBeginFrames(is_active_ && renderer_needs_begin_frames_);
267 } 290 }
268 291
269 void SynchronousCompositorImpl::SetInputHandler(
270 cc::InputHandler* input_handler) {
271 DCHECK(CalledOnValidThread());
272
273 if (input_handler_)
274 input_handler_->SetRootLayerScrollOffsetDelegate(NULL);
275
276 input_handler_ = input_handler;
277
278 if (input_handler_)
279 input_handler_->SetRootLayerScrollOffsetDelegate(this);
280 }
281
282 void SynchronousCompositorImpl::DidOverscroll( 292 void SynchronousCompositorImpl::DidOverscroll(
283 const DidOverscrollParams& params) { 293 const DidOverscrollParams& params) {
284 DCHECK(compositor_client_); 294 DCHECK(compositor_client_);
285 compositor_client_->DidOverscroll(params.accumulated_overscroll, 295 if (registered_with_client_) {
286 params.latest_overscroll_delta, 296 compositor_client_->DidOverscroll(params.accumulated_overscroll,
287 params.current_fling_velocity); 297 params.latest_overscroll_delta,
298 params.current_fling_velocity);
299 }
288 } 300 }
289 301
290 void SynchronousCompositorImpl::DidStopFlinging() { 302 void SynchronousCompositorImpl::DidStopFlinging() {
291 // It's important that the fling-end notification follow the same path as it 303 // It's important that the fling-end notification follow the same path as it
292 // takes on other platforms (using an IPC). This ensures consistent 304 // takes on other platforms (using an IPC). This ensures consistent
293 // bookkeeping at all stages of the input pipeline. 305 // bookkeeping at all stages of the input pipeline.
294 contents_->GetRenderProcessHost()->OnMessageReceived( 306 contents_->GetRenderProcessHost()->OnMessageReceived(
295 InputHostMsg_DidStopFlinging(routing_id_)); 307 InputHostMsg_DidStopFlinging(routing_id_));
296 } 308 }
297 309
(...skipping 10 matching lines...) Expand all
308 RenderProcessHost* rph = contents_->GetRenderProcessHost(); 320 RenderProcessHost* rph = contents_->GetRenderProcessHost();
309 for (ScopedVector<IPC::Message>::const_iterator i = messages.begin(); 321 for (ScopedVector<IPC::Message>::const_iterator i = messages.begin();
310 i != messages.end(); 322 i != messages.end();
311 ++i) { 323 ++i) {
312 rph->OnMessageReceived(**i); 324 rph->OnMessageReceived(**i);
313 } 325 }
314 } 326 }
315 327
316 void SynchronousCompositorImpl::DidActivatePendingTree() { 328 void SynchronousCompositorImpl::DidActivatePendingTree() {
317 DCHECK(compositor_client_); 329 DCHECK(compositor_client_);
318 compositor_client_->DidUpdateContent(); 330 if (registered_with_client_)
331 compositor_client_->DidUpdateContent();
319 DeliverMessages(); 332 DeliverMessages();
320 } 333 }
321 334
322 gfx::ScrollOffset SynchronousCompositorImpl::GetTotalScrollOffset() { 335 gfx::ScrollOffset SynchronousCompositorImpl::GetTotalScrollOffset() {
323 DCHECK(CalledOnValidThread()); 336 DCHECK(CalledOnValidThread());
324 DCHECK(compositor_client_); 337 DCHECK(compositor_client_);
338 if (!registered_with_client_)
339 return gfx::ScrollOffset();
325 // TODO(miletus): Make GetTotalRootLayerScrollOffset return 340 // TODO(miletus): Make GetTotalRootLayerScrollOffset return
326 // ScrollOffset. crbug.com/414283. 341 // ScrollOffset. crbug.com/414283.
327 return gfx::ScrollOffset( 342 return gfx::ScrollOffset(
328 compositor_client_->GetTotalRootLayerScrollOffset()); 343 compositor_client_->GetTotalRootLayerScrollOffset());
329 } 344 }
330 345
331 bool SynchronousCompositorImpl::IsExternalFlingActive() const { 346 bool SynchronousCompositorImpl::IsExternalFlingActive() const {
332 DCHECK(CalledOnValidThread()); 347 DCHECK(CalledOnValidThread());
333 DCHECK(compositor_client_); 348 DCHECK(compositor_client_);
349 if (!registered_with_client_)
350 return false;
334 return compositor_client_->IsExternalFlingActive(); 351 return compositor_client_->IsExternalFlingActive();
335 } 352 }
336 353
337 void SynchronousCompositorImpl::UpdateRootLayerState( 354 void SynchronousCompositorImpl::UpdateRootLayerState(
338 const gfx::ScrollOffset& total_scroll_offset, 355 const gfx::ScrollOffset& total_scroll_offset,
339 const gfx::ScrollOffset& max_scroll_offset, 356 const gfx::ScrollOffset& max_scroll_offset,
340 const gfx::SizeF& scrollable_size, 357 const gfx::SizeF& scrollable_size,
341 float page_scale_factor, 358 float page_scale_factor,
342 float min_page_scale_factor, 359 float min_page_scale_factor,
343 float max_page_scale_factor) { 360 float max_page_scale_factor) {
344 DCHECK(CalledOnValidThread()); 361 DCHECK(CalledOnValidThread());
345 DCHECK(compositor_client_); 362 DCHECK(compositor_client_);
346 363
347 // TODO(miletus): Pass in ScrollOffset. crbug.com/414283. 364 if (registered_with_client_) {
348 compositor_client_->UpdateRootLayerState( 365 // TODO(miletus): Pass in ScrollOffset. crbug.com/414283.
349 gfx::ScrollOffsetToVector2dF(total_scroll_offset), 366 compositor_client_->UpdateRootLayerState(
350 gfx::ScrollOffsetToVector2dF(max_scroll_offset), 367 gfx::ScrollOffsetToVector2dF(total_scroll_offset),
351 scrollable_size, 368 gfx::ScrollOffsetToVector2dF(max_scroll_offset),
352 page_scale_factor, 369 scrollable_size,
353 min_page_scale_factor, 370 page_scale_factor,
354 max_page_scale_factor); 371 min_page_scale_factor,
372 max_page_scale_factor);
373 }
355 } 374 }
356 375
357 // Not using base::NonThreadSafe as we want to enforce a more exacting threading 376 // Not using base::NonThreadSafe as we want to enforce a more exacting threading
358 // requirement: SynchronousCompositorImpl() must only be used on the UI thread. 377 // requirement: SynchronousCompositorImpl() must only be used on the UI thread.
359 bool SynchronousCompositorImpl::CalledOnValidThread() const { 378 bool SynchronousCompositorImpl::CalledOnValidThread() const {
360 return BrowserThread::CurrentlyOn(BrowserThread::UI); 379 return BrowserThread::CurrentlyOn(BrowserThread::UI);
361 } 380 }
362 381
363 // static 382 // static
364 void SynchronousCompositor::SetClientForWebContents( 383 void SynchronousCompositor::SetClientForWebContents(
365 WebContents* contents, 384 WebContents* contents,
366 SynchronousCompositorClient* client) { 385 SynchronousCompositorClient* client) {
367 DCHECK(contents); 386 DCHECK(contents);
368 if (client) { 387 if (client) {
369 g_factory.Get(); // Ensure it's initialized. 388 g_factory.Get(); // Ensure it's initialized.
370 SynchronousCompositorImpl::CreateForWebContents(contents); 389 SynchronousCompositorImpl::CreateForWebContents(contents);
371 } 390 }
372 SynchronousCompositorImpl* instance = 391 SynchronousCompositorImpl* instance =
373 SynchronousCompositorImpl::FromWebContents(contents); 392 SynchronousCompositorImpl::FromWebContents(contents);
374 DCHECK(instance); 393 DCHECK(instance);
375 instance->SetClient(client); 394 instance->SetClient(client);
376 } 395 }
377 396
378 } // namespace content 397 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/android/in_process/synchronous_compositor_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698