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

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

Issue 11858007: Splits SmoothGestureController from RenderWidgetHostImpl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Single smooth scroll Created 7 years, 10 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 11 matching lines...) Expand all
22 #include "content/browser/gpu/gpu_process_host_ui_shim.h" 22 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
23 #include "content/browser/gpu/gpu_surface_tracker.h" 23 #include "content/browser/gpu/gpu_surface_tracker.h"
24 #include "content/browser/renderer_host/backing_store.h" 24 #include "content/browser/renderer_host/backing_store.h"
25 #include "content/browser/renderer_host/backing_store_manager.h" 25 #include "content/browser/renderer_host/backing_store_manager.h"
26 #include "content/browser/renderer_host/gesture_event_filter.h" 26 #include "content/browser/renderer_host/gesture_event_filter.h"
27 #include "content/browser/renderer_host/overscroll_controller.h" 27 #include "content/browser/renderer_host/overscroll_controller.h"
28 #include "content/browser/renderer_host/render_process_host_impl.h" 28 #include "content/browser/renderer_host/render_process_host_impl.h"
29 #include "content/browser/renderer_host/render_view_host_impl.h" 29 #include "content/browser/renderer_host/render_view_host_impl.h"
30 #include "content/browser/renderer_host/render_widget_helper.h" 30 #include "content/browser/renderer_host/render_widget_helper.h"
31 #include "content/browser/renderer_host/render_widget_host_delegate.h" 31 #include "content/browser/renderer_host/render_widget_host_delegate.h"
32 #include "content/browser/renderer_host/smooth_scroll_gesture_controller.h"
32 #include "content/browser/renderer_host/tap_suppression_controller.h" 33 #include "content/browser/renderer_host/tap_suppression_controller.h"
33 #include "content/browser/renderer_host/touch_event_queue.h" 34 #include "content/browser/renderer_host/touch_event_queue.h"
34 #include "content/common/accessibility_messages.h" 35 #include "content/common/accessibility_messages.h"
35 #include "content/common/content_constants_internal.h" 36 #include "content/common/content_constants_internal.h"
36 #include "content/common/gpu/gpu_messages.h" 37 #include "content/common/gpu/gpu_messages.h"
37 #include "content/common/view_messages.h" 38 #include "content/common/view_messages.h"
38 #include "content/port/browser/render_widget_host_view_port.h" 39 #include "content/port/browser/render_widget_host_view_port.h"
39 #include "content/port/browser/smooth_scroll_gesture.h"
40 #include "content/public/browser/compositor_util.h" 40 #include "content/public/browser/compositor_util.h"
41 #include "content/public/browser/native_web_keyboard_event.h" 41 #include "content/public/browser/native_web_keyboard_event.h"
42 #include "content/public/browser/notification_service.h" 42 #include "content/public/browser/notification_service.h"
43 #include "content/public/browser/notification_types.h" 43 #include "content/public/browser/notification_types.h"
44 #include "content/public/browser/user_metrics.h" 44 #include "content/public/browser/user_metrics.h"
45 #include "content/public/common/content_constants.h" 45 #include "content/public/common/content_constants.h"
46 #include "content/public/common/content_switches.h" 46 #include "content/public/common/content_switches.h"
47 #include "content/public/common/result_codes.h" 47 #include "content/public/common/result_codes.h"
48 #include "skia/ext/image_operations.h" 48 #include "skia/ext/image_operations.h"
49 #include "skia/ext/platform_canvas.h" 49 #include "skia/ext/platform_canvas.h"
(...skipping 30 matching lines...) Expand all
80 80
81 namespace content { 81 namespace content {
82 namespace { 82 namespace {
83 83
84 // How long to (synchronously) wait for the renderer to respond with a 84 // How long to (synchronously) wait for the renderer to respond with a
85 // PaintRect message, when our backing-store is invalid, before giving up and 85 // PaintRect message, when our backing-store is invalid, before giving up and
86 // returning a null or incorrectly sized backing-store from GetBackingStore. 86 // returning a null or incorrectly sized backing-store from GetBackingStore.
87 // This timeout impacts the "choppiness" of our window resize perf. 87 // This timeout impacts the "choppiness" of our window resize perf.
88 const int kPaintMsgTimeoutMS = 50; 88 const int kPaintMsgTimeoutMS = 50;
89 89
90 // How many milliseconds apart synthetic scroll messages should be sent.
91 static const int kSyntheticScrollMessageIntervalMs = 8;
92
93 // Returns |true| if the two wheel events should be coalesced. 90 // Returns |true| if the two wheel events should be coalesced.
94 bool ShouldCoalesceMouseWheelEvents(const WebMouseWheelEvent& last_event, 91 bool ShouldCoalesceMouseWheelEvents(const WebMouseWheelEvent& last_event,
95 const WebMouseWheelEvent& new_event) { 92 const WebMouseWheelEvent& new_event) {
96 return last_event.modifiers == new_event.modifiers && 93 return last_event.modifiers == new_event.modifiers &&
97 last_event.scrollByPage == new_event.scrollByPage && 94 last_event.scrollByPage == new_event.scrollByPage &&
98 last_event.hasPreciseScrollingDeltas 95 last_event.hasPreciseScrollingDeltas
99 == new_event.hasPreciseScrollingDeltas && 96 == new_event.hasPreciseScrollingDeltas &&
100 last_event.phase == new_event.phase && 97 last_event.phase == new_event.phase &&
101 last_event.momentumPhase == new_event.momentumPhase; 98 last_event.momentumPhase == new_event.momentumPhase;
102 } 99 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 view_being_painted_(false), 167 view_being_painted_(false),
171 ignore_input_events_(false), 168 ignore_input_events_(false),
172 text_direction_updated_(false), 169 text_direction_updated_(false),
173 text_direction_(WebKit::WebTextDirectionLeftToRight), 170 text_direction_(WebKit::WebTextDirectionLeftToRight),
174 text_direction_canceled_(false), 171 text_direction_canceled_(false),
175 suppress_next_char_events_(false), 172 suppress_next_char_events_(false),
176 pending_mouse_lock_request_(false), 173 pending_mouse_lock_request_(false),
177 allow_privileged_mouse_lock_(false), 174 allow_privileged_mouse_lock_(false),
178 has_touch_handler_(false), 175 has_touch_handler_(false),
179 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 176 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
180 tick_active_smooth_scroll_gestures_task_posted_(false), 177 smooth_scroll_gesture_controller_(new SmoothScrollGestureController()),
181 touch_event_queue_(new TouchEventQueue(this)), 178 touch_event_queue_(new TouchEventQueue(this)),
182 gesture_event_filter_(new GestureEventFilter(this)), 179 gesture_event_filter_(new GestureEventFilter(this)),
183 touch_event_state_(INPUT_EVENT_ACK_STATE_UNKNOWN) { 180 touch_event_state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {
184 CHECK(delegate_); 181 CHECK(delegate_);
185 if (routing_id_ == MSG_ROUTING_NONE) { 182 if (routing_id_ == MSG_ROUTING_NONE) {
186 routing_id_ = process_->GetNextRoutingID(); 183 routing_id_ = process_->GetNextRoutingID();
187 surface_id_ = GpuSurfaceTracker::Get()->AddSurfaceForRenderer( 184 surface_id_ = GpuSurfaceTracker::Get()->AddSurfaceForRenderer(
188 process_->GetID(), 185 process_->GetID(),
189 routing_id_); 186 routing_id_);
190 } else { 187 } else {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 return; 295 return;
299 296
300 last_view_screen_rect_ = view_->GetViewBounds(); 297 last_view_screen_rect_ = view_->GetViewBounds();
301 last_window_screen_rect_ = view_->GetBoundsInRootWindow(); 298 last_window_screen_rect_ = view_->GetBoundsInRootWindow();
302 Send(new ViewMsg_UpdateScreenRects( 299 Send(new ViewMsg_UpdateScreenRects(
303 GetRoutingID(), last_view_screen_rect_, last_window_screen_rect_)); 300 GetRoutingID(), last_view_screen_rect_, last_window_screen_rect_));
304 waiting_for_screen_rects_ack_ = true; 301 waiting_for_screen_rects_ack_ = true;
305 } 302 }
306 303
307 int RenderWidgetHostImpl::SyntheticScrollMessageInterval() const { 304 int RenderWidgetHostImpl::SyntheticScrollMessageInterval() const {
308 return kSyntheticScrollMessageIntervalMs; 305 return smooth_scroll_gesture_controller_->SyntheticScrollMessageInterval();
309 } 306 }
310 307
311 void RenderWidgetHostImpl::SetOverscrollControllerEnabled(bool enabled) { 308 void RenderWidgetHostImpl::SetOverscrollControllerEnabled(bool enabled) {
312 if (!enabled) 309 if (!enabled)
313 overscroll_controller_.reset(); 310 overscroll_controller_.reset();
314 else if (!overscroll_controller_.get()) 311 else if (!overscroll_controller_.get())
315 overscroll_controller_.reset(new OverscrollController(this)); 312 overscroll_controller_.reset(new OverscrollController(this));
316 } 313 }
317 314
318 void RenderWidgetHostImpl::SuppressNextCharEvents() { 315 void RenderWidgetHostImpl::SuppressNextCharEvents() {
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after
1204 // However, the touch-events are not sent to the renderer. So send and ACK 1201 // However, the touch-events are not sent to the renderer. So send and ACK
1205 // to the touch-event queue immediately. Mark the event as not processed, 1202 // to the touch-event queue immediately. Mark the event as not processed,
1206 // to make sure that the touch-scroll gesture that initiated the 1203 // to make sure that the touch-scroll gesture that initiated the
1207 // overscroll is updated properly. 1204 // overscroll is updated properly.
1208 touch_event_queue_->ProcessTouchAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 1205 touch_event_queue_->ProcessTouchAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
1209 } 1206 }
1210 return; 1207 return;
1211 } 1208 }
1212 1209
1213 in_process_event_types_.push(input_event.type); 1210 in_process_event_types_.push(input_event.type);
1211 smooth_scroll_gesture_controller_->OnForwardInputEvent();
rjkroege 2013/02/21 19:26:33 In the SmoothScrollGestureController, you say that
bulach 2013/02/22 16:55:14 Done.
1214 1212
1215 // Transmit any pending wheel events on a non-wheel event. This ensures that 1213 // Transmit any pending wheel events on a non-wheel event. This ensures that
1216 // the renderer receives the final PhaseEnded wheel event, which is necessary 1214 // the renderer receives the final PhaseEnded wheel event, which is necessary
1217 // to terminate rubber-banding, for example. 1215 // to terminate rubber-banding, for example.
1218 if (input_event.type != WebInputEvent::MouseWheel) { 1216 if (input_event.type != WebInputEvent::MouseWheel) {
1219 for (size_t i = 0; i < coalesced_mouse_wheel_events_.size(); ++i) { 1217 for (size_t i = 0; i < coalesced_mouse_wheel_events_.size(); ++i) {
1220 SendInputEvent(coalesced_mouse_wheel_events_[i], 1218 SendInputEvent(coalesced_mouse_wheel_events_[i],
1221 sizeof(WebMouseWheelEvent), false); 1219 sizeof(WebMouseWheelEvent), false);
1222 } 1220 }
1223 coalesced_mouse_wheel_events_.clear(); 1221 coalesced_mouse_wheel_events_.clear();
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
1764 in_process_event_types_.pop(); 1762 in_process_event_types_.pop();
1765 1763
1766 // Log the time delta for processing an input event. 1764 // Log the time delta for processing an input event.
1767 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; 1765 TimeDelta delta = TimeTicks::Now() - input_event_start_time_;
1768 UMA_HISTOGRAM_TIMES("MPArch.RWH_InputEventDelta", delta); 1766 UMA_HISTOGRAM_TIMES("MPArch.RWH_InputEventDelta", delta);
1769 1767
1770 // Cancel pending hung renderer checks since the renderer is responsive. 1768 // Cancel pending hung renderer checks since the renderer is responsive.
1771 if (decrement_in_flight_event_count() == 0) 1769 if (decrement_in_flight_event_count() == 0)
1772 StopHangMonitorTimeout(); 1770 StopHangMonitorTimeout();
1773 1771
1774 // If an input ack is pending, then hold off ticking the gesture 1772 smooth_scroll_gesture_controller_->OnInputEventACK(this);
1775 // until we get an input ack.
1776 if (in_process_event_types_.empty() &&
1777 !active_smooth_scroll_gestures_.empty())
1778 TickActiveSmoothScrollGesture();
1779 1773
1780 int type = static_cast<int>(event_type); 1774 int type = static_cast<int>(event_type);
1781 if (type < WebInputEvent::Undefined) { 1775 if (type < WebInputEvent::Undefined) {
1782 RecordAction(UserMetricsAction("BadMessageTerminate_RWH2")); 1776 RecordAction(UserMetricsAction("BadMessageTerminate_RWH2"));
1783 process_->ReceivedBadMessage(); 1777 process_->ReceivedBadMessage();
1784 } else if (type == WebInputEvent::MouseMove) { 1778 } else if (type == WebInputEvent::MouseMove) {
1785 mouse_move_pending_ = false; 1779 mouse_move_pending_ = false;
1786 1780
1787 // now, we can send the next mouse move event 1781 // now, we can send the next mouse move event
1788 if (next_mouse_move_.get()) { 1782 if (next_mouse_move_.get()) {
(...skipping 19 matching lines...) Expand all
1808 // (OnInputEventAck) method, but not on other platforms; using 1802 // (OnInputEventAck) method, but not on other platforms; using
1809 // 'void' instead is just as safe (since NotificationSource 1803 // 'void' instead is just as safe (since NotificationSource
1810 // is not actually typesafe) and avoids this error. 1804 // is not actually typesafe) and avoids this error.
1811 NotificationService::current()->Notify( 1805 NotificationService::current()->Notify(
1812 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK, 1806 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK,
1813 Source<void>(this), 1807 Source<void>(this),
1814 Details<int>(&type)); 1808 Details<int>(&type));
1815 } 1809 }
1816 1810
1817 void RenderWidgetHostImpl::OnBeginSmoothScroll( 1811 void RenderWidgetHostImpl::OnBeginSmoothScroll(
1818 int gesture_id, const ViewHostMsg_BeginSmoothScroll_Params &params) { 1812 const ViewHostMsg_BeginSmoothScroll_Params& params,
1813 bool* smooth_scroll_started) {
1819 if (!view_) 1814 if (!view_)
1820 return; 1815 return;
1821 active_smooth_scroll_gestures_.insert( 1816 *smooth_scroll_started =
1822 std::make_pair(gesture_id, 1817 smooth_scroll_gesture_controller_->OnBeginSmoothScroll(view_, params);
1823 view_->CreateSmoothScrollGesture(
1824 params.scroll_down, params.pixels_to_scroll,
1825 params.mouse_event_x, params.mouse_event_y)));
1826
1827 // If an input ack is pending, then hold off ticking the gesture
1828 // until we get an input ack.
1829 if (!in_process_event_types_.empty())
1830 return;
1831 if (tick_active_smooth_scroll_gestures_task_posted_)
1832 return;
1833 TickActiveSmoothScrollGesture();
1834 }
1835
1836 void RenderWidgetHostImpl::TickActiveSmoothScrollGesture() {
1837 TRACE_EVENT0("input", "RenderWidgetHostImpl::TickActiveSmoothScrollGesture");
1838 tick_active_smooth_scroll_gestures_task_posted_ = false;
1839 if (active_smooth_scroll_gestures_.empty()) {
1840 TRACE_EVENT_INSTANT0("input", "EarlyOut_NoActiveScrollGesture");
1841 return;
1842 }
1843
1844 base::TimeTicks now = TimeTicks::HighResNow();
1845 base::TimeDelta preferred_interval =
1846 base::TimeDelta::FromMilliseconds(kSyntheticScrollMessageIntervalMs);
1847 base::TimeDelta time_until_next_ideal_interval =
1848 (last_smooth_scroll_gestures_tick_time_ + preferred_interval) -
1849 now;
1850 if (time_until_next_ideal_interval.InMilliseconds() > 0) {
1851 TRACE_EVENT_INSTANT1(
1852 "input", "EarlyOut_TickedTooRecently",
1853 "delay", time_until_next_ideal_interval.InMilliseconds());
1854 // Post a task.
1855 tick_active_smooth_scroll_gestures_task_posted_ = true;
1856 MessageLoop::current()->PostDelayedTask(
1857 FROM_HERE,
1858 base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture,
1859 weak_factory_.GetWeakPtr()),
1860 time_until_next_ideal_interval);
1861 return;
1862 }
1863
1864 last_smooth_scroll_gestures_tick_time_ = now;
1865
1866 // Separate ticking of gestures from sending their completion messages.
1867 std::vector<int> ids_that_are_done;
1868 for (SmoothScrollGestureMap::iterator it =
1869 active_smooth_scroll_gestures_.begin();
1870 it != active_smooth_scroll_gestures_.end();
1871 ++it) {
1872
1873 bool active = it->second->ForwardInputEvents(now, this);
1874 if (!active)
1875 ids_that_are_done.push_back(it->first);
1876 }
1877
1878 // Delete completed gestures and send their completion event.
1879 for(size_t i = 0; i < ids_that_are_done.size(); i++) {
1880 int id = ids_that_are_done[i];
1881 SmoothScrollGestureMap::iterator it =
1882 active_smooth_scroll_gestures_.find(id);
1883 DCHECK(it != active_smooth_scroll_gestures_.end());
1884 active_smooth_scroll_gestures_.erase(it);
1885
1886 Send(new ViewMsg_SmoothScrollCompleted(routing_id_, id));
1887 }
1888
1889 // No need to post the next tick if an input is in flight.
1890 if (!in_process_event_types_.empty())
1891 return;
1892
1893 TRACE_EVENT_INSTANT1("input", "PostTickTask",
1894 "delay", preferred_interval.InMilliseconds());
1895 tick_active_smooth_scroll_gestures_task_posted_ = true;
1896 MessageLoop::current()->PostDelayedTask(
1897 FROM_HERE,
1898 base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture,
1899 weak_factory_.GetWeakPtr()),
1900 preferred_interval);
1901 } 1818 }
1902 1819
1903 void RenderWidgetHostImpl::OnSelectRangeAck() { 1820 void RenderWidgetHostImpl::OnSelectRangeAck() {
1904 select_range_pending_ = false; 1821 select_range_pending_ = false;
1905 if (next_selection_range_.get()) { 1822 if (next_selection_range_.get()) {
1906 scoped_ptr<SelectionRange> next(next_selection_range_.Pass()); 1823 scoped_ptr<SelectionRange> next(next_selection_range_.Pass());
1907 SelectRange(next->start, next->end); 1824 SelectRange(next->start, next->end);
1908 } 1825 }
1909 } 1826 }
1910 1827
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
2430 return; 2347 return;
2431 2348
2432 OnRenderAutoResized(new_size); 2349 OnRenderAutoResized(new_size);
2433 } 2350 }
2434 2351
2435 void RenderWidgetHostImpl::DetachDelegate() { 2352 void RenderWidgetHostImpl::DetachDelegate() {
2436 delegate_ = NULL; 2353 delegate_ = NULL;
2437 } 2354 }
2438 2355
2439 } // namespace content 2356 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698