diff options
-rw-r--r-- | include/input/InputWindow.h | 4 | ||||
-rw-r--r-- | libs/input/InputWindow.cpp | 20 | ||||
-rw-r--r-- | libs/input/tests/InputWindow_test.cpp | 6 | ||||
-rw-r--r-- | libs/ui/Transform.cpp | 8 | ||||
-rw-r--r-- | libs/ui/include/ui/Transform.h | 3 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/Entry.cpp | 10 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/Entry.h | 9 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 74 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputTarget.cpp | 43 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputTarget.h | 33 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 12 | ||||
-rw-r--r-- | services/inputflinger/tests/InputFlingerService_test.cpp | 4 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 22 | ||||
-rw-r--r-- | services/surfaceflinger/LayerProtoHelper.cpp | 3 | ||||
-rw-r--r-- | services/surfaceflinger/layerproto/layers.proto | 5 |
15 files changed, 115 insertions, 141 deletions
diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h index 233c7aea4f..d82f6fe59e 100644 --- a/include/input/InputWindow.h +++ b/include/input/InputWindow.h @@ -158,10 +158,6 @@ struct InputWindowInfo : public Parcelable { // in scaling of the TOUCH_MAJOR/TOUCH_MINOR axis. float globalScaleFactor = 1.0f; - // Scaling factors applied to individual windows. - float windowXScale = 1.0f; - float windowYScale = 1.0f; - // Transform applied to individual windows. ui::Transform transform; diff --git a/libs/input/InputWindow.cpp b/libs/input/InputWindow.cpp index 36c1f8068d..d5d35e6a96 100644 --- a/libs/input/InputWindow.cpp +++ b/libs/input/InputWindow.cpp @@ -57,7 +57,7 @@ bool InputWindowInfo::operator==(const InputWindowInfo& info) const { info.frameLeft == frameLeft && info.frameTop == frameTop && info.frameRight == frameRight && info.frameBottom == frameBottom && info.surfaceInset == surfaceInset && info.globalScaleFactor == globalScaleFactor && - info.windowXScale == windowXScale && info.windowYScale == windowYScale && + info.transform == transform && info.touchableRegion.hasSameRects(touchableRegion) && info.visible == visible && info.canReceiveKeys == canReceiveKeys && info.trustedOverlay == trustedOverlay && info.hasFocus == hasFocus && info.hasWallpaper == hasWallpaper && @@ -93,8 +93,12 @@ status_t InputWindowInfo::writeToParcel(android::Parcel* parcel) const { parcel->writeInt32(frameBottom) ?: parcel->writeInt32(surfaceInset) ?: parcel->writeFloat(globalScaleFactor) ?: - parcel->writeFloat(windowXScale) ?: - parcel->writeFloat(windowYScale) ?: + parcel->writeFloat(transform.dsdx()) ?: + parcel->writeFloat(transform.dtdx()) ?: + parcel->writeFloat(transform.tx()) ?: + parcel->writeFloat(transform.dtdy()) ?: + parcel->writeFloat(transform.dsdy()) ?: + parcel->writeFloat(transform.ty()) ?: parcel->writeBool(visible) ?: parcel->writeBool(canReceiveKeys) ?: parcel->writeBool(hasFocus) ?: @@ -132,14 +136,19 @@ status_t InputWindowInfo::readFromParcel(const android::Parcel* parcel) { flags = Flags<Flag>(parcel->readInt32()); type = static_cast<Type>(parcel->readInt32()); + float dsdx, dtdx, tx, dtdy, dsdy, ty; status = parcel->readInt32(&frameLeft) ?: parcel->readInt32(&frameTop) ?: parcel->readInt32(&frameRight) ?: parcel->readInt32(&frameBottom) ?: parcel->readInt32(&surfaceInset) ?: parcel->readFloat(&globalScaleFactor) ?: - parcel->readFloat(&windowXScale) ?: - parcel->readFloat(&windowYScale) ?: + parcel->readFloat(&dsdx) ?: + parcel->readFloat(&dtdx) ?: + parcel->readFloat(&tx) ?: + parcel->readFloat(&dtdy) ?: + parcel->readFloat(&dsdy) ?: + parcel->readFloat(&ty) ?: parcel->readBool(&visible) ?: parcel->readBool(&canReceiveKeys) ?: parcel->readBool(&hasFocus) ?: @@ -165,6 +174,7 @@ status_t InputWindowInfo::readFromParcel(const android::Parcel* parcel) { } touchableRegionCropHandle = parcel->readStrongBinder(); + transform.set(std::array<float, 9>{dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1}); return OK; } diff --git a/libs/input/tests/InputWindow_test.cpp b/libs/input/tests/InputWindow_test.cpp index e7a4587bfc..3da869b739 100644 --- a/libs/input/tests/InputWindow_test.cpp +++ b/libs/input/tests/InputWindow_test.cpp @@ -53,8 +53,7 @@ TEST(InputWindowInfo, Parcelling) { i.frameBottom = 19; i.surfaceInset = 17; i.globalScaleFactor = 0.3; - i.windowXScale = 0.4; - i.windowYScale = 0.5; + i.transform.set(std::array<float, 9>{0.4, -1, 100, 0.5, 0, 40, 0, 0, 1}); i.visible = false; i.canReceiveKeys = false; i.hasFocus = false; @@ -85,8 +84,7 @@ TEST(InputWindowInfo, Parcelling) { ASSERT_EQ(i.frameBottom, i2.frameBottom); ASSERT_EQ(i.surfaceInset, i2.surfaceInset); ASSERT_EQ(i.globalScaleFactor, i2.globalScaleFactor); - ASSERT_EQ(i.windowXScale, i2.windowXScale); - ASSERT_EQ(i.windowYScale, i2.windowYScale); + ASSERT_EQ(i.transform, i2.transform); ASSERT_EQ(i.visible, i2.visible); ASSERT_EQ(i.canReceiveKeys, i2.canReceiveKeys); ASSERT_EQ(i.hasFocus, i2.hasFocus); diff --git a/libs/ui/Transform.cpp b/libs/ui/Transform.cpp index 3bf3903929..5424a3ca9e 100644 --- a/libs/ui/Transform.cpp +++ b/libs/ui/Transform.cpp @@ -133,6 +133,14 @@ float Transform::dsdy() const { return mMatrix[1][1]; } +float Transform::getScaleX() const { + return sqrt(dsdx() * dsdx()) + (dtdx() * dtdx()); +} + +float Transform::getScaleY() const { + return sqrt((dtdy() * dtdy()) + (dsdy() * dsdy())); +} + void Transform::reset() { mType = IDENTITY; for(size_t i = 0; i < 3; i++) { diff --git a/libs/ui/include/ui/Transform.h b/libs/ui/include/ui/Transform.h index cf59467367..2612e821d0 100644 --- a/libs/ui/include/ui/Transform.h +++ b/libs/ui/include/ui/Transform.h @@ -74,6 +74,9 @@ public: float dtdy() const; float dsdy() const; + float getScaleX() const; + float getScaleY() const; + // modify the transform void reset(); void set(float tx, float ty); diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp index fdbb1d1b55..26a16448f7 100644 --- a/services/inputflinger/dispatcher/Entry.cpp +++ b/services/inputflinger/dispatcher/Entry.cpp @@ -240,17 +240,13 @@ void MotionEntry::appendDescription(std::string& msg) const { volatile int32_t DispatchEntry::sNextSeqAtomic; -DispatchEntry::DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, float xOffset, - float yOffset, float globalScaleFactor, float windowXScale, - float windowYScale) +DispatchEntry::DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, ui::Transform transform, + float globalScaleFactor) : seq(nextSeq()), eventEntry(eventEntry), targetFlags(targetFlags), - xOffset(xOffset), - yOffset(yOffset), + transform(transform), globalScaleFactor(globalScaleFactor), - windowXScale(windowXScale), - windowYScale(windowYScale), deliveryTime(0), resolvedAction(0), resolvedFlags(0) { diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h index 6b7697dde6..5dfcdd1965 100644 --- a/services/inputflinger/dispatcher/Entry.h +++ b/services/inputflinger/dispatcher/Entry.h @@ -193,11 +193,8 @@ struct DispatchEntry { EventEntry* eventEntry; // the event to dispatch int32_t targetFlags; - float xOffset; - float yOffset; + ui::Transform transform; float globalScaleFactor; - float windowXScale = 1.0f; - float windowYScale = 1.0f; // Both deliveryTime and timeoutTime are only populated when the entry is sent to the app, // and will be undefined before that. nsecs_t deliveryTime; // time when the event was actually delivered @@ -209,8 +206,8 @@ struct DispatchEntry { int32_t resolvedAction; int32_t resolvedFlags; - DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, float xOffset, float yOffset, - float globalScaleFactor, float windowXScale, float windowYScale); + DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, ui::Transform transform, + float globalScaleFactor); ~DispatchEntry(); inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; } diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 3bdbcce79b..a4538bbbf9 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -271,12 +271,11 @@ static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) { static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget, EventEntry* eventEntry, int32_t inputTargetFlags) { - if (inputTarget.useDefaultPointerInfo()) { - const PointerInfo& pointerInfo = inputTarget.getDefaultPointerInfo(); + if (inputTarget.useDefaultPointerTransform()) { + const ui::Transform& transform = inputTarget.getDefaultPointerTransform(); return std::make_unique<DispatchEntry>(eventEntry, // increments ref - inputTargetFlags, pointerInfo.xOffset, - pointerInfo.yOffset, inputTarget.globalScaleFactor, - pointerInfo.windowXScale, pointerInfo.windowYScale); + inputTargetFlags, transform, + inputTarget.globalScaleFactor); } ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION); @@ -286,28 +285,24 @@ static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inp // Use the first pointer information to normalize all other pointers. This could be any pointer // as long as all other pointers are normalized to the same value and the final DispatchEntry - // uses the offset and scale for the normalized pointer. - const PointerInfo& firstPointerInfo = - inputTarget.pointerInfos[inputTarget.pointerIds.firstMarkedBit()]; + // uses the transform for the normalized pointer. + const ui::Transform& firstPointerTransform = + inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()]; + ui::Transform inverseFirstTransform = firstPointerTransform.inverse(); // Iterate through all pointers in the event to normalize against the first. for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) { const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex]; uint32_t pointerId = uint32_t(pointerProperties.id); - const PointerInfo& currPointerInfo = inputTarget.pointerInfos[pointerId]; - - // The scale factor is the ratio of the current pointers scale to the normalized scale. - float scaleXDiff = currPointerInfo.windowXScale / firstPointerInfo.windowXScale; - float scaleYDiff = currPointerInfo.windowYScale / firstPointerInfo.windowYScale; + const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId]; pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]); - // First apply the current pointers offset to set the window at 0,0 - pointerCoords[pointerIndex].applyOffset(currPointerInfo.xOffset, currPointerInfo.yOffset); - // Next scale the coordinates. - pointerCoords[pointerIndex].scale(1, scaleXDiff, scaleYDiff); - // Lastly, offset the coordinates so they're in the normalized pointer's frame. - pointerCoords[pointerIndex].applyOffset(-firstPointerInfo.xOffset, - -firstPointerInfo.yOffset); + // First, apply the current pointer's transform to update the coordinates into + // window space. + pointerCoords[pointerIndex].transform(currTransform); + // Next, apply the inverse transform of the normalized coordinates so the + // current coordinates are transformed into the normalized coordinate space. + pointerCoords[pointerIndex].transform(inverseFirstTransform); } MotionEntry* combinedMotionEntry = @@ -329,10 +324,8 @@ static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inp std::unique_ptr<DispatchEntry> dispatchEntry = std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref - inputTargetFlags, firstPointerInfo.xOffset, - firstPointerInfo.yOffset, inputTarget.globalScaleFactor, - firstPointerInfo.windowXScale, - firstPointerInfo.windowYScale); + inputTargetFlags, firstPointerTransform, + inputTarget.globalScaleFactor); combinedMotionEntry->release(); return dispatchEntry; } @@ -2044,8 +2037,7 @@ void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowH ALOG_ASSERT(it->flags == targetFlags); ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor); - it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop, - windowInfo->windowXScale, windowInfo->windowYScale); + it->addPointers(pointerIds, windowInfo->transform); } void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, @@ -2068,7 +2060,9 @@ void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xO InputTarget target; target.inputChannel = monitor.inputChannel; target.flags = InputTarget::FLAG_DISPATCH_AS_IS; - target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */); + ui::Transform t; + t.set(xOffset, yOffset); + target.setDefaultPointerTransform(t); inputTargets.push_back(target); } @@ -2587,15 +2581,9 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, const PointerCoords* usingCoords = motionEntry->pointerCoords; // Set the X and Y offset and X and Y scale depending on the input source. - float xOffset = 0.0f, yOffset = 0.0f; - float xScale = 1.0f, yScale = 1.0f; if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) { float globalScaleFactor = dispatchEntry->globalScaleFactor; - xScale = dispatchEntry->windowXScale; - yScale = dispatchEntry->windowYScale; - xOffset = dispatchEntry->xOffset * xScale; - yOffset = dispatchEntry->yOffset * yScale; if (globalScaleFactor != 1.0f) { for (uint32_t i = 0; i < motionEntry->pointerCount; i++) { scaledCoords[i] = motionEntry->pointerCoords[i]; @@ -2630,8 +2618,12 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, dispatchEntry->resolvedFlags, motionEntry->edgeFlags, motionEntry->metaState, motionEntry->buttonState, - motionEntry->classification, xScale, yScale, - xOffset, yOffset, motionEntry->xPrecision, + motionEntry->classification, + dispatchEntry->transform.dsdx(), + dispatchEntry->transform.dsdy(), + dispatchEntry->transform.tx(), + dispatchEntry->transform.ty(), + motionEntry->xPrecision, motionEntry->yPrecision, motionEntry->xCursorPosition, motionEntry->yCursorPosition, @@ -2909,8 +2901,7 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( getWindowHandleLocked(connection->inputChannel->getConnectionToken()); if (windowHandle != nullptr) { const InputWindowInfo* windowInfo = windowHandle->getInfo(); - target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop, - windowInfo->windowXScale, windowInfo->windowYScale); + target.setDefaultPointerTransform(windowInfo->transform); target.globalScaleFactor = windowInfo->globalScaleFactor; } target.inputChannel = connection->inputChannel; @@ -2975,8 +2966,7 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( getWindowHandleLocked(connection->inputChannel->getConnectionToken()); if (windowHandle != nullptr) { const InputWindowInfo* windowInfo = windowHandle->getInfo(); - target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop, - windowInfo->windowXScale, windowInfo->windowYScale); + target.setDefaultPointerTransform(windowInfo->transform); target.globalScaleFactor = windowInfo->globalScaleFactor; } target.inputChannel = connection->inputChannel; @@ -4219,7 +4209,7 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, " "flags=%s, type=0x%08x, " "frame=[%d,%d][%d,%d], globalScale=%f, " - "windowScale=(%f,%f), touchableRegion=", + "touchableRegion=", i, windowInfo->name.c_str(), windowInfo->displayId, windowInfo->portalToDisplayId, toString(windowInfo->paused), @@ -4232,8 +4222,7 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { static_cast<int32_t>(windowInfo->type), windowInfo->frameLeft, windowInfo->frameTop, windowInfo->frameRight, windowInfo->frameBottom, - windowInfo->globalScaleFactor, windowInfo->windowXScale, - windowInfo->windowYScale); + windowInfo->globalScaleFactor); dumpRegion(dump, windowInfo->touchableRegion); dump += StringPrintf(", inputFeatures=%s", windowInfo->inputFeatures.string().c_str()); @@ -4241,6 +4230,7 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { "ms\n", windowInfo->ownerPid, windowInfo->ownerUid, millis(windowInfo->dispatchingTimeout)); + windowInfo->transform.dump(dump, INDENT4 "transform="); } } else { dump += INDENT2 "Windows: <none>\n"; diff --git a/services/inputflinger/dispatcher/InputTarget.cpp b/services/inputflinger/dispatcher/InputTarget.cpp index 0588374292..f6958d4666 100644 --- a/services/inputflinger/dispatcher/InputTarget.cpp +++ b/services/inputflinger/dispatcher/InputTarget.cpp @@ -42,12 +42,11 @@ std::string dispatchModeToString(int32_t dispatchMode) { return StringPrintf("%" PRId32, dispatchMode); } -void InputTarget::addPointers(BitSet32 newPointerIds, float xOffset, float yOffset, - float windowXScale, float windowYScale) { +void InputTarget::addPointers(BitSet32 newPointerIds, const ui::Transform& transform) { // The pointerIds can be empty, but still a valid InputTarget. This can happen for Monitors // and non splittable windows since we will just use all the pointers from the input event. if (newPointerIds.isEmpty()) { - setDefaultPointerInfo(xOffset, yOffset, windowXScale, windowYScale); + setDefaultPointerTransform(transform); return; } @@ -57,47 +56,39 @@ void InputTarget::addPointers(BitSet32 newPointerIds, float xOffset, float yOffs pointerIds |= newPointerIds; while (!newPointerIds.isEmpty()) { int32_t pointerId = newPointerIds.clearFirstMarkedBit(); - pointerInfos[pointerId].xOffset = xOffset; - pointerInfos[pointerId].yOffset = yOffset; - pointerInfos[pointerId].windowXScale = windowXScale; - pointerInfos[pointerId].windowYScale = windowYScale; + pointerTransforms[pointerId] = transform; } } -void InputTarget::setDefaultPointerInfo(float xOffset, float yOffset, float windowXScale, - float windowYScale) { +void InputTarget::setDefaultPointerTransform(const ui::Transform& transform) { pointerIds.clear(); - pointerInfos[0].xOffset = xOffset; - pointerInfos[0].yOffset = yOffset; - pointerInfos[0].windowXScale = windowXScale; - pointerInfos[0].windowYScale = windowYScale; + pointerTransforms[0] = transform; } -bool InputTarget::useDefaultPointerInfo() const { +bool InputTarget::useDefaultPointerTransform() const { return pointerIds.isEmpty(); } -const PointerInfo& InputTarget::getDefaultPointerInfo() const { - return pointerInfos[0]; +const ui::Transform& InputTarget::getDefaultPointerTransform() const { + return pointerTransforms[0]; } std::string InputTarget::getPointerInfoString() const { - if (useDefaultPointerInfo()) { - const PointerInfo& pointerInfo = getDefaultPointerInfo(); - return StringPrintf("xOffset=%.1f, yOffset=%.1f windowScaleFactor=(%.1f, %.1f)", - pointerInfo.xOffset, pointerInfo.yOffset, pointerInfo.windowXScale, - pointerInfo.windowYScale); + std::string out; + if (useDefaultPointerTransform()) { + const ui::Transform& transform = getDefaultPointerTransform(); + transform.dump(out, "default"); + return out; } - std::string out; for (uint32_t i = pointerIds.firstMarkedBit(); i <= pointerIds.lastMarkedBit(); i++) { if (!pointerIds.hasBit(i)) { continue; } - out += StringPrintf("\n pointerId %d: xOffset=%.1f, yOffset=%.1f " - "windowScaleFactor=(%.1f, %.1f)", - i, pointerInfos[i].xOffset, pointerInfos[i].yOffset, - pointerInfos[i].windowXScale, pointerInfos[i].windowYScale); + + out += "\n"; + const std::string name = "pointerId " + std::to_string(i) + ":"; + pointerTransforms[i].dump(out, name.c_str()); } return out; } diff --git a/services/inputflinger/dispatcher/InputTarget.h b/services/inputflinger/dispatcher/InputTarget.h index 499a75fdac..4287538935 100644 --- a/services/inputflinger/dispatcher/InputTarget.h +++ b/services/inputflinger/dispatcher/InputTarget.h @@ -18,28 +18,13 @@ #define _UI_INPUT_INPUTDISPATCHER_INPUTTARGET_H #include <input/InputTransport.h> +#include <ui/Transform.h> #include <utils/BitSet.h> #include <utils/RefBase.h> namespace android::inputdispatcher { /* - * Information about each pointer for an InputTarget. This includes offset and scale so - * all pointers can be normalized to a single offset and scale. - * - * These values are ignored for KeyEvents - */ -struct PointerInfo { - // The x and y offset to add to a MotionEvent as it is delivered. - float xOffset = 0.0f; - float yOffset = 0.0f; - - // Scaling factor to apply to MotionEvent as it is delivered. - float windowXScale = 1.0f; - float windowYScale = 1.0f; -}; - -/* * An input target specifies how an input event is to be dispatched to a particular window * including the window's input channel, control flags, a timeout, and an X / Y offset to * be added to input event coordinates to compensate for the absolute position of the @@ -119,13 +104,11 @@ struct InputTarget { // if FLAG_SPLIT is set. BitSet32 pointerIds; // The data is stored by the pointerId. Use the bit position of pointerIds to look up - // PointerInfo per pointerId. - PointerInfo pointerInfos[MAX_POINTERS]; + // Transform per pointerId. + ui::Transform pointerTransforms[MAX_POINTERS]; - void addPointers(BitSet32 pointerIds, float xOffset, float yOffset, float windowXScale, - float windowYScale); - void setDefaultPointerInfo(float xOffset, float yOffset, float windowXScale, - float windowYScale); + void addPointers(BitSet32 pointerIds, const ui::Transform& transform); + void setDefaultPointerTransform(const ui::Transform& transform); /** * Returns whether the default pointer information should be used. This will be true when the @@ -133,13 +116,13 @@ struct InputTarget { * and non splittable windows since we want all pointers for the EventEntry to go to this * target. */ - bool useDefaultPointerInfo() const; + bool useDefaultPointerTransform() const; /** - * Returns the default PointerInfo object. This should be used when useDefaultPointerInfo is + * Returns the default Transform object. This should be used when useDefaultPointerTransform is * true. */ - const PointerInfo& getDefaultPointerInfo() const; + const ui::Transform& getDefaultPointerTransform() const; std::string getPointerInfoString() const; }; diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index c749806190..cee66a7ded 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -773,6 +773,7 @@ public: mInfo.frameTop = 0; mInfo.frameRight = WIDTH; mInfo.frameBottom = HEIGHT; + mInfo.transform.set(0, 0); mInfo.globalScaleFactor = 1.0; mInfo.touchableRegion.clear(); mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT)); @@ -801,16 +802,14 @@ public: mInfo.frameTop = frame.top; mInfo.frameRight = frame.right; mInfo.frameBottom = frame.bottom; + mInfo.transform.set(frame.left, frame.top); mInfo.touchableRegion.clear(); mInfo.addTouchableRegion(frame); } void setFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags = flags; } - void setWindowScale(float xScale, float yScale) { - mInfo.windowXScale = xScale; - mInfo.windowYScale = yScale; - } + void setWindowScale(float xScale, float yScale) { mInfo.transform.set(xScale, 0, 0, yScale); } void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) { consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId, @@ -2458,9 +2457,8 @@ protected: // Helper function to convert the point from screen coordinates into the window's space static PointF getPointInWindow(const InputWindowInfo* windowInfo, const PointF& point) { - float x = windowInfo->windowXScale * (point.x - windowInfo->frameLeft); - float y = windowInfo->windowYScale * (point.y - windowInfo->frameTop); - return {x, y}; + vec2 vals = windowInfo->transform.transform(point.x, point.y); + return {vals.x, vals.y}; } void consumeMotionEvent(const sp<FakeWindowHandle>& window, int32_t expectedAction, diff --git a/services/inputflinger/tests/InputFlingerService_test.cpp b/services/inputflinger/tests/InputFlingerService_test.cpp index 193fe77878..f661bbaa43 100644 --- a/services/inputflinger/tests/InputFlingerService_test.cpp +++ b/services/inputflinger/tests/InputFlingerService_test.cpp @@ -275,8 +275,8 @@ void InputFlingerServiceTest::SetUp() { mInfo.frameBottom = TestInfoFrameBottom; mInfo.surfaceInset = TestInfoSurfaceInset; mInfo.globalScaleFactor = TestInfoGlobalScaleFactor; - mInfo.windowXScale = TestInfoWindowXScale; - mInfo.windowYScale = TestInfoWindowYScale; + mInfo.transform.set(std::array<float, 9>{TestInfoWindowXScale, 0, TestInfoFrameLeft, 0, + TestInfoWindowYScale, TestInfoFrameTop, 0, 0, 1}); mInfo.touchableRegion = TestInfoTouchableRegion; mInfo.visible = TestInfoVisible; mInfo.canReceiveKeys = TestInfoCanReceiveKeys; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 70822bd02b..89c95d2846 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2387,17 +2387,8 @@ InputWindowInfo Layer::fillInputInfo() { } ui::Transform t = getTransform(); - const float xScale = t.dsdx(); - const float yScale = t.dsdy(); int32_t xSurfaceInset = info.surfaceInset; int32_t ySurfaceInset = info.surfaceInset; - if (xScale != 1.0f || yScale != 1.0f) { - info.windowXScale *= (xScale != 0.0f) ? 1.0f / xScale : 0.0f; - info.windowYScale *= (yScale != 0.0f) ? 1.0f / yScale : 0.0f; - info.touchableRegion.scaleSelf(xScale, yScale); - xSurfaceInset = std::round(xSurfaceInset * xScale); - ySurfaceInset = std::round(ySurfaceInset * yScale); - } // Transform layer size to screen space and inset it by surface insets. // If this is a portal window, set the touchableRegion to the layerBounds. @@ -2407,6 +2398,15 @@ InputWindowInfo Layer::fillInputInfo() { if (!layerBounds.isValid()) { layerBounds = getCroppedBufferSize(getDrawingState()); } + + const float xScale = t.getScaleX(); + const float yScale = t.getScaleY(); + if (xScale != 1.0f || yScale != 1.0f) { + info.touchableRegion.scaleSelf(xScale, yScale); + xSurfaceInset = std::round(xSurfaceInset * xScale); + ySurfaceInset = std::round(ySurfaceInset * yScale); + } + layerBounds = t.transform(layerBounds); // clamp inset to layer bounds @@ -2421,6 +2421,10 @@ InputWindowInfo Layer::fillInputInfo() { info.frameRight = layerBounds.right; info.frameBottom = layerBounds.bottom; + ui::Transform inputTransform(t); + inputTransform.set(layerBounds.left, layerBounds.top); + info.transform = inputTransform.inverse(); + // Position the touchable region relative to frame screen location and restrict it to frame // bounds. info.touchableRegion = info.touchableRegion.translate(info.frameLeft, info.frameTop); diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp index dd65cf4271..5d99908b77 100644 --- a/services/surfaceflinger/LayerProtoHelper.cpp +++ b/services/surfaceflinger/LayerProtoHelper.cpp @@ -151,8 +151,7 @@ void LayerProtoHelper::writeToProto( proto->set_has_wallpaper(inputInfo.hasWallpaper); proto->set_global_scale_factor(inputInfo.globalScaleFactor); - proto->set_window_x_scale(inputInfo.windowXScale); - proto->set_window_y_scale(inputInfo.windowYScale); + LayerProtoHelper::writeToProto(inputInfo.transform, proto->mutable_transform()); proto->set_replace_touchable_region_with_crop(inputInfo.replaceTouchableRegionWithCrop); auto cropLayer = touchableRegionBounds.promote(); if (cropLayer != nullptr) { diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto index 7f1f542e4b..8458d54356 100644 --- a/services/surfaceflinger/layerproto/layers.proto +++ b/services/surfaceflinger/layerproto/layers.proto @@ -196,12 +196,13 @@ message InputWindowInfoProto { bool has_wallpaper = 9; float global_scale_factor = 10; - float window_x_scale = 11; - float window_y_scale = 12; + float window_x_scale = 11 [deprecated=true]; + float window_y_scale = 12 [deprecated=true]; uint32 crop_layer_id = 13; bool replace_touchable_region_with_crop = 14; RectProto touchable_region_crop = 15; + TransformProto transform = 16; } message ColorTransformProto { |