Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e05b7f5 authored by Arpit Singh's avatar Arpit Singh
Browse files

Use a single map in topology graph

Refactor topology graph to store a single map entry per display instead
of multiple maps.

Test: atest inputflinger_tests
Bug: 245989146
Flag: EXEMPT refactor
Change-Id: Ib08896d1dcf80ee3d96a178debf1a044d0032e2f
parent 47a99875
Loading
Loading
Loading
Loading
+10 −13
Original line number Diff line number Diff line
@@ -56,10 +56,14 @@ struct DisplayTopologyAdjacentDisplay {
 * Directed Graph representation of Display Topology.
 */
struct DisplayTopologyGraph {
    struct Properties {
        std::vector<DisplayTopologyAdjacentDisplay> adjacentDisplays;
        int32_t density;
        FloatRect boundsInGlobalDp;
    };

    ui::LogicalDisplayId primaryDisplayId = ui::LogicalDisplayId::INVALID;
    std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>> graph;
    std::unordered_map<ui::LogicalDisplayId, int> displaysDensity;
    std::unordered_map<ui::LogicalDisplayId, FloatRect> boundsInGlobalDp;
    std::unordered_map<ui::LogicalDisplayId, Properties> graph;

    DisplayTopologyGraph() = default;
    std::string dump() const;
@@ -68,18 +72,11 @@ struct DisplayTopologyGraph {
    // Returns error if a valid graph cannot be built from the supplied components.
    static base::Result<const DisplayTopologyGraph> create(
            ui::LogicalDisplayId primaryDisplay,
            std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>>&&
                    adjacencyGraph,
            std::unordered_map<ui::LogicalDisplayId, int>&& displaysDensityMap,
            std::unordered_map<ui::LogicalDisplayId, FloatRect>&& boundsInGlobalDpMap);
            std::unordered_map<ui::LogicalDisplayId, Properties>&& topologyGraph);

private:
    DisplayTopologyGraph(
            ui::LogicalDisplayId primaryDisplay,
            std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>>&&
                    adjacencyGraph,
            std::unordered_map<ui::LogicalDisplayId, int>&& displaysDensityMap,
            std::unordered_map<ui::LogicalDisplayId, FloatRect>&& boundsInGlobalDp);
    DisplayTopologyGraph(ui::LogicalDisplayId primaryDisplay,
                         std::unordered_map<ui::LogicalDisplayId, Properties>&& topologyGraph);
};

} // namespace android
+74 −79
Original line number Diff line number Diff line
@@ -34,6 +34,34 @@ namespace android {

namespace {

std::string logicalDisplayIdToString(const ui::LogicalDisplayId& displayId) {
    return base::StringPrintf("displayId(%d)", displayId.val());
}

std::string adjacentDisplayToString(const DisplayTopologyAdjacentDisplay& adjacentDisplay) {
    return adjacentDisplay.dump();
}

std::string floatRectToString(const FloatRect& floatRect) {
    std::string dump;
    dump += base::StringPrintf("FloatRect(%f, %f, %f, %f)", floatRect.left, floatRect.top,
                               floatRect.right, floatRect.bottom);
    return dump;
}

std::string displayPropertiesToString(const DisplayTopologyGraph::Properties& displayProperties) {
    std::string dump;
    dump += "AdjacentDisplays: ";
    dump += dumpVector(displayProperties.adjacentDisplays, adjacentDisplayToString);
    dump += '\n';
    dump += base::StringPrintf("Density: %d", displayProperties.density);
    dump += '\n';
    dump += "Bounds: ";
    dump += floatRectToString(displayProperties.boundsInGlobalDp);
    dump += '\n';
    return dump;
}

DisplayTopologyPosition getOppositePosition(DisplayTopologyPosition position) {
    switch (position) {
        case DisplayTopologyPosition::LEFT:
@@ -47,30 +75,50 @@ DisplayTopologyPosition getOppositePosition(DisplayTopologyPosition position) {
    }
}

bool validatePrimaryDisplay(ui::LogicalDisplayId primaryDisplayId,
                            const std::unordered_map<ui::LogicalDisplayId, int>& displaysDensity) {
bool validatePrimaryDisplay(
        ui::LogicalDisplayId primaryDisplayId,
        const std::unordered_map<ui::LogicalDisplayId, DisplayTopologyGraph::Properties>&
                topologyGraph) {
    return primaryDisplayId != ui::LogicalDisplayId::INVALID &&
            displaysDensity.contains(primaryDisplayId);
            topologyGraph.contains(primaryDisplayId);
}

bool validateTopologyGraph(
        const std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>>&
                graph) {
    for (const auto& [sourceDisplay, adjacentDisplays] : graph) {
        for (const DisplayTopologyAdjacentDisplay& adjacentDisplay : adjacentDisplays) {
            const auto adjacentGraphIt = graph.find(adjacentDisplay.displayId);
            if (adjacentGraphIt == graph.end()) {
        const std::unordered_map<ui::LogicalDisplayId, DisplayTopologyGraph::Properties>&
                topologyGraph) {
    for (const auto& [sourceDisplay, displayProperties] : topologyGraph) {
        if (!sourceDisplay.isValid()) {
            LOG(ERROR) << "Invalid display in topology graph: " << sourceDisplay;
            return false;
        }
        if (displayProperties.boundsInGlobalDp.getHeight() <= 0 ||
            displayProperties.boundsInGlobalDp.getWidth() <= 0) {
            LOG(ERROR) << "Invalid display-bounds for " << logicalDisplayIdToString(sourceDisplay)
                       << " in topology graph: "
                       << floatRectToString(displayProperties.boundsInGlobalDp);
            return false;
        }
        if (displayProperties.density <= 0) {
            LOG(ERROR) << "Invalid density for " << logicalDisplayIdToString(sourceDisplay)
                       << "in topology graph: " << displayProperties.density;
            return false;
        }
        for (const DisplayTopologyAdjacentDisplay& adjacentDisplay :
             displayProperties.adjacentDisplays) {
            const auto adjacentGraphIt = topologyGraph.find(adjacentDisplay.displayId);
            if (adjacentGraphIt == topologyGraph.end()) {
                LOG(ERROR) << "Missing adjacent display in topology graph: "
                           << adjacentDisplay.displayId << " for source " << sourceDisplay;
                return false;
            }
            const auto reverseEdgeIt =
                    std::find_if(adjacentGraphIt->second.begin(), adjacentGraphIt->second.end(),
                    std::find_if(adjacentGraphIt->second.adjacentDisplays.begin(),
                                 adjacentGraphIt->second.adjacentDisplays.end(),
                                 [sourceDisplay](const DisplayTopologyAdjacentDisplay&
                                                         reverseAdjacentDisplay) {
                                     return sourceDisplay == reverseAdjacentDisplay.displayId;
                                 });
            if (reverseEdgeIt == adjacentGraphIt->second.end()) {
            if (reverseEdgeIt == adjacentGraphIt->second.adjacentDisplays.end()) {
                LOG(ERROR) << "Missing reverse edge in topology graph for: " << sourceDisplay
                           << " -> " << adjacentDisplay.displayId;
                return false;
@@ -96,69 +144,28 @@ bool validateTopologyGraph(
    return true;
}

bool validateDensities(const std::unordered_map<ui::LogicalDisplayId,
                                                std::vector<DisplayTopologyAdjacentDisplay>>& graph,
                       const std::unordered_map<ui::LogicalDisplayId, int>& displaysDensity) {
    for (const auto& [sourceDisplay, adjacentDisplays] : graph) {
        if (!displaysDensity.contains(sourceDisplay)) {
            LOG(ERROR) << "Missing density value in topology graph for display: " << sourceDisplay;
            return false;
        }
    }
    return true;
}

std::string logicalDisplayIdToString(const ui::LogicalDisplayId& displayId) {
    return base::StringPrintf("displayId(%d)", displayId.val());
}

std::string adjacentDisplayToString(const DisplayTopologyAdjacentDisplay& adjacentDisplay) {
    return adjacentDisplay.dump();
}

std::string adjacentDisplayVectorToString(
        const std::vector<DisplayTopologyAdjacentDisplay>& adjacentDisplays) {
    return dumpVector(adjacentDisplays, adjacentDisplayToString);
}

std::string floatRectToString(const FloatRect& floatRect) {
    std::string dump;
    dump += base::StringPrintf("FloatRect(%f, %f, %f, %f)", floatRect.left, floatRect.top,
                               floatRect.right, floatRect.bottom);
    return dump;
}

bool areTopologyGraphComponentsValid(
        ui::LogicalDisplayId primaryDisplayId,
        const std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>>&
                graph,
        const std::unordered_map<ui::LogicalDisplayId, int>& displaysDensity) {
        const std::unordered_map<ui::LogicalDisplayId, DisplayTopologyGraph::Properties>&
                topologyGraph) {
    if (!input_flags::enable_display_topology_validation()) {
        return true;
    }
    return validatePrimaryDisplay(primaryDisplayId, displaysDensity) &&
            validateTopologyGraph(graph) && validateDensities(graph, displaysDensity);
    return validatePrimaryDisplay(primaryDisplayId, topologyGraph) &&
            validateTopologyGraph(topologyGraph);
}

std::string dumpTopologyGraphComponents(
        ui::LogicalDisplayId primaryDisplayId,
        const std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>>&
                graph,
        const std::unordered_map<ui::LogicalDisplayId, int>& displaysDensity,
        const std::unordered_map<ui::LogicalDisplayId, FloatRect> boundsInGlobalDp) {
        const std::unordered_map<ui::LogicalDisplayId, DisplayTopologyGraph::Properties>&
                topologyGraph) {
    std::string dump;
    dump += base::StringPrintf("PrimaryDisplayId: %d\n", primaryDisplayId.val());
    dump += base::StringPrintf("TopologyGraph:\n");
    dump += addLinePrefix(dumpMap(graph, logicalDisplayIdToString, adjacentDisplayVectorToString),
    dump += addLinePrefix(dumpMap(topologyGraph, logicalDisplayIdToString,
                                  displayPropertiesToString),
                          INDENT);
    dump += "\n";
    dump += base::StringPrintf("DisplaysDensity:\n");
    dump += addLinePrefix(dumpMap(displaysDensity, logicalDisplayIdToString), INDENT);
    dump += "\n";
    dump += base::StringPrintf("DisplaysBoundsInGlobalDp:\n");
    dump += addLinePrefix(dumpMap(boundsInGlobalDp, logicalDisplayIdToString, floatRectToString),
                          INDENT);

    return dump;
}

@@ -174,33 +181,21 @@ std::string DisplayTopologyAdjacentDisplay::dump() const {

DisplayTopologyGraph::DisplayTopologyGraph(
        ui::LogicalDisplayId primaryDisplay,
        std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>>&&
                adjacencyGraph,
        std::unordered_map<ui::LogicalDisplayId, int>&& displaysDensityMap,
        std::unordered_map<ui::LogicalDisplayId, FloatRect>&& boundsInGlobalDpMap)
      : primaryDisplayId(primaryDisplay),
        graph(std::move(adjacencyGraph)),
        displaysDensity(std::move(displaysDensityMap)),
        boundsInGlobalDp(std::move(boundsInGlobalDpMap)) {}
        std::unordered_map<ui::LogicalDisplayId, Properties>&& topologyGraph)
      : primaryDisplayId(primaryDisplay), graph(std::move(topologyGraph)) {}

std::string DisplayTopologyGraph::dump() const {
    return dumpTopologyGraphComponents(primaryDisplayId, graph, displaysDensity, boundsInGlobalDp);
    return dumpTopologyGraphComponents(primaryDisplayId, graph);
}

base::Result<const DisplayTopologyGraph> DisplayTopologyGraph::create(
        ui::LogicalDisplayId primaryDisplay,
        std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>>&&
                adjacencyGraph,
        std::unordered_map<ui::LogicalDisplayId, int>&& displaysDensityMap,
        std::unordered_map<ui::LogicalDisplayId, FloatRect>&& boundsInGlobalDp) {
    // Todo(b/401220484): add validation for display bounds
    if (areTopologyGraphComponentsValid(primaryDisplay, adjacencyGraph, displaysDensityMap)) {
        return DisplayTopologyGraph(primaryDisplay, std::move(adjacencyGraph),
                                    std::move(displaysDensityMap), std::move(boundsInGlobalDp));
        std::unordered_map<ui::LogicalDisplayId, Properties>&& topologyGraph) {
    if (areTopologyGraphComponentsValid(primaryDisplay, topologyGraph)) {
        return DisplayTopologyGraph(primaryDisplay, std::move(topologyGraph));
    }
    return base::Error() << "Invalid display topology components: "
                         << dumpTopologyGraphComponents(primaryDisplay, adjacencyGraph,
                                                        displaysDensityMap, boundsInGlobalDp);
                         << dumpTopologyGraphComponents(primaryDisplay, topologyGraph);
}

} // namespace android
+4 −3
Original line number Diff line number Diff line
@@ -1030,7 +1030,8 @@ PointerChoreographer::findDestinationDisplayLocked(const ui::LogicalDisplayId so
        LOG(WARNING) << "Source display missing from topology " << sourceDisplayId;
        return std::nullopt;
    }
    for (const DisplayTopologyAdjacentDisplay& adjacentDisplay : sourceNode->second) {
    for (const DisplayTopologyAdjacentDisplay& adjacentDisplay :
         sourceNode->second.adjacentDisplays) {
        if (adjacentDisplay.position != sourceBoundary) {
            continue;
        }
@@ -1043,8 +1044,8 @@ PointerChoreographer::findDestinationDisplayLocked(const ui::LogicalDisplayId so
        }
        // As displays can have different densities we need to do all calculations in
        // density-independent-pixels a.k.a. dp values.
        const int sourceDensity = mTopology.displaysDensity.at(sourceDisplayId);
        const int adjacentDisplayDensity = mTopology.displaysDensity.at(adjacentDisplay.displayId);
        const int sourceDensity = mTopology.graph.at(sourceDisplayId).density;
        const int adjacentDisplayDensity = mTopology.graph.at(adjacentDisplay.displayId).density;
        const float sourceCursorOffsetDp = pxToDp(sourceCursorOffsetPx, sourceDensity);
        const int32_t edgeSizePx = sourceBoundary == DisplayTopologyPosition::TOP ||
                        sourceBoundary == DisplayTopologyPosition::BOTTOM
+107 −61

File changed.

Preview size limit exceeded, changes collapsed.

+8 −10
Original line number Diff line number Diff line
@@ -15481,18 +15481,16 @@ protected:
    const DisplayTopologyGraph mTopology =
            DisplayTopologyGraph::create(/*primaryDisplayId=*/DISPLAY_ID,
                                         /*adjacencyGraph=*/
                                         /*topologyGraph=*/
                                         {{DISPLAY_ID,
                                           {{SECOND_DISPLAY_ID, DisplayTopologyPosition::TOP,
                                             0.0f}}},
                                           {{{SECOND_DISPLAY_ID, DisplayTopologyPosition::TOP,
                                              0.0f}},
                                            DENSITY_MEDIUM,
                                            FloatRect(0, -500, 500, 0)}},
                                          {SECOND_DISPLAY_ID,
                                           {{DISPLAY_ID, DisplayTopologyPosition::BOTTOM, 0.0f}}}},
                                         /*displaysDensity=*/
                                         {{DISPLAY_ID, DENSITY_MEDIUM},
                                          {SECOND_DISPLAY_ID, DENSITY_MEDIUM}},
                                         /*absoluteDisplayBoundsDp=*/
                                         {{DISPLAY_ID, FloatRect(0, -500, 500, 0)},
                                          {SECOND_DISPLAY_ID, FloatRect(0, 0, 500, 5000)}})
                                           {{{DISPLAY_ID, DisplayTopologyPosition::BOTTOM, 0.0f}},
                                            DENSITY_MEDIUM,
                                            FloatRect(0, 0, 500, 5000)}}})
                    .value();
    void SetUp() override {
Loading