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

Commit 0cc69e10 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

SF: Track starting layer state with transaction tracing

In order to recreate the layer state from transaction traces,
we need to know the starting layer state. We need to start
with an initial state, then replay the transactions from the
trace to recreate the layer states.

Keeping track of the initial layer state while maintaining
a ring buffer of transactions is expensive since it would
require accessing the drawing state from the tracing
thread.

This cl builds and updates a transaction that will
recreate the layer's starting state. As transactions are
evicted from the ring buffer, they are used to update
the starting state transactions.

Test: presubmit
Bug: 200284593
Change-Id: Ifaba8fb061fca4acc15df661483217552011aa09
parent 7891e96d
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -4355,6 +4355,16 @@ status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, sp<IBinder>* outHa
        return result;
    }

    int parentId = -1;
    // We can safely promote the layer in binder thread because we have a strong reference
    // to the layer's handle inside this scope or we were passed in a sp reference to the layer.
    sp<Layer> parentSp = parent.promote();
    if (parentSp != nullptr) {
        parentId = parentSp->getSequence();
    }
    mTransactionTracing.onLayerAdded((*outHandle)->localBinder(), layer->sequence, args.name,
                                     args.flags, parentId);

    setTransactionFlags(eTransactionNeeded);
    *outLayerId = layer->sequence;
    return result;
@@ -6592,6 +6602,7 @@ void SurfaceFlinger::onLayerDestroyed(Layer* layer) {
    if (!layer->isRemovedFromCurrentState()) {
        mScheduler->deregisterLayer(layer);
    }
    mTransactionTracing.onLayerRemoved(layer->getSequence());
}

void SurfaceFlinger::onLayerUpdate() {
+1 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ bool LayerTracing::disable() {
    mEnabled = false;
    LayersTraceFileProto fileProto = createTraceFileProto();
    mBuffer->writeToFile(fileProto, FILE_NAME);
    mBuffer->reset();
    return true;
}

+15 −20
Original line number Diff line number Diff line
@@ -39,26 +39,28 @@ public:
    void setSize(size_t newSize) { mSizeInBytes = newSize; }
    EntryProto& front() { return mStorage.front(); }
    const EntryProto& front() const { return mStorage.front(); }
    const EntryProto& back() const { return mStorage.back(); }

    void reset(size_t newSize) {
    void reset() {
        // use the swap trick to make sure memory is released
        std::queue<EntryProto>().swap(mStorage);
        mSizeInBytes = newSize;
        std::deque<EntryProto>().swap(mStorage);
        mUsedInBytes = 0U;
    }
    void flush(FileProto& fileProto) {
        fileProto.mutable_entry()->Reserve(static_cast<int>(mStorage.size()));
        while (!mStorage.empty()) {
            auto entry = fileProto.add_entry();
            entry->Swap(&mStorage.front());
            mStorage.pop();

    void writeToProto(FileProto& fileProto) {
        fileProto.mutable_entry()->Reserve(static_cast<int>(mStorage.size()) +
                                           fileProto.entry().size());
        for (const EntryProto& entry : mStorage) {
            EntryProto* entryProto = fileProto.add_entry();
            *entryProto = entry;
        }
    }

    status_t writeToFile(FileProto& fileProto, std::string filename) {
        ATRACE_CALL();
        writeToProto(fileProto);
        std::string output;
        if (!writeToString(fileProto, &output)) {
        if (!fileProto.SerializeToString(&output)) {
            ALOGE("Could not serialize proto.");
            return UNKNOWN_ERROR;
        }
@@ -72,13 +74,6 @@ public:
        return NO_ERROR;
    }

    bool writeToString(FileProto& fileProto, std::string* outString) {
        ATRACE_CALL();
        flush(fileProto);
        reset(mSizeInBytes);
        return fileProto.SerializeToString(outString);
    }

    std::vector<EntryProto> emplace(EntryProto&& proto) {
        std::vector<EntryProto> replacedEntries;
        size_t protoSize = static_cast<size_t>(proto.ByteSize());
@@ -88,10 +83,10 @@ public:
            }
            mUsedInBytes -= static_cast<size_t>(mStorage.front().ByteSize());
            replacedEntries.emplace_back(mStorage.front());
            mStorage.pop();
            mStorage.pop_front();
        }
        mUsedInBytes += protoSize;
        mStorage.emplace();
        mStorage.emplace_back();
        mStorage.back().Swap(&proto);
        return replacedEntries;
    }
@@ -112,7 +107,7 @@ public:
private:
    size_t mUsedInBytes = 0U;
    size_t mSizeInBytes = 0U;
    std::queue<EntryProto> mStorage;
    std::deque<EntryProto> mStorage;
};

} // namespace android
+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ proto::TransactionState TransactionProtoParser::toProto(const TransactionState&
}

proto::TransactionState TransactionProtoParser::toProto(
        std::vector<std::pair<int32_t /* layerId */, TracingLayerState>> states) {
        const std::unordered_map<int32_t /* layerId */, TracingLayerState> states) {
    proto::TransactionState proto;
    for (auto& [layerId, state] : states) {
        proto::LayerState layerProto = toProto(state, nullptr);
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ public:
    static proto::TransactionState toProto(const TransactionState&, LayerHandleToIdFn getLayerIdFn,
                                           DisplayHandleToIdFn getDisplayIdFn);
    static proto::TransactionState toProto(
            std::vector<std::pair<int32_t /* layerId */, TracingLayerState>>);
            const std::unordered_map<int32_t /* layerId */, TracingLayerState>);

    static proto::LayerCreationArgs toProto(const TracingLayerCreationArgs& args);

Loading