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

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

Merge changes I4a3150c9,I0343abb4 into main

* changes:
  Surface: expose allowAllocation method
  Surface: Provide more useful/platform-y buffer methods
parents ed619471 e77d47e5
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@
#include <gui/Surface.h>

#include <condition_variable>
#include <cstddef>
#include <cstdint>
#include <deque>
#include <mutex>
#include <thread>
@@ -161,6 +163,12 @@ void Surface::allocateBuffers() {
            mReqFormat, mReqUsage);
}

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
status_t Surface::allowAllocation(bool allowAllocation) {
    return mGraphicBufferProducer->allowAllocation(allowAllocation);
}
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

status_t Surface::setGenerationNumber(uint32_t generation) {
    status_t result = mGraphicBufferProducer->setGenerationNumber(generation);
    if (result == NO_ERROR) {
@@ -693,6 +701,50 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    return OK;
}

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer, sp<Fence>* outFence) {
    if (buffer == nullptr || outFence == nullptr) {
        return BAD_VALUE;
    }

    android_native_buffer_t* anb;
    int fd = -1;
    status_t res = dequeueBuffer(&anb, &fd);
    *buffer = GraphicBuffer::from(anb);
    *outFence = sp<Fence>::make(fd);
    return res;
}

status_t Surface::queueBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& fd) {
    if (buffer == nullptr) {
        return BAD_VALUE;
    }
    return queueBuffer(buffer.get(), fd ? fd->get() : -1);
}

status_t Surface::detachBuffer(const sp<GraphicBuffer>& buffer) {
    if (nullptr == buffer) {
        return BAD_VALUE;
    }

    Mutex::Autolock lock(mMutex);

    uint64_t bufferId = buffer->getId();
    for (int slot = 0; slot < Surface::NUM_BUFFER_SLOTS; ++slot) {
        auto& bufferSlot = mSlots[slot];
        if (bufferSlot.buffer != nullptr && bufferSlot.buffer->getId() == bufferId) {
            bufferSlot.buffer = nullptr;
            bufferSlot.dirtyRegion = Region::INVALID_REGION;
            return mGraphicBufferProducer->detachBuffer(slot);
        }
    }

    return BAD_VALUE;
}

#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

