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_egl_cursor_layer.h" 0010 #include "core/iccprofile.h" 0011 #include "drm_buffer.h" 0012 #include "drm_egl_backend.h" 0013 #include "drm_gpu.h" 0014 #include "drm_output.h" 0015 #include "drm_pipeline.h" 0016 0017 #include <gbm.h> 0018 0019 namespace KWin 0020 { 0021 0022 static OutputTransform drmToOutputTransform(DrmPipeline *pipeline) 0023 { 0024 auto angle = DrmPlane::transformationToDegrees(pipeline->renderOrientation()); 0025 if (angle < 0) { 0026 angle += 360; 0027 } 0028 OutputTransform flip = (pipeline->renderOrientation() & DrmPlane::Transformation::ReflectX) ? OutputTransform::FlipX : OutputTransform(); 0029 switch (angle % 360) { 0030 case 0: 0031 return flip; 0032 case 90: 0033 return flip.combine(OutputTransform::Rotate90); 0034 case 180: 0035 return flip.combine(OutputTransform::Rotate180); 0036 case 270: 0037 return flip.combine(OutputTransform::Rotate270); 0038 default: 0039 Q_UNREACHABLE(); 0040 } 0041 } 0042 0043 EglGbmCursorLayer::EglGbmCursorLayer(EglGbmBackend *eglBackend, DrmPipeline *pipeline) 0044 : DrmPipelineLayer(pipeline) 0045 , m_surface(pipeline->gpu(), eglBackend, pipeline->gpu()->atomicModeSetting() ? EglGbmLayerSurface::BufferTarget::Linear : EglGbmLayerSurface::BufferTarget::Dumb, EglGbmLayerSurface::FormatOption::RequireAlpha) 0046 { 0047 } 0048 0049 std::optional<OutputLayerBeginFrameInfo> EglGbmCursorLayer::beginFrame() 0050 { 0051 // note that this allows blending to happen in sRGB or PQ encoding. 0052 // That's technically incorrect, but it looks okay and is intentionally allowed 0053 // as the hardware cursor is more important than an incorrectly blended cursor edge 0054 return m_surface.startRendering(m_pipeline->gpu()->cursorSize(), drmToOutputTransform(m_pipeline).combine(OutputTransform::FlipY), m_pipeline->cursorFormats(), m_pipeline->colorDescription(), m_pipeline->output()->channelFactors(), m_pipeline->iccProfile(), m_pipeline->output()->needsColormanagement()); 0055 } 0056 0057 bool EglGbmCursorLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) 0058 { 0059 return m_surface.endRendering(damagedRegion); 0060 } 0061 0062 QRegion EglGbmCursorLayer::currentDamage() const 0063 { 0064 return {}; 0065 } 0066 0067 std::shared_ptr<DrmFramebuffer> EglGbmCursorLayer::currentBuffer() const 0068 { 0069 return m_surface.currentBuffer(); 0070 } 0071 0072 bool EglGbmCursorLayer::checkTestBuffer() 0073 { 0074 return false; 0075 } 0076 0077 void EglGbmCursorLayer::releaseBuffers() 0078 { 0079 m_surface.destroyResources(); 0080 } 0081 0082 std::chrono::nanoseconds EglGbmCursorLayer::queryRenderTime() const 0083 { 0084 return m_surface.queryRenderTime(); 0085 } 0086 0087 std::optional<QSize> EglGbmCursorLayer::fixedSize() const 0088 { 0089 return m_pipeline->gpu()->cursorSize(); 0090 } 0091 }