Merge "Speculatively schedule input consumption" into klp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
3f83674150
@@ -48,7 +48,7 @@ public abstract class InputEventReceiver {
|
|||||||
InputChannel inputChannel, MessageQueue messageQueue);
|
InputChannel inputChannel, MessageQueue messageQueue);
|
||||||
private static native void nativeDispose(int receiverPtr);
|
private static native void nativeDispose(int receiverPtr);
|
||||||
private static native void nativeFinishInputEvent(int receiverPtr, int seq, boolean handled);
|
private static native void nativeFinishInputEvent(int receiverPtr, int seq, boolean handled);
|
||||||
private static native void nativeConsumeBatchedInputEvents(int receiverPtr,
|
private static native boolean nativeConsumeBatchedInputEvents(int receiverPtr,
|
||||||
long frameTimeNanos);
|
long frameTimeNanos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -165,14 +165,17 @@ public abstract class InputEventReceiver {
|
|||||||
*
|
*
|
||||||
* @param frameTimeNanos The time in the {@link System#nanoTime()} time base
|
* @param frameTimeNanos The time in the {@link System#nanoTime()} time base
|
||||||
* when the current display frame started rendering, or -1 if unknown.
|
* when the current display frame started rendering, or -1 if unknown.
|
||||||
|
*
|
||||||
|
* @return Whether a batch was consumed
|
||||||
*/
|
*/
|
||||||
public final void consumeBatchedInputEvents(long frameTimeNanos) {
|
public final boolean consumeBatchedInputEvents(long frameTimeNanos) {
|
||||||
if (mReceiverPtr == 0) {
|
if (mReceiverPtr == 0) {
|
||||||
Log.w(TAG, "Attempted to consume batched input events but the input event "
|
Log.w(TAG, "Attempted to consume batched input events but the input event "
|
||||||
+ "receiver has already been disposed.");
|
+ "receiver has already been disposed.");
|
||||||
} else {
|
} else {
|
||||||
nativeConsumeBatchedInputEvents(mReceiverPtr, frameTimeNanos);
|
return nativeConsumeBatchedInputEvents(mReceiverPtr, frameTimeNanos);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from native code.
|
// Called from native code.
|
||||||
|
|||||||
@@ -5635,7 +5635,13 @@ public final class ViewRootImpl implements ViewParent,
|
|||||||
if (mConsumeBatchedInputScheduled) {
|
if (mConsumeBatchedInputScheduled) {
|
||||||
mConsumeBatchedInputScheduled = false;
|
mConsumeBatchedInputScheduled = false;
|
||||||
if (mInputEventReceiver != null) {
|
if (mInputEventReceiver != null) {
|
||||||
mInputEventReceiver.consumeBatchedInputEvents(frameTimeNanos);
|
if (mInputEventReceiver.consumeBatchedInputEvents(frameTimeNanos)) {
|
||||||
|
// If we consumed a batch here, we want to go ahead and schedule the
|
||||||
|
// consumption of batched input events on the next frame. Otherwise, we would
|
||||||
|
// wait until we have more input events pending and might get starved by other
|
||||||
|
// things occurring in the process.
|
||||||
|
scheduleConsumeBatchedInput();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
doProcessInputEvents();
|
doProcessInputEvents();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ public:
|
|||||||
status_t initialize();
|
status_t initialize();
|
||||||
void dispose();
|
void dispose();
|
||||||
status_t finishInputEvent(uint32_t seq, bool handled);
|
status_t finishInputEvent(uint32_t seq, bool handled);
|
||||||
status_t consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime);
|
status_t consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime,
|
||||||
|
bool* outConsumedBatch);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~NativeInputEventReceiver();
|
virtual ~NativeInputEventReceiver();
|
||||||
@@ -167,7 +168,7 @@ int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data)
|
|||||||
|
|
||||||
if (events & ALOOPER_EVENT_INPUT) {
|
if (events & ALOOPER_EVENT_INPUT) {
|
||||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||||
status_t status = consumeEvents(env, false /*consumeBatches*/, -1);
|
status_t status = consumeEvents(env, false /*consumeBatches*/, -1, NULL);
|
||||||
mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
|
mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
|
||||||
return status == OK || status == NO_MEMORY ? 1 : 0;
|
return status == OK || status == NO_MEMORY ? 1 : 0;
|
||||||
}
|
}
|
||||||
@@ -214,7 +215,7 @@ int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
|
status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
|
||||||
bool consumeBatches, nsecs_t frameTime) {
|
bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
|
||||||
#if DEBUG_DISPATCH_CYCLE
|
#if DEBUG_DISPATCH_CYCLE
|
||||||
ALOGD("channel '%s' ~ Consuming input events, consumeBatches=%s, frameTime=%lld.",
|
ALOGD("channel '%s' ~ Consuming input events, consumeBatches=%s, frameTime=%lld.",
|
||||||
getInputChannelName(), consumeBatches ? "true" : "false", frameTime);
|
getInputChannelName(), consumeBatches ? "true" : "false", frameTime);
|
||||||
@@ -223,6 +224,9 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
|
|||||||
if (consumeBatches) {
|
if (consumeBatches) {
|
||||||
mBatchedInputEventPending = false;
|
mBatchedInputEventPending = false;
|
||||||
}
|
}
|
||||||
|
if (outConsumedBatch) {
|
||||||
|
*outConsumedBatch = false;
|
||||||
|
}
|
||||||
|
|
||||||
ScopedLocalRef<jobject> receiverObj(env, NULL);
|
ScopedLocalRef<jobject> receiverObj(env, NULL);
|
||||||
bool skipCallbacks = false;
|
bool skipCallbacks = false;
|
||||||
@@ -285,13 +289,17 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
|
|||||||
static_cast<KeyEvent*>(inputEvent));
|
static_cast<KeyEvent*>(inputEvent));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AINPUT_EVENT_TYPE_MOTION:
|
case AINPUT_EVENT_TYPE_MOTION: {
|
||||||
#if DEBUG_DISPATCH_CYCLE
|
#if DEBUG_DISPATCH_CYCLE
|
||||||
ALOGD("channel '%s' ~ Received motion event.", getInputChannelName());
|
ALOGD("channel '%s' ~ Received motion event.", getInputChannelName());
|
||||||
#endif
|
#endif
|
||||||
inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
|
MotionEvent* motionEvent = static_cast<MotionEvent*>(inputEvent);
|
||||||
static_cast<MotionEvent*>(inputEvent));
|
if ((motionEvent->getAction() & AMOTION_EVENT_ACTION_MOVE) && outConsumedBatch) {
|
||||||
|
*outConsumedBatch = true;
|
||||||
|
}
|
||||||
|
inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false); // InputConsumer should prevent this from ever happening
|
assert(false); // InputConsumer should prevent this from ever happening
|
||||||
@@ -370,16 +378,20 @@ static void nativeFinishInputEvent(JNIEnv* env, jclass clazz, jint receiverPtr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nativeConsumeBatchedInputEvents(JNIEnv* env, jclass clazz, jint receiverPtr,
|
static bool nativeConsumeBatchedInputEvents(JNIEnv* env, jclass clazz, jint receiverPtr,
|
||||||
jlong frameTimeNanos) {
|
jlong frameTimeNanos) {
|
||||||
sp<NativeInputEventReceiver> receiver =
|
sp<NativeInputEventReceiver> receiver =
|
||||||
reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
|
reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
|
||||||
status_t status = receiver->consumeEvents(env, true /*consumeBatches*/, frameTimeNanos);
|
bool consumedBatch;
|
||||||
|
status_t status = receiver->consumeEvents(env, true /*consumeBatches*/, frameTimeNanos,
|
||||||
|
&consumedBatch);
|
||||||
if (status && status != DEAD_OBJECT && !env->ExceptionCheck()) {
|
if (status && status != DEAD_OBJECT && !env->ExceptionCheck()) {
|
||||||
String8 message;
|
String8 message;
|
||||||
message.appendFormat("Failed to consume batched input event. status=%d", status);
|
message.appendFormat("Failed to consume batched input event. status=%d", status);
|
||||||
jniThrowRuntimeException(env, message.string());
|
jniThrowRuntimeException(env, message.string());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return consumedBatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -392,7 +404,7 @@ static JNINativeMethod gMethods[] = {
|
|||||||
(void*)nativeDispose },
|
(void*)nativeDispose },
|
||||||
{ "nativeFinishInputEvent", "(IIZ)V",
|
{ "nativeFinishInputEvent", "(IIZ)V",
|
||||||
(void*)nativeFinishInputEvent },
|
(void*)nativeFinishInputEvent },
|
||||||
{ "nativeConsumeBatchedInputEvents", "(IJ)V",
|
{ "nativeConsumeBatchedInputEvents", "(IJ)Z",
|
||||||
(void*)nativeConsumeBatchedInputEvents },
|
(void*)nativeConsumeBatchedInputEvents },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user