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

Commit ac513c2f authored by John Reck's avatar John Reck
Browse files

Fix NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS handling

Fixes: 123541940
Test: CTS HardwareRendererTests#testLotsOfBuffers
Change-Id: I5d96e615f552c4faa0e6dcaaaa828c871eaf6c8e
parent cd62e442
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -222,7 +222,17 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
    const SkISize maxSize = SkISize::Make(caps.maxImageExtent.width, caps.maxImageExtent.height);
    ComputeWindowSizeAndTransform(&windowInfo, minSize, maxSize);

    windowInfo.bufferCount = std::max<uint32_t>(VulkanSurface::sMaxBufferCount, caps.minImageCount);
    int query_value;
    int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
    if (err != 0 || query_value < 0) {
        ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err,
              query_value);
        return nullptr;
    }
    auto min_undequeued_buffers = static_cast<uint32_t>(query_value);

    windowInfo.bufferCount = min_undequeued_buffers
            + std::max(VulkanSurface::sTargetBufferCount, caps.minImageCount);
    if (caps.maxImageCount > 0 && windowInfo.bufferCount > caps.maxImageCount) {
        // Application must settle for fewer images than desired:
        windowInfo.bufferCount = caps.maxImageCount;
@@ -357,10 +367,9 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window
        return false;
    }

    // Lower layer insists that we have at least two buffers.
    err = native_window_set_buffer_count(window, std::max(2, windowInfo.bufferCount));
    err = native_window_set_buffer_count(window, windowInfo.bufferCount);
    if (err != 0) {
        ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%d) failed: %s (%d)",
        ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%zu) failed: %s (%d)",
              windowInfo.bufferCount, strerror(-err), err);
        return false;
    }
@@ -392,7 +401,7 @@ VulkanSurface::~VulkanSurface() {
}

void VulkanSurface::releaseBuffers() {
    for (uint32_t i = 0; i < VulkanSurface::sMaxBufferCount; i++) {
    for (uint32_t i = 0; i < mWindowInfo.bufferCount; i++) {
        VulkanSurface::NativeBufferInfo& bufferInfo = mNativeBuffers[i];

        if (bufferInfo.buffer.get() != nullptr && bufferInfo.dequeued) {
+9 −3
Original line number Diff line number Diff line
@@ -83,14 +83,19 @@ private:
     * as private to this class.
     *
     */
    static constexpr int sMaxBufferCount = 3;

    // How many buffers we want to be able to use ourselves. We want 1 in active rendering with
    // 1 more queued, so 2. This will be added to NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, which is
    // how many buffers the consumer needs (eg, 1 for SurfaceFlinger), getting to a typically
    // triple-buffered queue as a result.
    static constexpr uint32_t sTargetBufferCount = 2;

    struct WindowInfo {
        SkISize size;
        PixelFormat pixelFormat;
        android_dataspace dataspace;
        int transform;
        int bufferCount;
        size_t bufferCount;
        uint64_t windowUsageFlags;

        // size of the ANativeWindow if the inverse of transform requires us to swap width/height
@@ -111,7 +116,8 @@ private:
                                              const SkISize& maxSize);
    void releaseBuffers();

    NativeBufferInfo mNativeBuffers[VulkanSurface::sMaxBufferCount];
    // TODO: Just use a vector?
    NativeBufferInfo mNativeBuffers[android::BufferQueueDefs::NUM_BUFFER_SLOTS];

    sp<ANativeWindow> mNativeWindow;
    WindowInfo mWindowInfo;