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 }