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

Commit 99a0afba authored by Eric Penner's avatar Eric Penner
Browse files

BufferQueueProducer: Throttle EGL frame production.

Throttling was previously controlled by a combination of the
driver and the number of buffers in the queue. This patch makes
a more consistent trade-off, which allows two GPU frames pending
but not three. More buffering could improve throughput in the
case of varying frame times, but this also increases latency.

Bug: 17502897
Change-Id: I4ee68019ca94c635294c5959931a555a6c4ef2df
parent 6c925ede
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -197,6 +197,12 @@ private:

    uint32_t mStickyTransform;

    // This saves the fence from the last queueBuffer, such that the
    // next queueBuffer call can throttle buffer production. The prior
    // queueBuffer's fence is not nessessarily available elsewhere,
    // since the previous buffer might have already been acquired.
    sp<Fence> mLastQueueBufferFence;

}; // class BufferQueueProducer

} // namespace android
+11 −1
Original line number Diff line number Diff line
@@ -38,7 +38,8 @@ BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) :
    mCore(core),
    mSlots(core->mSlots),
    mConsumerName(),
    mStickyTransform(0) {}
    mStickyTransform(0),
    mLastQueueBufferFence(Fence::NO_FENCE) {}

BufferQueueProducer::~BufferQueueProducer() {}

@@ -644,6 +645,15 @@ status_t BufferQueueProducer::queueBuffer(int slot,
        ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
    } // Autolock scope

    // Wait without lock held
    if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
        // Waiting here allows for two full buffers to be queued but not a
        // third. In the event that frames take varying time, this makes a
        // small trade-off in favor of latency rather than throughput.
        mLastQueueBufferFence->waitForever("Throttling EGL Production");
        mLastQueueBufferFence = fence;
    }

    // Call back without lock held
    if (listener != NULL) {
        listener->onFrameAvailable();