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

Commit 8af62f24 authored by Priyanka Advani (xWF)'s avatar Priyanka Advani (xWF) Committed by Android (Google) Code Review
Browse files

Revert "Read from BufferReleaseChannel in background thread"

This reverts commit 5ab65e9e.

Reason for revert: Droidmonitor created revert due to b/362800004. Will be verifying through ABTD before submission.

Change-Id: I440606b3da7f4d4c85f5900ac9b9e6fb18ccd8fa
parent 5ab65e9e
Loading
Loading
Loading
Loading
+10 −151
Original line number Diff line number Diff line
@@ -22,14 +22,11 @@

#include <com_android_graphics_libgui_flags.h>
#include <cutils/atomic.h>
#include <ftl/fake_guard.h>
#include <gui/BLASTBufferQueue.h>
#include <gui/BufferItemConsumer.h>
#include <gui/BufferQueueConsumer.h>
#include <gui/BufferQueueCore.h>
#include <gui/BufferQueueProducer.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>

#include <gui/FrameRateUtils.h>
#include <gui/GLConsumer.h>
@@ -77,12 +74,6 @@ namespace android {
    std::unique_lock _lock{mutex};        \
    base::ScopedLockAssertion assumeLocked(mutex);

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
static ReleaseBufferCallback EMPTY_RELEASE_CALLBACK =
        [](const ReleaseCallbackId&, const sp<Fence>& /*releaseFence*/,
           std::optional<uint32_t> /*currentMaxAcquiredBufferCount*/) {};
#endif

void BLASTBufferItemConsumer::onDisconnect() {
    Mutex::Autolock lock(mMutex);
    mPreviouslyConnected = mCurrentlyConnected;
@@ -224,12 +215,6 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati
            },
            this);

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
    std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> bufferReleaseConsumer;
    gui::BufferReleaseChannel::open(mName, bufferReleaseConsumer, mBufferReleaseProducer);
    mBufferReleaseReader = std::make_shared<BufferReleaseReader>(std::move(bufferReleaseConsumer));
#endif

    BQA_LOGV("BLASTBufferQueue created");
}

@@ -259,9 +244,6 @@ BLASTBufferQueue::~BLASTBufferQueue() {
void BLASTBufferQueue::onFirstRef() {
    // safe default, most producers are expected to override this
    mProducer->setMaxDequeuedBufferCount(2);
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
    mBufferReleaseThread.start(sp<BLASTBufferQueue>::fromExisting(this));
#endif
}

void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height,
@@ -287,9 +269,6 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width,
    if (surfaceControlChanged) {
        t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure,
                   layer_state_t::eEnableBackpressure);
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
        t.setBufferReleaseChannel(mSurfaceControl, mBufferReleaseProducer);
#endif
        applyTransaction = true;
    }
    mTransformHint = mSurfaceControl->getTransformHint();
@@ -407,7 +386,6 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence
                                                    stat.latchTime,
                                                    stat.frameEventStats.dequeueReadyTime);
                }
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
                auto currFrameNumber = stat.frameEventStats.frameNumber;
                std::vector<ReleaseCallbackId> staleReleases;
                for (const auto& [key, value]: mSubmitted) {
@@ -423,7 +401,6 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence
                                                stat.currentMaxAcquiredBufferCount,
                                                true /* fakeRelease */);
                }
#endif
            } else {
                BQA_LOGE("Failed to find matching SurfaceControl in transactionCallback");
            }
@@ -434,15 +411,6 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence
    }
}

void BLASTBufferQueue::flushShadowQueue() {
    BQA_LOGV("flushShadowQueue");
    int numFramesToFlush = mNumFrameAvailable;
    while (numFramesToFlush > 0) {
        acquireNextBufferLocked(std::nullopt);
        numFramesToFlush--;
    }
}

// Unlike transactionCallbackThunk the release buffer callback does not extend the life of the
// BBQ. This is because if the BBQ is destroyed, then the buffers will be released by the client.
// So we pass in a weak pointer to the BBQ and if it still alive, then we release the buffer.
@@ -460,6 +428,15 @@ ReleaseBufferCallback BLASTBufferQueue::makeReleaseBufferCallbackThunk() {
    };
}

void BLASTBufferQueue::flushShadowQueue() {
    BQA_LOGV("flushShadowQueue");
    int numFramesToFlush = mNumFrameAvailable;
    while (numFramesToFlush > 0) {
        acquireNextBufferLocked(std::nullopt);
        numFramesToFlush--;
    }
}

