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

Commit dda5d58c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Plumb FrameEventHistory to client"

parents 21a64de2 871d6357
Loading
Loading
Loading
Loading
+84 −4
Original line number Diff line number Diff line
@@ -31,6 +31,68 @@ using namespace std::chrono_literals;

namespace android {

void BLASTBufferItemConsumer::onDisconnect() {
    Mutex::Autolock lock(mFrameEventHistoryMutex);
    mPreviouslyConnected = mCurrentlyConnected;
    mCurrentlyConnected = false;
    if (mPreviouslyConnected) {
        mDisconnectEvents.push(mCurrentFrameNumber);
    }
    mFrameEventHistory.onDisconnect();
}

void BLASTBufferItemConsumer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
                                                       FrameEventHistoryDelta* outDelta) {
    Mutex::Autolock lock(mFrameEventHistoryMutex);
    if (newTimestamps) {
        // BufferQueueProducer only adds a new timestamp on
        // queueBuffer
        mCurrentFrameNumber = newTimestamps->frameNumber;
        mFrameEventHistory.addQueue(*newTimestamps);
    }
    if (outDelta) {
        // frame event histories will be processed
        // only after the producer connects and requests
        // deltas for the first time.  Forward this intent
        // to SF-side to turn event processing back on
        mPreviouslyConnected = mCurrentlyConnected;
        mCurrentlyConnected = true;
        mFrameEventHistory.getAndResetDelta(outDelta);
    }
}

void BLASTBufferItemConsumer::updateFrameTimestamps(uint64_t frameNumber, nsecs_t refreshStartTime,
                                                    const sp<Fence>& glDoneFence,
                                                    const sp<Fence>& presentFence,
                                                    const sp<Fence>& prevReleaseFence,
                                                    CompositorTiming compositorTiming,
                                                    nsecs_t latchTime, nsecs_t dequeueReadyTime) {
    Mutex::Autolock lock(mFrameEventHistoryMutex);

    // if the producer is not connected, don't bother updating,
    // the next producer that connects won't access this frame event
    if (!mCurrentlyConnected) return;
    std::shared_ptr<FenceTime> glDoneFenceTime = std::make_shared<FenceTime>(glDoneFence);
    std::shared_ptr<FenceTime> presentFenceTime = std::make_shared<FenceTime>(presentFence);
    std::shared_ptr<FenceTime> releaseFenceTime = std::make_shared<FenceTime>(prevReleaseFence);

    mFrameEventHistory.addLatch(frameNumber, latchTime);
    mFrameEventHistory.addRelease(frameNumber, dequeueReadyTime, std::move(releaseFenceTime));
    mFrameEventHistory.addPreComposition(frameNumber, refreshStartTime);
    mFrameEventHistory.addPostComposition(frameNumber, glDoneFenceTime, presentFenceTime,
                                          compositorTiming);
}

void BLASTBufferItemConsumer::getConnectionEvents(uint64_t frameNumber, bool* needsDisconnect) {
    bool disconnect = false;
    Mutex::Autolock lock(mFrameEventHistoryMutex);
    while (!mDisconnectEvents.empty() && mDisconnectEvents.front() <= frameNumber) {
        disconnect = true;
        mDisconnectEvents.pop();
    }
    if (needsDisconnect != nullptr) *needsDisconnect = disconnect;
}

BLASTBufferQueue::BLASTBufferQueue(const sp<SurfaceControl>& surface, int width, int height)
      : mSurfaceControl(surface),
        mWidth(width),
