summaryrefslogtreecommitdiff
path: root/libs/input/TouchVideoFrame.cpp
diff options
context:
space:
mode:
author Siarhei Vishniakou <svv@google.com> 2019-02-15 17:21:03 -0600
committer Siarhei Vishniakou <svv@google.com> 2019-02-19 19:04:23 -0600
commit8154bbdf6bb2c5de865e9408a1452bbfd3c37a17 (patch)
tree7e48bc263df7ef3cd5da2dfc00fd40525d240d39 /libs/input/TouchVideoFrame.cpp
parent6b76bdf9b7ac8046234900cafdcccf2145d3c5c7 (diff)
Rotate TouchVideoFrames
When a screen orientation change happens, the touch coordinates are adjusted in InputReader to accomodate this rotation. When the user is holding the device, the origin (0, 0) is always at the top left of the screen. However, currently, the TouchVideoFrames are not being rotated. This presents a problem, because the touch coordinates cannot be directly matched to the heatmap, as received in the HAL. To account for this, we rotate the touch video frame. Test: atest libinput_tests inputflinger_tests Bug: 123241238 Change-Id: Iff45c68b1d2b237d2b1657ed76f50bb23ef8468a
Diffstat (limited to 'libs/input/TouchVideoFrame.cpp')
-rw-r--r--libs/input/TouchVideoFrame.cpp58
1 files changed, 58 insertions, 0 deletions
diff --git a/libs/input/TouchVideoFrame.cpp b/libs/input/TouchVideoFrame.cpp
index 35cb4a73ea..8a4298a36f 100644
--- a/libs/input/TouchVideoFrame.cpp
+++ b/libs/input/TouchVideoFrame.cpp
@@ -39,4 +39,62 @@ const std::vector<int16_t>& TouchVideoFrame::getData() const { return mData; }
const struct timeval& TouchVideoFrame::getTimestamp() const { return mTimestamp; }
+void TouchVideoFrame::rotate(int32_t orientation) {
+ switch (orientation) {
+ case DISPLAY_ORIENTATION_90:
+ rotateQuarterTurn(true /*clockwise*/);
+ break;
+ case DISPLAY_ORIENTATION_180:
+ rotate180();
+ break;
+ case DISPLAY_ORIENTATION_270:
+ rotateQuarterTurn(false /*clockwise*/);
+ break;
+ }
+}
+
+/**
+ * Rotate once clockwise by a quarter turn === rotate 90 degrees
+ * Rotate once counterclockwise by a quarter turn === rotate 270 degrees
+ * For a clockwise rotation:
+ * An element at position (i, j) is rotated to (j, height - i - 1)
+ * For a counterclockwise rotation:
+ * An element at position (i, j) is rotated to (width - j - 1, i)
+ */
+void TouchVideoFrame::rotateQuarterTurn(bool clockwise) {
+ std::vector<int16_t> rotated(mData.size());
+ for (size_t i = 0; i < mHeight; i++) {
+ for (size_t j = 0; j < mWidth; j++) {
+ size_t iRotated, jRotated;
+ if (clockwise) {
+ iRotated = j;
+ jRotated = mHeight - i - 1;
+ } else {
+ iRotated = mWidth - j - 1;
+ jRotated = i;
+ }
+ size_t indexRotated = iRotated * mHeight + jRotated;
+ rotated[indexRotated] = mData[i * mWidth + j];
+ }
+ }
+ mData = std::move(rotated);
+ std::swap(mHeight, mWidth);
+}
+
+/**
+ * An element at position (i, j) is rotated to (height - i - 1, width - j - 1)
+ * This is equivalent to moving element [i] to position [height * width - i - 1]
+ * Since element at [height * width - i - 1] would move to position [i],
+ * we can just swap elements [i] and [height * width - i - 1].
+ */
+void TouchVideoFrame::rotate180() {
+ if (mData.size() == 0) {
+ return;
+ }
+ // Just need to swap elements i and (height * width - 1 - i)
+ for (size_t i = 0; i < mData.size() / 2; i++) {
+ std::swap(mData[i], mData[mHeight * mWidth - 1 - i]);
+ }
+}
+
} // namespace android