void BLASTBufferQueue::releaseBufferCallback(
        const ReleaseCallbackId& id, const sp<Fence>& releaseFence,
        std::optional<uint32_t> currentMaxAcquiredBufferCount) {
@@ -640,12 +617,7 @@ status_t BLASTBufferQueue::acquireNextBufferLocked(
                           bufferItem.mGraphicBuffer->getHeight(), bufferItem.mTransform,
                           bufferItem.mScalingMode, crop);

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
    ReleaseBufferCallback releaseBufferCallback =
            applyTransaction ? EMPTY_RELEASE_CALLBACK : makeReleaseBufferCallbackThunk();
#else
    auto releaseBufferCallback = makeReleaseBufferCallbackThunk();
#endif
    sp<Fence> fence = bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE;

    nsecs_t dequeueTime = -1;
@@ -1387,120 +1359,7 @@ bool BLASTBufferQueue::isSameSurfaceControl(const sp<SurfaceControl>& surfaceCon
void BLASTBufferQueue::setTransactionHangCallback(
        std::function<void(const std::string&)> callback) {
    std::lock_guard _lock{mMutex};
    mTransactionHangCallback = std::move(callback);
    mTransactionHangCallback = callback;
}

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)

BLASTBufferQueue::BufferReleaseReader::BufferReleaseReader(
        std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> endpoint)
      : mEndpoint{std::move(endpoint)} {
    mEpollFd = android::base::unique_fd{epoll_create1(0)};
    LOG_ALWAYS_FATAL_IF(!mEpollFd.ok(),
                        "Failed to create buffer release epoll file descriptor. errno=%d "
                        "message='%s'",
                        errno, strerror(errno));

    epoll_event registerEndpointFd{};
    registerEndpointFd.events = EPOLLIN;
    registerEndpointFd.data.fd = mEndpoint->getFd();
    status_t status =
            epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mEndpoint->getFd(), &registerEndpointFd);
    LOG_ALWAYS_FATAL_IF(status == -1,
                        "Failed to register buffer release consumer file descriptor with epoll. "
                        "errno=%d message='%s'",
                        errno, strerror(errno));

    mEventFd = android::base::unique_fd(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
    LOG_ALWAYS_FATAL_IF(!mEventFd.ok(),
                        "Failed to create buffer release event file descriptor. errno=%d "
                        "message='%s'",
                        errno, strerror(errno));

    epoll_event registerEventFd{};
    registerEventFd.events = EPOLLIN;
    registerEventFd.data.fd = mEventFd.get();
    status = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mEventFd.get(), &registerEventFd);
    LOG_ALWAYS_FATAL_IF(status == -1,
                        "Failed to register buffer release event file descriptor with epoll. "
                        "errno=%d message='%s'",
                        errno, strerror(errno));
}

BLASTBufferQueue::BufferReleaseReader& BLASTBufferQueue::BufferReleaseReader::operator=(
        BufferReleaseReader&& other) {
    if (this != &other) {
        ftl::FakeGuard guard{mMutex};
        ftl::FakeGuard otherGuard{other.mMutex};
        mEndpoint = std::move(other.mEndpoint);
        mEpollFd = std::move(other.mEpollFd);
        mEventFd = std::move(other.mEventFd);
    }
    return *this;
}

status_t BLASTBufferQueue::BufferReleaseReader::readBlocking(ReleaseCallbackId& outId,
                                                             sp<Fence>& outFence,
                                                             uint32_t& outMaxAcquiredBufferCount) {
    epoll_event event{};
    while (true) {
        int eventCount = epoll_wait(mEpollFd.get(), &event, 1 /* maxevents */, -1 /* timeout */);
        if (eventCount == 1) {
            break;
        }
        if (eventCount == -1 && errno != EINTR) {
            ALOGE("epoll_wait error while waiting for buffer release. errno=%d message='%s'", errno,
                  strerror(errno));
        }
    }

    if (event.data.fd == mEventFd.get()) {
        uint64_t value;
        if (read(mEventFd.get(), &value, sizeof(uint64_t)) == -1 && errno != EWOULDBLOCK) {
            ALOGE("error while reading from eventfd. errno=%d message='%s'", errno,
                  strerror(errno));
        }
        return WOULD_BLOCK;
    }

    std::lock_guard lock{mMutex};
    return mEndpoint->readReleaseFence(outId, outFence, outMaxAcquiredBufferCount);
}

void BLASTBufferQueue::BufferReleaseReader::interruptBlockingRead() {
    uint64_t value = 1;
    if (write(mEventFd.get(), &value, sizeof(uint64_t)) == -1) {
        ALOGE("failed to notify dequeue event. errno=%d message='%s'", errno, strerror(errno));
    }
}

void BLASTBufferQueue::BufferReleaseThread::start(const sp<BLASTBufferQueue>& bbq) {
    mRunning = std::make_shared<std::atomic_bool>(true);
    mReader = bbq->mBufferReleaseReader;
    std::thread([running = mRunning, reader = mReader, weakBbq = wp<BLASTBufferQueue>(bbq)]() {
        pthread_setname_np(pthread_self(), "BufferReleaseThread");
        while (*running) {
            ReleaseCallbackId id;
            sp<Fence> fence;
            uint32_t maxAcquiredBufferCount;
            if (status_t status = reader->readBlocking(id, fence, maxAcquiredBufferCount);
                status != OK) {
                continue;
            }
            sp<BLASTBufferQueue> bbq = weakBbq.promote();
            if (!bbq) {
                return;
            }
            bbq->releaseBufferCallback(id, fence, maxAcquiredBufferCount);
        }
    }).detach();
}

