summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/render_widget.cc
diff options
context:
space:
mode:
authorjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-04 00:42:21 +0000
committerjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-04 00:42:21 +0000
commitee3d3addf3c97aab93c735e03a264f1ba486c2e7 (patch)
tree57c353feaf31e961d0f1e76b2b026cfb40d8eeb2 /chrome/renderer/render_widget.cc
parentadea95416730f56928e046c134b760daf0a87f36 (diff)
downloadchromium_src-ee3d3addf3c97aab93c735e03a264f1ba486c2e7.zip
chromium_src-ee3d3addf3c97aab93c735e03a264f1ba486c2e7.tar.gz
chromium_src-ee3d3addf3c97aab93c735e03a264f1ba486c2e7.tar.bz2
Calculate animation_floor_time_ only when actually updating animations
This ensures that imperative animations still hit the target framerate if we can render fast enough regardless of when in the animation loop the page calls webkitRequestAnimationFrame(). BUG=71379 TEST= Review URL: http://codereview.chromium.org/6409007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73717 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/render_widget.cc')
-rw-r--r--chrome/renderer/render_widget.cc53
1 files changed, 39 insertions, 14 deletions
diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc
index d96ef05..7187e3c 100644
--- a/chrome/renderer/render_widget.cc
+++ b/chrome/renderer/render_widget.cc
@@ -77,7 +77,8 @@ RenderWidget::RenderWidget(RenderThreadBase* render_thread,
pending_window_rect_count_(0),
suppress_next_char_events_(false),
is_accelerated_compositing_active_(false),
- animation_update_pending_(false) {
+ animation_update_pending_(false),
+ animation_waiting_for_paint_(false) {
RenderProcess::current()->AddRefProcess();
DCHECK(render_thread_);
}
@@ -488,11 +489,17 @@ void RenderWidget::CallDoDeferredUpdate() {
}
void RenderWidget::UpdateAnimationsIfNeeded() {
- if (webwidget_ && !is_hidden() && animation_update_pending_) {
+ if (webwidget_ && !is_hidden() && animation_update_pending_ &&
+ !animation_waiting_for_paint_) {
base::Time now = base::Time::Now();
if (now >= animation_floor_time_) {
- animation_update_pending_ = false;
- webwidget_->animate();
+ UpdateAnimationsAndFloorTime();
+ // If updating the animation caused invalidations, make sure that we paint
+ // at least once before we call animate() again.
+ // Update layout first as that might cause further invalidations.
+ webwidget_->layout();
+ if (paint_aggregator_.HasPendingUpdate())
+ animation_waiting_for_paint_ = true;
} else {
// This code uses base::Time::Now() to calculate the floor and next fire
// time because javascript's Date object uses base::Time::Now(). The
@@ -501,7 +508,7 @@ void RenderWidget::UpdateAnimationsIfNeeded() {
// The upshot of all this is that this function might be called before
// base::Time::Now() has advanced past the animation_floor_time_. To
// avoid exposing this delay to javascript, we keep posting delayed
- // tasks until we observe base::Time::Now() advancing far enough.
+ // tasks until base::Time::Now() has advanced far enough.
int64 delay = (animation_floor_time_ - now).InMillisecondsRoundedUp();
MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
this, &RenderWidget::UpdateAnimationsIfNeeded), delay);
@@ -509,6 +516,13 @@ void RenderWidget::UpdateAnimationsIfNeeded() {
}
}
+void RenderWidget::UpdateAnimationsAndFloorTime() {
+ animation_update_pending_ = false;
+ animation_floor_time_ =
+ base::Time::Now() + base::TimeDelta::FromMilliseconds(16);
+ webwidget_->animate();
+}
+
void RenderWidget::DoDeferredUpdate() {
if (!webwidget_ || update_reply_pending())
return;
@@ -520,8 +534,21 @@ void RenderWidget::DoDeferredUpdate() {
return;
}
- if (base::Time::Now() > animation_floor_time_)
- UpdateAnimationsIfNeeded();
+ if (animation_update_pending_) {
+ if (animation_waiting_for_paint_) {
+ // If we have pending animation updates but need to paint before updating
+ // them, post a task to UpdateAnimationsIfNeeded that will either update
+ // animations directly (if the animation floor time has passed by the time
+ // the function runs) or post a delayed task if the floor time is not yet
+ // reached.
+ MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &RenderWidget::UpdateAnimationsIfNeeded));
+ } else if (base::Time::Now() > animation_floor_time_) {
+ // Otherwise, if it's time to update the animations go ahead.
+ UpdateAnimationsAndFloorTime();
+ }
+ }
+ animation_waiting_for_paint_ = false;
// Layout may generate more invalidation. It may also enable the
// GPU acceleration, so make sure to run layout before we send the
@@ -715,13 +742,11 @@ void RenderWidget::scheduleComposite() {
}
void RenderWidget::scheduleAnimation() {
- if (!animation_update_pending_) {
- animation_update_pending_ = true;
- animation_floor_time_ =
- base::Time::Now() + base::TimeDelta::FromMilliseconds(10);
- MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
- this, &RenderWidget::UpdateAnimationsIfNeeded), 10);
- }
+ if (!animation_update_pending_) {
+ animation_update_pending_ = true;
+ MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &RenderWidget::UpdateAnimationsIfNeeded));
+ }
}
void RenderWidget::didChangeCursor(const WebCursorInfo& cursor_info) {