diff options
| author | 2017-08-22 01:06:33 +0000 | |
|---|---|---|
| committer | 2017-08-22 01:06:33 +0000 | |
| commit | 58854c2a55b3375dd1af8346f427c02eed78444c (patch) | |
| tree | 9095347158a9108bb90b91fe92fea6c36d14e956 | |
| parent | 2b3b34cf7e0b25125951ba33f067fa3588251b88 (diff) | |
| parent | 0aeec07971d86c635412c672bd69d91f589a0cd9 (diff) | |
Merge "Fix resampling logic for duplicate events."
| -rw-r--r-- | include/input/InputTransport.h | 31 | ||||
| -rw-r--r-- | libs/input/InputTransport.cpp | 68 |
2 files changed, 62 insertions, 37 deletions
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h index efa1ffbfee..0dd15b1221 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -370,14 +370,14 @@ private: int32_t idToIndex[MAX_POINTER_ID + 1]; PointerCoords pointers[MAX_POINTERS]; - void initializeFrom(const InputMessage* msg) { - eventTime = msg->body.motion.eventTime; + void initializeFrom(const InputMessage& msg) { + eventTime = msg.body.motion.eventTime; idBits.clear(); - for (uint32_t i = 0; i < msg->body.motion.pointerCount; i++) { - uint32_t id = msg->body.motion.pointers[i].properties.id; + for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) { + uint32_t id = msg.body.motion.pointers[i].properties.id; idBits.markBit(id); idToIndex[id] = i; - pointers[i].copyFrom(msg->body.motion.pointers[i].coords); + pointers[i].copyFrom(msg.body.motion.pointers[i].coords); } } @@ -402,7 +402,7 @@ private: lastResample.idBits.clear(); } - void addHistory(const InputMessage* msg) { + void addHistory(const InputMessage& msg) { historyCurrent ^= 1; if (historySize < 2) { historySize += 1; @@ -413,6 +413,21 @@ private: const History* getHistory(size_t index) const { return &history[(historyCurrent + index) & 1]; } + + bool recentCoordinatesAreIdentical(uint32_t id) const { + // Return true if the two most recently received "raw" coordinates are identical + if (historySize < 2) { + return false; + } + float currentX = getHistory(0)->getPointerById(id).getX(); + float currentY = getHistory(0)->getPointerById(id).getY(); + float previousX = getHistory(1)->getPointerById(id).getX(); + float previousY = getHistory(1)->getPointerById(id).getY(); + if (currentX == previousX && currentY == previousY) { + return true; + } + return false; + } }; Vector<TouchState> mTouchStates; @@ -432,8 +447,8 @@ private: Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent, int32_t* displayId); - void updateTouchState(InputMessage* msg); - void rewriteMessage(const TouchState& state, InputMessage* msg); + void updateTouchState(InputMessage& msg); + bool rewriteMessage(const TouchState& state, InputMessage& msg); void resampleTouchState(nsecs_t frameTime, MotionEvent* event, const InputMessage *next); diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index 63e98bb540..9abd04ca04 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -496,7 +496,7 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory, MotionEvent* motionEvent = factory->createMotionEvent(); if (! motionEvent) return NO_MEMORY; - updateTouchState(&mMsg); + updateTouchState(mMsg); initializeMotionEvent(motionEvent, &mMsg); *outSeq = mMsg.body.motion.seq; *outEvent = motionEvent; @@ -564,7 +564,7 @@ status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory, uint32_t chain = 0; for (size_t i = 0; i < count; i++) { InputMessage& msg = batch.samples.editItemAt(i); - updateTouchState(&msg); + updateTouchState(msg); if (i) { SeqChain seqChain; seqChain.seq = msg.body.motion.seq; @@ -584,20 +584,19 @@ status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory, return OK; } -void InputConsumer::updateTouchState(InputMessage* msg) { +void InputConsumer::updateTouchState(InputMessage& msg) { if (!mResampleTouch || - !(msg->body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) { + !(msg.body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) { return; } - int32_t deviceId = msg->body.motion.deviceId; - int32_t source = msg->body.motion.source; - nsecs_t eventTime = msg->body.motion.eventTime; + int32_t deviceId = msg.body.motion.deviceId; + int32_t source = msg.body.motion.source; // Update the touch state history to incorporate the new input message. // If the message is in the past relative to the most recently produced resampled // touch, then use the resampled time and coordinates instead. - switch (msg->body.motion.action & AMOTION_EVENT_ACTION_MASK) { + switch (msg.body.motion.action & AMOTION_EVENT_ACTION_MASK) { case AMOTION_EVENT_ACTION_DOWN: { ssize_t index = findTouchState(deviceId, source); if (index < 0) { @@ -615,9 +614,8 @@ void InputConsumer::updateTouchState(InputMessage* msg) { if (index >= 0) { TouchState& touchState = mTouchStates.editItemAt(index); touchState.addHistory(msg); - if (eventTime < touchState.lastResample.eventTime) { - rewriteMessage(touchState, msg); - } else { + bool messageRewritten = rewriteMessage(touchState, msg); + if (!messageRewritten) { touchState.lastResample.idBits.clear(); } } @@ -628,7 +626,7 @@ void InputConsumer::updateTouchState(InputMessage* msg) { ssize_t index = findTouchState(deviceId, source); if (index >= 0) { TouchState& touchState = mTouchStates.editItemAt(index); - touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId()); + touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId()); rewriteMessage(touchState, msg); } break; @@ -639,7 +637,7 @@ void InputConsumer::updateTouchState(InputMessage* msg) { if (index >= 0) { TouchState& touchState = mTouchStates.editItemAt(index); rewriteMessage(touchState, msg); - touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId()); + touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId()); } break; } @@ -666,23 +664,28 @@ void InputConsumer::updateTouchState(InputMessage* msg) { } } -void InputConsumer::rewriteMessage(const TouchState& state, InputMessage* msg) { - for (uint32_t i = 0; i < msg->body.motion.pointerCount; i++) { - uint32_t id = msg->body.motion.pointers[i].properties.id; +bool InputConsumer::rewriteMessage(const TouchState& state, InputMessage& msg) { + bool messageRewritten = false; + nsecs_t eventTime = msg.body.motion.eventTime; + for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) { + uint32_t id = msg.body.motion.pointers[i].properties.id; if (state.lastResample.idBits.hasBit(id)) { - PointerCoords& msgCoords = msg->body.motion.pointers[i].coords; + PointerCoords& msgCoords = msg.body.motion.pointers[i].coords; const PointerCoords& resampleCoords = state.lastResample.getPointerById(id); + if (eventTime < state.lastResample.eventTime || + state.recentCoordinatesAreIdentical(id)) { + msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX()); + msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY()); #if DEBUG_RESAMPLING - ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id, - resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_X), - resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_Y), - msgCoords.getAxisValue(AMOTION_EVENT_AXIS_X), - msgCoords.getAxisValue(AMOTION_EVENT_AXIS_Y)); + ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id, + resampleCoords.getX(), resampleCoords.getY(), + msgCoords.getX(), msgCoords.getY()); #endif - msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX()); - msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY()); + messageRewritten = true; + } } } + return messageRewritten; } void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, @@ -710,6 +713,7 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, } // Ensure that the current sample has all of the pointers that need to be reported. + // Also ensure that the past two "real" touch events do not contain duplicate coordinates const History* current = touchState.getHistory(0); size_t pointerCount = event->getPointerCount(); for (size_t i = 0; i < pointerCount; i++) { @@ -720,6 +724,12 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, #endif return; } + if (touchState.recentCoordinatesAreIdentical(id)) { +#if DEBUG_RESAMPLING + ALOGD("Not resampled, past two historical events have duplicate coordinates"); +#endif + return; + } } // Find the data to use for resampling. @@ -729,12 +739,12 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, if (next) { // Interpolate between current sample and future sample. // So current->eventTime <= sampleTime <= future.eventTime. - future.initializeFrom(next); + future.initializeFrom(*next); other = &future; nsecs_t delta = future.eventTime - current->eventTime; if (delta < RESAMPLE_MIN_DELTA) { #if DEBUG_RESAMPLING - ALOGD("Not resampled, delta time is too small: %lld ns.", delta); + ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta); #endif return; } @@ -746,12 +756,12 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, nsecs_t delta = current->eventTime - other->eventTime; if (delta < RESAMPLE_MIN_DELTA) { #if DEBUG_RESAMPLING - ALOGD("Not resampled, delta time is too small: %lld ns.", delta); + ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta); #endif return; } else if (delta > RESAMPLE_MAX_DELTA) { #if DEBUG_RESAMPLING - ALOGD("Not resampled, delta time is too large: %lld ns.", delta); + ALOGD("Not resampled, delta time is too large: %" PRId64 " ns.", delta); #endif return; } @@ -759,7 +769,7 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, if (sampleTime > maxPredict) { #if DEBUG_RESAMPLING ALOGD("Sample time is too far in the future, adjusting prediction " - "from %lld to %lld ns.", + "from %" PRId64 " to %" PRId64 " ns.", sampleTime - current->eventTime, maxPredict - current->eventTime); #endif sampleTime = maxPredict; |