BLASTBufferQueue::BufferReleaseThread::~BufferReleaseThread() {
    *mRunning = false;
    mReader->interruptBlockingRead();
}

#endif

} // namespace android
+0 −45
Original line number Diff line number Diff line
@@ -331,51 +331,6 @@ private:
    std::function<void(const std::string&)> mTransactionHangCallback;

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

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
    class BufferReleaseReader {
    public:
        BufferReleaseReader() = default;
        BufferReleaseReader(std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint>);
        BufferReleaseReader& operator=(BufferReleaseReader&&);

        // Block until we can read a buffer release message.
        //
        // Returns:
        // * OK if a ReleaseCallbackId and Fence were successfully read.
        // * WOULD_BLOCK if the blocking read was interrupted by interruptBlockingRead.
        // * UNKNOWN_ERROR if something went wrong.
        status_t readBlocking(ReleaseCallbackId& outId, sp<Fence>& outReleaseFence,
                              uint32_t& outMaxAcquiredBufferCount);

        // Signals the reader's eventfd to wake up any threads waiting on readBlocking.
        void interruptBlockingRead();

    private:
        std::mutex mMutex;
        std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> mEndpoint GUARDED_BY(mMutex);
        android::base::unique_fd mEpollFd;
        android::base::unique_fd mEventFd;
    };

    // BufferReleaseChannel is used to communicate buffer releases from SurfaceFlinger to
    // the client. See BBQBufferQueueProducer::dequeueBuffer for details.
    std::shared_ptr<BufferReleaseReader> mBufferReleaseReader;
    std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> mBufferReleaseProducer;

    class BufferReleaseThread {
    public:
        BufferReleaseThread() = default;
        ~BufferReleaseThread();
        void start(const sp<BLASTBufferQueue>&);

    private:
        std::shared_ptr<std::atomic_bool> mRunning;
        std::shared_ptr<BufferReleaseReader> mReader;
    };

    BufferReleaseThread mBufferReleaseThread;
#endif
};

} // namespace android
+4 −19
Original line number Diff line number Diff line
@@ -2529,24 +2529,15 @@ void Layer::cloneDrawingState(const Layer* from) {
void Layer::callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
                                      const sp<GraphicBuffer>& buffer, uint64_t framenumber,
                                      const sp<Fence>& releaseFence) {
    if (!listener && !mBufferReleaseChannel) {
    if (!listener) {
        return;
    }

    SFTRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64, getDebugName(), framenumber);

    ReleaseCallbackId callbackId{buffer->getId(), framenumber};
    const sp<Fence>& fence = releaseFence ? releaseFence : Fence::NO_FENCE;
    uint32_t currentMaxAcquiredBufferCount =
            mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);

    if (listener) {
        listener->onReleaseBuffer(callbackId, fence, currentMaxAcquiredBufferCount);
    }

    if (mBufferReleaseChannel) {
        mBufferReleaseChannel->writeReleaseFence(callbackId, fence, currentMaxAcquiredBufferCount);
    }
    listener->onReleaseBuffer({buffer->getId(), framenumber},
                              releaseFence ? releaseFence : Fence::NO_FENCE,
                              currentMaxAcquiredBufferCount);
}

sp<CallbackHandle> Layer::findCallbackHandle() {
@@ -2664,7 +2655,6 @@ void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult,

void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
    for (const auto& handle : mDrawingState.callbackHandles) {
        handle->bufferReleaseChannel = mBufferReleaseChannel;
        handle->transformHint = mTransformHint;
        handle->dequeueReadyTime = dequeueReadyTime;
        handle->currentMaxAcquiredBufferCount =
@@ -4103,11 +4093,6 @@ bool Layer::setTrustedPresentationInfo(TrustedPresentationThresholds const& thre
    return haveTrustedPresentationListener;
}

void Layer::setBufferReleaseChannel(
        const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel) {
    mBufferReleaseChannel = channel;
}

void Layer::updateLastLatchTime(nsecs_t latchTime) {
    mLastLatchTime = latchTime;
}
+0 −3
Original line number Diff line number Diff line
@@ -543,7 +543,6 @@ public:
    };

    BufferInfo mBufferInfo;
    std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> mBufferReleaseChannel;

    // implements compositionengine::LayerFE
    const compositionengine::LayerFECompositionState* getCompositionState() const;
@@ -799,8 +798,6 @@ public:

    bool setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds,
                                    TrustedPresentationListener const& listener);
    void setBufferReleaseChannel(
            const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel);

    // Creates a new handle each time, so we only expect
    // this to be called once.
+0 −4
Original line number Diff line number Diff line
@@ -5115,10 +5115,6 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f
        }
    }

    if (what & layer_state_t::eBufferReleaseChannelChanged) {
        layer->setBufferReleaseChannel(s.bufferReleaseChannel);
    }

    const auto& requestedLayerState = mLayerLifecycleManager.getLayerFromId(layer->getSequence());
    bool willPresentCurrentTransaction = requestedLayerState &&
            (requestedLayerState->hasReadyFrame() ||
Loading