@@ -39,7 +101,7 @@ BLASTBufferQueue::BLASTBufferQueue(const sp<SurfaceControl>& surface, int width,
    BufferQueue::createBufferQueue(&mProducer, &mConsumer);
    mConsumer->setMaxAcquiredBufferCount(MAX_ACQUIRED_BUFFERS);
    mBufferItemConsumer =
            new BufferItemConsumer(mConsumer, AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER, 1, true);
            new BLASTBufferItemConsumer(mConsumer, AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER, 1, true);
    static int32_t id = 0;
    auto name = std::string("BLAST Consumer") + std::to_string(id);
    id++;
@@ -79,11 +141,21 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence
    std::unique_lock _lock{mMutex};
    ATRACE_CALL();

    if (mPendingReleaseItem.item.mGraphicBuffer != nullptr) {
        if (stats.size() > 0) {
            mPendingReleaseItem.releaseFence = stats[0].previousReleaseFence;
    if (!stats.empty()) {
        mTransformHint = stats[0].transformHint;
        mBufferItemConsumer->setTransformHint(mTransformHint);
        mBufferItemConsumer->updateFrameTimestamps(stats[0].frameEventStats.frameNumber,
                                                   stats[0].frameEventStats.refreshStartTime,
                                                   stats[0].frameEventStats.gpuCompositionDoneFence,
                                                   stats[0].presentFence,
                                                   stats[0].previousReleaseFence,
                                                   stats[0].frameEventStats.compositorTiming,
                                                   stats[0].latchTime,
                                                   stats[0].frameEventStats.dequeueReadyTime);
    }
    if (mPendingReleaseItem.item.mGraphicBuffer != nullptr) {
        if (!stats.empty()) {
            mPendingReleaseItem.releaseFence = stats[0].previousReleaseFence;
        } else {
            ALOGE("Warning: no SurfaceControlStats returned in BLASTBufferQueue callback");
            mPendingReleaseItem.releaseFence = nullptr;
@@ -144,6 +216,14 @@ void BLASTBufferQueue::processNextBufferLocked() {
    mNumAcquired++;
    mSubmitted.push(bufferItem);

    bool needsDisconnect = false;
    mBufferItemConsumer->getConnectionEvents(bufferItem.mFrameNumber, &needsDisconnect);

    // if producer disconnected before, notify SurfaceFlinger
    if (needsDisconnect) {
        t->notifyProducerDisconnect(mSurfaceControl);
    }

    // Ensure BLASTBufferQueue stays alive until we receive the transaction complete callback.
    incStrong((void*)transactionCallbackThunk);

+70 −0
Original line number Diff line number Diff line
@@ -30,6 +30,66 @@ enum class Tag : uint32_t {

} // Anonymous namespace

status_t FrameEventHistoryStats::writeToParcel(Parcel* output) const {
    status_t err = output->writeUint64(frameNumber);
    if (err != NO_ERROR) return err;

    if (gpuCompositionDoneFence) {
        err = output->writeBool(true);
        if (err != NO_ERROR) return err;

        err = output->write(*gpuCompositionDoneFence);
    } else {
        err = output->writeBool(false);
    }
    if (err != NO_ERROR) return err;

    err = output->writeInt64(compositorTiming.deadline);
    if (err != NO_ERROR) return err;

    err = output->writeInt64(compositorTiming.interval);
    if (err != NO_ERROR) return err;

    err = output->writeInt64(compositorTiming.presentLatency);
    if (err != NO_ERROR) return err;

    err = output->writeInt64(refreshStartTime);
    if (err != NO_ERROR) return err;

    err = output->writeInt64(dequeueReadyTime);
    return err;
}

status_t FrameEventHistoryStats::readFromParcel(const Parcel* input) {
    status_t err = input->readUint64(&frameNumber);
    if (err != NO_ERROR) return err;

    bool hasFence = false;
    err = input->readBool(&hasFence);
    if (err != NO_ERROR) return err;

    if (hasFence) {
        gpuCompositionDoneFence = new Fence();
        err = input->read(*gpuCompositionDoneFence);
        if (err != NO_ERROR) return err;
    }

    err = input->readInt64(&(compositorTiming.deadline));
    if (err != NO_ERROR) return err;

    err = input->readInt64(&(compositorTiming.interval));
    if (err != NO_ERROR) return err;

    err = input->readInt64(&(compositorTiming.presentLatency));
    if (err != NO_ERROR) return err;

    err = input->readInt64(&refreshStartTime);
    if (err != NO_ERROR) return err;

    err = input->readInt64(&dequeueReadyTime);
    return err;
}

status_t SurfaceStats::writeToParcel(Parcel* output) const {
    status_t err = output->writeStrongBinder(surfaceControl);
    if (err != NO_ERROR) {
@@ -49,6 +109,11 @@ status_t SurfaceStats::writeToParcel(Parcel* output) const {
        err = output->writeBool(false);
    }
    err = output->writeUint32(transformHint);
    if (err != NO_ERROR) {
        return err;
    }

    err = output->writeParcelable(eventStats);
    return err;
}

@@ -74,6 +139,11 @@ status_t SurfaceStats::readFromParcel(const Parcel* input) {
        }
    }
    err = input->readUint32(&transformHint);
    if (err != NO_ERROR) {
        return err;
    }

    err = input->readParcelable(&eventStats);
    return err;
}

+16 −2
Original line number Diff line number Diff line
@@ -222,8 +222,10 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener
                surfaceControlStats
                        .emplace_back(callbacksMap[callbackId]
                                              .surfaceControls[surfaceStats.surfaceControl],
                                      surfaceStats.acquireTime, surfaceStats.previousReleaseFence,
                                      surfaceStats.transformHint);
                                      transactionStats.latchTime, surfaceStats.acquireTime,
                                      transactionStats.presentFence,
                                      surfaceStats.previousReleaseFence, surfaceStats.transformHint,
                                      surfaceStats.eventStats);
                if (callbacksMap[callbackId].surfaceControls[surfaceStats.surfaceControl]) {
                    callbacksMap[callbackId]
                            .surfaceControls[surfaceStats.surfaceControl]
@@ -1235,6 +1237,18 @@ SurfaceComposerClient::Transaction::addTransactionCompletedCallback(
    return *this;
}

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::notifyProducerDisconnect(
        const sp<SurfaceControl>& sc) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }

    s->what |= layer_state_t::eProducerDisconnect;
    return *this;
}

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::detachChildren(
        const sp<SurfaceControl>& sc) {
    layer_state_t* s = getLayerState(sc);
+30 −1
Original line number Diff line number Diff line
@@ -33,6 +33,35 @@ namespace android {

class BufferItemConsumer;

class BLASTBufferItemConsumer : public BufferItemConsumer {
public:
    BLASTBufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
                            int bufferCount, bool controlledByApp)
          : BufferItemConsumer(consumer, consumerUsage, bufferCount, controlledByApp),
            mCurrentlyConnected(false),
            mPreviouslyConnected(false) {}

    void onDisconnect() override;
    void addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
                                  FrameEventHistoryDelta* outDelta) override
            REQUIRES(mFrameEventHistoryMutex);
    void updateFrameTimestamps(uint64_t frameNumber, nsecs_t refreshStartTime,
                               const sp<Fence>& gpuCompositionDoneFence,
                               const sp<Fence>& presentFence, const sp<Fence>& prevReleaseFence,
                               CompositorTiming compositorTiming, nsecs_t latchTime,
                               nsecs_t dequeueReadyTime) REQUIRES(mFrameEventHistoryMutex);
    void getConnectionEvents(uint64_t frameNumber, bool* needsDisconnect);

private:
    uint64_t mCurrentFrameNumber = 0;

    Mutex mFrameEventHistoryMutex;
    ConsumerFrameEventHistory mFrameEventHistory GUARDED_BY(mFrameEventHistoryMutex);
    std::queue<uint64_t> mDisconnectEvents GUARDED_BY(mFrameEventHistoryMutex);
    bool mCurrentlyConnected GUARDED_BY(mFrameEventHistoryMutex);
    bool mPreviouslyConnected GUARDED_BY(mFrameEventHistoryMutex);
};

class BLASTBufferQueue
    : public ConsumerBase::FrameAvailableListener, public BufferItemConsumer::BufferFreedListener
{
@@ -89,7 +118,7 @@ private:

    sp<IGraphicBufferConsumer> mConsumer;
    sp<IGraphicBufferProducer> mProducer;
    sp<BufferItemConsumer> mBufferItemConsumer;
    sp<BLASTBufferItemConsumer> mBufferItemConsumer;

    SurfaceComposerClient::Transaction* mNextTransaction GUARDED_BY(mMutex);
};
+0 −1
Original line number Diff line number Diff line
@@ -174,7 +174,6 @@ struct NewFrameEventsEntry {
    std::shared_ptr<FenceTime> acquireFence{FenceTime::NO_FENCE};
};


// Used by the consumer to keep track of which fields it already sent to
// the producer.
class FrameEventDirtyFields {
Loading