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

Side by Side Diff: content/browser/renderer_host/compositor_impl_android.cc

Issue 239963002: Android: Move scheduling logic to CompositorImpl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/renderer_host/compositor_impl_android.h" 5 #include "content/browser/renderer_host/compositor_impl_android.h"
6 6
7 #include <android/bitmap.h> 7 #include <android/bitmap.h>
8 #include <android/native_window_jni.h> 8 #include <android/native_window_jni.h>
9 9
10 #include "base/android/jni_android.h" 10 #include "base/android/jni_android.h"
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 231 }
232 232
233 CompositorImpl::CompositorImpl(CompositorClient* client, 233 CompositorImpl::CompositorImpl(CompositorClient* client,
234 gfx::NativeWindow root_window) 234 gfx::NativeWindow root_window)
235 : root_layer_(cc::Layer::Create()), 235 : root_layer_(cc::Layer::Create()),
236 has_transparent_background_(false), 236 has_transparent_background_(false),
237 device_scale_factor_(1), 237 device_scale_factor_(1),
238 window_(NULL), 238 window_(NULL),
239 surface_id_(0), 239 surface_id_(0),
240 client_(client), 240 client_(client),
241 root_window_(root_window) { 241 root_window_(root_window),
242 did_post_swapbuffers_(false),
243 ignore_schedule_composite_(false),
244 needs_composite_(false),
245 should_composite_on_vsync_(false),
246 did_composite_outside_vsync_(false),
247 pending_swapbuffers_(0U),
248 weak_factory_(this) {
242 DCHECK(client); 249 DCHECK(client);
243 DCHECK(root_window); 250 DCHECK(root_window);
244 ImageTransportFactoryAndroid::AddObserver(this); 251 ImageTransportFactoryAndroid::AddObserver(this);
245 root_window->AttachCompositor(this); 252 root_window->AttachCompositor(this);
246 } 253 }
247 254
248 CompositorImpl::~CompositorImpl() { 255 CompositorImpl::~CompositorImpl() {
249 root_window_->DetachCompositor(); 256 root_window_->DetachCompositor();
250 ImageTransportFactoryAndroid::RemoveObserver(this); 257 ImageTransportFactoryAndroid::RemoveObserver(this);
251 // Clean-up any surface references. 258 // Clean-up any surface references.
252 SetSurface(NULL); 259 SetSurface(NULL);
253 } 260 }
254 261
255 void CompositorImpl::Composite() { 262 void CompositorImpl::PostComposite(base::TimeDelta delay) {
256 if (host_) 263 base::MessageLoop::current()->PostDelayedTask(
Sami 2014/05/09 13:21:14 Is there a chance we could post this task several
no sievers 2014/05/09 22:53:44 ScheduleComposite() has an early-out if needs_comp
257 host_->Composite(gfx::FrameTime::Now()); 264 FROM_HERE,
265 base::Bind(&CompositorImpl::Composite, weak_factory_.GetWeakPtr(), false),
266 delay);
267 }
268
269 void CompositorImpl::Composite(bool is_vsync) {
270 if (!host_)
271 return;
272
273 if (!needs_composite_)
274 return;
275
276 if (!is_vsync && should_composite_on_vsync_) {
277 TRACE_EVENT0("compositor", "CompositorImpl_DeferCompositeToVSync");
278 root_window_->RequestVSyncUpdate();
279 return;
280 }
281
282 // Don't Composite immediately more than once in between vsync ticks.
Sami 2014/05/09 13:21:14 Maybe add something like this as a safeguard: DCHE
no sievers 2014/05/09 22:53:44 Actually obsolete now with your other comment addr
283 if (did_composite_outside_vsync_) {
284 TRACE_EVENT0("compositor", "CompositorImpl_ThrottleComposite");
285 PostComposite(vsync_period_);
Sami 2014/05/09 13:21:14 Just thinking out loud here: we generally composit
no sievers 2014/05/09 22:53:44 Yea I was wondering too and logged when it happens
286 return;
287 }
288
289 const unsigned int kMaxSwapBuffers = 2U;
290 DCHECK_LE(pending_swapbuffers_, kMaxSwapBuffers);
291 if (pending_swapbuffers_ == kMaxSwapBuffers) {
292 TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit");
293 if (should_composite_on_vsync_)
294 root_window_->RequestVSyncUpdate();
295 else
296 PostComposite(vsync_period_);
Sami 2014/05/09 13:21:14 Should we instead trigger the composite as soon as
no sievers 2014/05/09 22:53:44 I was actually wondering if this is better for lat
297 return;
298 }
299
300 // Reset state before Layout+Composite since that might create more
301 // requests to Composite that we need to respect.
302 needs_composite_ = false;
303 should_composite_on_vsync_ = false;
304
305 // Ignore ScheduleComposite() from layer tree changes during Layout.
306 ignore_schedule_composite_ = true;
307 client_->Layout();
308 ignore_schedule_composite_ = false;
309
310 did_post_swapbuffers_ = false;
311 host_->Composite(gfx::FrameTime::Now());
Sami 2014/05/09 13:21:14 This should probably be derived from the most rece
no sievers 2014/05/09 22:53:44 Hmm if we composite on vsync, now is the vsync tim
312 if (did_post_swapbuffers_)
313 pending_swapbuffers_++;
314
315 if (!is_vsync) {
316 // Need to track vsync to avoid compositing more than once per frame.
317 root_window_->RequestVSyncUpdate();
318 did_composite_outside_vsync_ = true;
319 }
258 } 320 }
259 321
260 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) { 322 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
261 root_layer_->RemoveAllChildren(); 323 root_layer_->RemoveAllChildren();
262 if (root_layer) 324 if (root_layer)
263 root_layer_->AddChild(root_layer); 325 root_layer_->AddChild(root_layer);
264 } 326 }
265 327
266 void CompositorImpl::SetWindowSurface(ANativeWindow* window) { 328 void CompositorImpl::SetWindowSurface(ANativeWindow* window) {
267 GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get(); 329 GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 content::RegisterViewSurface(surface_id_, j_surface.obj()); 371 content::RegisterViewSurface(surface_id_, j_surface.obj());
310 } 372 }
311 } 373 }
312 374
313 void CompositorImpl::SetVisible(bool visible) { 375 void CompositorImpl::SetVisible(bool visible) {
314 if (!visible) { 376 if (!visible) {
315 ui_resource_map_.clear(); 377 ui_resource_map_.clear();
316 host_.reset(); 378 host_.reset();
317 client_->UIResourcesAreInvalid(); 379 client_->UIResourcesAreInvalid();
318 } else if (!host_) { 380 } else if (!host_) {
381 needs_composite_ = false;
382 did_composite_outside_vsync_ = false;
383 should_composite_on_vsync_ = false;
384 pending_swapbuffers_ = 0;
319 cc::LayerTreeSettings settings; 385 cc::LayerTreeSettings settings;
320 settings.refresh_rate = 60.0; 386 settings.refresh_rate = 60.0;
321 settings.impl_side_painting = false; 387 settings.impl_side_painting = false;
322 settings.allow_antialiasing = false; 388 settings.allow_antialiasing = false;
323 settings.calculate_top_controls_position = false; 389 settings.calculate_top_controls_position = false;
324 settings.top_controls_height = 0.f; 390 settings.top_controls_height = 0.f;
325 settings.highp_threshold_min = 2048; 391 settings.highp_threshold_min = 2048;
326 392
327 CommandLine* command_line = CommandLine::ForCurrentProcess(); 393 CommandLine* command_line = CommandLine::ForCurrentProcess();
328 settings.initial_debug_state.SetRecordRenderingStats( 394 settings.initial_debug_state.SetRecordRenderingStats(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 host_->set_has_transparent_background(flag); 433 host_->set_has_transparent_background(flag);
368 } 434 }
369 435
370 bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) { 436 bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) {
371 if (host_) 437 if (host_)
372 return host_->CompositeAndReadback(pixels, rect); 438 return host_->CompositeAndReadback(pixels, rect);
373 else 439 else
374 return false; 440 return false;
375 } 441 }
376 442
443 void CompositorImpl::SetNeedsComposite() {
444 if (!host_.get())
445 return;
446
447 needs_composite_ = true;
448 should_composite_on_vsync_ = true;
Sami 2014/05/09 13:21:14 Doesn't this have the effect of re-scheduling any
no sievers 2014/05/09 22:53:44 Done.
449 root_window_->RequestVSyncUpdate();
450 }
451
377 cc::UIResourceId CompositorImpl::GenerateUIResourceFromUIResourceBitmap( 452 cc::UIResourceId CompositorImpl::GenerateUIResourceFromUIResourceBitmap(
378 const cc::UIResourceBitmap& bitmap, 453 const cc::UIResourceBitmap& bitmap,
379 bool is_transient) { 454 bool is_transient) {
380 if (!host_) 455 if (!host_)
381 return 0; 456 return 0;
382 457
383 cc::UIResourceId id = 0; 458 cc::UIResourceId id = 0;
384 scoped_ptr<cc::UIResourceClient> resource; 459 scoped_ptr<cc::UIResourceClient> resource;
385 if (is_transient) { 460 if (is_transient) {
386 scoped_ptr<TransientUIResource> transient_resource = 461 scoped_ptr<TransientUIResource> transient_resource =
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 return make_scoped_ptr( 536 return make_scoped_ptr(
462 new WebGraphicsContext3DCommandBufferImpl(surface_id, 537 new WebGraphicsContext3DCommandBufferImpl(surface_id,
463 url, 538 url,
464 gpu_channel_host.get(), 539 gpu_channel_host.get(),
465 attributes, 540 attributes,
466 lose_context_when_out_of_memory, 541 lose_context_when_out_of_memory,
467 limits, 542 limits,
468 NULL)); 543 NULL));
469 } 544 }
470 545
546 void CompositorImpl::Layout() {
547 // TODO: If we get this callback from the SingleThreadProxy, we need
548 // to stop calling it ourselves in Composite() below.
Sami 2014/05/09 13:21:14 Composite() is above, not below :)
no sievers 2014/05/09 22:53:44 Done :)
549 NOTREACHED();
550 client_->Layout();
551 }
552
471 scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface( 553 scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface(
472 bool fallback) { 554 bool fallback) {
473 blink::WebGraphicsContext3D::Attributes attrs; 555 blink::WebGraphicsContext3D::Attributes attrs;
474 attrs.shareResources = true; 556 attrs.shareResources = true;
475 attrs.noAutomaticFlushes = true; 557 attrs.noAutomaticFlushes = true;
476 558
477 DCHECK(window_); 559 DCHECK(window_);
478 DCHECK(surface_id_); 560 DCHECK(surface_id_);
479 561
480 scoped_refptr<ContextProviderCommandBuffer> context_provider = 562 scoped_refptr<ContextProviderCommandBuffer> context_provider =
481 ContextProviderCommandBuffer::Create( 563 ContextProviderCommandBuffer::Create(
482 CreateGpuProcessViewContext(attrs, surface_id_), "BrowserCompositor"); 564 CreateGpuProcessViewContext(attrs, surface_id_), "BrowserCompositor");
483 if (!context_provider.get()) { 565 if (!context_provider.get()) {
484 LOG(ERROR) << "Failed to create 3D context for compositor."; 566 LOG(ERROR) << "Failed to create 3D context for compositor.";
485 return scoped_ptr<cc::OutputSurface>(); 567 return scoped_ptr<cc::OutputSurface>();
486 } 568 }
487 569
488 return scoped_ptr<cc::OutputSurface>( 570 return scoped_ptr<cc::OutputSurface>(
489 new OutputSurfaceWithoutParent(context_provider)); 571 new OutputSurfaceWithoutParent(context_provider));
490 } 572 }
491 573
492 void CompositorImpl::OnLostResources() { 574 void CompositorImpl::OnLostResources() {
493 client_->DidLoseResources(); 575 client_->DidLoseResources();
494 } 576 }
495 577
496 void CompositorImpl::DidCompleteSwapBuffers() { 578 void CompositorImpl::ScheduleComposite() {
497 client_->OnSwapBuffersCompleted(); 579 if (needs_composite_ || ignore_schedule_composite_)
498 } 580 return;
499 581
500 void CompositorImpl::ScheduleComposite() { 582 needs_composite_ = true;
501 client_->ScheduleComposite(); 583 PostComposite(base::TimeDelta());
502 } 584 }
503 585
504 void CompositorImpl::ScheduleAnimation() { 586 void CompositorImpl::ScheduleAnimation() {
505 ScheduleComposite(); 587 ScheduleComposite();
506 } 588 }
507 589
508 void CompositorImpl::DidPostSwapBuffers() { 590 void CompositorImpl::DidPostSwapBuffers() {
509 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers"); 591 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers");
510 client_->OnSwapBuffersPosted(); 592 did_post_swapbuffers_ = true;
593 }
594
595 void CompositorImpl::DidCompleteSwapBuffers() {
596 TRACE_EVENT0("compositor", "CompositorImpl::DidCompleteSwapBuffers");
597 DCHECK_GT(pending_swapbuffers_, 0U);
598 client_->OnSwapBuffersCompleted(pending_swapbuffers_--);
511 } 599 }
512 600
513 void CompositorImpl::DidAbortSwapBuffers() { 601 void CompositorImpl::DidAbortSwapBuffers() {
514 TRACE_EVENT0("compositor", "CompositorImpl::DidAbortSwapBuffers"); 602 TRACE_EVENT0("compositor", "CompositorImpl::DidAbortSwapBuffers");
515 client_->OnSwapBuffersCompleted(); 603 DCHECK_GT(pending_swapbuffers_, 0U);
604 client_->OnSwapBuffersCompleted(pending_swapbuffers_--);
516 } 605 }
517 606
518 void CompositorImpl::DidCommit() { 607 void CompositorImpl::DidCommit() {
519 root_window_->OnCompositingDidCommit(); 608 root_window_->OnCompositingDidCommit();
520 } 609 }
521 610
522 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { 611 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) {
523 root_layer_->AddChild(layer); 612 root_layer_->AddChild(layer);
524 } 613 }
525 614
615 void CompositorImpl::OnVSync(base::TimeTicks frame_time,
616 base::TimeDelta vsync_period) {
617 vsync_period_ = vsync_period;
618 did_composite_outside_vsync_ = false;
619
620 if (should_composite_on_vsync_)
621 Composite(true);
622 }
623
526 } // namespace content 624 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698