diff --git a/include/ui/Input.h b/include/ui/Input.h index c9f694a8f..f1385a039 100644 --- a/include/ui/Input.h +++ b/include/ui/Input.h @@ -206,10 +206,17 @@ struct PointerCoords { float getAxisValue(int32_t axis) const; status_t setAxisValue(int32_t axis, float value); - float* editAxisValue(int32_t axis); void scale(float scale); + inline float getX() const { + return getAxisValue(AMOTION_EVENT_AXIS_X); + } + + inline float getY() const { + return getAxisValue(AMOTION_EVENT_AXIS_Y); + } + #ifdef HAVE_ANDROID_OS status_t readFromParcel(Parcel* parcel); status_t writeToParcel(Parcel* parcel) const; diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h index 600017e89..9452e86d6 100644 --- a/include/utils/BitSet.h +++ b/include/utils/BitSet.h @@ -68,6 +68,30 @@ struct BitSet32 { // Result is undefined if all bits are unmarked. inline uint32_t lastMarkedBit() const { return 31 - __builtin_ctz(value); } + // Finds the first marked bit in the set and clears it. Returns the bit index. + // Result is undefined if all bits are unmarked. + inline uint32_t clearFirstMarkedBit() { + uint32_t n = firstMarkedBit(); + clearBit(n); + return n; + } + + // Finds the first unmarked bit in the set and marks it. Returns the bit index. + // Result is undefined if all bits are marked. + inline uint32_t markFirstUnmarkedBit() { + uint32_t n = firstUnmarkedBit(); + markBit(n); + return n; + } + + // Finds the last marked bit in the set and clears it. Returns the bit index. + // Result is undefined if all bits are unmarked. + inline uint32_t clearLastMarkedBit() { + uint32_t n = lastMarkedBit(); + clearBit(n); + return n; + } + // Gets the index of the specified bit in the set, which is the number of // marked bits that appear before the specified bit. inline uint32_t getIndexOfBit(uint32_t n) const { diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp index 0af7f8043..688b99892 100644 --- a/libs/ui/Input.cpp +++ b/libs/ui/Input.cpp @@ -280,6 +280,9 @@ status_t PointerCoords::setAxisValue(int32_t axis, float value) { uint64_t axisBit = 1LL << axis; uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL)); if (!(bits & axisBit)) { + if (value == 0) { + return OK; // axes with value 0 do not need to be stored + } uint32_t count = __builtin_popcountll(bits); if (count >= MAX_AXES) { tooManyAxes(axis); @@ -294,23 +297,10 @@ status_t PointerCoords::setAxisValue(int32_t axis, float value) { return OK; } -float* PointerCoords::editAxisValue(int32_t axis) { - if (axis < 0 || axis > 63) { - return NULL; - } - - uint64_t axisBit = 1LL << axis; - if (!(bits & axisBit)) { - return NULL; - } - uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL)); - return &values[index]; -} - static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) { - float* value = c.editAxisValue(axis); - if (value) { - *value *= scaleFactor; + float value = c.getAxisValue(axis); + if (value != 0) { + c.setAxisValue(axis, value * scaleFactor); } } @@ -574,20 +564,14 @@ void MotionEvent::transform(const SkMatrix* matrix) { size_t numSamples = mSamplePointerCoords.size(); for (size_t i = 0; i < numSamples; i++) { PointerCoords& c = mSamplePointerCoords.editItemAt(i); - float* xPtr = c.editAxisValue(AMOTION_EVENT_AXIS_X); - float* yPtr = c.editAxisValue(AMOTION_EVENT_AXIS_Y); - if (xPtr && yPtr) { - float x = *xPtr + oldXOffset; - float y = *yPtr + oldYOffset; - matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), & point); - *xPtr = SkScalarToFloat(point.fX) - newXOffset; - *yPtr = SkScalarToFloat(point.fY) - newYOffset; - } + float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset; + float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset; + matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point); + c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset); + c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset); - float* orientationPtr = c.editAxisValue(AMOTION_EVENT_AXIS_ORIENTATION); - if (orientationPtr) { - *orientationPtr = transformAngle(matrix, *orientationPtr); - } + float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION); + c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation)); } } @@ -727,7 +711,7 @@ void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Posi } while (idBits.count() > MAX_POINTERS) { - idBits.clearBit(idBits.lastMarkedBit()); + idBits.clearLastMarkedBit(); } Movement& movement = mMovements[mIndex]; @@ -776,7 +760,7 @@ void VelocityTracker::addMovement(const MotionEvent* event) { // We do this on down instead of on up because the client may want to query the // final velocity for a pointer that just went up. BitSet32 downIdBits; - downIdBits.markBit(event->getActionIndex()); + downIdBits.markBit(event->getPointerId(event->getActionIndex())); clearPointers(downIdBits); break; } diff --git a/libs/ui/tests/InputEvent_test.cpp b/libs/ui/tests/InputEvent_test.cpp index e48d5b7dc..e21c464a1 100644 --- a/libs/ui/tests/InputEvent_test.cpp +++ b/libs/ui/tests/InputEvent_test.cpp @@ -52,9 +52,6 @@ TEST_F(PointerCoordsTest, AxisValues) { ASSERT_EQ(0, coords.getAxisValue(1)) << "getAxisValue should return zero because axis is not present"; - ASSERT_EQ(NULL, coords.editAxisValue(0)) - << "editAxisValue should return null because axis is not present"; - // Set first axis. ASSERT_EQ(OK, coords.setAxisValue(1, 5)); ASSERT_EQ(0x00000002ULL, coords.bits); @@ -96,26 +93,17 @@ TEST_F(PointerCoordsTest, AxisValues) { ASSERT_EQ(2, coords.getAxisValue(3)) << "getAxisValue should return value of axis"; - // Edit an existing axis value in place. - valuePtr = coords.editAxisValue(1); - ASSERT_EQ(5, *valuePtr) - << "editAxisValue should return pointer to axis value"; - - *valuePtr = 7; - ASSERT_EQ(7, coords.getAxisValue(1)) - << "getAxisValue should return value of axis"; - // Set an axis with an id between the others. (inserting value in the middle) ASSERT_EQ(OK, coords.setAxisValue(2, 1)); ASSERT_EQ(0x0000000fULL, coords.bits); ASSERT_EQ(4, coords.values[0]); - ASSERT_EQ(7, coords.values[1]); + ASSERT_EQ(5, coords.values[1]); ASSERT_EQ(1, coords.values[2]); ASSERT_EQ(2, coords.values[3]); ASSERT_EQ(4, coords.getAxisValue(0)) << "getAxisValue should return value of axis"; - ASSERT_EQ(7, coords.getAxisValue(1)) + ASSERT_EQ(5, coords.getAxisValue(1)) << "getAxisValue should return value of axis"; ASSERT_EQ(1, coords.getAxisValue(2)) << "getAxisValue should return value of axis";