File indexing completed on 2024-11-10 04:56:27
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #include "drm_dmabuf_feedback.h" 0010 0011 #include "drm_egl_backend.h" 0012 #include "drm_gpu.h" 0013 #include "wayland/surface.h" 0014 0015 namespace KWin 0016 { 0017 0018 DmabufFeedback::DmabufFeedback(DrmGpu *gpu, EglGbmBackend *eglBackend) 0019 : m_gpu(gpu) 0020 , m_eglBackend(eglBackend) 0021 { 0022 } 0023 0024 void DmabufFeedback::renderingSurface() 0025 { 0026 if (m_surface && !m_attemptedThisFrame) { 0027 if (const auto &feedback = m_surface->dmabufFeedbackV1()) { 0028 feedback->setTranches({}); 0029 } 0030 m_surface = nullptr; 0031 } 0032 m_attemptedThisFrame = false; 0033 } 0034 0035 void DmabufFeedback::scanoutSuccessful(SurfaceInterface *surface) 0036 { 0037 if (surface != m_surface) { 0038 if (m_surface && m_surface->dmabufFeedbackV1()) { 0039 m_surface->dmabufFeedbackV1()->setTranches({}); 0040 } 0041 m_surface = surface; 0042 m_attemptedFormats = {}; 0043 } 0044 } 0045 0046 void DmabufFeedback::scanoutFailed(SurfaceInterface *surface, const QMap<uint32_t, QList<uint64_t>> &formats) 0047 { 0048 m_attemptedThisFrame = true; 0049 if (surface != m_surface) { 0050 m_attemptedFormats = {}; 0051 if (m_surface && m_surface->dmabufFeedbackV1()) { 0052 m_surface->dmabufFeedbackV1()->setTranches({}); 0053 } 0054 m_surface = surface; 0055 } 0056 if (const auto &feedback = m_surface->dmabufFeedbackV1()) { 0057 const DmaBufAttributes *dmabufAttrs = surface->buffer()->dmabufAttributes(); 0058 if (!m_attemptedFormats[dmabufAttrs->format].contains(dmabufAttrs->modifier)) { 0059 m_attemptedFormats[dmabufAttrs->format] << dmabufAttrs->modifier; 0060 QList<LinuxDmaBufV1Feedback::Tranche> scanoutTranches; 0061 const auto tranches = m_eglBackend->tranches(); 0062 for (const auto &tranche : tranches) { 0063 LinuxDmaBufV1Feedback::Tranche scanoutTranche; 0064 for (auto it = tranche.formatTable.constBegin(); it != tranche.formatTable.constEnd(); it++) { 0065 const uint32_t format = it.key(); 0066 const auto trancheModifiers = it.value(); 0067 const auto drmModifiers = formats[format]; 0068 for (const auto &mod : trancheModifiers) { 0069 if (drmModifiers.contains(mod) && !m_attemptedFormats[format].contains(mod)) { 0070 scanoutTranche.formatTable[format] << mod; 0071 } 0072 } 0073 } 0074 if (!scanoutTranche.formatTable.isEmpty()) { 0075 scanoutTranche.device = m_gpu->deviceId(); 0076 scanoutTranche.flags = LinuxDmaBufV1Feedback::TrancheFlag::Scanout; 0077 scanoutTranches << scanoutTranche; 0078 } 0079 } 0080 feedback->setTranches(scanoutTranches); 0081 } 0082 } 0083 } 0084 0085 }