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

Commit adf632ba authored by Vishnu Nair's avatar Vishnu Nair
Browse files

BlastBufferQueue: Pass client dequeue times to SurfaceFlinger

SF keeps track of client dequeue, queue, acquire etc. timestamps to
construct frame rendering timelines for developers. With BBQ, SF no
longer has access to this data, so pass the dequeue time along with
the buffers.

Ideally this data should flow to the perfetto trace directly from the client
but this is a temp solution while some perf issues with client logging
is sorted out.

Bug: 176931912
Test: manual tests
Change-Id: Ic88170c1fb20850662cb99325ac42b7232a02817
parent 162b5e90
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,4 +25,5 @@ enum LayerMetadataKey {
    METADATA_MOUSE_CURSOR = 4,
    METADATA_ACCESSIBILITY_ID = 5,
    METADATA_OWNER_PID = 6,
    METADATA_DEQUEUE_TIME = 7,
}
+20 −0
Original line number Diff line number Diff line
@@ -354,6 +354,16 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) {
        t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh);
        mAutoRefresh = bufferItem.mAutoRefresh;
    }
    {
        std::unique_lock _lock{mTimestampMutex};
        auto dequeueTime = mDequeueTimestamps.find(buffer->getId());
        if (dequeueTime != mDequeueTimestamps.end()) {
            Parcel p;
            p.writeInt64(dequeueTime->second);
            t->setMetadata(mSurfaceControl, METADATA_DEQUEUE_TIME, p);
            mDequeueTimestamps.erase(dequeueTime);
        }
    }

    auto mergeTransaction =
            [&t, currentFrameNumber = bufferItem.mFrameNumber](
@@ -412,6 +422,16 @@ void BLASTBufferQueue::onFrameReplaced(const BufferItem& item) {
    // Do nothing since we are not storing unacquired buffer items locally.
}

void BLASTBufferQueue::onFrameDequeued(const uint64_t bufferId) {
    std::unique_lock _lock{mTimestampMutex};
    mDequeueTimestamps[bufferId] = systemTime();
};

void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {
    std::unique_lock _lock{mTimestampMutex};
    mDequeueTimestamps.erase(bufferId);
};

void BLASTBufferQueue::setNextTransaction(SurfaceComposerClient::Transaction* t) {
    std::lock_guard _lock{mMutex};
    mNextTransaction = t;
+12 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <android-base/stringprintf.h>
#include <binder/Parcel.h>
#include <gui/LayerMetadata.h>
#include <inttypes.h>

#include "android/view/LayerMetadataKey.h"

@@ -113,6 +114,15 @@ void LayerMetadata::setInt32(uint32_t key, int32_t value) {
    memcpy(data.data(), p.data(), p.dataSize());
}

std::optional<int64_t> LayerMetadata::getInt64(uint32_t key) const {
    if (!has(key)) return std::nullopt;
    const std::vector<uint8_t>& data = mMap.at(key);
    if (data.size() < sizeof(int64_t)) return std::nullopt;
    Parcel p;
    p.setData(data.data(), data.size());
    return p.readInt64();
}

std::string LayerMetadata::itemToString(uint32_t key, const char* separator) const {
    if (!has(key)) return std::string();
    switch (static_cast<view::LayerMetadataKey>(key)) {
@@ -124,6 +134,8 @@ std::string LayerMetadata::itemToString(uint32_t key, const char* separator) con
            return StringPrintf("taskId%s%d", separator, getInt32(key, 0));
        case view::LayerMetadataKey::METADATA_OWNER_PID:
            return StringPrintf("ownerPID%s%d", separator, getInt32(key, 0));
        case view::LayerMetadataKey::METADATA_DEQUEUE_TIME:
            return StringPrintf("dequeueTime%s%" PRId64, separator, *getInt64(key));
        default:
            return StringPrintf("%d%s%dbytes", key, separator,
                                static_cast<int>(mMap.at(key).size()));
+11 −1
Original line number Diff line number Diff line
@@ -78,6 +78,8 @@ public:
    void onBufferFreed(const wp<GraphicBuffer>&/* graphicBuffer*/) override { /* TODO */ }
    void onFrameReplaced(const BufferItem& item) override;
    void onFrameAvailable(const BufferItem& item) override;
    void onFrameDequeued(const uint64_t) override;
    void onFrameCancelled(const uint64_t) override;

    void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
            const std::vector<SurfaceControlStats>& stats);
@@ -168,7 +170,15 @@ private:

    // Queues up transactions using this token in SurfaceFlinger. This prevents queued up
    // transactions from other parts of the client from blocking this transaction.
    const sp<IBinder> mApplyToken = new BBinder();
    const sp<IBinder> mApplyToken GUARDED_BY(mMutex) = new BBinder();

    // Guards access to mDequeueTimestamps since we cannot hold to mMutex in onFrameDequeued or
    // we will deadlock.
    std::mutex mTimestampMutex;
    // Tracks buffer dequeue times by the client. This info is sent to SurfaceFlinger which uses
    // it for debugging purposes.
    std::unordered_map<uint64_t /* bufferId */, nsecs_t> mDequeueTimestamps
            GUARDED_BY(mTimestampMutex);
};

} // namespace android
+3 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ enum {
    METADATA_MOUSE_CURSOR = 4,
    METADATA_ACCESSIBILITY_ID = 5,
    METADATA_OWNER_PID = 6,
    METADATA_DEQUEUE_TIME = 7
};

struct LayerMetadata : public Parcelable {
@@ -51,6 +52,8 @@ struct LayerMetadata : public Parcelable {
    bool has(uint32_t key) const;
    int32_t getInt32(uint32_t key, int32_t fallback) const;
    void setInt32(uint32_t key, int32_t value);
    std::optional<int64_t> getInt64(uint32_t key) const;
    void setInt64(uint32_t key, int64_t value);

    std::string itemToString(uint32_t key, const char* separator) const;
};
Loading