KWin
Loading...
Searching...
No Matches
virtual_backend.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: 2015 Martin Gräßlin <mgraesslin@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9#include "virtual_backend.h"
10
11#include "virtual_egl_backend.h"
12#include "virtual_output.h"
14
15#include <fcntl.h>
16#include <gbm.h>
17#include <xf86drm.h>
18
19namespace KWin
20{
21
22static FileDescriptor findRenderDevice()
23{
24 const int deviceCount = drmGetDevices2(0, nullptr, 0);
25 if (deviceCount <= 0) {
26 return FileDescriptor{};
27 }
28
29 QList<drmDevice *> devices(deviceCount);
30 if (drmGetDevices2(0, devices.data(), devices.size()) < 0) {
31 return FileDescriptor{};
32 }
33 auto deviceCleanup = qScopeGuard([&devices]() {
34 drmFreeDevices(devices.data(), devices.size());
35 });
36
37 for (drmDevice *device : std::as_const(devices)) {
38 // If it's a vgem device, prefer the primary node because gbm will attempt to allocate
39 // dumb buffers and they can be allocated only on the primary node.
40 int nodeType = DRM_NODE_RENDER;
41 if (device->bustype == DRM_BUS_PLATFORM) {
42 if (strcmp(device->businfo.platform->fullname, "vgem") == 0) {
43 nodeType = DRM_NODE_PRIMARY;
44 }
45 }
46
47 if (device->available_nodes & (1 << nodeType)) {
48 FileDescriptor fd{open(device->nodes[nodeType], O_RDWR | O_CLOEXEC)};
49 if (fd.isValid()) {
50 return fd;
51 }
52 }
53 }
54
55 return FileDescriptor{};
56}
57
59 : OutputBackend(parent)
60{
61 m_drmFileDescriptor = findRenderDevice();
62 if (m_drmFileDescriptor.isValid()) {
63 m_gbmDevice = gbm_create_device(m_drmFileDescriptor.get());
64 }
65}
66
68{
69 if (m_gbmDevice) {
70 gbm_device_destroy(m_gbmDevice);
71 }
72}
73
75{
76 return true;
77}
78
79QList<CompositingType> VirtualBackend::supportedCompositors() const
80{
81 QList<CompositingType> compositingTypes;
82 if (m_gbmDevice) {
83 compositingTypes.append(OpenGLCompositing);
84 }
85 compositingTypes.append(QPainterCompositing);
86 return compositingTypes;
87}
88
89gbm_device *VirtualBackend::gbmDevice() const
90{
91 return m_gbmDevice;
92}
93
94std::unique_ptr<QPainterBackend> VirtualBackend::createQPainterBackend()
95{
96 return std::make_unique<VirtualQPainterBackend>(this);
97}
98
99std::unique_ptr<OpenGLBackend> VirtualBackend::createOpenGLBackend()
100{
101 return std::make_unique<VirtualEglBackend>(this);
102}
103
105{
106 return m_outputs;
107}
108
109VirtualOutput *VirtualBackend::createOutput(const OutputInfo &info)
110{
111 VirtualOutput *output = new VirtualOutput(this, info.internal);
112 output->init(info.geometry.topLeft(), info.geometry.size() * info.scale, info.scale);
113 m_outputs.append(output);
114 Q_EMIT outputAdded(output);
115 output->updateEnabled(true);
116 return output;
117}
118
120{
121 VirtualOutput *output = createOutput(info);
122 Q_EMIT outputsQueried();
123 return output;
124}
125
126void VirtualBackend::setVirtualOutputs(const QList<OutputInfo> &infos)
127{
128 const QList<VirtualOutput *> removed = m_outputs;
129
130 for (const auto &info : infos) {
131 createOutput(info);
132 }
133
134 for (VirtualOutput *output : removed) {
135 output->updateEnabled(false);
136 m_outputs.removeOne(output);
137 Q_EMIT outputRemoved(output);
138 output->unref();
139 }
140
141 Q_EMIT outputsQueried();
142}
143
144void VirtualBackend::setEglDisplay(std::unique_ptr<EglDisplay> &&display)
145{
146 m_display = std::move(display);
147}
148
150{
151 return m_display.get();
152}
153
154} // namespace KWin
155
156#include "moc_virtual_backend.cpp"
void outputAdded(Output *output)
void outputRemoved(Output *output)
void unref()
Definition output.cpp:350
std::unique_ptr< QPainterBackend > createQPainterBackend() override
Output * addOutput(const OutputInfo &info)
QList< CompositingType > supportedCompositors() const override
bool initialize() override
VirtualBackend(QObject *parent=nullptr)
EglDisplay * sceneEglDisplayObject() const override
gbm_device * gbmDevice() const
std::unique_ptr< OpenGLBackend > createOpenGLBackend() override
void setEglDisplay(std::unique_ptr< EglDisplay > &&display)
void setVirtualOutputs(const QList< OutputInfo > &infos)
Outputs outputs() const override
void updateEnabled(bool enabled)
void init(const QPoint &logicalPosition, const QSize &pixelSize, qreal scale)
@ QPainterCompositing
Definition globals.h:39
@ OpenGLCompositing
Definition globals.h:37