File indexing completed on 2025-04-20 10:57:36
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 #include "drm_shadow_buffer.h" 0010 0011 #include "drm_logging.h" 0012 #include "drm_output.h" 0013 0014 namespace KWin 0015 { 0016 0017 static const float vertices[] = { 0018 -1.0f, 0019 1.0f, 0020 -1.0f, 0021 -1.0f, 0022 1.0f, 0023 -1.0f, 0024 0025 -1.0f, 0026 1.0f, 0027 1.0f, 0028 -1.0f, 0029 1.0f, 0030 1.0f, 0031 }; 0032 0033 static const float texCoords[] = { 0034 0.0f, 1.0f, 0035 0.0f, 0.0f, 0036 1.0f, 0.0f, 0037 0038 0.0f, 1.0f, 0039 1.0f, 0.0f, 0040 1.0f, 1.0f}; 0041 0042 ShadowBuffer::ShadowBuffer(const QSize &size, const GbmFormat &format) 0043 : m_size(size) 0044 , m_drmFormat(format.drmFormat) 0045 { 0046 m_texture = std::make_unique<GLTexture>(internalFormat(format), size); 0047 m_texture->setFilter(GL_NEAREST); 0048 m_texture->setYInverted(true); 0049 0050 m_fbo = std::make_unique<GLFramebuffer>(m_texture.get()); 0051 if (!m_fbo->valid()) { 0052 qCCritical(KWIN_DRM) << "Error: framebuffer not complete!"; 0053 return; 0054 } 0055 0056 m_vbo = std::make_unique<GLVertexBuffer>(KWin::GLVertexBuffer::Static); 0057 m_vbo->setData(6, 2, vertices, texCoords); 0058 } 0059 0060 ShadowBuffer::~ShadowBuffer() 0061 { 0062 } 0063 0064 void ShadowBuffer::render(DrmPlane::Transformations transform) 0065 { 0066 QMatrix4x4 mvpMatrix; 0067 if (transform & DrmPlane::Transformation::Rotate90) { 0068 mvpMatrix.rotate(90, 0, 0, 1); 0069 } else if (transform & DrmPlane::Transformation::Rotate180) { 0070 mvpMatrix.rotate(180, 0, 0, 1); 0071 } else if (transform & DrmPlane::Transformation::Rotate270) { 0072 mvpMatrix.rotate(270, 0, 0, 1); 0073 } 0074 if (transform & DrmPlane::Transformation::ReflectX) { 0075 mvpMatrix.scale(-1, 1); 0076 } 0077 if (transform & DrmPlane::Transformation::ReflectY) { 0078 mvpMatrix.scale(1, -1); 0079 } 0080 0081 auto shader = ShaderManager::instance()->pushShader(ShaderTrait::MapTexture); 0082 shader->setUniform(GLShader::ModelViewProjectionMatrix, mvpMatrix); 0083 0084 m_texture->bind(); 0085 m_vbo->render(GL_TRIANGLES); 0086 ShaderManager::instance()->popShader(); 0087 } 0088 0089 GLFramebuffer *ShadowBuffer::fbo() const 0090 { 0091 return m_fbo.get(); 0092 } 0093 0094 std::shared_ptr<GLTexture> ShadowBuffer::texture() const 0095 { 0096 return m_texture; 0097 } 0098 0099 bool ShadowBuffer::isComplete() const 0100 { 0101 return m_fbo->valid() && m_vbo; 0102 } 0103 0104 uint32_t ShadowBuffer::drmFormat() const 0105 { 0106 return m_drmFormat; 0107 } 0108 0109 GLint ShadowBuffer::internalFormat(const GbmFormat &format) const 0110 { 0111 if (format.bpp <= 24) { 0112 return GL_RGBA8; 0113 } else if (format.bpp <= 30) { 0114 return GL_RGB10_A2; 0115 } else { 0116 return GL_RGBA16; 0117 } 0118 } 0119 0120 }