Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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; |
| 606 base::Time now = base::Time::Now(); | 607 if(IsRenderingVSyncd()) { |
| 607 if (now >= animation_floor_time_) { | 608 base::Time now = base::Time::Now(); |
| 608 animation_floor_time_ = now + base::TimeDelta::FromMilliseconds(16); | 609 if (now >= animation_floor_time_) { |
| 609 // Set a timer to call us back after 16ms (targetting 60FPS) before | 610 animation_floor_time_ = now + base::TimeDelta::FromMilliseconds(16); |
| 610 // running animation callbacks so that if a callback requests another | 611 // Set a timer to call us back after 16ms (targetting 60FPS) before |
| 611 // we'll be sure to run it at the proper time. | 612 // running animation callbacks so that if a callback requests another |
| 612 MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod( | 613 // we'll be sure to run it at the proper time. |
| 613 this, &RenderWidget::AnimationCallback), 16); | 614 MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod( |
| 615 this, &RenderWidget::AnimationCallback), 16); | |
|
jamesr
2011/05/26 02:20:15
would it be sufficient to leave this function unch
| |
| 616 animation_task_posted_ = true; | |
| 617 animation_update_pending_ = false; | |
| 618 #ifdef WEBWIDGET_HAS_ANIMATE_CHANGES | |
| 619 webwidget_->animate(0.0); | |
| 620 #else | |
| 621 webwidget_->animate(); | |
| 622 #endif | |
| 623 return; | |
| 624 } | |
| 625 TRACE_EVENT0("renderer", "EarlyOut_AnimatedInLast16ms"); | |
| 626 if (animation_task_posted_) | |
| 627 return; | |
| 628 // This code uses base::Time::Now() to calculate the floor and next fire | |
| 629 // time because javascript's Date object uses base::Time::Now(). The | |
| 630 // message loop uses base::TimeTicks, which on windows can have a | |
| 631 // different granularity than base::Time. | |
| 632 // The upshot of all this is that this function might be called before | |
| 633 // base::Time::Now() has advanced past the animation_floor_time_. To | |
| 634 // avoid exposing this delay to javascript, we keep posting delayed | |
| 635 // tasks until base::Time::Now() has advanced far enough. | |
| 636 int64 delay = (animation_floor_time_ - now).InMillisecondsRoundedUp(); | |
| 614 animation_task_posted_ = true; | 637 animation_task_posted_ = true; |
| 638 MessageLoop::current()->PostDelayedTask(FROM_HERE, | |
| 639 NewRunnableMethod(this, &RenderWidget::AnimationCallback), delay); | |
| 640 } else { | |
| 615 animation_update_pending_ = false; | 641 animation_update_pending_ = false; |
| 616 #ifdef WEBWIDGET_HAS_ANIMATE_CHANGES | 642 #ifdef WEBWIDGET_HAS_ANIMATE_CHANGES |
| 617 webwidget_->animate(0.0); | 643 webwidget_->animate(0.0); |
| 618 #else | 644 #else |
| 619 webwidget_->animate(); | 645 webwidget_->animate(); |
| 620 #endif | 646 #endif |
| 621 return; | 647 // Set a delayed task to call us back "immediately" if more animation is |
| 648 // requested, using delayed tasks to keep scheduling consistent. If we have | |
| 649 // hit the throttling threshold for swapbuffers, this task will be harmless. | |
| 650 // so that we get equivalent scheduling to the non-vsync'd case. | |
| 651 if(animation_update_pending_) { | |
| 652 MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod( | |
| 653 this, &RenderWidget::AnimationCallback), 0); | |
| 654 animation_task_posted_ = true; | |
| 655 } | |
| 622 } | 656 } |
| 623 if (animation_task_posted_) | 657 } |
| 624 return; | 658 |
| 625 // This code uses base::Time::Now() to calculate the floor and next fire | 659 bool RenderWidget::IsRenderingVSyncd() { |
| 626 // time because javascript's Date object uses base::Time::Now(). The | 660 // TODO(nduca): Forcing a driver to disable vsync (e.g. in a control panel) is |
| 627 // message loop uses base::TimeTicks, which on windows can have a | 661 // not caught by this check. This will lead to artificially low frame rates |
| 628 // different granularity than base::Time. | 662 // for people who force vsync off at a driver level and expect Chrome to speed |
| 629 // The upshot of all this is that this function might be called before | 663 // up. |
| 630 // base::Time::Now() has advanced past the animation_floor_time_. To | 664 return !CommandLine::ForCurrentProcess()->HasSwitch( |
| 631 // avoid exposing this delay to javascript, we keep posting delayed | 665 switches::kDisableGpuVsync); |
| 632 // tasks until base::Time::Now() has advanced far enough. | |
| 633 int64 delay = (animation_floor_time_ - now).InMillisecondsRoundedUp(); | |
| 634 animation_task_posted_ = true; | |
| 635 MessageLoop::current()->PostDelayedTask(FROM_HERE, | |
| 636 NewRunnableMethod(this, &RenderWidget::AnimationCallback), delay); | |
| 637 } | 666 } |
| 638 | 667 |
| 639 void RenderWidget::InvalidationCallback() { | 668 void RenderWidget::InvalidationCallback() { |
| 640 invalidation_task_posted_ = false; | 669 invalidation_task_posted_ = false; |
| 641 DoDeferredUpdateAndSendInputAck(); | 670 DoDeferredUpdateAndSendInputAck(); |
| 642 } | 671 } |
| 643 | 672 |
| 644 void RenderWidget::DoDeferredUpdateAndSendInputAck() { | 673 void RenderWidget::DoDeferredUpdateAndSendInputAck() { |
| 645 DoDeferredUpdate(); | 674 DoDeferredUpdate(); |
| 646 | 675 |
| (...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1306 | 1335 |
| 1307 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { | 1336 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { |
| 1308 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin(); | 1337 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin(); |
| 1309 i != plugin_window_moves_.end(); ++i) { | 1338 i != plugin_window_moves_.end(); ++i) { |
| 1310 if (i->window == window) { | 1339 if (i->window == window) { |
| 1311 plugin_window_moves_.erase(i); | 1340 plugin_window_moves_.erase(i); |
| 1312 break; | 1341 break; |
| 1313 } | 1342 } |
| 1314 } | 1343 } |
| 1315 } | 1344 } |
| OLD | NEW |