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 |