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

Commit 74149656 authored by Jesse Hall's avatar Jesse Hall
Browse files

Release virtual display buffer immediately after HWC set

Previously we only queued a virtual display buffer to the sink when
the next frame was about to be displayed. This may delay the "last"
frame of an animation indefinitely. Now we queue the buffer as soon as
HWC set() returns and gives us the release fence.

Bug: 8384764
Change-Id: I3844a188e0f6ef6ff28f3e11477cfa063a924b1a
parent fae23b87
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -236,7 +236,7 @@ void DisplayDevice::swapBuffers(HWComposer& hwc) const {
void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
    if (hwc.initCheck() == NO_ERROR) {
    if (hwc.initCheck() == NO_ERROR) {
        int fd = hwc.getAndResetReleaseFenceFd(mType);
        int fd = hwc.getAndResetReleaseFenceFd(mType);
        mDisplaySurface->setReleaseFenceFd(fd);
        mDisplaySurface->onFrameCommitted(fd);
    }
    }
}
}


+1 −13
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


#undef LOG_TAG
#undef LOG_TAG
#define LOG_TAG "BQInterposer"
#define LOG_TAG "BQInterposer"
//#define LOG_NDEBUG 0


#include "BufferQueueInterposer.h"
#include "BufferQueueInterposer.h"


@@ -42,19 +43,6 @@ BufferQueueInterposer::BufferQueueInterposer(
    mAcquired(false)
    mAcquired(false)
{
{
    BQI_LOGV("BufferQueueInterposer sink=%p", sink.get());
    BQI_LOGV("BufferQueueInterposer sink=%p", sink.get());

    // We need one additional dequeued buffer beyond what the source needs.
    // To have more than one (the default), we must call setBufferCount. But
    // we have no way of knowing what the sink has set as the minimum buffer
    // count, so if we just call setBufferCount(3) it may fail (and does, on
    // one device using a video encoder sink). So far on the devices we care
    // about, this is the smallest value that works.
    //
    // TODO: Change IGraphicBufferProducer and implementations to support this.
    // Maybe change it so both the consumer and producer declare how many
    // buffers they need, and the IGBP adds them? Then BQInterposer would just
    // add 1 to the source's buffer count.
    mSink->setBufferCount(6);
}
}


BufferQueueInterposer::~BufferQueueInterposer() {
BufferQueueInterposer::~BufferQueueInterposer() {
+8 −8
Original line number Original line Diff line number Diff line
@@ -59,20 +59,20 @@ namespace android {
//   existing interfaces have some problems when the implementation isn't the
//   existing interfaces have some problems when the implementation isn't the
//   final consumer.
//   final consumer.
//
//
// - The interposer needs at least one buffer in addition to those used by the
// - The client of the interposer may need one or more buffers in addition to
//   source and sink. setBufferCount and QueueBufferOutput both need to
//   those used by the source and sink. IGraphicBufferProducer will probably
//   account for this. It's not possible currently to do this generically,
//   need to change to allow the producer to specify how many buffers it needs
//   since we can't find out how many buffers the source and sink need. (See
//   to dequeue at a time, and then the interposer can add its requirements to
//   the horrible hack in the BufferQueueInterposer constructor).
//   those of the source.
//
//
// - Abandoning, disconnecting, and connecting need to pass through somehow.
// - Abandoning, disconnecting, and connecting need to pass through somehow.
//   There needs to be a way to tell the interposer client to release its
//   There needs to be a way to tell the interposer client to release its
//   buffer immediately so it can be queued/released, e.g. when the source
//   buffer immediately so it can be queued/released, e.g. when the source
//   calls disconnect().
//   calls disconnect().
//
//
// - Right now the source->BQI queue is synchronous even if the BQI->sink
// - Right now the source->BQI queue is synchronous even if the BQI->sink queue
//   queue is asynchronous. Need to figure out how asynchronous should behave
//   is asynchronous. Need to figure out how asynchronous should behave and
//   and implement that.
//   implement that.


class BufferQueueInterposer : public BnGraphicBufferProducer {
class BufferQueueInterposer : public BnGraphicBufferProducer {
public:
public:
+8 −7
Original line number Original line Diff line number Diff line
@@ -43,15 +43,16 @@ public:
    // this frame. Some implementations may only push a new buffer to
    // this frame. Some implementations may only push a new buffer to
    // HWComposer if GLES composition took place, others need to push a new
    // HWComposer if GLES composition took place, others need to push a new
    // buffer on every frame.
    // buffer on every frame.
    //
    // advanceFrame must be followed by a call to  onFrameCommitted before
    // advanceFrame may be called again.
    virtual status_t advanceFrame() = 0;
    virtual status_t advanceFrame() = 0;


    // setReleaseFenceFd stores a fence file descriptor that will signal when
    // onFrameCommitted is called after the frame has been committed to the
    // the current buffer is no longer being read. This fence will be returned
    // hardware composer and a release fence is available for the buffer.
    // to the producer when the current buffer is released by updateTexImage().
    // Further operations on the buffer can be queued as long as they wait for
    // Multiple fences can be set for a given buffer; they will be merged into
    // the fence to signal.
    // a single union fence. The GLConsumer will close the file descriptor
    virtual void onFrameCommitted(int fenceFd) = 0;
    // when finished with it.
    virtual status_t setReleaseFenceFd(int fenceFd) = 0;


    virtual void dump(String8& result) const = 0;
    virtual void dump(String8& result) const = 0;


+2 −4
Original line number Original line Diff line number Diff line
@@ -140,17 +140,15 @@ void FramebufferSurface::freeBufferLocked(int slotIndex) {
    }
    }
}
}


status_t FramebufferSurface::setReleaseFenceFd(int fenceFd) {
void FramebufferSurface::onFrameCommitted(int fenceFd) {
    status_t err = NO_ERROR;
    if (fenceFd >= 0) {
    if (fenceFd >= 0) {
        sp<Fence> fence(new Fence(fenceFd));
        sp<Fence> fence(new Fence(fenceFd));
        if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
        if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
            err = addReleaseFence(mCurrentBufferSlot, fence);
            status_t err = addReleaseFence(mCurrentBufferSlot, fence);
            ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)",
            ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)",
                    strerror(-err), err);
                    strerror(-err), err);
        }
        }
    }
    }
    return err;
}
}


status_t FramebufferSurface::compositionComplete()
status_t FramebufferSurface::compositionComplete()
Loading