OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 ¶ms) { | 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 Loading... | |
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 |
OLD | NEW |