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

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

Merge "Surface: add getRemovedBuffer API" into oc-dev

parents f60ab411 e572fd7b
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -257,10 +257,25 @@ public:
    virtual int query(int what, int* value) const;

    virtual int connect(int api, const sp<IProducerListener>& listener);

    // When reportBufferRemoval is true, clients must call getAndFlushRemovedBuffers to fetch
    // GraphicBuffers removed from this surface after a dequeueBuffer, detachNextBuffer or
    // attachBuffer call. This allows clients with their own buffer caches to free up buffers no
    // longer in use by this surface.
    virtual int connect(
            int api, const sp<IProducerListener>& listener,
            bool reportBufferRemoval);
    virtual int detachNextBuffer(sp<GraphicBuffer>* outBuffer,
            sp<Fence>* outFence);
    virtual int attachBuffer(ANativeWindowBuffer*);

    // When client connects to Surface with reportBufferRemoval set to true, any buffers removed
    // from this Surface will be collected and returned here. Once this method returns, these
    // buffers will no longer be referenced by this Surface unless they are attached to this
    // Surface later. The list of removed buffers will only be stored until the next dequeueBuffer,
    // detachNextBuffer, or attachBuffer call.
    status_t getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out);

protected:
    enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS };
    enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };
@@ -414,6 +429,9 @@ protected:
    // A cached copy of the FrameEventHistory maintained by the consumer.
    bool mEnableFrameTimestamps = false;
    std::unique_ptr<ProducerFrameEventHistory> mFrameEventHistory;

    bool mReportRemovedBuffers = false;
    std::vector<sp<GraphicBuffer>> mRemovedBuffers;
};

} // namespace android
+35 −1
Original line number Diff line number Diff line
@@ -505,7 +505,11 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
         mFrameEventHistory->applyDelta(frameTimestamps);
    }

    if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
    if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) {
        if (mReportRemovedBuffers && (gbuf != nullptr)) {
            mRemovedBuffers.clear();
            mRemovedBuffers.push_back(gbuf);
        }
        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
        if (result != NO_ERROR) {
            ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
@@ -1075,10 +1079,16 @@ int Surface::connect(int api) {
}

int Surface::connect(int api, const sp<IProducerListener>& listener) {
    return connect(api, listener, false);
}

int Surface::connect(
        int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) {
    ATRACE_CALL();
    ALOGV("Surface::connect");
    Mutex::Autolock lock(mMutex);
    IGraphicBufferProducer::QueueBufferOutput output;
    mReportRemovedBuffers = reportBufferRemoval;
    int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
    if (err == NO_ERROR) {
        mDefaultWidth = output.width;
@@ -1109,6 +1119,7 @@ int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) {
    ATRACE_CALL();
    ALOGV("Surface::disconnect");
    Mutex::Autolock lock(mMutex);
    mRemovedBuffers.clear();
    mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
    mSharedBufferHasBeenQueued = false;
    freeAllBuffers();
@@ -1156,9 +1167,16 @@ int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
        *outFence = Fence::NO_FENCE;
    }

    if (mReportRemovedBuffers) {
        mRemovedBuffers.clear();
    }

    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
        if (mSlots[i].buffer != NULL &&
                mSlots[i].buffer->handle == buffer->handle) {
            if (mReportRemovedBuffers) {
                mRemovedBuffers.push_back(mSlots[i].buffer);
            }
            mSlots[i].buffer = NULL;
        }
    }
@@ -1184,6 +1202,10 @@ int Surface::attachBuffer(ANativeWindowBuffer* buffer)
        graphicBuffer->mGenerationNumber = priorGeneration;
        return result;
    }
    if (mReportRemovedBuffers && (mSlots[attachedSlot].buffer != nullptr)) {
        mRemovedBuffers.clear();
        mRemovedBuffers.push_back(mSlots[attachedSlot].buffer);
    }
    mSlots[attachedSlot].buffer = graphicBuffer;

    return NO_ERROR;
@@ -1617,4 +1639,16 @@ status_t Surface::getUniqueId(uint64_t* outId) const {
    return mGraphicBufferProducer->getUniqueId(outId);
}

status_t Surface::getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out) {
    if (out == nullptr) {
        ALOGE("%s: out must not be null!", __FUNCTION__);
        return BAD_VALUE;
    }

    Mutex::Autolock lock(mMutex);
    *out = mRemovedBuffers;
    mRemovedBuffers.clear();
    return OK;
}

}; // namespace android