int Surface::dequeueBuffers(std::vector<BatchBuffer>* buffers) {
    using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
    using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
+22 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define ANDROID_GUI_SURFACE_H

#include <android/gui/FrameTimelineInfo.h>
#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferQueueDefs.h>
#include <gui/HdrMetadata.h>
#include <gui/IGraphicBufferProducer.h>
@@ -35,6 +36,8 @@

namespace android {

class GraphicBuffer;

namespace gui {
class ISurfaceComposer;
} // namespace gui
@@ -164,6 +167,11 @@ public:
     */
    virtual void allocateBuffers();

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
    // See IGraphicBufferProducer::allowAllocation
    status_t allowAllocation(bool allowAllocation);
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

    /* Sets the generation number on the IGraphicBufferProducer and updates the
     * generation number on any buffers attached to the Surface after this call.
     * See IGBP::setGenerationNumber for more information. */
@@ -395,6 +403,20 @@ public:
    static status_t attachAndQueueBufferWithDataspace(Surface* surface, sp<GraphicBuffer> buffer,
                                                      ui::Dataspace dataspace);

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
    // Dequeues a buffer and its outFence, which must be signalled before the buffer can be used.
    status_t dequeueBuffer(sp<GraphicBuffer>* buffer, sp<Fence>* outFence);

    // Queues a buffer, with an optional fd fence that captures pending work on the buffer. This
    // buffer must have been returned by dequeueBuffer or associated with this Surface via an
    // attachBuffer operation.
    status_t queueBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& fd = Fence::NO_FENCE);

    // Detaches this buffer, dissociating it from this Surface. This buffer must have been returned
    // by queueBuffer or associated with this Surface via an attachBuffer operation.
    status_t detachBuffer(const sp<GraphicBuffer>& buffer);
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

    // Batch version of dequeueBuffer, cancelBuffer and queueBuffer
    // Note that these batched operations are not supported when shared buffer mode is being used.
    struct BatchBuffer {
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ cc_test {
        "-Wthread-safety",
        "-DCOM_ANDROID_GRAPHICS_LIBGUI_FLAGS_BQ_SETFRAMERATE=true",
        "-DCOM_ANDROID_GRAPHICS_LIBGUI_FLAGS_BQ_EXTENDEDALLOCATE=true",
        "-DCOM_ANDROID_GRAPHICS_LIBGUI_FLAGS_WB_PLATFORM_API_IMPROVEMENTS=true",
    ],

    srcs: [
+90 −1
Original line number Diff line number Diff line
@@ -24,23 +24,26 @@
#include <android/gui/ISurfaceComposer.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <binder/ProcessState.h>
#include <com_android_graphics_libgui_flags.h>
#include <configstore/Utils.h>
#include <gui/AidlStatusUtil.h>
#include <gui/BufferItemConsumer.h>
#include <gui/CpuConsumer.h>
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SyncScreenCaptureListener.h>
#include <inttypes.h>
#include <private/gui/ComposerService.h>
#include <private/gui/ComposerServiceAIDL.h>
#include <sys/types.h>
#include <ui/BufferQueueDefs.h>
#include <ui/DisplayMode.h>
#include <ui/GraphicBuffer.h>
#include <ui/Rect.h>
#include <utils/Errors.h>
#include <utils/String8.h>

#include <cstddef>
#include <limits>
#include <thread>

@@ -2225,4 +2228,90 @@ TEST_F(SurfaceTest, BatchIllegalOperations) {
    ASSERT_EQ(NO_ERROR, surface->disconnect(NATIVE_WINDOW_API_CPU));
}

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

TEST_F(SurfaceTest, PlatformBufferMethods) {
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&producer, &consumer);

    sp<CpuConsumer> cpuConsumer = sp<CpuConsumer>::make(consumer, 1);
    sp<Surface> surface = sp<Surface>::make(producer);
    sp<StubSurfaceListener> listener = sp<StubSurfaceListener>::make();
    sp<GraphicBuffer> buffer;
    sp<Fence> fence;

    EXPECT_EQ(OK,
              surface->connect(NATIVE_WINDOW_API_CPU, listener, /* reportBufferRemoval */ false));

    //
    // Verify nullptrs are handled safely:
    //

    EXPECT_EQ(BAD_VALUE, surface->dequeueBuffer((sp<GraphicBuffer>*)nullptr, nullptr));
    EXPECT_EQ(BAD_VALUE, surface->dequeueBuffer((sp<GraphicBuffer>*)nullptr, &fence));
    EXPECT_EQ(BAD_VALUE, surface->dequeueBuffer(&buffer, nullptr));
    EXPECT_EQ(BAD_VALUE, surface->queueBuffer(nullptr, nullptr));
    EXPECT_EQ(BAD_VALUE, surface->detachBuffer(nullptr));

    //
    // Verify dequeue/queue:
    //

    EXPECT_EQ(OK, surface->dequeueBuffer(&buffer, &fence));
    EXPECT_NE(nullptr, buffer);
    EXPECT_EQ(OK, surface->queueBuffer(buffer, fence));

    //
    // Verify dequeue/detach:
    //

    wp<GraphicBuffer> weakBuffer;
    {
        EXPECT_EQ(OK, surface->dequeueBuffer(&buffer, &fence));

        EXPECT_EQ(OK, surface->detachBuffer(buffer));

        weakBuffer = buffer;
        buffer = nullptr;
    }
    EXPECT_EQ(nullptr, weakBuffer.promote()) << "Weak buffer still held by Surface.";

    //
    // Verify detach without borrowing the buffer does not work:
    //

    sp<GraphicBuffer> heldTooLongBuffer;
    EXPECT_EQ(OK, surface->dequeueBuffer(&heldTooLongBuffer, &fence));
    EXPECT_EQ(OK, surface->queueBuffer(heldTooLongBuffer));
    EXPECT_EQ(BAD_VALUE, surface->detachBuffer(heldTooLongBuffer));
}

TEST_F(SurfaceTest, AllowAllocation) {
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&producer, &consumer);

    // controlledByApp must be true to disable blocking
    sp<CpuConsumer> cpuConsumer = sp<CpuConsumer>::make(consumer, 1, /*controlledByApp*/ true);
    sp<Surface> surface = sp<Surface>::make(producer, /*controlledByApp*/ true);
    sp<StubSurfaceListener> listener = sp<StubSurfaceListener>::make();
    sp<GraphicBuffer> buffer;
    sp<Fence> fence;

    EXPECT_EQ(OK,
              surface->connect(NATIVE_WINDOW_API_CPU, listener, /* reportBufferRemoval */ false));
    EXPECT_EQ(OK, surface->allowAllocation(false));

    EXPECT_EQ(OK, surface->setDequeueTimeout(-1));
    EXPECT_EQ(WOULD_BLOCK, surface->dequeueBuffer(&buffer, &fence));

    EXPECT_EQ(OK, surface->setDequeueTimeout(10));
    EXPECT_EQ(TIMED_OUT, surface->dequeueBuffer(&buffer, &fence));

    EXPECT_EQ(OK, surface->allowAllocation(true));
    EXPECT_EQ(OK, surface->dequeueBuffer(&buffer, &fence));
}
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

} // namespace android