File indexing completed on 2025-04-20 10:57:33

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 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "drm_dumb_swapchain.h"
0011 #include "drm_buffer.h"
0012 #include "drm_dumb_buffer.h"
0013 #include "drm_gpu.h"
0014 #include "drm_logging.h"
0015 
0016 namespace KWin
0017 {
0018 
0019 DumbSwapchain::DumbSwapchain(DrmGpu *gpu, const QSize &size, uint32_t drmFormat)
0020     : m_size(size)
0021     , m_format(drmFormat)
0022 {
0023     for (int i = 0; i < 2; i++) {
0024         auto buffer = DrmDumbBuffer::createDumbBuffer(gpu, size, drmFormat);
0025         if (!buffer->map(QImage::Format::Format_ARGB32)) {
0026             break;
0027         }
0028         buffer->image()->fill(Qt::black);
0029         m_slots.append(Slot{
0030             .buffer = buffer,
0031             .age = 0,
0032         });
0033     }
0034     m_damageJournal.setCapacity(2);
0035     if (m_slots.count() < 2) {
0036         qCWarning(KWIN_DRM) << "Failed to create dumb buffers for swapchain!";
0037         m_slots.clear();
0038     }
0039 }
0040 
0041 std::shared_ptr<DrmDumbBuffer> DumbSwapchain::acquireBuffer(QRegion *needsRepaint)
0042 {
0043     if (m_slots.isEmpty()) {
0044         return {};
0045     }
0046     index = (index + 1) % m_slots.count();
0047     if (needsRepaint) {
0048         *needsRepaint = m_damageJournal.accumulate(m_slots[index].age, infiniteRegion());
0049     }
0050     return m_slots[index].buffer;
0051 }
0052 
0053 std::shared_ptr<DrmDumbBuffer> DumbSwapchain::currentBuffer() const
0054 {
0055     return m_slots[index].buffer;
0056 }
0057 
0058 void DumbSwapchain::releaseBuffer(const std::shared_ptr<DrmDumbBuffer> &buffer, const QRegion &damage)
0059 {
0060     Q_ASSERT(m_slots[index].buffer == buffer);
0061 
0062     for (qsizetype i = 0; i < m_slots.count(); ++i) {
0063         if (m_slots[i].buffer == buffer) {
0064             m_slots[i].age = 1;
0065         } else if (m_slots[i].age > 0) {
0066             m_slots[i].age++;
0067         }
0068     }
0069     m_damageJournal.add(damage);
0070 }
0071 
0072 uint32_t DumbSwapchain::drmFormat() const
0073 {
0074     return m_format;
0075 }
0076 
0077 qsizetype DumbSwapchain::slotCount() const
0078 {
0079     return m_slots.count();
0080 }
0081 
0082 QSize DumbSwapchain::size() const
0083 {
0084     return m_size;
0085 }
0086 
0087 bool DumbSwapchain::isEmpty() const
0088 {
0089     return m_slots.isEmpty();
0090 }
0091 
0092 }