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 |