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

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

Merge "Add tracing thread for RenderEngine's fences" into udc-dev

parents f8710d14 0e7d8fde
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -217,6 +217,7 @@ cc_library_shared {
        "DebugEGLImageTracker.cpp",
        "DisplayEventDispatcher.cpp",
        "DisplayEventReceiver.cpp",
        "FenceMonitor.cpp",
        "GLConsumer.cpp",
        "IConsumerListener.cpp",
        "IGraphicBufferConsumer.cpp",
+89 −0
Original line number Diff line number Diff line
/*
 * Copyright 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include <gui/FenceMonitor.h>
#include <gui/TraceUtils.h>
#include <log/log.h>

#include <thread>

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();
}

void FenceMonitor::queueFence(const sp<Fence>& fence) {
    char message[64];

    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);
        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);
    ATRACE_NAME(message);

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

void FenceMonitor::loop() {
    while (true) {
        threadLoop();
    }
}

void FenceMonitor::threadLoop() {
    sp<Fence> fence;
    uint32_t fenceNum;
    {
        std::unique_lock<std::mutex> lock(mMutex);
        while (mQueue.empty()) {
            mCondition.wait(lock);
        }
        fence = mQueue[0];
        fenceNum = mFencesSignaled;
    }
    {
        char message[64];
        snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum);
        ATRACE_NAME(message);

        status_t result = fence->waitForever(message);
        if (result != OK) {
            ALOGE("Error waiting for fence: %d", result);
        }
    }
    {
        std::lock_guard<std::mutex> lock(mMutex);
        mQueue.pop_front();
        mFencesSignaled++;
        ATRACE_INT(mName, int32_t(mQueue.size()));
    }
}

} // namespace android::gui
 No newline at end of file
+4 −79
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <android/gui/DisplayStatInfo.h>
#include <android/native_window.h>

#include <gui/FenceMonitor.h>
#include <gui/TraceUtils.h>
#include <utils/Log.h>
#include <utils/NativeHandle.h>
@@ -545,82 +546,6 @@ int Surface::setSwapInterval(int interval) {
    return NO_ERROR;
}

class FenceMonitor {
public:
    explicit 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();
    }

    void queueFence(const sp<Fence>& fence) {
        char message[64];

        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);
            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);
        ATRACE_NAME(message);

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

private:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"
    void loop() {
        while (true) {
            threadLoop();
        }
    }
#pragma clang diagnostic pop

    void threadLoop() {
        sp<Fence> fence;
        uint32_t fenceNum;
        {
            std::unique_lock<std::mutex> lock(mMutex);
            while (mQueue.empty()) {
                mCondition.wait(lock);
            }
            fence = mQueue[0];
            fenceNum = mFencesSignaled;
        }
        {
            char message[64];
            snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum);
            ATRACE_NAME(message);

            status_t result = fence->waitForever(message);
            if (result != OK) {
                ALOGE("Error waiting for fence: %d", result);
            }
        }
        {
            std::lock_guard<std::mutex> lock(mMutex);
            mQueue.pop_front();
            mFencesSignaled++;
            ATRACE_INT(mName, int32_t(mQueue.size()));
        }
    }

    const char* mName;
    uint32_t mFencesQueued;
    uint32_t mFencesSignaled;
    std::deque<sp<Fence>> mQueue;
    std::condition_variable mCondition;
    std::mutex mMutex;
};

void Surface::getDequeueBufferInputLocked(
        IGraphicBufferProducer::DequeueBufferInput* dequeueInput) {
    LOG_ALWAYS_FATAL_IF(dequeueInput == nullptr, "input is null");
@@ -694,7 +619,7 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    ALOGE_IF(fence == nullptr, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);

    if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
        static FenceMonitor hwcReleaseThread("HWC release");
        static gui::FenceMonitor hwcReleaseThread("HWC release");
        hwcReleaseThread.queueFence(fence);
    }

@@ -893,7 +818,7 @@ int Surface::dequeueBuffers(std::vector<BatchBuffer>* buffers) {
        sp<GraphicBuffer>& gbuf(mSlots[slot].buffer);

        if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
            static FenceMonitor hwcReleaseThread("HWC release");
            static gui::FenceMonitor hwcReleaseThread("HWC release");
            hwcReleaseThread.queueFence(output.fence);
        }

@@ -1163,7 +1088,7 @@ void Surface::onBufferQueuedLocked(int slot, sp<Fence> fence,
    mQueueBufferCondition.broadcast();

    if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
        static FenceMonitor gpuCompletionThread("GPU completion");
        static gui::FenceMonitor gpuCompletionThread("GPU completion");
        gpuCompletionThread.queueFence(fence);
    }
}
+44 −0
Original line number Diff line number Diff line
/*
 * Copyright 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <cstdint>
#include <deque>
#include <mutex>

#include <ui/Fence.h>

namespace android::gui {

class FenceMonitor {
public:
    explicit FenceMonitor(const char* name);
    void queueFence(const sp<Fence>& fence);

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

    const char* mName;
    uint32_t mFencesQueued;
    uint32_t mFencesSignaled;
    std::deque<sp<Fence>> mQueue;
    std::condition_variable mCondition;
    std::mutex mMutex;
};

} // namespace android::gui
 No newline at end of file
+12 −5
Original line number Diff line number Diff line
@@ -39,10 +39,10 @@
#include <SkPath.h>
#include <SkPoint.h>
#include <SkPoint3.h>
#include <SkRRect.h>
#include <SkRect.h>
#include <SkRefCnt.h>
#include <SkRegion.h>
#include <SkRRect.h>
#include <SkRuntimeEffect.h>
#include <SkSamplingOptions.h>
#include <SkScalar.h>
@@ -51,9 +51,11 @@
#include <SkString.h>
#include <SkSurface.h>
#include <SkTileMode.h>
#include <src/core/SkTraceEventCommon.h>
#include <android-base/stringprintf.h>
#include <gui/FenceMonitor.h>
#include <gui/TraceUtils.h>
#include <pthread.h>
#include <src/core/SkTraceEventCommon.h>
#include <sync/sync.h>
#include <ui/BlurRegion.h>
#include <ui/DataspaceUtils.h>
@@ -63,6 +65,7 @@

#include <cmath>
#include <cstdint>
#include <deque>
#include <memory>
#include <numeric>

@@ -229,7 +232,6 @@ static inline SkM44 getSkM44(const android::mat4& matrix) {
static inline SkPoint3 getSkPoint3(const android::vec3& vector) {
    return SkPoint3::Make(vector.x, vector.y, vector.z);
}

} // namespace

namespace android {
@@ -1134,8 +1136,13 @@ void SkiaRenderEngine::drawLayersInternal(
        activeSurface->flush();
    }

    base::unique_fd drawFence = flushAndSubmit(grContext);
    resultPromise->set_value(sp<Fence>::make(std::move(drawFence)));
    auto drawFence = sp<Fence>::make(flushAndSubmit(grContext));

    if (ATRACE_ENABLED()) {
        static gui::FenceMonitor sMonitor("RE Completion");
        sMonitor.queueFence(drawFence);
    }
    resultPromise->set_value(std::move(drawFence));
}

size_t SkiaRenderEngine::getMaxTextureSize() const {