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

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

Merge "libgui: Add discardFreeBuffers callback to producer" into qt-qpr1-dev

parents a785d00d 8a9d62f6
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -166,7 +166,9 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
                        mCore->mFreeBuffers.push_back(front->mSlot);
                    }

                    if (mCore->mBufferReleasedCbEnabled) {
                        listener = mCore->mConnectedProducerListener;
                    }
                    ++numDroppedBuffers;
                }

@@ -457,7 +459,9 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
            mCore->mFreeBuffers.push_back(slot);
        }

        if (mCore->mBufferReleasedCbEnabled) {
            listener = mCore->mConnectedProducerListener;
        }
        BQ_LOGV("releaseBuffer: releasing slot %d", slot);

        mCore->mDequeueCondition.notify_all();
@@ -668,7 +672,7 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
        BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
        mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
        VALIDATE_CONSISTENCY();
        if (delta < 0) {
        if (delta < 0 && mCore->mBufferReleasedCbEnabled) {
            listener = mCore->mConsumerListener;
        }
    }
+7 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ BufferQueueCore::BufferQueueCore() :
    mConnectedApi(NO_CONNECTED_API),
    mLinkedToDeath(),
    mConnectedProducerListener(),
    mBufferReleasedCbEnabled(false),
    mSlots(),
    mQueue(),
    mFreeSlots(),
@@ -260,6 +261,12 @@ void BufferQueueCore::freeAllBuffersLocked() {
}

void BufferQueueCore::discardFreeBuffersLocked() {
    // Notify producer about the discarded buffers.
    if (mConnectedProducerListener != nullptr && mFreeBuffers.size() > 0) {
        std::vector<int32_t> freeBuffers(mFreeBuffers.begin(), mFreeBuffers.end());
        mConnectedProducerListener->onBuffersDiscarded(freeBuffers);
    }

    for (int s : mFreeBuffers) {
        mFreeSlots.insert(s);
        clearBufferSlotLocked(s);
+2 −3
Original line number Diff line number Diff line
@@ -1221,9 +1221,8 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
                    }
                    mCore->mLinkedToDeath = listener;
                }
                if (listener->needsReleaseNotify()) {
                mCore->mConnectedProducerListener = listener;
                }
                mCore->mBufferReleasedCbEnabled = listener->needsReleaseNotify();
            }
            break;
        default:
+26 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ namespace android {
enum {
    ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION,
    NEEDS_RELEASE_NOTIFY,
    ON_BUFFERS_DISCARDED,
};

class BpProducerListener : public BpInterface<IProducerListener>
@@ -56,6 +57,13 @@ public:
        }
        return result;
    }

    virtual void onBuffersDiscarded(const std::vector<int>& discardedSlots) {
        Parcel data, reply;
        data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
        data.writeInt32Vector(discardedSlots);
        remote()->transact(ON_BUFFERS_DISCARDED, data, &reply, IBinder::FLAG_ONEWAY);
    }
};

// Out-of-line virtual method definition to trigger vtable emission in this
@@ -76,6 +84,10 @@ public:
    virtual bool needsReleaseNotify() override {
        return mBase->needsReleaseNotify();
    }

    virtual void onBuffersDiscarded(const std::vector<int32_t>& discardedSlots) override {
        return mBase->onBuffersDiscarded(discardedSlots);
    }
};

IMPLEMENT_HYBRID_META_INTERFACE(ProducerListener,
@@ -92,6 +104,17 @@ status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data,
            CHECK_INTERFACE(IProducerListener, data, reply);
            reply->writeBool(needsReleaseNotify());
            return NO_ERROR;
        case ON_BUFFERS_DISCARDED: {
            CHECK_INTERFACE(IProducerListener, data, reply);
            std::vector<int32_t> discardedSlots;
            status_t result = data.readInt32Vector(&discardedSlots);
            if (result != NO_ERROR) {
                ALOGE("ON_BUFFERS_DISCARDED failed to read discardedSlots: %d", result);
                return result;
            }
            onBuffersDiscarded(discardedSlots);
            return NO_ERROR;
        }
    }
    return BBinder::onTransact(code, data, reply, flags);
}
@@ -104,4 +127,7 @@ bool BnProducerListener::needsReleaseNotify() {
    return true;
}

void BnProducerListener::onBuffersDiscarded(const std::vector<int32_t>& /*discardedSlots*/) {
}

} // namespace android
+49 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@

#include <ui/DisplayStatInfo.h>
#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>
#include <ui/HdrCapabilities.h>
#include <ui/Region.h>

@@ -1286,6 +1287,14 @@ int Surface::connect(int api, const sp<IProducerListener>& listener) {
    return connect(api, listener, false);
}

int Surface::connect(
        int api, bool reportBufferRemoval, const sp<SurfaceListener>& sListener) {
    if (sListener != nullptr) {
        mListenerProxy = new ProducerListenerProxy(this, sListener);
    }
    return connect(api, mListenerProxy, reportBufferRemoval);
}

int Surface::connect(
        int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) {
    ATRACE_CALL();
@@ -1684,6 +1693,28 @@ void Surface::freeAllBuffers() {
    }
}

status_t Surface::getAndFlushBuffersFromSlots(const std::vector<int32_t>& slots,
        std::vector<sp<GraphicBuffer>>* outBuffers) {
    ALOGV("Surface::getAndFlushBuffersFromSlots");
    for (int32_t i : slots) {
        if (i < 0 || i >= NUM_BUFFER_SLOTS) {
            ALOGE("%s: Invalid slotIndex: %d", __FUNCTION__, i);
            return BAD_VALUE;
        }
    }

    Mutex::Autolock lock(mMutex);
    for (int32_t i : slots) {
        if (mSlots[i].buffer == nullptr) {
            ALOGW("%s: Discarded slot %d doesn't contain buffer!", __FUNCTION__, i);
            continue;
        }
        outBuffers->push_back(mSlots[i].buffer);
        mSlots[i].buffer = nullptr;
    }
    return OK;
}

void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {
    ATRACE_CALL();
    ALOGV("Surface::setSurfaceDamage");
@@ -1951,4 +1982,22 @@ status_t Surface::attachAndQueueBufferWithDataspace(Surface* surface, sp<Graphic
    return err;
}

void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vector<int32_t>& slots) {
    ATRACE_CALL();
    sp<Surface> parent = mParent.promote();
    if (parent == nullptr) {
        return;
    }

    std::vector<sp<GraphicBuffer>> discardedBufs;
    status_t res = parent->getAndFlushBuffersFromSlots(slots, &discardedBufs);
    if (res != OK) {
        ALOGE("%s: Failed to get buffers from slots: %s(%d)", __FUNCTION__,
                strerror(-res), res);
        return;
    }

    mSurfaceListener->onBuffersDiscarded(discardedBufs);
}

}; // namespace android
Loading