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

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: rebase 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_this_frame_(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(
257 host_->Composite(gfx::FrameTime::Now()); 264 FROM_HERE,
265 base::Bind(&CompositorImpl::Composite,
266 weak_factory_.GetWeakPtr(),
267 COMPOSITE_IMMEDIATELY),
268 delay);
269 }
270
271 void CompositorImpl::Composite(CompositingTrigger trigger) {
272 if (!host_)
273 return;
274
275 if (!needs_composite_)
276 return;
277
278 if (trigger != COMPOSITE_ON_VSYNC && should_composite_on_vsync_) {
279 TRACE_EVENT0("compositor", "CompositorImpl_DeferCompositeToVSync");
280 root_window_->RequestVSyncUpdate();
281 return;
282 }
283
284 // Don't Composite more than once in between vsync ticks.
285 if (did_composite_this_frame_) {
286 TRACE_EVENT0("compositor", "CompositorImpl_ThrottleComposite");
287 if (should_composite_on_vsync_)
288 root_window_->RequestVSyncUpdate();
289 else
290 PostComposite(vsync_period_);
brianderson 2014/05/10 00:24:40 Why PostComposite a vsync period away here instead
no sievers 2014/05/12 19:49:41 It would transition to vsync scheduling immediatel
291 return;
292 }
293
294 const unsigned int kMaxSwapBuffers = 2U;
295 DCHECK_LE(pending_swapbuffers_, kMaxSwapBuffers);
296 if (pending_swapbuffers_ == kMaxSwapBuffers) {
297 TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit");
298 if (should_composite_on_vsync_)
299 root_window_->RequestVSyncUpdate();
300 else
301 PostComposite(vsync_period_);
302 return;
303 }
304
305 // Reset state before Layout+Composite since that might create more
306 // requests to Composite that we need to respect.
307 needs_composite_ = false;
308 should_composite_on_vsync_ = false;
309
310 // Ignore ScheduleComposite() from layer tree changes during Layout.
brianderson 2014/05/10 00:24:40 What happens if you don't ignore?
no sievers 2014/05/12 19:49:41 It would post a task to Composite() unnecessarily.
311 ignore_schedule_composite_ = true;
312 client_->Layout();
313 ignore_schedule_composite_ = false;
314
315 did_post_swapbuffers_ = false;
316 host_->Composite(gfx::FrameTime::Now());
317 if (did_post_swapbuffers_)
318 pending_swapbuffers_++;
319
320 if (trigger != COMPOSITE_ON_VSYNC) {
321 // Need to track vsync to avoid compositing more than once per frame.
322 root_window_->RequestVSyncUpdate();
323 }
324 did_composite_this_frame_ = true;
258 } 325 }
259 326
260 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) { 327 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
261 root_layer_->RemoveAllChildren(); 328 root_layer_->RemoveAllChildren();
262 if (root_layer) 329 if (root_layer)
263 root_layer_->AddChild(root_layer); 330 root_layer_->AddChild(root_layer);
264 } 331 }
265 332
266 void CompositorImpl::SetWindowSurface(ANativeWindow* window) { 333 void CompositorImpl::SetWindowSurface(ANativeWindow* window) {
267 GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get(); 334 GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 content::RegisterViewSurface(surface_id_, j_surface.obj()); 376 content::RegisterViewSurface(surface_id_, j_surface.obj());
310 } 377 }
311 } 378 }
312 379
313 void CompositorImpl::SetVisible(bool visible) { 380 void CompositorImpl::SetVisible(bool visible) {
314 if (!visible) { 381 if (!visible) {
315 ui_resource_map_.clear(); 382 ui_resource_map_.clear();
316 host_.reset(); 383 host_.reset();
317 client_->UIResourcesAreInvalid(); 384 client_->UIResourcesAreInvalid();
318 } else if (!host_) { 385 } else if (!host_) {
386 needs_composite_ = false;
387 did_composite_this_frame_ = false;
388 should_composite_on_vsync_ = false;
389 pending_swapbuffers_ = 0;
brianderson 2014/05/10 00:24:40 Do you not get pending acks when you go invisible?
no sievers 2014/05/12 19:49:41 Yes, I was running into accounting problems and it
319 cc::LayerTreeSettings settings; 390 cc::LayerTreeSettings settings;
320 settings.refresh_rate = 60.0; 391 settings.refresh_rate = 60.0;
321 settings.impl_side_painting = false; 392 settings.impl_side_painting = false;
322 settings.allow_antialiasing = false; 393 settings.allow_antialiasing = false;
323 settings.calculate_top_controls_position = false; 394 settings.calculate_top_controls_position = false;
324 settings.top_controls_height = 0.f; 395 settings.top_controls_height = 0.f;
325 settings.highp_threshold_min = 2048; 396 settings.highp_threshold_min = 2048;
326 397
327 CommandLine* command_line = CommandLine::ForCurrentProcess(); 398 CommandLine* command_line = CommandLine::ForCurrentProcess();
328 settings.initial_debug_state.SetRecordRenderingStats( 399 settings.initial_debug_state.SetRecordRenderingStats(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 host_->set_has_transparent_background(flag); 438 host_->set_has_transparent_background(flag);
368 } 439 }
369 440
370 bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) { 441 bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) {
371 if (host_) 442 if (host_)
372 return host_->CompositeAndReadback(pixels, rect); 443 return host_->CompositeAndReadback(pixels, rect);
373 else 444 else
374 return false; 445 return false;
375 } 446 }
376 447
448 void CompositorImpl::SetNeedsComposite() {
brianderson 2014/05/10 00:24:40 Is this the signal we get when the tab stack wants
no sievers 2014/05/12 19:49:41 Yea exactly. It's needed because we don't get a ca
449 if (!host_.get() || needs_composite_)
450 return;
451
452 needs_composite_ = true;
453
454 // For explicit requests we try to composite regularly on vsync.
455 should_composite_on_vsync_ = true;
456 root_window_->RequestVSyncUpdate();
457 }
458
377 cc::UIResourceId CompositorImpl::GenerateUIResourceFromUIResourceBitmap( 459 cc::UIResourceId CompositorImpl::GenerateUIResourceFromUIResourceBitmap(
378 const cc::UIResourceBitmap& bitmap, 460 const cc::UIResourceBitmap& bitmap,
379 bool is_transient) { 461 bool is_transient) {
380 if (!host_) 462 if (!host_)
381 return 0; 463 return 0;
382 464
383 cc::UIResourceId id = 0; 465 cc::UIResourceId id = 0;
384 scoped_ptr<cc::UIResourceClient> resource; 466 scoped_ptr<cc::UIResourceClient> resource;
385 if (is_transient) { 467 if (is_transient) {
386 scoped_ptr<TransientUIResource> transient_resource = 468 scoped_ptr<TransientUIResource> transient_resource =
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 return make_scoped_ptr( 543 return make_scoped_ptr(
462 new WebGraphicsContext3DCommandBufferImpl(surface_id, 544 new WebGraphicsContext3DCommandBufferImpl(surface_id,
463 url, 545 url,
464 gpu_channel_host.get(), 546 gpu_channel_host.get(),
465 attributes, 547 attributes,
466 lose_context_when_out_of_memory, 548 lose_context_when_out_of_memory,
467 limits, 549 limits,
468 NULL)); 550 NULL));
469 } 551 }
470 552
553 void CompositorImpl::Layout() {
554 // TODO: If we get this callback from the SingleThreadProxy, we need
555 // to stop calling it ourselves in CompositorImpl::Composite().
556 NOTREACHED();
557 client_->Layout();
558 }
559
471 scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface( 560 scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface(
472 bool fallback) { 561 bool fallback) {
473 blink::WebGraphicsContext3D::Attributes attrs; 562 blink::WebGraphicsContext3D::Attributes attrs;
474 attrs.shareResources = true; 563 attrs.shareResources = true;
475 attrs.noAutomaticFlushes = true; 564 attrs.noAutomaticFlushes = true;
476 565
477 DCHECK(window_); 566 DCHECK(window_);
478 DCHECK(surface_id_); 567 DCHECK(surface_id_);
479 568
480 scoped_refptr<ContextProviderCommandBuffer> context_provider = 569 scoped_refptr<ContextProviderCommandBuffer> context_provider =
481 ContextProviderCommandBuffer::Create( 570 ContextProviderCommandBuffer::Create(
482 CreateGpuProcessViewContext(attrs, surface_id_), "BrowserCompositor"); 571 CreateGpuProcessViewContext(attrs, surface_id_), "BrowserCompositor");
483 if (!context_provider.get()) { 572 if (!context_provider.get()) {
484 LOG(ERROR) << "Failed to create 3D context for compositor."; 573 LOG(ERROR) << "Failed to create 3D context for compositor.";
485 return scoped_ptr<cc::OutputSurface>(); 574 return scoped_ptr<cc::OutputSurface>();
486 } 575 }
487 576
488 return scoped_ptr<cc::OutputSurface>( 577 return scoped_ptr<cc::OutputSurface>(
489 new OutputSurfaceWithoutParent(context_provider)); 578 new OutputSurfaceWithoutParent(context_provider));
490 } 579 }
491 580
492 void CompositorImpl::OnLostResources() { 581 void CompositorImpl::OnLostResources() {
493 client_->DidLoseResources(); 582 client_->DidLoseResources();
494 } 583 }
495 584
496 void CompositorImpl::DidCompleteSwapBuffers() { 585 void CompositorImpl::ScheduleComposite() {
497 client_->OnSwapBuffersCompleted(); 586 if (needs_composite_ || ignore_schedule_composite_)
498 } 587 return;
499 588
500 void CompositorImpl::ScheduleComposite() { 589 needs_composite_ = true;
501 client_->ScheduleComposite(); 590
591 // We currently expect layer tree invalidations at most once per frame
592 // during normal operation and therefore try to composite immediately
593 // to minimize latency.
594 PostComposite(base::TimeDelta());
502 } 595 }
503 596
504 void CompositorImpl::ScheduleAnimation() { 597 void CompositorImpl::ScheduleAnimation() {
505 ScheduleComposite(); 598 ScheduleComposite();
506 } 599 }
507 600
508 void CompositorImpl::DidPostSwapBuffers() { 601 void CompositorImpl::DidPostSwapBuffers() {
509 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers"); 602 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers");
510 client_->OnSwapBuffersPosted(); 603 did_post_swapbuffers_ = true;
604 }
605
606 void CompositorImpl::DidCompleteSwapBuffers() {
607 TRACE_EVENT0("compositor", "CompositorImpl::DidCompleteSwapBuffers");
608 DCHECK_GT(pending_swapbuffers_, 0U);
609 client_->OnSwapBuffersCompleted(pending_swapbuffers_--);
brianderson 2014/05/10 00:24:40 Can you decrement after the function call?
no sievers 2014/05/12 19:49:41 Isn't that the same?
511 } 610 }
512 611
513 void CompositorImpl::DidAbortSwapBuffers() { 612 void CompositorImpl::DidAbortSwapBuffers() {
514 TRACE_EVENT0("compositor", "CompositorImpl::DidAbortSwapBuffers"); 613 TRACE_EVENT0("compositor", "CompositorImpl::DidAbortSwapBuffers");
515 client_->OnSwapBuffersCompleted(); 614 DCHECK_GT(pending_swapbuffers_, 0U);
615 client_->OnSwapBuffersCompleted(pending_swapbuffers_--);
516 } 616 }
517 617
518 void CompositorImpl::DidCommit() { 618 void CompositorImpl::DidCommit() {
519 root_window_->OnCompositingDidCommit(); 619 root_window_->OnCompositingDidCommit();
520 } 620 }
521 621
522 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { 622 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) {
523 root_layer_->AddChild(layer); 623 root_layer_->AddChild(layer);
524 } 624 }
525 625
626 void CompositorImpl::OnVSync(base::TimeTicks frame_time,
627 base::TimeDelta vsync_period) {
628 vsync_period_ = vsync_period;
629 did_composite_this_frame_ = false;
630
631 if (should_composite_on_vsync_)
632 Composite(COMPOSITE_ON_VSYNC);
633 }
634
526 } // namespace content 635 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698