File indexing completed on 2024-11-10 04:56:56

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2021 Xaver Hugl <xaver.hugl@gmail.com>
0006     SPDX-FileCopyrightText: 2023 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "platformsupport/scenes/qpainter/qpainterswapchain.h"
0012 #include "core/graphicsbufferview.h"
0013 #include "core/graphicsbufferallocator.h"
0014 #include "utils/common.h"
0015 
0016 namespace KWin
0017 {
0018 
0019 QPainterSwapchainSlot::QPainterSwapchainSlot(GraphicsBuffer *buffer)
0020     : m_buffer(buffer)
0021     , m_view(std::make_unique<GraphicsBufferView>(buffer, GraphicsBuffer::Read | GraphicsBuffer::Write))
0022 {
0023 }
0024 
0025 QPainterSwapchainSlot::~QPainterSwapchainSlot()
0026 {
0027     m_view.reset();
0028     m_buffer->drop();
0029 }
0030 
0031 GraphicsBuffer *QPainterSwapchainSlot::buffer() const
0032 {
0033     return m_buffer;
0034 }
0035 
0036 GraphicsBufferView *QPainterSwapchainSlot::view() const
0037 {
0038     return m_view.get();
0039 }
0040 
0041 int QPainterSwapchainSlot::age() const
0042 {
0043     return m_age;
0044 }
0045 
0046 QPainterSwapchain::QPainterSwapchain(GraphicsBufferAllocator *allocator, const QSize &size, uint32_t format)
0047     : m_allocator(allocator)
0048     , m_size(size)
0049     , m_format(format)
0050 {
0051 }
0052 
0053 QPainterSwapchain::~QPainterSwapchain()
0054 {
0055 }
0056 
0057 QSize QPainterSwapchain::size() const
0058 {
0059     return m_size;
0060 }
0061 
0062 uint32_t QPainterSwapchain::format() const
0063 {
0064     return m_format;
0065 }
0066 
0067 std::shared_ptr<QPainterSwapchainSlot> QPainterSwapchain::acquire()
0068 {
0069     for (const auto &slot : std::as_const(m_slots)) {
0070         if (!slot->buffer()->isReferenced()) {
0071             return slot;
0072         }
0073     }
0074 
0075     GraphicsBuffer *buffer = m_allocator->allocate(GraphicsBufferOptions{
0076         .size = m_size,
0077         .format = m_format,
0078         .software = true,
0079     });
0080     if (!buffer) {
0081         qCWarning(KWIN_QPAINTER) << "Failed to allocate a qpainter swapchain graphics buffer";
0082         return nullptr;
0083     }
0084 
0085     auto slot = std::make_shared<QPainterSwapchainSlot>(buffer);
0086     m_slots.append(slot);
0087 
0088     return slot;
0089 }
0090 
0091 void QPainterSwapchain::release(std::shared_ptr<QPainterSwapchainSlot> slot)
0092 {
0093     for (qsizetype i = 0; i < m_slots.count(); ++i) {
0094         if (m_slots[i] == slot) {
0095             m_slots[i]->m_age = 1;
0096         } else if (m_slots[i]->m_age > 0) {
0097             m_slots[i]->m_age++;
0098         }
0099     }
0100 }
0101 
0102 }