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

Commit 851cfe83 authored by Jesse Hall's avatar Jesse Hall
Browse files

Isolate knowledge that fb target == output buffer

HWComposer didn't allow the virtual display output buffer to be set
directly, instead it always used the framebuffer target buffer.
DisplayDevice was only providing the framebuffer release fence to
DisplaySurfaces after a commit.

This change fixes both of these, so both HWComposer and DisplayDevice
should continue to work if VirtualDisplaySurface changes to use
separate framebuffer and output buffers. It's also more correct since
VirtualDisplaySurface uses the correct release fence when queueing the
buffer to the sink.

Bug: 8384764
Change-Id: I95c71e8d4f67705e23f122259ec8dd5dbce70dcf
parent afaf14b9
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -235,8 +235,7 @@ void DisplayDevice::swapBuffers(HWComposer& hwc) const {

void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
    if (hwc.initCheck() == NO_ERROR) {
        sp<Fence> fence = hwc.getAndResetReleaseFence(mType);
        mDisplaySurface->onFrameCommitted(fence);
        mDisplaySurface->onFrameCommitted();
    }
}

+3 −4
Original line number Diff line number Diff line
@@ -49,10 +49,9 @@ public:
    virtual status_t advanceFrame() = 0;

    // onFrameCommitted is called after the frame has been committed to the
    // hardware composer and a release fence is available for the buffer.
    // Further operations on the buffer can be queued as long as they wait for
    // the fence to signal.
    virtual void onFrameCommitted(const sp<Fence>& fence) = 0;
    // hardware composer. The surface collects the release fence for this
    // frame's buffer.
    virtual void onFrameCommitted() = 0;

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

+2 −1
Original line number Diff line number Diff line
@@ -140,7 +140,8 @@ void FramebufferSurface::freeBufferLocked(int slotIndex) {
    }
}

void FramebufferSurface::onFrameCommitted(const sp<Fence>& fence) {
void FramebufferSurface::onFrameCommitted() {
    sp<Fence> fence = mHwc.getAndResetReleaseFence(mDisplayType);
    if (fence->isValid() &&
            mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
        status_t err = addReleaseFence(mCurrentBufferSlot, fence);
+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ public:

    virtual status_t compositionComplete();
    virtual status_t advanceFrame();
    virtual void onFrameCommitted(const sp<Fence>& fence);
    virtual void onFrameCommitted();

    // Implementation of DisplaySurface::dump(). Note that ConsumerBase also
    // has a non-virtual dump() with the same signature.
+31 −16
Original line number Diff line number Diff line
@@ -657,15 +657,12 @@ status_t HWComposer::commit() {
            mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW);
        }

        // For virtual displays, the framebufferTarget buffer also serves as
        // the HWC output buffer, so we need to copy the buffer handle and
        // dup() the acquire fence.
        for (size_t i=VIRTUAL_DISPLAY_ID_BASE; i<mNumDisplays; i++) {
            DisplayData& disp(mDisplayData[i]);
            if (disp.framebufferTarget) {
                mLists[i]->outbuf = disp.framebufferTarget->handle;
            if (disp.outbufHandle) {
                mLists[i]->outbuf = disp.outbufHandle;
                mLists[i]->outbufAcquireFenceFd =
                        dup(disp.framebufferTarget->acquireFenceFd);
                        disp.outbufAcquireFence->dup();
            }
        }

@@ -706,17 +703,15 @@ status_t HWComposer::acquire(int disp) {

void HWComposer::disconnectDisplay(int disp) {
    LOG_ALWAYS_FATAL_IF(disp < 0 || disp == HWC_DISPLAY_PRIMARY);
    if (disp >= HWC_NUM_DISPLAY_TYPES) {
        // nothing to do for these yet
        return;
    }
    DisplayData& dd(mDisplayData[disp]);
    if (dd.list != NULL) {
    free(dd.list);
    dd.list = NULL;
    dd.framebufferTarget = NULL;    // points into dd.list
    dd.fbTargetHandle = NULL;
    }
    dd.outbufHandle = NULL;
    dd.lastRetireFence = Fence::NO_FENCE;
    dd.lastDisplayFence = Fence::NO_FENCE;
    dd.outbufAcquireFence = Fence::NO_FENCE;
}

int HWComposer::getVisualID() const {
@@ -765,6 +760,25 @@ void HWComposer::fbDump(String8& result) {
    }
}

status_t HWComposer::setOutputBuffer(int32_t id, const sp<Fence>& acquireFence,
        const sp<GraphicBuffer>& buf) {
    if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
        return BAD_INDEX;
    if (id < VIRTUAL_DISPLAY_ID_BASE)
        return INVALID_OPERATION;

    DisplayData& disp(mDisplayData[id]);
    disp.outbufHandle = buf->handle;
    disp.outbufAcquireFence = acquireFence;
    return NO_ERROR;
}

sp<Fence> HWComposer::getLastRetireFence(int32_t id) {
    if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
        return Fence::NO_FENCE;
    return mDisplayData[id].lastRetireFence;
}

/*
 * Helper template to implement a concrete HWCLayer
 * This holds the pointer to the concrete hwc layer type
@@ -1071,6 +1085,7 @@ HWComposer::DisplayData::DisplayData()
    capacity(0), list(NULL),
    framebufferTarget(NULL), fbTargetHandle(0),
    lastRetireFence(Fence::NO_FENCE), lastDisplayFence(Fence::NO_FENCE),
    outbufHandle(NULL), outbufAcquireFence(Fence::NO_FENCE),
    events(0)
{}

Loading