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

Side by Side Diff: content/browser/renderer_host/render_widget_host_impl.cc

Issue 11013043: beginSmoothScroll should send wheel ticks at constant velocity. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 2 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/browser/renderer_host/render_widget_host_impl.h" 5 #include "content/browser/renderer_host/render_widget_host_impl.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 view_being_painted_(false), 140 view_being_painted_(false),
141 ignore_input_events_(false), 141 ignore_input_events_(false),
142 text_direction_updated_(false), 142 text_direction_updated_(false),
143 text_direction_(WebKit::WebTextDirectionLeftToRight), 143 text_direction_(WebKit::WebTextDirectionLeftToRight),
144 text_direction_canceled_(false), 144 text_direction_canceled_(false),
145 suppress_next_char_events_(false), 145 suppress_next_char_events_(false),
146 pending_mouse_lock_request_(false), 146 pending_mouse_lock_request_(false),
147 allow_privileged_mouse_lock_(false), 147 allow_privileged_mouse_lock_(false),
148 has_touch_handler_(false), 148 has_touch_handler_(false),
149 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 149 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
150 tick_active_smooth_scroll_gestures_task_posted_(false),
150 gesture_event_filter_(new GestureEventFilter(this)) { 151 gesture_event_filter_(new GestureEventFilter(this)) {
151 CHECK(delegate_); 152 CHECK(delegate_);
152 if (routing_id_ == MSG_ROUTING_NONE) { 153 if (routing_id_ == MSG_ROUTING_NONE) {
153 routing_id_ = process_->GetNextRoutingID(); 154 routing_id_ = process_->GetNextRoutingID();
154 surface_id_ = GpuSurfaceTracker::Get()->AddSurfaceForRenderer( 155 surface_id_ = GpuSurfaceTracker::Get()->AddSurfaceForRenderer(
155 process_->GetID(), 156 process_->GetID(),
156 routing_id_); 157 routing_id_);
157 } else { 158 } else {
158 // TODO(piman): This is a O(N) lookup, where we could forward the 159 // TODO(piman): This is a O(N) lookup, where we could forward the
159 // information from the RenderWidgetHelper. The problem is that doing so 160 // information from the RenderWidgetHelper. The problem is that doing so
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1585 } else if (WebInputEvent::isKeyboardEventType(type)) { 1586 } else if (WebInputEvent::isKeyboardEventType(type)) {
1586 ProcessKeyboardEventAck(type, processed); 1587 ProcessKeyboardEventAck(type, processed);
1587 } else if (type == WebInputEvent::MouseWheel) { 1588 } else if (type == WebInputEvent::MouseWheel) {
1588 ProcessWheelAck(processed); 1589 ProcessWheelAck(processed);
1589 } else if (WebInputEvent::isTouchEventType(type)) { 1590 } else if (WebInputEvent::isTouchEventType(type)) {
1590 ProcessTouchAck(event_type, processed); 1591 ProcessTouchAck(event_type, processed);
1591 } else if (WebInputEvent::isGestureEventType(type)) { 1592 } else if (WebInputEvent::isGestureEventType(type)) {
1592 ProcessGestureAck(processed, type); 1593 ProcessGestureAck(processed, type);
1593 } 1594 }
1594 1595
1596 // If an input ack is pending, then hold off ticking the gesture
1597 // until we get an input ack.
1598 if (in_process_event_types_.size() == 0 &&
1599 !active_smooth_scroll_gestures_.empty())
1600 TickActiveSmoothScrollGesture();
1601
1595 // This is used only for testing, and the other end does not use the 1602 // This is used only for testing, and the other end does not use the
1596 // source object. On linux, specifying 1603 // source object. On linux, specifying
1597 // Source<RenderWidgetHost> results in a very strange 1604 // Source<RenderWidgetHost> results in a very strange
1598 // runtime error in the epilogue of the enclosing 1605 // runtime error in the epilogue of the enclosing
1599 // (OnMsgInputEventAck) method, but not on other platforms; using 1606 // (OnMsgInputEventAck) method, but not on other platforms; using
1600 // 'void' instead is just as safe (since NotificationSource 1607 // 'void' instead is just as safe (since NotificationSource
1601 // is not actually typesafe) and avoids this error. 1608 // is not actually typesafe) and avoids this error.
1602 NotificationService::current()->Notify( 1609 NotificationService::current()->Notify(
1603 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK, 1610 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK,
1604 Source<void>(this), 1611 Source<void>(this),
1605 Details<int>(&type)); 1612 Details<int>(&type));
1606 } 1613 }
1607 1614
1608 void RenderWidgetHostImpl::OnMsgBeginSmoothScroll( 1615 void RenderWidgetHostImpl::OnMsgBeginSmoothScroll(
1609 int gesture_id, bool scroll_down, bool scroll_far, int mouse_event_x, 1616 int gesture_id, bool scroll_down, bool scroll_far, int mouse_event_x,
1610 int mouse_event_y) { 1617 int mouse_event_y) {
1611 if (!view_) 1618 if (!view_)
1612 return; 1619 return;
1613 active_smooth_scroll_gestures_.insert( 1620 active_smooth_scroll_gestures_.insert(
1614 std::make_pair(gesture_id, 1621 std::make_pair(gesture_id,
1615 view_->CreateSmoothScrollGesture( 1622 view_->CreateSmoothScrollGesture(
1616 scroll_down, scroll_far, mouse_event_x, 1623 scroll_down, scroll_far, mouse_event_x,
1617 mouse_event_y))); 1624 mouse_event_y)));
1625
1626 // If an input ack is pending, then hold off ticking the gesture
1627 // until we get an input ack.
1628 if (!in_process_event_types_.empty())
1629 return;
1630 if (tick_active_smooth_scroll_gestures_task_posted_)
1631 return;
1618 TickActiveSmoothScrollGesture(); 1632 TickActiveSmoothScrollGesture();
1619 } 1633 }
1620 1634
1621 void RenderWidgetHostImpl::TickActiveSmoothScrollGesture() { 1635 void RenderWidgetHostImpl::TickActiveSmoothScrollGesture() {
1622 if (active_smooth_scroll_gestures_.size() == 0) 1636 TRACE_EVENT0("input", "RenderWidgetHostImpl::TickActiveSmoothScrollGesture");
1637 tick_active_smooth_scroll_gestures_task_posted_ = false;
1638 if (active_smooth_scroll_gestures_.empty()) {
1639 TRACE_EVENT_INSTANT0("input", "EarlyOut_NoActiveScrollGesture");
1623 return; 1640 return;
1641 }
1624 1642
1625 TimeTicks now = TimeTicks::HighResNow(); 1643 base::TimeTicks now = TimeTicks::HighResNow();
1644 base::TimeDelta preferred_interval =
1645 base::TimeDelta::FromMilliseconds(kSyntheticScrollMessageIntervalMs);
1646 base::TimeDelta time_until_next_ideal_interval =
1647 (last_smooth_scroll_gestures_tick_time_ + preferred_interval) -
1648 now;
1649 if (time_until_next_ideal_interval.InMilliseconds() > 0) {
1650 TRACE_EVENT_INSTANT1(
1651 "input", "EarlyOut_TickedTooRecently",
1652 "delay", time_until_next_ideal_interval.InMilliseconds());
1653 // Post a task.
1654 tick_active_smooth_scroll_gestures_task_posted_ = true;
1655 MessageLoop::current()->PostDelayedTask(
1656 FROM_HERE,
1657 base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture,
1658 weak_factory_.GetWeakPtr()),
1659 time_until_next_ideal_interval);
1660 return;
1661 }
1626 1662
1627 // Post the next tick right away so it is regular. 1663 last_smooth_scroll_gestures_tick_time_ = now;
1628 MessageLoop::current()->PostDelayedTask(
1629 FROM_HERE,
1630 base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture,
1631 weak_factory_.GetWeakPtr()),
1632 base::TimeDelta::FromMilliseconds(kSyntheticScrollMessageIntervalMs));
1633 1664
1634 // Separate ticking of gestures from sending their completion messages. 1665 // Separate ticking of gestures from sending their completion messages.
1635 std::vector<int> ids_that_are_done; 1666 std::vector<int> ids_that_are_done;
1636 for (SmoothScrollGestureMap::iterator it = 1667 for (SmoothScrollGestureMap::iterator it =
1637 active_smooth_scroll_gestures_.begin(); 1668 active_smooth_scroll_gestures_.begin();
1638 it != active_smooth_scroll_gestures_.end(); 1669 it != active_smooth_scroll_gestures_.end();
1639 ++it) { 1670 ++it) {
1640 1671
1641 bool active = it->second->ForwardInputEvents(now, this); 1672 bool active = it->second->ForwardInputEvents(now, this);
1642 if (!active) 1673 if (!active)
1643 ids_that_are_done.push_back(it->first); 1674 ids_that_are_done.push_back(it->first);
1644 } 1675 }
1645 1676
1646 // Delete completed gestures and send their completion event. 1677 // Delete completed gestures and send their completion event.
1647 for(size_t i = 0; i < ids_that_are_done.size(); i++) { 1678 for(size_t i = 0; i < ids_that_are_done.size(); i++) {
1648 int id = ids_that_are_done[i]; 1679 int id = ids_that_are_done[i];
1649 SmoothScrollGestureMap::iterator it = 1680 SmoothScrollGestureMap::iterator it =
1650 active_smooth_scroll_gestures_.find(id); 1681 active_smooth_scroll_gestures_.find(id);
1651 DCHECK(it != active_smooth_scroll_gestures_.end()); 1682 DCHECK(it != active_smooth_scroll_gestures_.end());
1652 active_smooth_scroll_gestures_.erase(it); 1683 active_smooth_scroll_gestures_.erase(it);
1653 1684
1654 Send(new ViewMsg_SmoothScrollCompleted(routing_id_, id)); 1685 Send(new ViewMsg_SmoothScrollCompleted(routing_id_, id));
1655 } 1686 }
1687
1688 // No need to post the next tick if an input is in flight.
1689 if (!in_process_event_types_.empty())
1690 return;
1691
1692 TRACE_EVENT_INSTANT1("input", "PostTickTask",
1693 "delay", preferred_interval.InMilliseconds());
1694 tick_active_smooth_scroll_gestures_task_posted_ = true;
1695 MessageLoop::current()->PostDelayedTask(
1696 FROM_HERE,
1697 base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture,
1698 weak_factory_.GetWeakPtr()),
1699 preferred_interval);
1656 } 1700 }
1657 1701
1658 void RenderWidgetHostImpl::OnMsgSelectRangeAck() { 1702 void RenderWidgetHostImpl::OnMsgSelectRangeAck() {
1659 select_range_pending_ = false; 1703 select_range_pending_ = false;
1660 if (next_selection_range_.get()) { 1704 if (next_selection_range_.get()) {
1661 scoped_ptr<SelectionRange> next(next_selection_range_.Pass()); 1705 scoped_ptr<SelectionRange> next(next_selection_range_.Pass());
1662 SelectRange(next->start, next->end); 1706 SelectRange(next->start, next->end);
1663 } 1707 }
1664 } 1708 }
1665 1709
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
2075 return; 2119 return;
2076 2120
2077 OnRenderAutoResized(new_size); 2121 OnRenderAutoResized(new_size);
2078 } 2122 }
2079 2123
2080 void RenderWidgetHostImpl::DetachDelegate() { 2124 void RenderWidgetHostImpl::DetachDelegate() {
2081 delegate_ = NULL; 2125 delegate_ = NULL;
2082 } 2126 }
2083 2127
2084 } // namespace content 2128 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_impl.h ('k') | content/browser/renderer_host/render_widget_host_view_base.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698