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

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

Issue 6409007: Calculate animation_floor_time_ only when actually updating animations (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add a NULL check for webwidget_ (thanks to apatrick) Created 9 years, 10 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
« no previous file with comments | « chrome/renderer/render_widget.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/renderer/render_widget.h" 5 #include "chrome/renderer/render_widget.h"
6 6
7 #include "app/surface/transport_dib.h" 7 #include "app/surface/transport_dib.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 needs_repainting_on_restore_(false), 70 needs_repainting_on_restore_(false),
71 has_focus_(false), 71 has_focus_(false),
72 handling_input_event_(false), 72 handling_input_event_(false),
73 closing_(false), 73 closing_(false),
74 input_method_is_active_(false), 74 input_method_is_active_(false),
75 text_input_type_(WebKit::WebTextInputTypeNone), 75 text_input_type_(WebKit::WebTextInputTypeNone),
76 popup_type_(popup_type), 76 popup_type_(popup_type),
77 pending_window_rect_count_(0), 77 pending_window_rect_count_(0),
78 suppress_next_char_events_(false), 78 suppress_next_char_events_(false),
79 is_accelerated_compositing_active_(false), 79 is_accelerated_compositing_active_(false),
80 animation_update_pending_(false) { 80 animation_update_pending_(false),
81 animation_waiting_for_paint_(false) {
81 RenderProcess::current()->AddRefProcess(); 82 RenderProcess::current()->AddRefProcess();
82 DCHECK(render_thread_); 83 DCHECK(render_thread_);
83 } 84 }
84 85
85 RenderWidget::~RenderWidget() { 86 RenderWidget::~RenderWidget() {
86 DCHECK(!webwidget_) << "Leaking our WebWidget!"; 87 DCHECK(!webwidget_) << "Leaking our WebWidget!";
87 if (current_paint_buf_) { 88 if (current_paint_buf_) {
88 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); 89 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_);
89 current_paint_buf_ = NULL; 90 current_paint_buf_ = NULL;
90 } 91 }
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 } 482 }
482 483
483 void RenderWidget::CallDoDeferredUpdate() { 484 void RenderWidget::CallDoDeferredUpdate() {
484 DoDeferredUpdate(); 485 DoDeferredUpdate();
485 486
486 if (pending_input_event_ack_.get()) 487 if (pending_input_event_ack_.get())
487 Send(pending_input_event_ack_.release()); 488 Send(pending_input_event_ack_.release());
488 } 489 }
489 490
490 void RenderWidget::UpdateAnimationsIfNeeded() { 491 void RenderWidget::UpdateAnimationsIfNeeded() {
491 if (!is_hidden() && animation_update_pending_) { 492 if (webwidget_ && !is_hidden() && animation_update_pending_ &&
493 !animation_waiting_for_paint_) {
492 base::Time now = base::Time::Now(); 494 base::Time now = base::Time::Now();
493 if (now >= animation_floor_time_) { 495 if (now >= animation_floor_time_) {
494 animation_update_pending_ = false; 496 UpdateAnimationsAndFloorTime();
495 webwidget_->animate(); 497 // If updating the animation caused invalidations, make sure that we paint
498 // at least once before we call animate() again.
499 // Update layout first as that might cause further invalidations.
500 webwidget_->layout();
501 if (paint_aggregator_.HasPendingUpdate())
502 animation_waiting_for_paint_ = true;
496 } else { 503 } else {
497 // This code uses base::Time::Now() to calculate the floor and next fire 504 // This code uses base::Time::Now() to calculate the floor and next fire
498 // time because javascript's Date object uses base::Time::Now(). The 505 // time because javascript's Date object uses base::Time::Now(). The
499 // message loop uses base::TimeTicks, which on windows can have a 506 // message loop uses base::TimeTicks, which on windows can have a
500 // different granularity than base::Time. 507 // different granularity than base::Time.
501 // The upshot of all this is that this function might be called before 508 // The upshot of all this is that this function might be called before
502 // base::Time::Now() has advanced past the animation_floor_time_. To 509 // base::Time::Now() has advanced past the animation_floor_time_. To
503 // avoid exposing this delay to javascript, we keep posting delayed 510 // avoid exposing this delay to javascript, we keep posting delayed
504 // tasks until we observe base::Time::Now() advancing far enough. 511 // tasks until base::Time::Now() has advanced far enough.
505 int64 delay = (animation_floor_time_ - now).InMillisecondsRoundedUp(); 512 int64 delay = (animation_floor_time_ - now).InMillisecondsRoundedUp();
506 MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod( 513 MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
507 this, &RenderWidget::UpdateAnimationsIfNeeded), delay); 514 this, &RenderWidget::UpdateAnimationsIfNeeded), delay);
508 } 515 }
509 } 516 }
510 } 517 }
511 518
519 void RenderWidget::UpdateAnimationsAndFloorTime() {
520 animation_update_pending_ = false;
521 animation_floor_time_ =
522 base::Time::Now() + base::TimeDelta::FromMilliseconds(16);
523 webwidget_->animate();
524 }
525
512 void RenderWidget::DoDeferredUpdate() { 526 void RenderWidget::DoDeferredUpdate() {
513 if (!webwidget_ || update_reply_pending()) 527 if (!webwidget_ || update_reply_pending())
514 return; 528 return;
515 529
516 // Suppress updating when we are hidden. 530 // Suppress updating when we are hidden.
517 if (is_hidden_ || size_.IsEmpty()) { 531 if (is_hidden_ || size_.IsEmpty()) {
518 paint_aggregator_.ClearPendingUpdate(); 532 paint_aggregator_.ClearPendingUpdate();
519 needs_repainting_on_restore_ = true; 533 needs_repainting_on_restore_ = true;
520 return; 534 return;
521 } 535 }
522 536
523 if (base::Time::Now() > animation_floor_time_) 537 if (animation_update_pending_) {
524 UpdateAnimationsIfNeeded(); 538 if (animation_waiting_for_paint_) {
539 // If we have pending animation updates but need to paint before updating
540 // them, post a task to UpdateAnimationsIfNeeded that will either update
541 // animations directly (if the animation floor time has passed by the time
542 // the function runs) or post a delayed task if the floor time is not yet
543 // reached.
544 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
545 this, &RenderWidget::UpdateAnimationsIfNeeded));
546 } else if (base::Time::Now() > animation_floor_time_) {
547 // Otherwise, if it's time to update the animations go ahead.
548 UpdateAnimationsAndFloorTime();
549 }
550 }
551 animation_waiting_for_paint_ = false;
525 552
526 // Layout may generate more invalidation. It may also enable the 553 // Layout may generate more invalidation. It may also enable the
527 // GPU acceleration, so make sure to run layout before we send the 554 // GPU acceleration, so make sure to run layout before we send the
528 // GpuRenderingActivated message. 555 // GpuRenderingActivated message.
529 webwidget_->layout(); 556 webwidget_->layout();
530 557
531 // Suppress painting if nothing is dirty. This has to be done after updating 558 // Suppress painting if nothing is dirty. This has to be done after updating
532 // animations running layout as these may generate further invalidations. 559 // animations running layout as these may generate further invalidations.
533 if (!paint_aggregator_.HasPendingUpdate()) 560 if (!paint_aggregator_.HasPendingUpdate())
534 return; 561 return;
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 // TODO(nduca): replace with something a little less hacky. The reason this 735 // TODO(nduca): replace with something a little less hacky. The reason this
709 // hack is still used is because the Invalidate-DoDeferredUpdate loop 736 // hack is still used is because the Invalidate-DoDeferredUpdate loop
710 // contains a lot of host-renderer synchronization logic that is still 737 // contains a lot of host-renderer synchronization logic that is still
711 // important for the accelerated compositing case. The option of simply 738 // important for the accelerated compositing case. The option of simply
712 // duplicating all that code is less desirable than "faking out" the 739 // duplicating all that code is less desirable than "faking out" the
713 // invalidation path using a magical damage rect. 740 // invalidation path using a magical damage rect.
714 didInvalidateRect(WebRect(0, 0, 1, 1)); 741 didInvalidateRect(WebRect(0, 0, 1, 1));
715 } 742 }
716 743
717 void RenderWidget::scheduleAnimation() { 744 void RenderWidget::scheduleAnimation() {
718 if (!animation_update_pending_) { 745 if (!animation_update_pending_) {
719 animation_update_pending_ = true; 746 animation_update_pending_ = true;
720 animation_floor_time_ = 747 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
721 base::Time::Now() + base::TimeDelta::FromMilliseconds(10); 748 this, &RenderWidget::UpdateAnimationsIfNeeded));
722 MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod( 749 }
723 this, &RenderWidget::UpdateAnimationsIfNeeded), 10);
724 }
725 } 750 }
726 751
727 void RenderWidget::didChangeCursor(const WebCursorInfo& cursor_info) { 752 void RenderWidget::didChangeCursor(const WebCursorInfo& cursor_info) {
728 // TODO(darin): Eliminate this temporary. 753 // TODO(darin): Eliminate this temporary.
729 WebCursor cursor(cursor_info); 754 WebCursor cursor(cursor_info);
730 755
731 // Only send a SetCursor message if we need to make a change. 756 // Only send a SetCursor message if we need to make a change.
732 if (!current_cursor_.IsEqual(cursor)) { 757 if (!current_cursor_.IsEqual(cursor)) {
733 current_cursor_ = cursor; 758 current_cursor_ = cursor;
734 Send(new ViewHostMsg_SetCursor(routing_id_, cursor)); 759 Send(new ViewHostMsg_SetCursor(routing_id_, cursor));
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 1094
1070 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { 1095 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) {
1071 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin(); 1096 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin();
1072 i != plugin_window_moves_.end(); ++i) { 1097 i != plugin_window_moves_.end(); ++i) {
1073 if (i->window == window) { 1098 if (i->window == window) {
1074 plugin_window_moves_.erase(i); 1099 plugin_window_moves_.erase(i);
1075 break; 1100 break;
1076 } 1101 }
1077 } 1102 }
1078 } 1103 }
OLDNEW
« no previous file with comments | « chrome/renderer/render_widget.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698