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

Commit ce73b49f authored by Alec Mouri's avatar Alec Mouri Committed by Android (Google) Code Review
Browse files

Merge "Add some tracing for release fences" into main

parents b1d95d63 3118f969
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <sys/epoll.h>
#include <sys/eventfd.h>

#include <gui/FenceMonitor.h>
#include <gui/FrameRateUtils.h>
#include <gui/GLConsumer.h>
#include <gui/IProducerListener.h>
@@ -475,6 +476,16 @@ void BLASTBufferQueue::releaseBufferCallbackLocked(
    ATRACE_CALL();
    BQA_LOGV("releaseBufferCallback %s", id.to_string().c_str());

    if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
        if (!mFenceMonitor) {
            std::string monitorName = "release :";
            monitorName.append(mName.c_str());
            mFenceMonitor.emplace(monitorName.c_str());
        }

        mFenceMonitor->queueFence(releaseFence);
    }

    // Calculate how many buffers we need to hold before we release them back
    // to the buffer queue. This will prevent higher latency when we are running
    // on a lower refresh rate than the max supported. We only do that for EGL
+25 −11
Original line number Diff line number Diff line
@@ -25,9 +25,18 @@
namespace android::gui {

FenceMonitor::FenceMonitor(const char* name) : mName(name), mFencesQueued(0), mFencesSignaled(0) {
    std::thread thread(&FenceMonitor::loop, this);
    pthread_setname_np(thread.native_handle(), mName);
    thread.detach();
    mThread = std::thread(&FenceMonitor::loop, this);
}

FenceMonitor::~FenceMonitor() {
    {
        std::lock_guard<std::mutex> lock(mMutex);
        mStopped = true;
        mCondition.notify_one();
    }
    if (mThread.joinable()) {
        mThread.join();
    }
}

void FenceMonitor::queueFence(const sp<Fence>& fence) {
@@ -35,24 +44,26 @@ void FenceMonitor::queueFence(const sp<Fence>& fence) {

    std::lock_guard<std::mutex> lock(mMutex);
    if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) {
        snprintf(message, sizeof(message), "%s fence %u has signaled", mName, mFencesQueued);
        snprintf(message, sizeof(message), "%s fence %u has signaled", mName.c_str(),
                 mFencesQueued);
        ATRACE_NAME(message);
        // Need an increment on both to make the trace number correct.
        mFencesQueued++;
        mFencesSignaled++;
        return;
    }
    snprintf(message, sizeof(message), "Trace %s fence %u", mName, mFencesQueued);
    snprintf(message, sizeof(message), "Trace %s fence %u", mName.c_str(), mFencesQueued);
    ATRACE_NAME(message);

    mQueue.push_back(fence);
    mCondition.notify_one();
    mFencesQueued++;
    ATRACE_INT(mName, int32_t(mQueue.size()));
    ATRACE_INT(mName.c_str(), int32_t(mQueue.size()));
}

void FenceMonitor::loop() {
    while (true) {
    pthread_setname_np(pthread_self(), mName.c_str());
    while (!mStopped) {
        threadLoop();
    }
}
@@ -62,15 +73,18 @@ void FenceMonitor::threadLoop() {
    uint32_t fenceNum;
    {
        std::unique_lock<std::mutex> lock(mMutex);
        while (mQueue.empty()) {
        while (mQueue.empty() && !mStopped) {
            mCondition.wait(lock);
        }
        if (mStopped) {
            return;
        }
        fence = mQueue[0];
        fenceNum = mFencesSignaled;
    }
    {
        char message[64];
        snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum);
        snprintf(message, sizeof(message), "waiting for %s %u", mName.c_str(), fenceNum);
        ATRACE_NAME(message);

        status_t result = fence->waitForever(message);
@@ -82,7 +96,7 @@ void FenceMonitor::threadLoop() {
        std::lock_guard<std::mutex> lock(mMutex);
        mQueue.pop_front();
        mFencesSignaled++;
        ATRACE_INT(mName, int32_t(mQueue.size()));
        ATRACE_INT(mName.c_str(), int32_t(mQueue.size()));
    }
}

+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
#include <gui/FenceMonitor.h>
#include <gui/IGraphicBufferConsumer.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/SurfaceComposerClient.h>
@@ -316,6 +317,8 @@ private:

    std::unordered_set<uint64_t> mSyncedFrameNumbers GUARDED_BY(mMutex);

    std::optional<gui::FenceMonitor> mFenceMonitor GUARDED_BY(mMutex);

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
    class BufferReleaseReader {
    public:
+6 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <cstdint>
#include <deque>
#include <mutex>
#include <thread>

#include <ui/Fence.h>

@@ -28,17 +29,20 @@ class FenceMonitor {
public:
    explicit FenceMonitor(const char* name);
    void queueFence(const sp<Fence>& fence);
    ~FenceMonitor();

private:
    void loop();
    void threadLoop();

    const char* mName;
    std::string mName;
    uint32_t mFencesQueued;
    uint32_t mFencesSignaled;
    std::deque<sp<Fence>> mQueue;
    std::condition_variable mCondition;
    std::mutex mMutex;
    std::thread mThread;
    std::atomic_bool mStopped = false;
};

} // namespace android::gui
+4 −0
Original line number Diff line number Diff line
@@ -769,6 +769,10 @@ void Layer::prepareReleaseCallbacks(ftl::Future<FenceResult> futureFenceResult,
        // Older fences for the same layer stack can be dropped when a new fence arrives.
        // An assumption here is that RenderEngine performs work sequentially, so an
        // incoming fence will not fire before an existing fence.
        SFTRACE_NAME(
                ftl::Concat("Adding additional fence for: ", ftl::truncated<20>(mName.c_str()),
                            ", Replacing?: ", mAdditionalPreviousReleaseFences.contains(layerStack))
                        .c_str());
        mAdditionalPreviousReleaseFences.emplace_or_replace(layerStack,
                                                            std::move(futureFenceResult));
    }
Loading