diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 6719006..ce9c6e0 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -393,22 +393,23 @@
     // as long as all other pointers are normalized to the same value and the final DispatchEntry
     // uses the transform for the normalized pointer.
     const ui::Transform& firstPointerTransform =
-            inputTarget.pointerTransforms[firstMarkedBit(inputTarget.pointerIds)];
-    ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
+            inputTarget.getTransformForPointer(firstMarkedBit(inputTarget.getPointerIds()));
+    const ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
 
     // Iterate through all pointers in the event to normalize against the first.
-    for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount(); pointerIndex++) {
-        const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
-        uint32_t pointerId = uint32_t(pointerProperties.id);
-        const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
+    for (size_t i = 0; i < motionEntry.getPointerCount(); i++) {
+        PointerCoords& newCoords = pointerCoords[i];
 
-        pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
+        const auto pointerId = motionEntry.pointerProperties[i].id;
+        const ui::Transform& currTransform = inputTarget.getTransformForPointer(pointerId);
+
+        newCoords.copyFrom(motionEntry.pointerCoords[i]);
         // First, apply the current pointer's transform to update the coordinates into
         // window space.
-        pointerCoords[pointerIndex].transform(currTransform);
+        newCoords.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);
+        newCoords.transform(inverseFirstTransform);
     }
 
     std::unique_ptr<MotionEntry> combinedMotionEntry =
@@ -1630,14 +1631,12 @@
     if (connection == nullptr) {
         return; // Connection has gone away
     }
-    InputTarget target;
-    target.connection = connection;
     entry->dispatchInProgress = true;
     std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
             connection->getInputChannelName();
     std::string reason = std::string("reason=").append(entry->reason);
     android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
-    dispatchEventLocked(currentTime, entry, {target});
+    dispatchEventLocked(currentTime, entry, {{connection}});
 }
 
 void InputDispatcher::dispatchPointerCaptureChangedLocked(
@@ -1703,10 +1702,8 @@
         }
         return;
     }
-    InputTarget target;
-    target.connection = connection;
     entry->dispatchInProgress = true;
-    dispatchEventLocked(currentTime, entry, {target});
+    dispatchEventLocked(currentTime, entry, {{connection}});
 
     dropReason = DropReason::NOT_DROPPED;
 }
@@ -1739,9 +1736,7 @@
         if (connection == nullptr) {
             continue; // Connection has gone away
         }
-        InputTarget target;
-        target.connection = connection;
-        inputTargets.push_back(target);
+        inputTargets.emplace_back(connection);
     }
     return inputTargets;
 }
@@ -2022,10 +2017,8 @@
     if (connection == nullptr) {
         return; // Connection has gone away
     }
-    InputTarget target;
-    target.connection = connection;
     entry->dispatchInProgress = true;
-    dispatchEventLocked(currentTime, entry, {target});
+    dispatchEventLocked(currentTime, entry, {{connection}});
 }
 
 void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
@@ -2868,8 +2861,7 @@
         ALOGW("Not creating InputTarget for %s, no input channel", windowHandle->getName().c_str());
         return {};
     }
-    InputTarget inputTarget;
-    inputTarget.connection = connection;
+    InputTarget inputTarget{connection};
     inputTarget.windowHandle = windowHandle;
     inputTarget.dispatchMode = dispatchMode;
     inputTarget.flags = targetFlags;
@@ -2982,8 +2974,7 @@
     if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
 
     for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
-        InputTarget target;
-        target.connection = monitor.connection;
+        InputTarget target{monitor.connection};
         // target.firstDownTimeInTarget is not set for global monitors. It is only required in split
         // touch and global monitoring works as intended even without setting firstDownTimeInTarget
         if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
@@ -3275,7 +3266,7 @@
         ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, "
               "globalScaleFactor=%f, pointerIds=%s %s",
               connection->getInputChannelName().c_str(), inputTarget.flags.string().c_str(),
-              inputTarget.globalScaleFactor, bitsetToString(inputTarget.pointerIds).c_str(),
+              inputTarget.globalScaleFactor, bitsetToString(inputTarget.getPointerIds()).c_str(),
               inputTarget.getPointerInfoString().c_str());
     }
 
@@ -3297,7 +3288,7 @@
                             ftl::enum_string(eventEntry->type).c_str());
 
         const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
