KWin
Loading...
Searching...
No Matches
x11_windowed_qpainter_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*/
14#include "x11_windowed_output.h"
15
16#include <cerrno>
17#include <cmath>
18#include <drm_fourcc.h>
19#include <string.h>
20#include <xcb/present.h>
21
22namespace KWin
23{
24
26 : m_output(output)
27 , m_backend(backend)
28{
29}
30
34
35std::optional<OutputLayerBeginFrameInfo> X11WindowedQPainterPrimaryLayer::beginFrame()
36{
37 const QSize bufferSize = m_output->modeSize();
38 if (!m_swapchain || m_swapchain->size() != bufferSize) {
39 m_swapchain = std::make_unique<QPainterSwapchain>(m_backend->graphicsBufferAllocator(), bufferSize, m_output->backend()->driFormatForDepth(m_output->depth()));
40 }
41
42 m_current = m_swapchain->acquire();
43 if (!m_current) {
44 return std::nullopt;
45 }
46
47 QRegion repaint = m_output->exposedArea() + m_output->rect();
48 m_output->clearExposedArea();
49
50 m_renderStart = std::chrono::steady_clock::now();
52 .renderTarget = RenderTarget(m_current->view()->image()),
53 .repaint = repaint,
54 };
55}
56
57bool X11WindowedQPainterPrimaryLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
58{
59 m_renderTime = std::chrono::steady_clock::now() - m_renderStart;
60 return true;
61}
62
64{
65 xcb_pixmap_t pixmap = m_output->importBuffer(m_current->buffer());
66 Q_ASSERT(pixmap != XCB_PIXMAP_NONE);
67
68 xcb_xfixes_region_t valid = 0;
69 xcb_xfixes_region_t update = 0;
70 uint32_t serial = 0;
71 uint32_t options = 0;
72 uint64_t targetMsc = 0;
73
74 xcb_present_pixmap(m_output->backend()->connection(),
75 m_output->window(),
76 pixmap,
77 serial,
78 valid,
79 update,
80 0,
81 0,
82 XCB_NONE,
83 XCB_NONE,
84 XCB_NONE,
85 options,
86 targetMsc,
87 0,
88 0,
89 0,
90 nullptr);
91}
92
94{
95 return m_renderTime;
96}
97
102
103std::optional<OutputLayerBeginFrameInfo> X11WindowedQPainterCursorLayer::beginFrame()
104{
105 const auto tmp = size().expandedTo(QSize(64, 64));
106 const QSize bufferSize(std::ceil(tmp.width()), std::ceil(tmp.height()));
107 if (m_buffer.size() != bufferSize) {
108 m_buffer = QImage(bufferSize, QImage::Format_ARGB32_Premultiplied);
109 }
110
111 m_renderStart = std::chrono::steady_clock::now();
113 .renderTarget = RenderTarget(&m_buffer),
114 .repaint = infiniteRegion(),
115 };
116}
117
119{
120 return m_renderTime;
121}
122
123bool X11WindowedQPainterCursorLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
124{
125 m_renderTime = std::chrono::steady_clock::now() - m_renderStart;
126 m_output->cursor()->update(m_buffer, hotspot());
127 return true;
128}
129
132 , m_backend(backend)
133 , m_allocator(std::make_unique<ShmGraphicsBufferAllocator>())
134{
135 const auto outputs = m_backend->outputs();
136 for (Output *output : outputs) {
137 addOutput(output);
138 }
139
140 connect(backend, &X11WindowedBackend::outputAdded, this, &X11WindowedQPainterBackend::addOutput);
141 connect(backend, &X11WindowedBackend::outputRemoved, this, &X11WindowedQPainterBackend::removeOutput);
142}
143
148
149void X11WindowedQPainterBackend::addOutput(Output *output)
150{
151 X11WindowedOutput *x11Output = static_cast<X11WindowedOutput *>(output);
152 m_outputs[output] = Layers{
153 .primaryLayer = std::make_unique<X11WindowedQPainterPrimaryLayer>(x11Output, this),
154 .cursorLayer = std::make_unique<X11WindowedQPainterCursorLayer>(x11Output),
155 };
156}
157
158void X11WindowedQPainterBackend::removeOutput(Output *output)
159{
160 m_outputs.erase(output);
161}
162
167
168void X11WindowedQPainterBackend::present(Output *output, const std::shared_ptr<OutputFrame> &frame)
169{
170 m_outputs[output].primaryLayer->present();
171 static_cast<X11WindowedOutput *>(output)->framePending(frame);
172}
173
175{
176 return m_outputs[output].primaryLayer.get();
177}
178
180{
181 return m_outputs[output].cursorLayer.get();
182}
183
184}
185
186#include "moc_x11_windowed_qpainter_backend.cpp"
void outputAdded(Output *output)
void outputRemoved(Output *output)
QRect rect() const
Definition output.h:484
QSize modeSize() const
Definition output.cpp:480
QSizeF size() const
QPointF hotspot() const
xcb_connection_t * connection() const
uint32_t driFormatForDepth(int depth) const
Outputs outputs() const override
void update(const QImage &image, const QPointF &hotspot)
xcb_pixmap_t importBuffer(GraphicsBuffer *buffer)
X11WindowedCursor * cursor() const
X11WindowedBackend * backend() const
GraphicsBufferAllocator * graphicsBufferAllocator() const override
OutputLayer * cursorLayer(Output *output) override
void present(Output *output, const std::shared_ptr< OutputFrame > &frame) override
OutputLayer * primaryLayer(Output *output) override
X11WindowedQPainterBackend(X11WindowedBackend *backend)
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override
std::chrono::nanoseconds queryRenderTime() const override
std::optional< OutputLayerBeginFrameInfo > beginFrame() override
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override
std::optional< OutputLayerBeginFrameInfo > beginFrame() override
X11WindowedQPainterPrimaryLayer(X11WindowedOutput *output, X11WindowedQPainterBackend *backend)
std::chrono::nanoseconds queryRenderTime() const override
KWIN_EXPORT QRect infiniteRegion()
Definition globals.h:234
Options * options
Definition main.cpp:73