diff options
author | skyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-24 07:49:46 +0000 |
---|---|---|
committer | skyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-24 07:49:46 +0000 |
commit | 83488170c494d4009337e8a15fb7fad60e4597cc (patch) | |
tree | f985662f38fd262bec05817d847835d5d459b25c /content/browser/android | |
parent | c9414c9d105d4867577362bff8d0b03196326c17 (diff) | |
download | chromium_src-83488170c494d4009337e8a15fb7fad60e4597cc.zip chromium_src-83488170c494d4009337e8a15fb7fad60e4597cc.tar.gz chromium_src-83488170c494d4009337e8a15fb7fad60e4597cc.tar.bz2 |
Android: Use input events to trigger vsync
On JB+ versions of Android, input events are delivered right before the
vsync signal. Knowing this, we can mark the input events as the last
events to be delivered for the current vsync to let the renderer
compositor start rendering as soon as those messages have been received.
On average this lets rendering commence about 1 ms earlier than
otherwise.
When we do this we must also avoid sending two vsync notifications
during a single frame. For this reason we keep track of when the vsync
signal was triggered by input and inhibit the real vsync notification
for the same frame.
BUG=230336
Review URL: https://chromiumcodereview.appspot.com/13947036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@196082 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/android')
-rw-r--r-- | content/browser/android/content_view_core_impl.cc | 75 | ||||
-rw-r--r-- | content/browser/android/content_view_core_impl.h | 20 |
2 files changed, 52 insertions, 43 deletions
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index 8f7697b..befac7a 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc @@ -151,7 +151,6 @@ ContentViewCore* ContentViewCore::GetNativeContentViewCore(JNIEnv* env, ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj, bool hardware_accelerated, - bool input_events_delivered_at_vsync, WebContents* web_contents, ui::ViewAndroid* view_android, ui::WindowAndroid* window_android) @@ -159,7 +158,6 @@ ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj, web_contents_(static_cast<WebContentsImpl*>(web_contents)), root_layer_(cc::Layer::Create()), tab_crashed_(false), - input_events_delivered_at_vsync_(input_events_delivered_at_vsync), view_android_(view_android), window_android_(window_android) { CHECK(web_contents) << @@ -863,7 +861,6 @@ jboolean ContentViewCoreImpl::SendTouchEvent(JNIEnv* env, WebKit::WebTouchEvent event; TouchPoint::BuildWebTouchEvent(env, type, time_ms, GetDpiScale(), pts, event); - UpdateVSyncFlagOnInputEvent(&event); rwhv->SendTouchEvent(event); return true; } @@ -930,27 +927,19 @@ jboolean ContentViewCoreImpl::SendMouseWheelEvent(JNIEnv* env, } WebGestureEvent ContentViewCoreImpl::MakeGestureEvent( - WebInputEvent::Type type, long time_ms, float x, float y) const { + WebInputEvent::Type type, long time_ms, float x, float y, + InputEventVSyncStatus vsync_status) const { WebGestureEvent event; event.type = type; event.x = x / GetDpiScale(); event.y = y / GetDpiScale(); event.timeStampSeconds = time_ms / 1000.0; event.sourceDevice = WebGestureEvent::Touchscreen; - UpdateVSyncFlagOnInputEvent(&event); + if (vsync_status == LAST_INPUT_EVENT_FOR_VSYNC) + event.modifiers |= WebInputEvent::IsLastInputEventForCurrentVSync; return event; } -void ContentViewCoreImpl::UpdateVSyncFlagOnInputEvent( - WebKit::WebInputEvent* event) const { - if (!input_events_delivered_at_vsync_) - return; - if (event->type == WebInputEvent::GestureScrollUpdate || - event->type == WebInputEvent::GesturePinchUpdate || - event->type == WebInputEvent::TouchMove) - event->modifiers |= WebInputEvent::IsLastInputEventForCurrentVSync; -} - void ContentViewCoreImpl::SendGestureEvent( const WebKit::WebGestureEvent& event) { RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid(); @@ -961,20 +950,26 @@ void ContentViewCoreImpl::SendGestureEvent( void ContentViewCoreImpl::ScrollBegin(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureScrollBegin, time_ms, x, y); + WebInputEvent::GestureScrollBegin, time_ms, x, y, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); SendGestureEvent(event); } void ContentViewCoreImpl::ScrollEnd(JNIEnv* env, jobject obj, jlong time_ms) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureScrollEnd, time_ms, 0, 0); + WebInputEvent::GestureScrollEnd, time_ms, 0, 0, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); SendGestureEvent(event); } void ContentViewCoreImpl::ScrollBy(JNIEnv* env, jobject obj, jlong time_ms, - jfloat x, jfloat y, jfloat dx, jfloat dy) { + jfloat x, jfloat y, jfloat dx, jfloat dy, + jboolean last_input_event_for_vsync) { + InputEventVSyncStatus vsync_status = + last_input_event_for_vsync ? LAST_INPUT_EVENT_FOR_VSYNC + : NOT_LAST_INPUT_EVENT_FOR_VSYNC; WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureScrollUpdate, time_ms, x, y); + WebInputEvent::GestureScrollUpdate, time_ms, x, y, vsync_status); event.data.scrollUpdate.deltaX = -dx / GetDpiScale(); event.data.scrollUpdate.deltaY = -dy / GetDpiScale(); @@ -984,7 +979,8 @@ void ContentViewCoreImpl::ScrollBy(JNIEnv* env, jobject obj, jlong time_ms, void ContentViewCoreImpl::FlingStart(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y, jfloat vx, jfloat vy) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureFlingStart, time_ms, x, y); + WebInputEvent::GestureFlingStart, time_ms, x, y, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); // Velocity should not be scaled by DIP since that interacts poorly with the // deceleration constants. The DIP scaling is done on the renderer. @@ -996,7 +992,8 @@ void ContentViewCoreImpl::FlingStart(JNIEnv* env, jobject obj, jlong time_ms, void ContentViewCoreImpl::FlingCancel(JNIEnv* env, jobject obj, jlong time_ms) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureFlingCancel, time_ms, 0, 0); + WebInputEvent::GestureFlingCancel, time_ms, 0, 0, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); SendGestureEvent(event); } @@ -1004,7 +1001,8 @@ void ContentViewCoreImpl::SingleTap(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y, jboolean disambiguation_popup_tap) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureTap, time_ms, x, y); + WebInputEvent::GestureTap, time_ms, x, y, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); event.data.tap.tapCount = 1; if (!disambiguation_popup_tap) { @@ -1020,7 +1018,8 @@ void ContentViewCoreImpl::ShowPressState(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureTapDown, time_ms, x, y); + WebInputEvent::GestureTapDown, time_ms, x, y, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); SendGestureEvent(event); } @@ -1030,14 +1029,16 @@ void ContentViewCoreImpl::ShowPressCancel(JNIEnv* env, jfloat x, jfloat y) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureTapCancel, time_ms, x, y); + WebInputEvent::GestureTapCancel, time_ms, x, y, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); SendGestureEvent(event); } void ContentViewCoreImpl::DoubleTap(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureDoubleTap, time_ms, x, y); + WebInputEvent::GestureDoubleTap, time_ms, x, y, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); SendGestureEvent(event); } @@ -1045,7 +1046,8 @@ void ContentViewCoreImpl::LongPress(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y, jboolean disambiguation_popup_tap) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureLongPress, time_ms, x, y); + WebInputEvent::GestureLongPress, time_ms, x, y, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); if (!disambiguation_popup_tap) { const float touch_padding_dip = GetTouchPaddingDip(); @@ -1060,7 +1062,8 @@ void ContentViewCoreImpl::LongTap(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y, jboolean disambiguation_popup_tap) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureLongTap, time_ms, x, y); + WebInputEvent::GestureLongTap, time_ms, x, y, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); if (!disambiguation_popup_tap) { const float touch_padding_dip = GetTouchPaddingDip(); @@ -1074,21 +1077,28 @@ void ContentViewCoreImpl::LongTap(JNIEnv* env, jobject obj, jlong time_ms, void ContentViewCoreImpl::PinchBegin(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GesturePinchBegin, time_ms, x, y); + WebInputEvent::GesturePinchBegin, time_ms, x, y, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); SendGestureEvent(event); } void ContentViewCoreImpl::PinchEnd(JNIEnv* env, jobject obj, jlong time_ms) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GesturePinchEnd, time_ms, 0, 0); + WebInputEvent::GesturePinchEnd, time_ms, 0, 0, + NOT_LAST_INPUT_EVENT_FOR_VSYNC); SendGestureEvent(event); } void ContentViewCoreImpl::PinchBy(JNIEnv* env, jobject obj, jlong time_ms, jfloat anchor_x, jfloat anchor_y, - jfloat delta) { + jfloat delta, + jboolean last_input_event_for_vsync) { + InputEventVSyncStatus vsync_status = + last_input_event_for_vsync ? LAST_INPUT_EVENT_FOR_VSYNC + : NOT_LAST_INPUT_EVENT_FOR_VSYNC; WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GesturePinchUpdate, time_ms, anchor_x, anchor_y); + WebInputEvent::GesturePinchUpdate, time_ms, anchor_x, anchor_y, + vsync_status); event.data.pinchUpdate.scale = delta; SendGestureEvent(event); @@ -1521,13 +1531,12 @@ void ContentViewCoreImpl::SetUseDesktopUserAgent( // This is called for each ContentView. jint Init(JNIEnv* env, jobject obj, - jboolean input_events_delivered_at_vsync, jboolean hardware_accelerated, jint native_web_contents, jint view_android, jint window_android) { ContentViewCoreImpl* view = new ContentViewCoreImpl( - env, obj, input_events_delivered_at_vsync, hardware_accelerated, + env, obj, hardware_accelerated, reinterpret_cast<WebContents*>(native_web_contents), reinterpret_cast<ui::ViewAndroid*>(view_android), reinterpret_cast<ui::WindowAndroid*>(window_android)); diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h index 146f836..f10e7e18 100644 --- a/content/browser/android/content_view_core_impl.h +++ b/content/browser/android/content_view_core_impl.h @@ -42,7 +42,6 @@ class ContentViewCoreImpl : public ContentViewCore, ContentViewCoreImpl(JNIEnv* env, jobject obj, bool hardware_accelerated, - bool input_events_delivered_at_vsync, WebContents* web_contents, ui::ViewAndroid* view_android, ui::WindowAndroid* window_android); @@ -118,7 +117,8 @@ class ContentViewCoreImpl : public ContentViewCore, void ScrollBegin(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y); void ScrollEnd(JNIEnv* env, jobject obj, jlong time_ms); void ScrollBy(JNIEnv* env, jobject obj, jlong time_ms, - jfloat x, jfloat y, jfloat dx, jfloat dy); + jfloat x, jfloat y, jfloat dx, jfloat dy, + jboolean last_input_event_for_vsync); void FlingStart(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y, jfloat vx, jfloat vy); void FlingCancel(JNIEnv* env, jobject obj, jlong time_ms); @@ -140,8 +140,8 @@ class ContentViewCoreImpl : public ContentViewCore, void PinchBegin(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y); void PinchEnd(JNIEnv* env, jobject obj, jlong time_ms); void PinchBy(JNIEnv* env, jobject obj, jlong time_ms, - jfloat x, jfloat y, - jfloat delta); + jfloat x, jfloat y, jfloat delta, + jboolean last_input_event_for_vsync); void SelectBetweenCoordinates(JNIEnv* env, jobject obj, jfloat x1, jfloat y1, jfloat x2, jfloat y2); @@ -291,6 +291,11 @@ class ContentViewCoreImpl : public ContentViewCore, void SetVSyncNotificationEnabled(bool enabled); private: + enum InputEventVSyncStatus { + NOT_LAST_INPUT_EVENT_FOR_VSYNC, + LAST_INPUT_EVENT_FOR_VSYNC + }; + class ContentViewUserData; friend class ContentViewUserData; @@ -313,13 +318,11 @@ class ContentViewCoreImpl : public ContentViewCore, WebKit::WebGestureEvent MakeGestureEvent( WebKit::WebInputEvent::Type type, long time_ms, - float xPix, float yPix) const; + float x, float y, InputEventVSyncStatus vsync_status) const; gfx::Size GetViewportSizePix() const; gfx::Size GetViewportSizeOffsetPix() const; - void UpdateVSyncFlagOnInputEvent(WebKit::WebInputEvent* event) const; - void DeleteScaledSnapshotTexture(); void SendGestureEvent(const WebKit::WebGestureEvent& event); @@ -339,9 +342,6 @@ class ContentViewCoreImpl : public ContentViewCore, // Whether the renderer backing this ContentViewCore has crashed. bool tab_crashed_; - // Whether input events will be consistently delivered at vsync time. - bool input_events_delivered_at_vsync_; - // Device scale factor. float dpi_scale_; |