Chromium Code Reviews| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 view_being_painted_(false), | 154 view_being_painted_(false), |
| 158 ignore_input_events_(false), | 155 ignore_input_events_(false), |
| 159 text_direction_updated_(false), | 156 text_direction_updated_(false), |
| 160 text_direction_(WebKit::WebTextDirectionLeftToRight), | 157 text_direction_(WebKit::WebTextDirectionLeftToRight), |
| 161 text_direction_canceled_(false), | 158 text_direction_canceled_(false), |
| 162 suppress_next_char_events_(false), | 159 suppress_next_char_events_(false), |
| 163 pending_mouse_lock_request_(false), | 160 pending_mouse_lock_request_(false), |
| 164 allow_privileged_mouse_lock_(false), | 161 allow_privileged_mouse_lock_(false), |
| 165 has_touch_handler_(false), | 162 has_touch_handler_(false), |
| 166 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 163 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 167 tick_active_smooth_scroll_gestures_task_posted_(false), | 164 smooth_scroll_gesture_controller_(new SmoothScrollGestureController()), |
| 168 touch_event_queue_(new TouchEventQueue(this)), | 165 touch_event_queue_(new TouchEventQueue(this)), |
| 169 gesture_event_filter_(new GestureEventFilter(this)) { | 166 gesture_event_filter_(new GestureEventFilter(this)) { |
| 170 CHECK(delegate_); | 167 CHECK(delegate_); |
| 171 if (routing_id_ == MSG_ROUTING_NONE) { | 168 if (routing_id_ == MSG_ROUTING_NONE) { |
| 172 routing_id_ = process_->GetNextRoutingID(); | 169 routing_id_ = process_->GetNextRoutingID(); |
| 173 surface_id_ = GpuSurfaceTracker::Get()->AddSurfaceForRenderer( | 170 surface_id_ = GpuSurfaceTracker::Get()->AddSurfaceForRenderer( |
| 174 process_->GetID(), | 171 process_->GetID(), |
| 175 routing_id_); | 172 routing_id_); |
| 176 } else { | 173 } else { |
| 177 // TODO(piman): This is a O(N) lookup, where we could forward the | 174 // TODO(piman): This is a O(N) lookup, where we could forward the |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 284 return; | 281 return; |
| 285 | 282 |
| 286 last_view_screen_rect_ = view_->GetViewBounds(); | 283 last_view_screen_rect_ = view_->GetViewBounds(); |
| 287 last_window_screen_rect_ = view_->GetBoundsInRootWindow(); | 284 last_window_screen_rect_ = view_->GetBoundsInRootWindow(); |
| 288 Send(new ViewMsg_UpdateScreenRects( | 285 Send(new ViewMsg_UpdateScreenRects( |
| 289 GetRoutingID(), last_view_screen_rect_, last_window_screen_rect_)); | 286 GetRoutingID(), last_view_screen_rect_, last_window_screen_rect_)); |
| 290 waiting_for_screen_rects_ack_ = true; | 287 waiting_for_screen_rects_ack_ = true; |
| 291 } | 288 } |
| 292 | 289 |
| 293 int RenderWidgetHostImpl::SyntheticScrollMessageInterval() const { | 290 int RenderWidgetHostImpl::SyntheticScrollMessageInterval() const { |
| 294 return kSyntheticScrollMessageIntervalMs; | 291 return smooth_scroll_gesture_controller_->SyntheticScrollMessageInterval(); |
| 295 } | 292 } |
| 296 | 293 |
| 297 void RenderWidgetHostImpl::SetOverscrollControllerEnabled(bool enabled) { | 294 void RenderWidgetHostImpl::SetOverscrollControllerEnabled(bool enabled) { |
| 298 if (!enabled) | 295 if (!enabled) |
| 299 overscroll_controller_.reset(); | 296 overscroll_controller_.reset(); |
| 300 else if (!overscroll_controller_.get()) | 297 else if (!overscroll_controller_.get()) |
| 301 overscroll_controller_.reset(new OverscrollController(this)); | 298 overscroll_controller_.reset(new OverscrollController(this)); |
| 302 } | 299 } |
| 303 | 300 |
| 304 void RenderWidgetHostImpl::SuppressNextCharEvents() { | 301 void RenderWidgetHostImpl::SuppressNextCharEvents() { |
| (...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1162 return; | 1159 return; |
| 1163 } | 1160 } |
| 1164 | 1161 |
| 1165 in_process_event_types_.push(input_event.type); | 1162 in_process_event_types_.push(input_event.type); |
| 1166 | 1163 |
| 1167 // Transmit any pending wheel events on a non-wheel event. This ensures that | 1164 // Transmit any pending wheel events on a non-wheel event. This ensures that |
| 1168 // the renderer receives the final PhaseEnded wheel event, which is necessary | 1165 // the renderer receives the final PhaseEnded wheel event, which is necessary |
| 1169 // to terminate rubber-banding, for example. | 1166 // to terminate rubber-banding, for example. |
| 1170 if (input_event.type != WebInputEvent::MouseWheel) { | 1167 if (input_event.type != WebInputEvent::MouseWheel) { |
| 1171 for (size_t i = 0; i < coalesced_mouse_wheel_events_.size(); ++i) { | 1168 for (size_t i = 0; i < coalesced_mouse_wheel_events_.size(); ++i) { |
| 1172 SendInputEvent(coalesced_mouse_wheel_events_[i], | 1169 SendInputEvent(coalesced_mouse_wheel_events_[i], |
|
rjkroege
2013/02/22 17:24:37
you need it before this one too yes?
sadrul
2013/02/22 17:26:45
I think it makes sense to move both in_process_eve
bulach
2013/02/25 09:16:03
yeah, looks better, thanks!
| |
| 1173 sizeof(WebMouseWheelEvent), false); | 1170 sizeof(WebMouseWheelEvent), false); |
| 1174 } | 1171 } |
| 1175 coalesced_mouse_wheel_events_.clear(); | 1172 coalesced_mouse_wheel_events_.clear(); |
| 1176 } | 1173 } |
| 1177 | 1174 |
| 1175 smooth_scroll_gesture_controller_->OnForwardInputEvent(); | |
| 1178 SendInputEvent(input_event, event_size, is_keyboard_shortcut); | 1176 SendInputEvent(input_event, event_size, is_keyboard_shortcut); |
| 1179 | 1177 |
| 1180 // Any input event cancels a pending mouse move event. Note that | 1178 // Any input event cancels a pending mouse move event. Note that |
| 1181 // |next_mouse_move_| possibly owns |input_event|, so don't use |input_event| | 1179 // |next_mouse_move_| possibly owns |input_event|, so don't use |input_event| |
| 1182 // after this line. | 1180 // after this line. |
| 1183 next_mouse_move_.reset(); | 1181 next_mouse_move_.reset(); |
| 1184 | 1182 |
| 1185 StartHangMonitorTimeout( | 1183 StartHangMonitorTimeout( |
| 1186 TimeDelta::FromMilliseconds(hung_renderer_delay_ms_)); | 1184 TimeDelta::FromMilliseconds(hung_renderer_delay_ms_)); |
| 1187 } | 1185 } |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1715 in_process_event_types_.pop(); | 1713 in_process_event_types_.pop(); |
| 1716 | 1714 |
| 1717 // Log the time delta for processing an input event. | 1715 // Log the time delta for processing an input event. |
| 1718 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; | 1716 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; |
| 1719 UMA_HISTOGRAM_TIMES("MPArch.RWH_InputEventDelta", delta); | 1717 UMA_HISTOGRAM_TIMES("MPArch.RWH_InputEventDelta", delta); |
| 1720 | 1718 |
| 1721 // Cancel pending hung renderer checks since the renderer is responsive. | 1719 // Cancel pending hung renderer checks since the renderer is responsive. |
| 1722 if (decrement_in_flight_event_count() == 0) | 1720 if (decrement_in_flight_event_count() == 0) |
| 1723 StopHangMonitorTimeout(); | 1721 StopHangMonitorTimeout(); |
| 1724 | 1722 |
| 1725 // If an input ack is pending, then hold off ticking the gesture | 1723 smooth_scroll_gesture_controller_->OnInputEventACK(this); |
| 1726 // until we get an input ack. | |
| 1727 if (in_process_event_types_.empty() && | |
| 1728 !active_smooth_scroll_gestures_.empty()) | |
| 1729 TickActiveSmoothScrollGesture(); | |
| 1730 | 1724 |
| 1731 int type = static_cast<int>(event_type); | 1725 int type = static_cast<int>(event_type); |
| 1732 if (type < WebInputEvent::Undefined) { | 1726 if (type < WebInputEvent::Undefined) { |
| 1733 RecordAction(UserMetricsAction("BadMessageTerminate_RWH2")); | 1727 RecordAction(UserMetricsAction("BadMessageTerminate_RWH2")); |
| 1734 process_->ReceivedBadMessage(); | 1728 process_->ReceivedBadMessage(); |
| 1735 } else if (type == WebInputEvent::MouseMove) { | 1729 } else if (type == WebInputEvent::MouseMove) { |
| 1736 mouse_move_pending_ = false; | 1730 mouse_move_pending_ = false; |
| 1737 | 1731 |
| 1738 // now, we can send the next mouse move event | 1732 // now, we can send the next mouse move event |
| 1739 if (next_mouse_move_.get()) { | 1733 if (next_mouse_move_.get()) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1759 // (OnInputEventAck) method, but not on other platforms; using | 1753 // (OnInputEventAck) method, but not on other platforms; using |
| 1760 // 'void' instead is just as safe (since NotificationSource | 1754 // 'void' instead is just as safe (since NotificationSource |
| 1761 // is not actually typesafe) and avoids this error. | 1755 // is not actually typesafe) and avoids this error. |
| 1762 NotificationService::current()->Notify( | 1756 NotificationService::current()->Notify( |
| 1763 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK, | 1757 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK, |
| 1764 Source<void>(this), | 1758 Source<void>(this), |
| 1765 Details<int>(&type)); | 1759 Details<int>(&type)); |
| 1766 } | 1760 } |
| 1767 | 1761 |
| 1768 void RenderWidgetHostImpl::OnBeginSmoothScroll( | 1762 void RenderWidgetHostImpl::OnBeginSmoothScroll( |
| 1769 int gesture_id, const ViewHostMsg_BeginSmoothScroll_Params ¶ms) { | 1763 const ViewHostMsg_BeginSmoothScroll_Params& params, |
| 1764 bool* smooth_scroll_started) { | |
| 1770 if (!view_) | 1765 if (!view_) |
| 1771 return; | 1766 return; |
| 1772 active_smooth_scroll_gestures_.insert( | 1767 *smooth_scroll_started = |
| 1773 std::make_pair(gesture_id, | 1768 smooth_scroll_gesture_controller_->OnBeginSmoothScroll(view_, params); |
| 1774 view_->CreateSmoothScrollGesture( | |
| 1775 params.scroll_down, params.pixels_to_scroll, | |
| 1776 params.mouse_event_x, params.mouse_event_y))); | |
| 1777 | |
| 1778 // If an input ack is pending, then hold off ticking the gesture | |
| 1779 // until we get an input ack. | |
| 1780 if (!in_process_event_types_.empty()) | |
| 1781 return; | |
| 1782 if (tick_active_smooth_scroll_gestures_task_posted_) | |
| 1783 return; | |
| 1784 TickActiveSmoothScrollGesture(); | |
| 1785 } | |
| 1786 | |
| 1787 void RenderWidgetHostImpl::TickActiveSmoothScrollGesture() { | |
| 1788 TRACE_EVENT0("input", "RenderWidgetHostImpl::TickActiveSmoothScrollGesture"); | |
| 1789 tick_active_smooth_scroll_gestures_task_posted_ = false; | |
| 1790 if (active_smooth_scroll_gestures_.empty()) { | |
| 1791 TRACE_EVENT_INSTANT0("input", "EarlyOut_NoActiveScrollGesture"); | |
| 1792 return; | |
| 1793 } | |
| 1794 | |
| 1795 base::TimeTicks now = TimeTicks::HighResNow(); | |
| 1796 base::TimeDelta preferred_interval = | |
| 1797 base::TimeDelta::FromMilliseconds(kSyntheticScrollMessageIntervalMs); | |
| 1798 base::TimeDelta time_until_next_ideal_interval = | |
| 1799 (last_smooth_scroll_gestures_tick_time_ + preferred_interval) - | |
| 1800 now; | |
| 1801 if (time_until_next_ideal_interval.InMilliseconds() > 0) { | |
| 1802 TRACE_EVENT_INSTANT1( | |
| 1803 "input", "EarlyOut_TickedTooRecently", | |
| 1804 "delay", time_until_next_ideal_interval.InMilliseconds()); | |
| 1805 // Post a task. | |
| 1806 tick_active_smooth_scroll_gestures_task_posted_ = true; | |
| 1807 MessageLoop::current()->PostDelayedTask( | |
| 1808 FROM_HERE, | |
| 1809 base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture, | |
| 1810 weak_factory_.GetWeakPtr()), | |
| 1811 time_until_next_ideal_interval); | |
| 1812 return; | |
| 1813 } | |
| 1814 | |
| 1815 last_smooth_scroll_gestures_tick_time_ = now; | |
| 1816 | |
| 1817 // Separate ticking of gestures from sending their completion messages. | |
| 1818 std::vector<int> ids_that_are_done; | |
| 1819 for (SmoothScrollGestureMap::iterator it = | |
| 1820 active_smooth_scroll_gestures_.begin(); | |
| 1821 it != active_smooth_scroll_gestures_.end(); | |
| 1822 ++it) { | |
| 1823 | |
| 1824 bool active = it->second->ForwardInputEvents(now, this); | |
| 1825 if (!active) | |
| 1826 ids_that_are_done.push_back(it->first); | |
| 1827 } | |
| 1828 | |
| 1829 // Delete completed gestures and send their completion event. | |
| 1830 for(size_t i = 0; i < ids_that_are_done.size(); i++) { | |
| 1831 int id = ids_that_are_done[i]; | |
| 1832 SmoothScrollGestureMap::iterator it = | |
| 1833 active_smooth_scroll_gestures_.find(id); | |
| 1834 DCHECK(it != active_smooth_scroll_gestures_.end()); | |
| 1835 active_smooth_scroll_gestures_.erase(it); | |
| 1836 | |
| 1837 Send(new ViewMsg_SmoothScrollCompleted(routing_id_, id)); | |
| 1838 } | |
| 1839 | |
| 1840 // No need to post the next tick if an input is in flight. | |
| 1841 if (!in_process_event_types_.empty()) | |
| 1842 return; | |
| 1843 | |
| 1844 TRACE_EVENT_INSTANT1("input", "PostTickTask", | |
| 1845 "delay", preferred_interval.InMilliseconds()); | |
| 1846 tick_active_smooth_scroll_gestures_task_posted_ = true; | |
| 1847 MessageLoop::current()->PostDelayedTask( | |
| 1848 FROM_HERE, | |
| 1849 base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture, | |
| 1850 weak_factory_.GetWeakPtr()), | |
| 1851 preferred_interval); | |
| 1852 } | 1769 } |
| 1853 | 1770 |
| 1854 void RenderWidgetHostImpl::OnSelectRangeAck() { | 1771 void RenderWidgetHostImpl::OnSelectRangeAck() { |
| 1855 select_range_pending_ = false; | 1772 select_range_pending_ = false; |
| 1856 if (next_selection_range_.get()) { | 1773 if (next_selection_range_.get()) { |
| 1857 scoped_ptr<SelectionRange> next(next_selection_range_.Pass()); | 1774 scoped_ptr<SelectionRange> next(next_selection_range_.Pass()); |
| 1858 SelectRange(next->start, next->end); | 1775 SelectRange(next->start, next->end); |
| 1859 } | 1776 } |
| 1860 } | 1777 } |
| 1861 | 1778 |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2366 return; | 2283 return; |
| 2367 | 2284 |
| 2368 OnRenderAutoResized(new_size); | 2285 OnRenderAutoResized(new_size); |
| 2369 } | 2286 } |
| 2370 | 2287 |
| 2371 void RenderWidgetHostImpl::DetachDelegate() { | 2288 void RenderWidgetHostImpl::DetachDelegate() { |
| 2372 delegate_ = NULL; | 2289 delegate_ = NULL; |
| 2373 } | 2290 } |
| 2374 | 2291 |
| 2375 } // namespace content | 2292 } // namespace content |
| OLD | NEW |