KWin
Loading...
Searching...
No Matches
drm_plane.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
6 SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10#include "drm_plane.h"
11
12#include "config-kwin.h"
13
14#include "drm_buffer.h"
15#include "drm_commit.h"
16#include "drm_gpu.h"
17#include "drm_logging.h"
18#include "drm_pointer.h"
19
20#include <drm_fourcc.h>
21
22namespace KWin
23{
24
25DrmPlane::DrmPlane(DrmGpu *gpu, uint32_t planeId)
26 : DrmObject(gpu, planeId, DRM_MODE_OBJECT_PLANE)
27 , type(this, QByteArrayLiteral("type"), {
28 QByteArrayLiteral("Overlay"),
29 QByteArrayLiteral("Primary"),
30 QByteArrayLiteral("Cursor"),
31 })
32 , srcX(this, QByteArrayLiteral("SRC_X"))
33 , srcY(this, QByteArrayLiteral("SRC_Y"))
34 , srcW(this, QByteArrayLiteral("SRC_W"))
35 , srcH(this, QByteArrayLiteral("SRC_H"))
36 , crtcX(this, QByteArrayLiteral("CRTC_X"))
37 , crtcY(this, QByteArrayLiteral("CRTC_Y"))
38 , crtcW(this, QByteArrayLiteral("CRTC_W"))
39 , crtcH(this, QByteArrayLiteral("CRTC_H"))
40 , fbId(this, QByteArrayLiteral("FB_ID"))
41 , crtcId(this, QByteArrayLiteral("CRTC_ID"))
42 , rotation(this, QByteArrayLiteral("rotation"), {
43 QByteArrayLiteral("rotate-0"),
44 QByteArrayLiteral("rotate-90"),
45 QByteArrayLiteral("rotate-180"),
46 QByteArrayLiteral("rotate-270"),
47 QByteArrayLiteral("reflect-x"),
48 QByteArrayLiteral("reflect-y"),
49 })
50 , inFormats(this, QByteArrayLiteral("IN_FORMATS"))
51 , alpha(this, QByteArrayLiteral("alpha"))
52 , pixelBlendMode(this, QByteArrayLiteral("pixel blend mode"), {
53 QByteArrayLiteral("None"),
54 QByteArrayLiteral("Pre-multiplied"),
55 QByteArrayLiteral("Coverage"),
56 })
57 , colorEncoding(this, QByteArrayLiteral("COLOR_ENCODING"), {
58 QByteArrayLiteral("ITU-R BT.601 YCbCr"),
59 QByteArrayLiteral("ITU-R BT.709 YCbCr"),
60 QByteArrayLiteral("ITU-R BT.2020 YCbCr"),
61 })
62 , colorRange(this, QByteArrayLiteral("COLOR_RANGE"), {
63 QByteArrayLiteral("YCbCr limited range"),
64 QByteArrayLiteral("YCbCr full range"),
65 })
66 , vmHotspotX(this, QByteArrayLiteral("HOTSPOT_X"))
67 , vmHotspotY(this, QByteArrayLiteral("HOTSPOT_Y"))
68 , inFenceFd(this, QByteArrayLiteral("IN_FENCE_FD"))
69{
70}
71
73{
75 if (!p) {
76 qCWarning(KWIN_DRM) << "Failed to get kernel plane" << id();
77 return false;
78 }
80 type.update(props);
81 srcX.update(props);
82 srcY.update(props);
83 srcW.update(props);
84 srcH.update(props);
85 crtcX.update(props);
86 crtcY.update(props);
87 crtcW.update(props);
88 crtcH.update(props);
89 fbId.update(props);
90 crtcId.update(props);
91 rotation.update(props);
92 inFormats.update(props);
93 alpha.update(props);
95 colorEncoding.update(props);
96 colorRange.update(props);
97 vmHotspotX.update(props);
98 vmHotspotY.update(props);
99 inFenceFd.update(props);
100
101 if (!type.isValid() || !srcX.isValid() || !srcY.isValid() || !srcW.isValid() || !srcH.isValid()
102 || !crtcX.isValid() || !crtcY.isValid() || !crtcW.isValid() || !crtcH.isValid() || !fbId.isValid()) {
103 return false;
104 }
105
106 m_possibleCrtcs = p->possible_crtcs;
107
108 // read formats from blob if available and if modifiers are supported, and from the plane object if not
109 m_supportedFormats.clear();
110 if (inFormats.isValid() && inFormats.immutableBlob() && gpu()->addFB2ModifiersSupported()) {
111 drmModeFormatModifierIterator iterator{};
112 while (drmModeFormatModifierBlobIterNext(inFormats.immutableBlob(), &iterator)) {
113 m_supportedFormats[iterator.fmt].push_back(iterator.mod);
114 }
115 } else {
116 // if we don't have modifier support, assume the cursor needs a linear buffer
117 const QList<uint64_t> modifiers = {type.enumValue() == TypeIndex::Cursor ? DRM_FORMAT_MOD_LINEAR : DRM_FORMAT_MOD_INVALID};
118 for (uint32_t i = 0; i < p->count_formats; i++) {
119 m_supportedFormats.insert(p->formats[i], modifiers);
120 }
121 if (m_supportedFormats.isEmpty()) {
122 qCWarning(KWIN_DRM) << "Driver doesn't advertise any formats for this plane. Falling back to XRGB8888 without explicit modifiers";
123 m_supportedFormats.insert(DRM_FORMAT_XRGB8888, modifiers);
124 }
125 }
126 return true;
127}
128
129void DrmPlane::set(DrmAtomicCommit *commit, const QPoint &srcPos, const QSize &srcSize, const QRect &dst)
130{
131 // Src* are in 16.16 fixed point format
132 commit->addProperty(srcX, srcPos.x() << 16);
133 commit->addProperty(srcX, srcPos.x() << 16);
134 commit->addProperty(srcY, srcPos.y() << 16);
135 commit->addProperty(srcW, srcSize.width() << 16);
136 commit->addProperty(srcH, srcSize.height() << 16);
137 commit->addProperty(crtcX, dst.x());
138 commit->addProperty(crtcY, dst.y());
139 commit->addProperty(crtcW, dst.width());
140 commit->addProperty(crtcH, dst.height());
141}
142
143bool DrmPlane::isCrtcSupported(int pipeIndex) const
144{
145 return (m_possibleCrtcs & (1 << pipeIndex));
146}
147
148QMap<uint32_t, QList<uint64_t>> DrmPlane::formats() const
149{
150 return m_supportedFormats;
151}
152
153std::shared_ptr<DrmFramebuffer> DrmPlane::currentBuffer() const
154{
155 return m_current;
156}
157
158void DrmPlane::setCurrentBuffer(const std::shared_ptr<DrmFramebuffer> &b)
159{
160 m_current = b;
161}
162
164{
165 commit->addProperty(crtcId, 0);
166 commit->addBuffer(this, nullptr);
167}
168
170{
171 if (m_current) {
172 m_current->releaseBuffer();
173 }
174}
175
176int32_t DrmPlane::transformationToDegrees(DrmPlane::Transformations transformation)
177{
178 if (transformation & DrmPlane::Transformation::Rotate0) {
179 return 0;
180 } else if (transformation & DrmPlane::Transformation::Rotate90) {
181 return 90;
182 } else if (transformation & DrmPlane::Transformation::Rotate180) {
183 return 180;
184 } else {
185 return 270;
186 }
187}
188}
189
190#include "moc_drm_plane.cpp"
void addProperty(const DrmProperty &prop, uint64_t value)
void addBuffer(DrmPlane *plane, const std::shared_ptr< DrmFramebuffer > &buffer)
Enum enumValue() const
DrmPropertyList queryProperties() const
uint32_t id() const
DrmGpu * gpu() const
DrmEnumProperty< TypeIndex > type
Definition drm_plane.h:74
DrmProperty vmHotspotX
Definition drm_plane.h:91
DrmEnumProperty< Transformations > rotation
Definition drm_plane.h:85
DrmProperty inFenceFd
Definition drm_plane.h:93
void setCurrentBuffer(const std::shared_ptr< DrmFramebuffer > &b)
DrmProperty inFormats
Definition drm_plane.h:86
DrmProperty srcY
Definition drm_plane.h:76
void disable(DrmAtomicCommit *commit) override
DrmProperty crtcX
Definition drm_plane.h:79
DrmProperty alpha
Definition drm_plane.h:87
DrmProperty crtcW
Definition drm_plane.h:81
DrmProperty srcW
Definition drm_plane.h:77
DrmEnumProperty< ColorRange > colorRange
Definition drm_plane.h:90
DrmProperty fbId
Definition drm_plane.h:83
DrmEnumProperty< PixelBlendMode > pixelBlendMode
Definition drm_plane.h:88
DrmProperty srcH
Definition drm_plane.h:78
DrmProperty srcX
Definition drm_plane.h:75
QMap< uint32_t, QList< uint64_t > > formats() const
std::shared_ptr< DrmFramebuffer > currentBuffer() const
bool updateProperties() override
Definition drm_plane.cpp:72
DrmEnumProperty< ColorEncoding > colorEncoding
Definition drm_plane.h:89
void set(DrmAtomicCommit *commit, const QPoint &srcPos, const QSize &srcSize, const QRect &dst)
DrmProperty vmHotspotY
Definition drm_plane.h:92
DrmProperty crtcId
Definition drm_plane.h:84
DrmPlane(DrmGpu *gpu, uint32_t planeId)
Definition drm_plane.cpp:25
DrmProperty crtcH
Definition drm_plane.h:82
void releaseCurrentBuffer()
bool isCrtcSupported(int pipeIndex) const
DrmProperty crtcY
Definition drm_plane.h:80
static int32_t transformationToDegrees(Transformations transformation)
void update(DrmPropertyList &propertyList)
drmModePropertyBlobRes * immutableBlob() const
bool isValid() const
drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
Definition mock_drm.cpp:702
Session::Type type
Definition session.cpp:17
std::unique_ptr< T, DrmDeleter< T > > DrmUniquePtr