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

Side by Side Diff: content/renderer/render_widget.cc

Issue 6979020: When --disable-gpu-vsync, run requestAnimFrame callbacks at top speed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Simplify the vsync delay code. Created 9 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/renderer/render_widget.h" 5 #include "content/renderer/render_widget.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 12 matching lines...) Expand all
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h" 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h"
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenuInfo.h" 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenuInfo.h"
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRange.h" 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRange.h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" 28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" 29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
30 #include "ui/gfx/point.h" 30 #include "ui/gfx/point.h"
31 #include "ui/gfx/size.h" 31 #include "ui/gfx/size.h"
32 #include "ui/gfx/surface/transport_dib.h" 32 #include "ui/gfx/surface/transport_dib.h"
33 #include "ui/gfx/gl/gl_switches.h"
33 #include "webkit/glue/webkit_glue.h" 34 #include "webkit/glue/webkit_glue.h"
34 #include "webkit/plugins/npapi/webplugin.h" 35 #include "webkit/plugins/npapi/webplugin.h"
35 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" 36 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
36 37
37 #if defined(OS_POSIX) 38 #if defined(OS_POSIX)
38 #include "ipc/ipc_channel_posix.h" 39 #include "ipc/ipc_channel_posix.h"
39 #include "third_party/skia/include/core/SkPixelRef.h" 40 #include "third_party/skia/include/core/SkPixelRef.h"
40 #include "third_party/skia/include/core/SkMallocPixelRef.h" 41 #include "third_party/skia/include/core/SkMallocPixelRef.h"
41 #endif // defined(OS_POSIX) 42 #endif // defined(OS_POSIX)
42 43
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 579
579 SkIRect irect; 580 SkIRect irect;
580 irect.set(rect.x(), rect.y(), rect.right() - 1, rect.bottom() - 1); 581 irect.set(rect.x(), rect.y(), rect.right() - 1, rect.bottom() - 1);
581 canvas->drawIRect(irect, paint); 582 canvas->drawIRect(irect, paint);
582 } 583 }
583 584
584 void RenderWidget::AnimationCallback() { 585 void RenderWidget::AnimationCallback() {
585 animation_task_posted_ = false; 586 animation_task_posted_ = false;
586 if (!animation_update_pending_) 587 if (!animation_update_pending_)
587 return; 588 return;
588 if (!animation_floor_time_.is_null()) { 589 if (!animation_floor_time_.is_null() && IsRenderingVSyncd()) {
589 // Record when we fired (according to base::Time::Now()) relative to when 590 // Record when we fired (according to base::Time::Now()) relative to when
590 // we posted the task to quantify how much the base::Time/base::TimeTicks 591 // we posted the task to quantify how much the base::Time/base::TimeTicks
591 // skew is affecting animations. 592 // skew is affecting animations.
592 base::TimeDelta animation_callback_delay = base::Time::Now() - 593 base::TimeDelta animation_callback_delay = base::Time::Now() -
593 (animation_floor_time_ - base::TimeDelta::FromMilliseconds(16)); 594 (animation_floor_time_ - base::TimeDelta::FromMilliseconds(16));
594 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer4.AnimationCallbackDelayTime", 595 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer4.AnimationCallbackDelayTime",
595 animation_callback_delay, 596 animation_callback_delay,
596 base::TimeDelta::FromMilliseconds(0), 597 base::TimeDelta::FromMilliseconds(0),
597 base::TimeDelta::FromMilliseconds(30), 598 base::TimeDelta::FromMilliseconds(30),
598 25); 599 25);
599 } 600 }
600 DoDeferredUpdateAndSendInputAck(); 601 DoDeferredUpdateAndSendInputAck();
601 } 602 }
602 603
603 void RenderWidget::AnimateIfNeeded() { 604 void RenderWidget::AnimateIfNeeded() {
604 if (!animation_update_pending_) 605 if (!animation_update_pending_)
605 return; 606 return;
607
608 // Target 60FPS if vsync is on. Go as fast as we can if vsync is off.
609 int animationInterval = IsRenderingVSyncd() ? 16 : 0;
610
606 base::Time now = base::Time::Now(); 611 base::Time now = base::Time::Now();
607 if (now >= animation_floor_time_) { 612 if (now >= animation_floor_time_) {
608 animation_floor_time_ = now + base::TimeDelta::FromMilliseconds(16); 613 animation_floor_time_ = now +
609 // Set a timer to call us back after 16ms (targetting 60FPS) before 614 base::TimeDelta::FromMilliseconds(animationInterval);
615 // Set a timer to call us back after animationInterval before
610 // running animation callbacks so that if a callback requests another 616 // running animation callbacks so that if a callback requests another
611 // we'll be sure to run it at the proper time. 617 // we'll be sure to run it at the proper time.
612 MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod( 618 MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
613 this, &RenderWidget::AnimationCallback), 16); 619 this, &RenderWidget::AnimationCallback), animationInterval);
614 animation_task_posted_ = true; 620 animation_task_posted_ = true;
615 animation_update_pending_ = false; 621 animation_update_pending_ = false;
616 #ifdef WEBWIDGET_HAS_ANIMATE_CHANGES 622 #ifdef WEBWIDGET_HAS_ANIMATE_CHANGES
617 webwidget_->animate(0.0); 623 webwidget_->animate(0.0);
618 #else 624 #else
619 webwidget_->animate(); 625 webwidget_->animate();
620 #endif 626 #endif
621 return; 627 return;
622 } 628 }
629 TRACE_EVENT0("renderer", "EarlyOut_AnimatedTooRecently");
623 if (animation_task_posted_) 630 if (animation_task_posted_)
624 return; 631 return;
625 // This code uses base::Time::Now() to calculate the floor and next fire 632 // This code uses base::Time::Now() to calculate the floor and next fire
626 // time because javascript's Date object uses base::Time::Now(). The 633 // time because javascript's Date object uses base::Time::Now(). The
627 // message loop uses base::TimeTicks, which on windows can have a 634 // message loop uses base::TimeTicks, which on windows can have a
628 // different granularity than base::Time. 635 // different granularity than base::Time.
629 // The upshot of all this is that this function might be called before 636 // The upshot of all this is that this function might be called before
630 // base::Time::Now() has advanced past the animation_floor_time_. To 637 // base::Time::Now() has advanced past the animation_floor_time_. To
631 // avoid exposing this delay to javascript, we keep posting delayed 638 // avoid exposing this delay to javascript, we keep posting delayed
632 // tasks until base::Time::Now() has advanced far enough. 639 // tasks until base::Time::Now() has advanced far enough.
633 int64 delay = (animation_floor_time_ - now).InMillisecondsRoundedUp(); 640 int64 delay = (animation_floor_time_ - now).InMillisecondsRoundedUp();
634 animation_task_posted_ = true; 641 animation_task_posted_ = true;
635 MessageLoop::current()->PostDelayedTask(FROM_HERE, 642 MessageLoop::current()->PostDelayedTask(FROM_HERE,
636 NewRunnableMethod(this, &RenderWidget::AnimationCallback), delay); 643 NewRunnableMethod(this, &RenderWidget::AnimationCallback), delay);
637 } 644 }
638 645
646 bool RenderWidget::IsRenderingVSyncd() {
647 // TODO(nduca): Forcing a driver to disable vsync (e.g. in a control panel) is
648 // not caught by this check. This will lead to artificially low frame rates
649 // for people who force vsync off at a driver level and expect Chrome to speed
650 // up.
651 return !CommandLine::ForCurrentProcess()->HasSwitch(
jamesr 2011/06/02 22:07:53 nitpick: this is doing a string comparison (and a
652 switches::kDisableGpuVsync);
653 }
654
639 void RenderWidget::InvalidationCallback() { 655 void RenderWidget::InvalidationCallback() {
640 invalidation_task_posted_ = false; 656 invalidation_task_posted_ = false;
641 DoDeferredUpdateAndSendInputAck(); 657 DoDeferredUpdateAndSendInputAck();
642 } 658 }
643 659
644 void RenderWidget::DoDeferredUpdateAndSendInputAck() { 660 void RenderWidget::DoDeferredUpdateAndSendInputAck() {
645 DoDeferredUpdate(); 661 DoDeferredUpdate();
646 662
647 if (pending_input_event_ack_.get()) 663 if (pending_input_event_ack_.get())
648 Send(pending_input_event_ack_.release()); 664 Send(pending_input_event_ack_.release());
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 1322
1307 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { 1323 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) {
1308 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin(); 1324 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin();
1309 i != plugin_window_moves_.end(); ++i) { 1325 i != plugin_window_moves_.end(); ++i) {
1310 if (i->window == window) { 1326 if (i->window == window) {
1311 plugin_window_moves_.erase(i); 1327 plugin_window_moves_.erase(i);
1312 break; 1328 break;
1313 } 1329 }
1314 } 1330 }
1315 } 1331 }
OLDNEW
« content/renderer/render_widget.h ('K') | « content/renderer/render_widget.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698