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; |
| 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 Loading... | |
| 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 } |
| OLD | NEW |