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

Commit 39872bc1 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

[LayerTraceGenerator] fix mirrors and rel-z data

Now that we are using the new front end to
generate layers trace, we need to make a few fixes
so we can generate data that's parsable by winscope.

This means use a unique id instead of the layer id to
identify layers.

Test: presubmit
Fixes: 255901752
Change-Id: Ib30f7d8e2a5575803c455f947a1fd671095ea7e0
parent 191eeb8f
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -104,6 +104,16 @@ public:
        static const TraversalPath ROOT;
        static const TraversalPath ROOT;
    };
    };


    struct TraversalPathHash {
        std::size_t operator()(const LayerHierarchy::TraversalPath& key) const {
            uint32_t hashCode = key.id * 31;
            if (key.mirrorRootId != UNASSIGNED_LAYER_ID) {
                hashCode += key.mirrorRootId * 31;
            }
            return std::hash<size_t>{}(hashCode);
        }
    };

    // Helper class to add nodes to an existing traversal id and removes the
    // Helper class to add nodes to an existing traversal id and removes the
    // node when it goes out of scope.
    // node when it goes out of scope.
    class ScopedAddToTraversalPath {
    class ScopedAddToTraversalPath {
+8 −3
Original line number Original line Diff line number Diff line
@@ -28,9 +28,14 @@ LayerSnapshot::LayerSnapshot(const RequestedLayerState& state,
                             const LayerHierarchy::TraversalPath& path)
                             const LayerHierarchy::TraversalPath& path)
      : path(path) {
      : path(path) {
    static uint32_t sUniqueSequenceId = 0;
    static uint32_t sUniqueSequenceId = 0;
    // Provide a unique id for clones otherwise keeping using the sequence id.
    // Provide a unique id for all snapshots.
    // The seq id can still be useful for debugging if its available.
    // A front end layer can generate multiple snapshots if its mirrored.
    uniqueSequence = (path.isClone()) ? sUniqueSequenceId++ : state.id;
    // Additionally, if the layer is not reachable, we may choose to destroy
    // and recreate the snapshot in which case the unique sequence id will
    // change. The consumer shouldn't tie any lifetimes to this unique id but
    // register a LayerLifecycleManager::ILifecycleListener or get a list of
    // destroyed layers from LayerLifecycleManager.
    uniqueSequence = sUniqueSequenceId++;
    sequence = static_cast<int32_t>(state.id);
    sequence = static_cast<int32_t>(state.id);
    name = state.name;
    name = state.name;
    textureName = state.textureName;
    textureName = state.textureName;
+3 −11
Original line number Original line Diff line number Diff line
@@ -68,6 +68,7 @@ public:
    void update(const Args&);
    void update(const Args&);
    std::vector<std::unique_ptr<LayerSnapshot>>& getSnapshots();
    std::vector<std::unique_ptr<LayerSnapshot>>& getSnapshots();
    LayerSnapshot* getSnapshot(uint32_t layerId) const;
    LayerSnapshot* getSnapshot(uint32_t layerId) const;
    LayerSnapshot* getSnapshot(const LayerHierarchy::TraversalPath& id) const;


    typedef std::function<void(const LayerSnapshot& snapshot)> ConstVisitor;
    typedef std::function<void(const LayerSnapshot& snapshot)> ConstVisitor;


@@ -86,7 +87,6 @@ public:


private:
private:
    friend class LayerSnapshotTest;
    friend class LayerSnapshotTest;
    LayerSnapshot* getSnapshot(const LayerHierarchy::TraversalPath& id) const;
    static LayerSnapshot getRootSnapshot();
    static LayerSnapshot getRootSnapshot();


    // return true if we were able to successfully update the snapshots via
    // return true if we were able to successfully update the snapshots via
@@ -120,16 +120,8 @@ private:
    void updateChildState(LayerSnapshot& snapshot, const LayerSnapshot& childSnapshot,
    void updateChildState(LayerSnapshot& snapshot, const LayerSnapshot& childSnapshot,
                          const Args& args);
                          const Args& args);


    struct TraversalPathHash {
    std::unordered_map<LayerHierarchy::TraversalPath, LayerSnapshot*,
        std::size_t operator()(const LayerHierarchy::TraversalPath& key) const {
                       LayerHierarchy::TraversalPathHash>
            uint32_t hashCode = key.id * 31;
            if (key.mirrorRootId != UNASSIGNED_LAYER_ID) {
                hashCode += key.mirrorRootId * 31;
            }
            return std::hash<size_t>{}(hashCode);
        }
    };
    std::unordered_map<LayerHierarchy::TraversalPath, LayerSnapshot*, TraversalPathHash>
            mIdToSnapshot;
            mIdToSnapshot;
    std::vector<std::unique_ptr<LayerSnapshot>> mSnapshots;
    std::vector<std::unique_ptr<LayerSnapshot>> mSnapshots;
    LayerSnapshot mRootSnapshot;
    LayerSnapshot mRootSnapshot;
+79 −32
Original line number Original line Diff line number Diff line
@@ -15,6 +15,8 @@
 */
 */


// TODO(b/129481165): remove the #pragma below and fix conversion issues
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#include "FrontEnd/LayerCreationArgs.h"
#include "FrontEnd/LayerSnapshot.h"
#pragma clang diagnostic push
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wextra"
#pragma clang diagnostic ignored "-Wextra"
@@ -248,47 +250,88 @@ void LayerProtoHelper::readFromProto(const BlurRegion& proto, android::BlurRegio
    outRegion.bottom = proto.bottom();
    outRegion.bottom = proto.bottom();
}
}


void LayerProtoHelper::writeHierarchyToProto(
LayersProto LayerProtoFromSnapshotGenerator::generate(const frontend::LayerHierarchy& root) {
        LayersProto& outLayersProto, const frontend::LayerHierarchy& root,
    mLayersProto.clear_layers();
        const frontend::LayerSnapshotBuilder& snapshotBuilder,
    std::unordered_set<uint64_t> stackIdsToSkip;
        const std::unordered_map<uint32_t, sp<Layer>>& legacyLayers, uint32_t traceFlags) {
    if ((mTraceFlags & LayerTracing::TRACE_VIRTUAL_DISPLAYS) == 0) {
    using Variant = frontend::LayerHierarchy::Variant;
        for (const auto& [layerStack, displayInfo] : mDisplayInfos) {
    frontend::LayerSnapshot defaultSnapshot;
            if (displayInfo.isVirtual) {

                stackIdsToSkip.insert(layerStack.id);
    LayerProto* layerProto = outLayersProto.add_layers();
    const frontend::RequestedLayerState& layer = *root.getLayer();
    frontend::LayerSnapshot* snapshot = snapshotBuilder.getSnapshot(layer.id);

    if (!snapshot) {
        defaultSnapshot.uniqueSequence = layer.id;
        snapshot = &defaultSnapshot;
            }
            }
    writeSnapshotToProto(layerProto, layer, *snapshot, traceFlags);
    for (const auto& [child, variant] : root.mChildren) {
        if (variant == Variant::Attached || variant == Variant::Detached) {
            layerProto->add_children(child->getLayer()->id);
        } else if (variant == Variant::Relative) {
            layerProto->add_relatives(child->getLayer()->id);
        }
        }
    }
    }


    auto parent = root.getParent();
    frontend::LayerHierarchy::TraversalPath path = frontend::LayerHierarchy::TraversalPath::ROOT;
    if (parent && parent->getLayer()) {
    for (auto& [child, variant] : root.mChildren) {
        layerProto->set_parent(parent->getLayer()->id);
        if (variant != frontend::LayerHierarchy::Variant::Attached ||
            stackIdsToSkip.find(child->getLayer()->layerStack.id) != stackIdsToSkip.end()) {
            continue;
        }
        frontend::LayerHierarchy::ScopedAddToTraversalPath addChildToPath(path,
                                                                          child->getLayer()->id,
                                                                          variant);
        LayerProtoFromSnapshotGenerator::writeHierarchyToProto(*child, path);
    }

    // fill in relative and parent info
    for (int i = 0; i < mLayersProto.layers_size(); i++) {
        auto layerProto = mLayersProto.mutable_layers()->Mutable(i);
        auto it = mChildToRelativeParent.find(layerProto->id());
        if (it == mChildToRelativeParent.end()) {
            layerProto->set_z_order_relative_of(-1);
        } else {
        } else {
            layerProto->set_z_order_relative_of(it->second);
        }
        it = mChildToParent.find(layerProto->id());
        if (it == mChildToParent.end()) {
            layerProto->set_parent(-1);
            layerProto->set_parent(-1);
        } else {
            layerProto->set_parent(it->second);
        }
    }

    mDefaultSnapshots.clear();
    mChildToRelativeParent.clear();
    return std::move(mLayersProto);
}
}


    auto relativeParent = root.getRelativeParent();
frontend::LayerSnapshot* LayerProtoFromSnapshotGenerator::getSnapshot(
    if (relativeParent && relativeParent->getLayer()) {
        frontend::LayerHierarchy::TraversalPath& path, const frontend::RequestedLayerState& layer) {
        layerProto->set_z_order_relative_of(relativeParent->getLayer()->id);
    frontend::LayerSnapshot* snapshot = mSnapshotBuilder.getSnapshot(path);
    if (snapshot) {
        return snapshot;
    } else {
    } else {
        layerProto->set_z_order_relative_of(-1);
        mDefaultSnapshots[path] = frontend::LayerSnapshot(layer, path);
        return &mDefaultSnapshots[path];
    }
}

void LayerProtoFromSnapshotGenerator::writeHierarchyToProto(
        const frontend::LayerHierarchy& root, frontend::LayerHierarchy::TraversalPath& path) {
    using Variant = frontend::LayerHierarchy::Variant;
    LayerProto* layerProto = mLayersProto.add_layers();
    const frontend::RequestedLayerState& layer = *root.getLayer();
    frontend::LayerSnapshot* snapshot = getSnapshot(path, layer);
    LayerProtoHelper::writeSnapshotToProto(layerProto, layer, *snapshot, mTraceFlags);

    for (const auto& [child, variant] : root.mChildren) {
        frontend::LayerHierarchy::ScopedAddToTraversalPath addChildToPath(path,
                                                                          child->getLayer()->id,
                                                                          variant);
        frontend::LayerSnapshot* childSnapshot = getSnapshot(path, layer);
        if (variant == Variant::Attached || variant == Variant::Detached ||
            variant == Variant::Mirror) {
            mChildToParent[childSnapshot->uniqueSequence] = snapshot->uniqueSequence;
            layerProto->add_children(childSnapshot->uniqueSequence);
        } else if (variant == Variant::Relative) {
            mChildToRelativeParent[childSnapshot->uniqueSequence] = snapshot->uniqueSequence;
            layerProto->add_relatives(childSnapshot->uniqueSequence);
        }
    }
    }


    if (traceFlags & LayerTracing::TRACE_COMPOSITION) {
    if (mTraceFlags & LayerTracing::TRACE_COMPOSITION) {
        auto it = legacyLayers.find(layer.id);
        auto it = mLegacyLayers.find(layer.id);
        if (it != legacyLayers.end()) {
        if (it != mLegacyLayers.end()) {
            it->second->writeCompositionStateToProto(layerProto);
            it->second->writeCompositionStateToProto(layerProto);
        }
        }
    }
    }
@@ -298,7 +341,10 @@ void LayerProtoHelper::writeHierarchyToProto(
        if (variant == Variant::Detached) {
        if (variant == Variant::Detached) {
            continue;
            continue;
        }
        }
        writeHierarchyToProto(outLayersProto, *child, snapshotBuilder, legacyLayers, traceFlags);
        frontend::LayerHierarchy::ScopedAddToTraversalPath addChildToPath(path,
                                                                          child->getLayer()->id,
                                                                          variant);
        writeHierarchyToProto(*child, path);
    }
    }
}
}


@@ -345,6 +391,7 @@ void LayerProtoHelper::writeSnapshotToProto(LayerProto* layerInfo,
    layerInfo->set_shadow_radius(snapshot.shadowRadius);
    layerInfo->set_shadow_radius(snapshot.shadowRadius);


    layerInfo->set_id(snapshot.uniqueSequence);
    layerInfo->set_id(snapshot.uniqueSequence);
    layerInfo->set_original_id(snapshot.sequence);
    layerInfo->set_name(requestedState.name);
    layerInfo->set_name(requestedState.name);
    layerInfo->set_type("Layer");
    layerInfo->set_type("Layer");


+36 −5
Original line number Original line Diff line number Diff line
@@ -25,6 +25,9 @@
#include <ui/Rect.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <ui/Region.h>
#include <ui/Transform.h>
#include <ui/Transform.h>
#include <cstdint>
#include "FrontEnd/LayerHierarchy.h"
#include "FrontEnd/LayerSnapshot.h"


namespace android {
namespace android {
namespace surfaceflinger {
namespace surfaceflinger {
@@ -58,11 +61,6 @@ public:
    static void readFromProto(const ColorTransformProto& colorTransformProto, mat4& matrix);
    static void readFromProto(const ColorTransformProto& colorTransformProto, mat4& matrix);
    static void writeToProto(const android::BlurRegion region, BlurRegion*);
    static void writeToProto(const android::BlurRegion region, BlurRegion*);
    static void readFromProto(const BlurRegion& proto, android::BlurRegion& outRegion);
    static void readFromProto(const BlurRegion& proto, android::BlurRegion& outRegion);
    static void writeHierarchyToProto(LayersProto& layersProto,
                                      const frontend::LayerHierarchy& root,
                                      const frontend::LayerSnapshotBuilder& snapshotBuilder,
                                      const std::unordered_map<uint32_t, sp<Layer>>& mLegacyLayers,
                                      uint32_t traceFlags);
    static void writeSnapshotToProto(LayerProto* outProto,
    static void writeSnapshotToProto(LayerProto* outProto,
                                     const frontend::RequestedLayerState& requestedState,
                                     const frontend::RequestedLayerState& requestedState,
                                     const frontend::LayerSnapshot& snapshot, uint32_t traceFlags);
                                     const frontend::LayerSnapshot& snapshot, uint32_t traceFlags);
@@ -70,5 +68,38 @@ public:
            const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displayInfos);
            const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displayInfos);
};
};


class LayerProtoFromSnapshotGenerator {
public:
    LayerProtoFromSnapshotGenerator(
            const frontend::LayerSnapshotBuilder& snapshotBuilder,
            const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displayInfos,
            const std::unordered_map<uint32_t, sp<Layer>>& legacyLayers, uint32_t traceFlags)
          : mSnapshotBuilder(snapshotBuilder),
            mLegacyLayers(legacyLayers),
            mDisplayInfos(displayInfos),
            mTraceFlags(traceFlags) {}
    LayersProto generate(const frontend::LayerHierarchy& root);

private:
    void writeHierarchyToProto(const frontend::LayerHierarchy& root,
                               frontend::LayerHierarchy::TraversalPath& path);
    frontend::LayerSnapshot* getSnapshot(frontend::LayerHierarchy::TraversalPath& path,
                                         const frontend::RequestedLayerState& layer);

    const frontend::LayerSnapshotBuilder& mSnapshotBuilder;
    const std::unordered_map<uint32_t, sp<Layer>>& mLegacyLayers;
    const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& mDisplayInfos;
    uint32_t mTraceFlags;
    LayersProto mLayersProto;
    // winscope expects all the layers, so provide a snapshot even if it not currently drawing
    std::unordered_map<frontend::LayerHierarchy::TraversalPath, frontend::LayerSnapshot,
                       frontend::LayerHierarchy::TraversalPathHash>
            mDefaultSnapshots;
    std::unordered_map<uint32_t /* child unique seq*/, uint32_t /* relative parent unique seq*/>
            mChildToRelativeParent;
    std::unordered_map<uint32_t /* child unique seq*/, uint32_t /* parent unique seq*/>
            mChildToParent;
};

} // namespace surfaceflinger
} // namespace surfaceflinger
} // namespace android
} // namespace android
Loading