Loading libs/gui/Surface.cpp +32 −2 Original line number Diff line number Diff line Loading @@ -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; Loading libs/gui/include/gui/Surface.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading libs/gui/tests/Surface_test.cpp +53 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
libs/gui/Surface.cpp +32 −2 Original line number Diff line number Diff line Loading @@ -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; Loading
libs/gui/include/gui/Surface.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading
libs/gui/tests/Surface_test.cpp +53 −0 Original line number Diff line number Diff line Loading @@ -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