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

Commit 85add72b authored by Jim Shargo's avatar Jim Shargo Committed by Android (Google) Code Review
Browse files

Merge "Surface: Add 'isBufferOwned' call" into main

parents b1e7d3cf 729f721a
Loading
Loading
Loading
Loading
+32 −2
Original line number Diff line number Diff line
@@ -2230,17 +2230,47 @@ int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
    return NO_ERROR;
}

int Surface::isBufferOwned(const sp<GraphicBuffer>& buffer, bool* outIsOwned) const {
    ATRACE_CALL();

    if (buffer == nullptr) {
        ALOGE("%s: Bad input, buffer was null", __FUNCTION__);
        return BAD_VALUE;
    }
    if (outIsOwned == nullptr) {
        ALOGE("%s: Bad input, output was null", __FUNCTION__);
        return BAD_VALUE;
    }

    Mutex::Autolock lock(mMutex);

    int slot = this->getSlotFromBufferLocked(buffer->getNativeBuffer());
    if (slot == BAD_VALUE) {
        ALOGV("%s: Buffer %" PRIu64 " is not owned", __FUNCTION__, buffer->getId());
        *outIsOwned = false;
        return NO_ERROR;
    } else if (slot < 0) {
        ALOGV("%s: Buffer %" PRIu64 " look up failed (%d)", __FUNCTION__, buffer->getId(), slot);
        *outIsOwned = false;
        return slot;
    }

    *outIsOwned = true;
    return NO_ERROR;
}

int Surface::attachBuffer(ANativeWindowBuffer* buffer)
{
    ATRACE_CALL();
    ALOGV("Surface::attachBuffer");
    sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));

    ALOGV("Surface::attachBuffer bufferId=%" PRIu64, graphicBuffer->getId());

    Mutex::Autolock lock(mMutex);
    if (mReportRemovedBuffers) {
        mRemovedBuffers.clear();
    }

    sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
    uint32_t priorGeneration = graphicBuffer->mGenerationNumber;
    graphicBuffer->mGenerationNumber = mGenerationNumber;
    int32_t attachedSlot = -1;
+3 −0
Original line number Diff line number Diff line
@@ -442,6 +442,9 @@ public:
    status_t detachBuffer(const sp<GraphicBuffer>& buffer);
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

    // Sets outIsOwned to true if the given buffer is currently known to be owned by this Surface.
    status_t isBufferOwned(const sp<GraphicBuffer>& buffer, bool* outIsOwned) const;

    // Batch version of dequeueBuffer, cancelBuffer and queueBuffer
    // Note that these batched operations are not supported when shared buffer mode is being used.
    struct BatchBuffer {
+53 −0
Original line number Diff line number Diff line
@@ -2699,4 +2699,57 @@ TEST_F(SurfaceTest, UnlimitedSlots_BatchOperations) {
    EXPECT_EQ(128u, outputs.size());
}
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)

TEST_F(SurfaceTest, isBufferOwned) {
    const int TEST_USAGE_FLAGS = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER;
    auto [bufferItemConsumer, surface] = BufferItemConsumer::create(TEST_USAGE_FLAGS);

    sp<SurfaceListener> listener = sp<StubSurfaceListener>::make();
    ASSERT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, listener));

    sp<GraphicBuffer> surfaceAttachableBuffer =
            sp<GraphicBuffer>::make(10, 10, PIXEL_FORMAT_RGBA_8888, 1, TEST_USAGE_FLAGS);

    //
    // Attaching a buffer makes it owned.
    //

    bool isOwned;
    EXPECT_EQ(OK, surface->isBufferOwned(surfaceAttachableBuffer, &isOwned));
    EXPECT_FALSE(isOwned);

    EXPECT_EQ(OK, surface->attachBuffer(surfaceAttachableBuffer.get()));
    EXPECT_EQ(OK, surface->isBufferOwned(surfaceAttachableBuffer, &isOwned));
    EXPECT_TRUE(isOwned);

    //
    // A dequeued buffer is always owned.
    //

    sp<GraphicBuffer> buffer;
    sp<Fence> fence;
    EXPECT_EQ(OK, surface->dequeueBuffer(&buffer, &fence));
    EXPECT_EQ(OK, surface->isBufferOwned(buffer, &isOwned));
    EXPECT_TRUE(isOwned);

    //
    // A detached buffer is no longer owned.
    //

    EXPECT_EQ(OK, surface->detachBuffer(buffer));
    EXPECT_EQ(OK, surface->isBufferOwned(buffer, &isOwned));
    EXPECT_FALSE(isOwned);

    //
    // It's not currently possible to verify whether or not a consumer has attached a buffer until
    // it shows up on the Surface.
    //

    sp<GraphicBuffer> consumerAttachableBuffer =
            sp<GraphicBuffer>::make(10, 10, PIXEL_FORMAT_RGBA_8888, 1, TEST_USAGE_FLAGS);

    ASSERT_EQ(OK, bufferItemConsumer->attachBuffer(consumerAttachableBuffer));
    EXPECT_EQ(OK, surface->isBufferOwned(consumerAttachableBuffer, &isOwned));
    EXPECT_FALSE(isOwned);
}
} // namespace android