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

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

Issue 285373008: Android: Decouple animate from vsync (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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 #include "ui/gl/android/surface_texture_tracker.h" 50 #include "ui/gl/android/surface_texture_tracker.h"
51 #include "webkit/common/gpu/context_provider_in_process.h" 51 #include "webkit/common/gpu/context_provider_in_process.h"
52 #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl. h" 52 #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl. h"
53 53
54 namespace gfx { 54 namespace gfx {
55 class JavaBitmap; 55 class JavaBitmap;
56 } 56 }
57 57
58 namespace { 58 namespace {
59 59
60 const unsigned int kMaxSwapBuffers = 2U;
61
60 // Used to override capabilities_.adjust_deadline_for_parent to false 62 // Used to override capabilities_.adjust_deadline_for_parent to false
61 class OutputSurfaceWithoutParent : public cc::OutputSurface { 63 class OutputSurfaceWithoutParent : public cc::OutputSurface {
62 public: 64 public:
63 OutputSurfaceWithoutParent(const scoped_refptr< 65 OutputSurfaceWithoutParent(const scoped_refptr<
64 content::ContextProviderCommandBuffer>& context_provider) 66 content::ContextProviderCommandBuffer>& context_provider)
65 : cc::OutputSurface(context_provider) { 67 : cc::OutputSurface(context_provider) {
66 capabilities_.adjust_deadline_for_parent = false; 68 capabilities_.adjust_deadline_for_parent = false;
67 } 69 }
68 70
69 virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE { 71 virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE {
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 : root_layer_(cc::Layer::Create()), 237 : root_layer_(cc::Layer::Create()),
236 has_transparent_background_(false), 238 has_transparent_background_(false),
237 device_scale_factor_(1), 239 device_scale_factor_(1),
238 window_(NULL), 240 window_(NULL),
239 surface_id_(0), 241 surface_id_(0),
240 client_(client), 242 client_(client),
241 root_window_(root_window), 243 root_window_(root_window),
242 did_post_swapbuffers_(false), 244 did_post_swapbuffers_(false),
243 ignore_schedule_composite_(false), 245 ignore_schedule_composite_(false),
244 needs_composite_(false), 246 needs_composite_(false),
245 should_composite_on_vsync_(false), 247 needs_animate_(false),
248 will_composite_immediately_(false),
249 will_composite_eventually_(false),
246 did_composite_this_frame_(false), 250 did_composite_this_frame_(false),
247 pending_swapbuffers_(0U), 251 pending_swapbuffers_(0U),
248 weak_factory_(this) { 252 weak_factory_(this) {
249 DCHECK(client); 253 DCHECK(client);
250 DCHECK(root_window); 254 DCHECK(root_window);
251 ImageTransportFactoryAndroid::AddObserver(this); 255 ImageTransportFactoryAndroid::AddObserver(this);
252 root_window->AttachCompositor(this); 256 root_window->AttachCompositor(this);
253 } 257 }
254 258
255 CompositorImpl::~CompositorImpl() { 259 CompositorImpl::~CompositorImpl() {
256 root_window_->DetachCompositor(); 260 root_window_->DetachCompositor();
257 ImageTransportFactoryAndroid::RemoveObserver(this); 261 ImageTransportFactoryAndroid::RemoveObserver(this);
258 // Clean-up any surface references. 262 // Clean-up any surface references.
259 SetSurface(NULL); 263 SetSurface(NULL);
260 } 264 }
261 265
262 void CompositorImpl::PostComposite(base::TimeDelta delay) { 266 void CompositorImpl::PostComposite(CompositingTrigger trigger) {
267 base::TimeDelta delay;
268 switch (trigger) {
269 case COMPOSITE_IMMEDIATELY:
270 if (will_composite_immediately_)
271 return;
272 will_composite_immediately_ = true;
273 break;
274 case COMPOSITE_EVENTUALLY: {
275 if (will_composite_eventually_)
brianderson 2014/05/21 17:23:00 Can we also return early here if will_composite_im
no sievers 2014/05/23 02:49:44 Good catch. Done.
276 return;
277 will_composite_eventually_ = true;
278 const base::TimeDelta estimated_composite_time = vsync_period_ / 4;
279 const base::TimeTicks now = base::TimeTicks::Now();
280 bool skip_frame =
281 did_composite_this_frame_ || pending_swapbuffers_ == kMaxSwapBuffers;
282
283 if (!last_vsync_.is_null() && (now - last_vsync_) < vsync_period_) {
284 base::TimeTicks next_composite =
285 last_vsync_ + vsync_period_ - estimated_composite_time;
286 if (next_composite < now || skip_frame)
287 next_composite += vsync_period_;
288
289 delay = next_composite - now;
290 } else if (skip_frame) {
291 delay = vsync_period_;
292 }
293 }
294 break;
295 }
296 TRACE_EVENT2("cc", "CompositorImpl::PostComposite",
297 "trigger", trigger,
298 "delay", delay.InMillisecondsF());
263 base::MessageLoop::current()->PostDelayedTask( 299 base::MessageLoop::current()->PostDelayedTask(
brianderson 2014/05/21 17:23:00 If will_composite_immediately_ just became true an
no sievers 2014/05/23 02:49:44 I think the early-out in Composite() (!needs_compo
264 FROM_HERE, 300 FROM_HERE,
265 base::Bind(&CompositorImpl::Composite, 301 base::Bind(
266 weak_factory_.GetWeakPtr(), 302 &CompositorImpl::Composite, weak_factory_.GetWeakPtr(), trigger),
267 COMPOSITE_IMMEDIATELY),
268 delay); 303 delay);
269 } 304 }
270 305
271 void CompositorImpl::Composite(CompositingTrigger trigger) { 306 void CompositorImpl::Composite(CompositingTrigger trigger) {
272 if (!host_) 307 if (!host_)
273 return; 308 return;
274 309
310 will_composite_immediately_ &= trigger != COMPOSITE_IMMEDIATELY;
311 will_composite_eventually_ &= trigger != COMPOSITE_EVENTUALLY;
brianderson 2014/05/21 17:23:00 It is hard to decipher the intention here. Is this
no sievers 2014/05/23 02:49:44 Done. You're right, it's equivalent and more reada
312
275 if (!needs_composite_) 313 if (!needs_composite_)
276 return; 314 return;
277 315
278 if (trigger != COMPOSITE_ON_VSYNC && should_composite_on_vsync_) { 316 // Don't Composite more than once in between vsync ticks.
279 TRACE_EVENT0("compositor", "CompositorImpl_DeferCompositeToVSync"); 317 if (did_composite_this_frame_) {
280 root_window_->RequestVSyncUpdate(); 318 TRACE_EVENT0("compositor", "CompositorImpl_ThrottleComposite");
319 PostComposite(COMPOSITE_EVENTUALLY);
281 return; 320 return;
282 } 321 }
283 322
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_);
291 return;
292 }
293
294 const unsigned int kMaxSwapBuffers = 2U;
295 DCHECK_LE(pending_swapbuffers_, kMaxSwapBuffers); 323 DCHECK_LE(pending_swapbuffers_, kMaxSwapBuffers);
296 if (pending_swapbuffers_ == kMaxSwapBuffers) { 324 if (pending_swapbuffers_ == kMaxSwapBuffers) {
297 TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit"); 325 TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit");
298 if (should_composite_on_vsync_) 326 PostComposite(COMPOSITE_EVENTUALLY);
brianderson 2014/05/21 17:23:00 Instead of posting a composite, would it be better
no sievers 2014/05/23 02:49:44 Ok since Sami suggested this earlier too, will do
299 root_window_->RequestVSyncUpdate();
300 else
301 PostComposite(vsync_period_);
302 return; 327 return;
303 } 328 }
304 329
305 // Reset state before Layout+Composite since that might create more 330 // Reset state before Layout+Composite since that might create more
306 // requests to Composite that we need to respect. 331 // requests to Composite that we need to respect.
307 needs_composite_ = false; 332 needs_composite_ = false;
308 should_composite_on_vsync_ = false; 333 did_composite_this_frame_ = true;
309 334
310 // Ignore ScheduleComposite() from layer tree changes during Layout. 335 // Ignore ScheduleComposite() from layer tree changes during layout and
336 // animation updates that will already be reflected in the current frame
337 // we are about to draw.
311 ignore_schedule_composite_ = true; 338 ignore_schedule_composite_ = true;
312 client_->Layout(); 339 client_->Layout();
340
341 if (needs_animate_) {
342 needs_animate_ = false;
343 root_window_->Animate(gfx::FrameTime::Now());
344 }
313 ignore_schedule_composite_ = false; 345 ignore_schedule_composite_ = false;
314 346
315 did_post_swapbuffers_ = false; 347 did_post_swapbuffers_ = false;
316 host_->Composite(gfx::FrameTime::Now()); 348 host_->Composite(gfx::FrameTime::Now());
317 if (did_post_swapbuffers_) 349 if (did_post_swapbuffers_)
318 pending_swapbuffers_++; 350 pending_swapbuffers_++;
319 351
320 if (trigger != COMPOSITE_ON_VSYNC) { 352 // Need to track vsync to avoid compositing more than once per frame.
321 // Need to track vsync to avoid compositing more than once per frame. 353 root_window_->RequestVSyncUpdate();
322 root_window_->RequestVSyncUpdate();
323 }
324 did_composite_this_frame_ = true;
325 } 354 }
326 355
327 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) { 356 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
328 root_layer_->RemoveAllChildren(); 357 root_layer_->RemoveAllChildren();
329 if (root_layer) 358 if (root_layer)
330 root_layer_->AddChild(root_layer); 359 root_layer_->AddChild(root_layer);
331 } 360 }
332 361
333 void CompositorImpl::SetWindowSurface(ANativeWindow* window) { 362 void CompositorImpl::SetWindowSurface(ANativeWindow* window) {
334 GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get(); 363 GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 } 406 }
378 } 407 }
379 408
380 void CompositorImpl::SetVisible(bool visible) { 409 void CompositorImpl::SetVisible(bool visible) {
381 if (!visible) { 410 if (!visible) {
382 ui_resource_map_.clear(); 411 ui_resource_map_.clear();
383 host_.reset(); 412 host_.reset();
384 client_->UIResourcesAreInvalid(); 413 client_->UIResourcesAreInvalid();
385 } else if (!host_) { 414 } else if (!host_) {
386 needs_composite_ = false; 415 needs_composite_ = false;
416 needs_animate_ = false;
387 did_composite_this_frame_ = false; 417 did_composite_this_frame_ = false;
388 should_composite_on_vsync_ = false; 418 will_composite_immediately_ = false;
419 will_composite_eventually_ = false;
389 pending_swapbuffers_ = 0; 420 pending_swapbuffers_ = 0;
390 cc::LayerTreeSettings settings; 421 cc::LayerTreeSettings settings;
391 settings.refresh_rate = 60.0; 422 settings.refresh_rate = 60.0;
392 settings.impl_side_painting = false; 423 settings.impl_side_painting = false;
393 settings.allow_antialiasing = false; 424 settings.allow_antialiasing = false;
394 settings.calculate_top_controls_position = false; 425 settings.calculate_top_controls_position = false;
395 settings.top_controls_height = 0.f; 426 settings.top_controls_height = 0.f;
396 settings.highp_threshold_min = 2048; 427 settings.highp_threshold_min = 2048;
397 428
398 CommandLine* command_line = CommandLine::ForCurrentProcess(); 429 CommandLine* command_line = CommandLine::ForCurrentProcess();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 has_transparent_background_ = flag; 467 has_transparent_background_ = flag;
437 if (host_) 468 if (host_)
438 host_->set_has_transparent_background(flag); 469 host_->set_has_transparent_background(flag);
439 } 470 }
440 471
441 bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) { 472 bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) {
442 return false; 473 return false;
443 } 474 }
444 475
445 void CompositorImpl::SetNeedsComposite() { 476 void CompositorImpl::SetNeedsComposite() {
477 DCHECK(!needs_composite_ || will_composite_immediately_ ||
478 will_composite_eventually_);
446 if (!host_.get() || needs_composite_) 479 if (!host_.get() || needs_composite_)
447 return; 480 return;
448 481
449 needs_composite_ = true; 482 needs_composite_ = true;
450 483 PostComposite(COMPOSITE_EVENTUALLY);
451 // For explicit requests we try to composite regularly on vsync.
452 should_composite_on_vsync_ = true;
453 root_window_->RequestVSyncUpdate();
454 } 484 }
455 485
456 cc::UIResourceId CompositorImpl::GenerateUIResourceFromUIResourceBitmap( 486 cc::UIResourceId CompositorImpl::GenerateUIResourceFromUIResourceBitmap(
457 const cc::UIResourceBitmap& bitmap, 487 const cc::UIResourceBitmap& bitmap,
458 bool is_transient) { 488 bool is_transient) {
459 if (!host_) 489 if (!host_)
460 return 0; 490 return 0;
461 491
462 cc::UIResourceId id = 0; 492 cc::UIResourceId id = 0;
463 scoped_ptr<cc::UIResourceClient> resource; 493 scoped_ptr<cc::UIResourceClient> resource;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 603
574 return scoped_ptr<cc::OutputSurface>( 604 return scoped_ptr<cc::OutputSurface>(
575 new OutputSurfaceWithoutParent(context_provider)); 605 new OutputSurfaceWithoutParent(context_provider));
576 } 606 }
577 607
578 void CompositorImpl::OnLostResources() { 608 void CompositorImpl::OnLostResources() {
579 client_->DidLoseResources(); 609 client_->DidLoseResources();
580 } 610 }
581 611
582 void CompositorImpl::ScheduleComposite() { 612 void CompositorImpl::ScheduleComposite() {
583 if (needs_composite_ || ignore_schedule_composite_) 613 DCHECK(!needs_composite_ || will_composite_immediately_ ||
614 will_composite_eventually_);
615 if (ignore_schedule_composite_)
584 return; 616 return;
585 617
586 needs_composite_ = true; 618 needs_composite_ = true;
587 619 if (did_composite_this_frame_) {
588 // We currently expect layer tree invalidations at most once per frame 620 PostComposite(COMPOSITE_EVENTUALLY);
589 // during normal operation and therefore try to composite immediately 621 } else {
590 // to minimize latency. 622 // We currently expect layer tree invalidations at most once per frame
591 PostComposite(base::TimeDelta()); 623 // during normal operation and therefore try to composite immediately
624 // to minimize latency.
625 PostComposite(COMPOSITE_IMMEDIATELY);
626 }
592 } 627 }
593 628
594 void CompositorImpl::ScheduleAnimation() { 629 void CompositorImpl::ScheduleAnimation() {
595 ScheduleComposite(); 630 ScheduleComposite();
596 } 631 }
597 632
598 void CompositorImpl::DidPostSwapBuffers() { 633 void CompositorImpl::DidPostSwapBuffers() {
599 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers"); 634 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers");
600 did_post_swapbuffers_ = true; 635 did_post_swapbuffers_ = true;
601 } 636 }
(...skipping 19 matching lines...) Expand all
621 } 656 }
622 657
623 void CompositorImpl::RequestCopyOfOutputOnRootLayer( 658 void CompositorImpl::RequestCopyOfOutputOnRootLayer(
624 scoped_ptr<cc::CopyOutputRequest> request) { 659 scoped_ptr<cc::CopyOutputRequest> request) {
625 root_layer_->RequestCopyOfOutput(request.Pass()); 660 root_layer_->RequestCopyOfOutput(request.Pass());
626 } 661 }
627 662
628 void CompositorImpl::OnVSync(base::TimeTicks frame_time, 663 void CompositorImpl::OnVSync(base::TimeTicks frame_time,
629 base::TimeDelta vsync_period) { 664 base::TimeDelta vsync_period) {
630 vsync_period_ = vsync_period; 665 vsync_period_ = vsync_period;
666 last_vsync_ = frame_time;
631 did_composite_this_frame_ = false; 667 did_composite_this_frame_ = false;
brianderson 2014/05/21 17:23:00 If did_composite_this_frame_ is true at this point
no sievers 2014/05/23 02:49:44 You mean for when there is a ScheduleComposite(),
668 }
632 669
633 if (should_composite_on_vsync_) 670 void CompositorImpl::SetNeedsAnimate() {
634 Composite(COMPOSITE_ON_VSYNC); 671 DCHECK(!needs_animate_ || needs_composite_);
672 DCHECK(!needs_composite_ || will_composite_immediately_ ||
673 will_composite_eventually_);
674 needs_animate_ = true;
675
676 if (needs_composite_)
677 return;
678
679 TRACE_EVENT0("cc", "CompositorImpl::SetNeedsAnimate");
680 needs_composite_ = true;
681 PostComposite(COMPOSITE_EVENTUALLY);
635 } 682 }
636 683
637 } // namespace content 684 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698