Skip to content

Commit 729f721

Browse files
author
Jim Shargo
committed
Surface: Add 'isBufferOwned' call
Camera's StreamSplitter keeps track of buffers and won't attach them if they're already owned. This allows us to keep that behavior as we move over from IGBP to surfaces. Ideally, I think, IGBPs should fail to attach the same buffer multiple times. Even if not, this call should probably be to the IGBP instead of the Surface for more accuracy. But this replicates the old behavior. Bug: 340933206 Flag: com.android.graphics.libgui.flags.wb_stream_splitter Test: new test Change-Id: Idbb200202012c9eae2668616dcff277c925c3907
1 parent 835688b commit 729f721

File tree

3 files changed

+88
-2
lines changed

3 files changed

+88
-2
lines changed

libs/gui/Surface.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2230,17 +2230,47 @@ int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
22302230
return NO_ERROR;
22312231
}
22322232

2233+
int Surface::isBufferOwned(const sp<GraphicBuffer>& buffer, bool* outIsOwned) const {
2234+
ATRACE_CALL();
2235+
2236+
if (buffer == nullptr) {
2237+
ALOGE("%s: Bad input, buffer was null", __FUNCTION__);
2238+
return BAD_VALUE;
2239+
}
2240+
if (outIsOwned == nullptr) {
2241+
ALOGE("%s: Bad input, output was null", __FUNCTION__);
2242+
return BAD_VALUE;
2243+
}
2244+
2245+
Mutex::Autolock lock(mMutex);
2246+
2247+
int slot = this->getSlotFromBufferLocked(buffer->getNativeBuffer());
2248+
if (slot == BAD_VALUE) {
2249+
ALOGV("%s: Buffer %" PRIu64 " is not owned", __FUNCTION__, buffer->getId());
2250+
*outIsOwned = false;
2251+
return NO_ERROR;
2252+
} else if (slot < 0) {
2253+
ALOGV("%s: Buffer %" PRIu64 " look up failed (%d)", __FUNCTION__, buffer->getId(), slot);
2254+
*outIsOwned = false;
2255+
return slot;
2256+
}
2257+
2258+
*outIsOwned = true;
2259+
return NO_ERROR;
2260+
}
2261+
22332262
int Surface::attachBuffer(ANativeWindowBuffer* buffer)
22342263
{
22352264
ATRACE_CALL();
2236-
ALOGV("Surface::attachBuffer");
2265+
sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
2266+
2267+
ALOGV("Surface::attachBuffer bufferId=%" PRIu64, graphicBuffer->getId());
22372268

22382269
Mutex::Autolock lock(mMutex);
22392270
if (mReportRemovedBuffers) {
22402271
mRemovedBuffers.clear();
22412272
}
22422273

2243-
sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
22442274
uint32_t priorGeneration = graphicBuffer->mGenerationNumber;
22452275
graphicBuffer->mGenerationNumber = mGenerationNumber;
22462276
int32_t attachedSlot = -1;

libs/gui/include/gui/Surface.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,9 @@ class Surface
442442
status_t detachBuffer(const sp<GraphicBuffer>& buffer);
443443
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
444444

445+
// Sets outIsOwned to true if the given buffer is currently known to be owned by this Surface.
446+
status_t isBufferOwned(const sp<GraphicBuffer>& buffer, bool* outIsOwned) const;
447+
445448
// Batch version of dequeueBuffer, cancelBuffer and queueBuffer
446449
// Note that these batched operations are not supported when shared buffer mode is being used.
447450
struct BatchBuffer {

libs/gui/tests/Surface_test.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,4 +2653,57 @@ TEST_F(SurfaceTest, UnlimitedSlots_BatchOperations) {
26532653
EXPECT_EQ(128u, outputs.size());
26542654
}
26552655
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
2656+
2657+
TEST_F(SurfaceTest, isBufferOwned) {
2658+
const int TEST_USAGE_FLAGS = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER;
2659+
auto [bufferItemConsumer, surface] = BufferItemConsumer::create(TEST_USAGE_FLAGS);
2660+
2661+
sp<SurfaceListener> listener = sp<StubSurfaceListener>::make();
2662+
ASSERT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, listener));
2663+
2664+
sp<GraphicBuffer> surfaceAttachableBuffer =
2665+
sp<GraphicBuffer>::make(10, 10, PIXEL_FORMAT_RGBA_8888, 1, TEST_USAGE_FLAGS);
2666+
2667+
//
2668+
// Attaching a buffer makes it owned.
2669+
//
2670+
2671+
bool isOwned;
2672+
EXPECT_EQ(OK, surface->isBufferOwned(surfaceAttachableBuffer, &isOwned));
2673+
EXPECT_FALSE(isOwned);
2674+
2675+
EXPECT_EQ(OK, surface->attachBuffer(surfaceAttachableBuffer.get()));
2676+
EXPECT_EQ(OK, surface->isBufferOwned(surfaceAttachableBuffer, &isOwned));
2677+
EXPECT_TRUE(isOwned);
2678+
2679+
//
2680+
// A dequeued buffer is always owned.
2681+
//
2682+
2683+
sp<GraphicBuffer> buffer;
2684+
sp<Fence> fence;
2685+
EXPECT_EQ(OK, surface->dequeueBuffer(&buffer, &fence));
2686+
EXPECT_EQ(OK, surface->isBufferOwned(buffer, &isOwned));
2687+
EXPECT_TRUE(isOwned);
2688+
2689+
//
2690+
// A detached buffer is no longer owned.
2691+
//
2692+
2693+
EXPECT_EQ(OK, surface->detachBuffer(buffer));
2694+
EXPECT_EQ(OK, surface->isBufferOwned(buffer, &isOwned));
2695+
EXPECT_FALSE(isOwned);
2696+
2697+
//
2698+
// It's not currently possible to verify whether or not a consumer has attached a buffer until
2699+
// it shows up on the Surface.
2700+
//
2701+
2702+
sp<GraphicBuffer> consumerAttachableBuffer =
2703+
sp<GraphicBuffer>::make(10, 10, PIXEL_FORMAT_RGBA_8888, 1, TEST_USAGE_FLAGS);
2704+
2705+
ASSERT_EQ(OK, bufferItemConsumer->attachBuffer(consumerAttachableBuffer));
2706+
EXPECT_EQ(OK, surface->isBufferOwned(consumerAttachableBuffer, &isOwned));
2707+
EXPECT_FALSE(isOwned);
2708+
}
26562709
} // namespace android

0 commit comments

Comments
 (0)