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 }