summaryrefslogtreecommitdiffstats
path: root/content/browser/android
diff options
context:
space:
mode:
authorskyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-24 07:49:46 +0000
committerskyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-24 07:49:46 +0000
commit83488170c494d4009337e8a15fb7fad60e4597cc (patch)
treef985662f38fd262bec05817d847835d5d459b25c /content/browser/android
parentc9414c9d105d4867577362bff8d0b03196326c17 (diff)
downloadchromium_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.cc75
-rw-r--r--content/browser/android/content_view_core_impl.h20
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_;