-        if (inputTarget.pointerIds.count() != originalMotionEntry.getPointerCount()) {
+        if (inputTarget.getPointerIds().count() != originalMotionEntry.getPointerCount()) {
             if (!inputTarget.firstDownTimeInTarget.has_value()) {
                 logDispatchStateLocked();
                 LOG(FATAL) << "Splitting motion events requires a down time to be set for the "
@@ -3306,7 +3297,7 @@
                            << originalMotionEntry.getDescription();
             }
             std::unique_ptr<MotionEntry> splitMotionEntry =
-                    splitMotionEvent(originalMotionEntry, inputTarget.pointerIds,
+                    splitMotionEvent(originalMotionEntry, inputTarget.getPointerIds(),
                                      inputTarget.firstDownTimeInTarget.value());
             if (!splitMotionEntry) {
                 return; // split event was dropped
@@ -4107,7 +4098,7 @@
 
     const bool wasEmpty = connection->outboundQueue.empty();
     // The target to use if we don't find a window associated with the channel.
-    const InputTarget fallbackTarget{.connection = connection};
+    const InputTarget fallbackTarget{connection};
     const auto& token = connection->getToken();
 
     for (size_t i = 0; i < cancelationEvents.size(); i++) {
@@ -4225,8 +4216,7 @@
                                                  targetFlags, pointerIds, motionEntry.downTime,
                                                  targets);
                 } else {
-                    targets.emplace_back(
-                            InputTarget{.connection = connection, .flags = targetFlags});
+                    targets.emplace_back(connection, targetFlags);
                     const auto it = mDisplayInfos.find(motionEntry.displayId);
                     if (it != mDisplayInfos.end()) {
                         targets.back().displayTransform = it->second.transform;
diff --git a/services/inputflinger/dispatcher/InputTarget.cpp b/services/inputflinger/dispatcher/InputTarget.cpp
index 28e3c6d..35ad858 100644
--- a/services/inputflinger/dispatcher/InputTarget.cpp
+++ b/services/inputflinger/dispatcher/InputTarget.cpp
@@ -26,6 +26,15 @@
 
 namespace android::inputdispatcher {
 
+namespace {
+
+const static ui::Transform kIdentityTransform{};
+
+}
+
+InputTarget::InputTarget(const std::shared_ptr<Connection>& connection, ftl::Flags<Flags> flags)
+      : connection(connection), flags(flags) {}
+
 void InputTarget::addPointers(std::bitset<MAX_POINTER_ID + 1> newPointerIds,
                               const ui::Transform& transform) {
     // The pointerIds can be empty, but still a valid InputTarget. This can happen when there is no
@@ -36,31 +45,46 @@
     }
 
     // Ensure that the new set of pointers doesn't overlap with the current set of pointers.
-    if ((pointerIds & newPointerIds).any()) {
+    if ((getPointerIds() & newPointerIds).any()) {
         LOG(FATAL) << __func__ << " - overlap with incoming pointers "
                    << bitsetToString(newPointerIds) << " in " << *this;
     }
 
-    pointerIds |= newPointerIds;
-    for (size_t i = 0; i < newPointerIds.size(); i++) {
-        if (!newPointerIds.test(i)) {
-            continue;
+    for (auto& [existingTransform, existingPointers] : mPointerTransforms) {
+        if (transform == existingTransform) {
+            existingPointers |= newPointerIds;
+            return;
         }
-        pointerTransforms[i] = transform;
     }
+    mPointerTransforms.emplace_back(transform, newPointerIds);
 }
 
 void InputTarget::setDefaultPointerTransform(const ui::Transform& transform) {
-    pointerIds.reset();
-    pointerTransforms[0] = transform;
+    mPointerTransforms = {{transform, {}}};
 }
 
 bool InputTarget::useDefaultPointerTransform() const {
-    return pointerIds.none();
+    return mPointerTransforms.size() <= 1;
 }
 
 const ui::Transform& InputTarget::getDefaultPointerTransform() const {
-    return pointerTransforms[0];
+    if (!useDefaultPointerTransform()) {
+        LOG(FATAL) << __func__ << ": Not using default pointer transform";
+    }
+    return mPointerTransforms.size() == 1 ? mPointerTransforms[0].first : kIdentityTransform;
+}
+
+const ui::Transform& InputTarget::getTransformForPointer(int32_t pointerId) const {
+    for (const auto& [transform, ids] : mPointerTransforms) {
+        if (ids.test(pointerId)) {
+            return transform;
+        }
+    }
+
+    LOG(FATAL) << __func__
+               << ": Cannot get transform: The following Pointer ID does not exist in target: "
+               << pointerId;
+    return kIdentityTransform;
 }
 
 std::string InputTarget::getPointerInfoString() const {
@@ -71,17 +95,21 @@
         return out;
     }
 
-    for (uint32_t i = 0; i < pointerIds.size(); i++) {
-        if (!pointerIds.test(i)) {
-            continue;
-        }
-
-        const std::string name = "pointerId " + std::to_string(i) + ":";
-        pointerTransforms[i].dump(out, name.c_str(), "        ");
+    for (const auto& [transform, ids] : mPointerTransforms) {
+        const std::string name = "pointerIds " + bitsetToString(ids) + ":";
+        transform.dump(out, name.c_str(), "        ");
     }
     return out;
 }
 
+std::bitset<MAX_POINTER_ID + 1> InputTarget::getPointerIds() const {
+    PointerIds allIds;
+    for (const auto& [_, ids] : mPointerTransforms) {
+        allIds |= ids;
+    }
+    return allIds;
+}
+
 std::ostream& operator<<(std::ostream& out, const InputTarget& target) {
     out << "{connection=";
     if (target.connection != nullptr) {
diff --git a/services/inputflinger/dispatcher/InputTarget.h b/services/inputflinger/dispatcher/InputTarget.h
index 5728bdf..058639a 100644
--- a/services/inputflinger/dispatcher/InputTarget.h
+++ b/services/inputflinger/dispatcher/InputTarget.h
@@ -33,7 +33,8 @@
  * be added to input event coordinates to compensate for the absolute position of the
  * window area.
  */
-struct InputTarget {
+class InputTarget {
+public:
     using Flags = InputTargetFlags;
 
     enum class DispatchMode {
@@ -80,20 +81,17 @@
     // Current display transform. Used for compatibility for raw coordinates.
     ui::Transform displayTransform;
 
-    // The subset of pointer ids to include in motion events dispatched to this input target
-    // if FLAG_SPLIT is set.
-    std::bitset<MAX_POINTER_ID + 1> pointerIds;
     // Event time for the first motion event (ACTION_DOWN) dispatched to this input target if
     // FLAG_SPLIT is set.
     std::optional<nsecs_t> firstDownTimeInTarget;
-    // The data is stored by the pointerId. Use the bit position of pointerIds to look up
-    // Transform per pointerId.
-    ui::Transform pointerTransforms[MAX_POINTERS];
 
     // The window that this input target is being dispatched to. It is possible for this to be
     // null for cases like global monitors.
     sp<gui::WindowInfoHandle> windowHandle;
 
+    InputTarget() = default;
+    InputTarget(const std::shared_ptr<Connection>&, ftl::Flags<Flags> = {});
+
     void addPointers(std::bitset<MAX_POINTER_ID + 1> pointerIds, const ui::Transform& transform);
     void setDefaultPointerTransform(const ui::Transform& transform);
 
@@ -111,7 +109,22 @@
      */
     const ui::Transform& getDefaultPointerTransform() const;
 
+    const ui::Transform& getTransformForPointer(int32_t pointerId) const;
+
+    std::bitset<MAX_POINTER_ID + 1> getPointerIds() const;
+
     std::string getPointerInfoString() const;
+
+private:
+    template <typename K, typename V>
+    using ArrayMap = std::vector<std::pair<K, V>>;
+    using PointerIds = std::bitset<MAX_POINTER_ID + 1>;
+    // The mapping of pointer IDs to the transform that should be used for that collection of IDs.
+    // Each of the pointer IDs are mutually disjoint, and their union makes up pointer IDs to
+    // include in the motion events dispatched to this target. We use an ArrayMap to store this to
+    // avoid having to define hash or comparison functions for ui::Transform, which would be needed
+    // to use std::unordered_map or std::map respectively.
+    ArrayMap<ui::Transform, PointerIds> mPointerTransforms;
 };
 
 std::ostream& operator<<(std::ostream& out, const InputTarget& target);
