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

Commit 06312184 authored by Pablo Ceballos's avatar Pablo Ceballos
Browse files

SF: Force refresh when in single buffer mode

- Add a boolean to BufferItem to track whether single buffer mode is
  enabled. When it is, force SurfaceFlinger to acquire a new buffer
  and refresh on every vsync.

Bug 24940410

Change-Id: Iea67330c416b6fb14500865f98c67f1c12f23197
parent ccdfd60d
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -118,6 +118,13 @@ class BufferItem : public Flattenable<BufferItem> {
    // Describes the portion of the surface that has been modified since the
    // previous frame
    Region mSurfaceDamage;

    // Indicates that the BufferQueue is in single buffer mode
    bool mSingleBufferMode;

    // Indicates that this buffer was queued by the producer. When in single
    // buffer mode acquire() can return a BufferItem that wasn't in the queue.
    bool mQueuedBuffer;
};

} // namespace android
+3 −1
Original line number Diff line number Diff line
@@ -37,7 +37,9 @@ BufferItem::BufferItem() :
    mIsDroppable(false),
    mAcquireCalled(false),
    mTransformToDisplayInverse(false),
    mSurfaceDamage() {
    mSurfaceDamage(),
    mSingleBufferMode(false),
    mQueuedBuffer(true) {
}

BufferItem::~BufferItem() {}
+4 −0
Original line number Diff line number Diff line
@@ -203,11 +203,15 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
                    (mCore->mSingleBufferCache.transform &
                    NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
            outBuffer->mSurfaceDamage = Region::INVALID_REGION;
            outBuffer->mSingleBufferMode = true;
            outBuffer->mQueuedBuffer = false;
        } else {
            slot = front->mSlot;
            *outBuffer = *front;
        }

        outBuffer->mSingleBufferMode = mCore->mSingleBufferMode;

        ATRACE_BUFFER_INDEX(slot);

        BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }",
+2 −0
Original line number Diff line number Diff line
@@ -744,6 +744,8 @@ status_t BufferQueueProducer::queueBuffer(int slot,
                mCore->mDequeueBufferCannotBlock ||
                (mCore->mSingleBufferMode && mCore->mSingleBufferSlot == slot);
        item.mSurfaceDamage = surfaceDamage;
        item.mSingleBufferMode = mCore->mSingleBufferMode;
        item.mQueuedBuffer = true;

        mStickyTransform = stickyTransform;

+20 −10
Original line number Diff line number Diff line
@@ -1254,7 +1254,7 @@ void Layer::useEmptyDamage() {
// ----------------------------------------------------------------------------

bool Layer::shouldPresentNow(const DispSync& dispSync) const {
    if (mSidebandStreamChanged) {
    if (mSidebandStreamChanged || mSingleBufferMode) {
        return true;
    }

@@ -1278,7 +1278,7 @@ bool Layer::shouldPresentNow(const DispSync& dispSync) const {

bool Layer::onPreComposition() {
    mRefreshPending = false;
    return mQueuedFrames > 0 || mSidebandStreamChanged;
    return mQueuedFrames > 0 || mSidebandStreamChanged || mSingleBufferMode;
}

void Layer::onPostComposition() {
@@ -1335,7 +1335,7 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
    }

    Region outDirtyRegion;
    if (mQueuedFrames > 0) {
    if (mQueuedFrames > 0 || mSingleBufferMode) {

        // if we've already called updateTexImage() without going through
        // a composition step, we have to skip this layer at this point
@@ -1492,8 +1492,14 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
            }
        }

        // This boolean is used to make sure that SurfaceFlinger's shadow copy
        // of the buffer queue isn't modified when the buffer queue is returning
        // BufferItem's that weren't actually queued. This can happen in single
        // buffer mode.
        bool queuedBuffer = false;
        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
                mFlinger->mPrimaryDispSync, maxFrameNumber);
                mFlinger->mPrimaryDispSync, &mSingleBufferMode, &queuedBuffer,
                maxFrameNumber);
        if (updateResult == BufferQueue::PRESENT_LATER) {
            // Producer doesn't want buffer to be displayed yet.  Signal a
            // layer update so we check again at the next opportunity.
@@ -1502,16 +1508,18 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
            // If the buffer has been rejected, remove it from the shadow queue
            // and return early
            if (queuedBuffer) {
                Mutex::Autolock lock(mQueueItemLock);
                mQueueItems.removeAt(0);
                android_atomic_dec(&mQueuedFrames);
            }
            return outDirtyRegion;
        } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
            // This can occur if something goes wrong when trying to create the
            // EGLImage for this buffer. If this happens, the buffer has already
            // been released, so we need to clean up the queue and bug out
            // early.
            {
            if (queuedBuffer) {
                Mutex::Autolock lock(mQueueItemLock);
                mQueueItems.clear();
                android_atomic_and(0, &mQueuedFrames);
@@ -1526,7 +1534,8 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
            return outDirtyRegion;
        }

        { // Autolock scope
        if (queuedBuffer) {
            // Autolock scope
            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();

            Mutex::Autolock lock(mQueueItemLock);
@@ -1544,7 +1553,8 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)

        // Decrement the queued-frames count.  Signal another event if we
        // have more frames pending.
        if (android_atomic_dec(&mQueuedFrames) > 1) {
        if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
                || mSingleBufferMode) {
            mFlinger->signalLayerUpdate();
        }

Loading