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

Commit fc92e6f7 authored by Alec Mouri's avatar Alec Mouri Committed by Automerger Merge Worker
Browse files

Merge "Add tracing thread for RenderEngine's fences" into udc-dev am: 0f0c9770

parents 90c1c27f 0f0c9770
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -217,6 +217,7 @@ cc_library_shared {
        "DebugEGLImageTracker.cpp",
        "DebugEGLImageTracker.cpp",
        "DisplayEventDispatcher.cpp",
        "DisplayEventDispatcher.cpp",
        "DisplayEventReceiver.cpp",
        "DisplayEventReceiver.cpp",
        "FenceMonitor.cpp",
        "GLConsumer.cpp",
        "GLConsumer.cpp",
        "IConsumerListener.cpp",
        "IConsumerListener.cpp",
        "IGraphicBufferConsumer.cpp",
        "IGraphicBufferConsumer.cpp",
+89 −0
Original line number Original line 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 Original line Diff line number Diff line
@@ -30,6 +30,7 @@
#include <android/gui/DisplayStatInfo.h>
#include <android/gui/DisplayStatInfo.h>
#include <android/native_window.h>
#include <android/native_window.h>


#include <gui/FenceMonitor.h>
#include <gui/TraceUtils.h>
#include <gui/TraceUtils.h>
#include <utils/Log.h>
#include <utils/Log.h>
#include <utils/NativeHandle.h>
#include <utils/NativeHandle.h>
@@ -545,82 +546,6 @@ int Surface::setSwapInterval(int interval) {
    return NO_ERROR;
    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(
void Surface::getDequeueBufferInputLocked(
        IGraphicBufferProducer::DequeueBufferInput* dequeueInput) {
        IGraphicBufferProducer::DequeueBufferInput* dequeueInput) {
    LOG_ALWAYS_FATAL_IF(dequeueInput == nullptr, "input is null");
    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);
    ALOGE_IF(fence == nullptr, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);


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


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


        if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
        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);
            hwcReleaseThread.queueFence(output.fence);
        }
        }


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


    if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
    if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
        static FenceMonitor gpuCompletionThread("GPU completion");
        static gui::FenceMonitor gpuCompletionThread("GPU completion");
        gpuCompletionThread.queueFence(fence);
        gpuCompletionThread.queueFence(fence);
    }
    }
}
}
+44 −0
Original line number Original line 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 Original line Diff line number Diff line
@@ -39,10 +39,10 @@
#include <SkPath.h>
#include <SkPath.h>
#include <SkPoint.h>
#include <SkPoint.h>
#include <SkPoint3.h>
#include <SkPoint3.h>
#include <SkRRect.h>
#include <SkRect.h>
#include <SkRect.h>
#include <SkRefCnt.h>
#include <SkRefCnt.h>
#include <SkRegion.h>
#include <SkRegion.h>
#include <SkRRect.h>
#include <SkRuntimeEffect.h>
#include <SkRuntimeEffect.h>
#include <SkSamplingOptions.h>
#include <SkSamplingOptions.h>
#include <SkScalar.h>
#include <SkScalar.h>
@@ -51,9 +51,11 @@
#include <SkString.h>
#include <SkString.h>
#include <SkSurface.h>
#include <SkSurface.h>
#include <SkTileMode.h>
#include <SkTileMode.h>
#include <src/core/SkTraceEventCommon.h>
#include <android-base/stringprintf.h>
#include <android-base/stringprintf.h>
#include <gui/FenceMonitor.h>
#include <gui/TraceUtils.h>
#include <gui/TraceUtils.h>
#include <pthread.h>
#include <src/core/SkTraceEventCommon.h>
#include <sync/sync.h>
#include <sync/sync.h>
#include <ui/BlurRegion.h>
#include <ui/BlurRegion.h>
#include <ui/DataspaceUtils.h>
#include <ui/DataspaceUtils.h>
@@ -63,6 +65,7 @@


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


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

} // namespace
} // namespace


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


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

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


size_t SkiaRenderEngine::getMaxTextureSize() const {
size_t SkiaRenderEngine::getMaxTextureSize() const {