KWin
Loading...
Searching...
No Matches
backingstore.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 SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10#include "backingstore.h"
11#include "core/graphicsbuffer.h"
13#include "internalwindow.h"
14#include "logging.h"
15#include "swapchain.h"
16#include "window.h"
17
18#include <QPainter>
19#include <libdrm/drm_fourcc.h>
20
21namespace KWin
22{
23namespace QPA
24{
25
27 : QPlatformBackingStore(window)
28{
29}
30
32{
33 return m_bufferView->image();
34}
35
36void BackingStore::resize(const QSize &size, const QRegion &staticContents)
37{
38 QPlatformWindow *platformWindow = static_cast<QPlatformWindow *>(window()->handle());
39 platformWindow->invalidateSurface();
40}
41
42void BackingStore::beginPaint(const QRegion &region)
43{
44 Window *platformWindow = static_cast<Window *>(window()->handle());
45 Swapchain *swapchain = platformWindow->swapchain({{DRM_FORMAT_ARGB8888, {DRM_FORMAT_MOD_LINEAR}}});
46 if (!swapchain) {
47 qCCritical(KWIN_QPA, "Failed to ceate a swapchain for the backing store!");
48 return;
49 }
50
51 const auto oldBuffer = m_buffer;
52 m_buffer = swapchain->acquire();
53 if (!m_buffer) {
54 qCCritical(KWIN_QPA, "Failed to acquire a graphics buffer for the backing store");
55 return;
56 }
57
58 m_bufferView = std::make_unique<GraphicsBufferView>(m_buffer, GraphicsBuffer::Read | GraphicsBuffer::Write);
59 if (m_bufferView->isNull()) {
60 qCCritical(KWIN_QPA) << "Failed to map a graphics buffer for the backing store";
61 return;
62 }
63
64 if (oldBuffer && oldBuffer != m_buffer && oldBuffer->size() == m_buffer->size()) {
65 const GraphicsBufferView oldView(oldBuffer, GraphicsBuffer::Read);
66 std::memcpy(m_bufferView->image()->bits(), oldView.image()->constBits(), oldView.image()->sizeInBytes());
67 }
68
69 QImage *image = m_bufferView->image();
70 image->setDevicePixelRatio(platformWindow->devicePixelRatio());
71
72 if (image->hasAlphaChannel()) {
73 QPainter p(image);
74 p.setCompositionMode(QPainter::CompositionMode_Source);
75 const QColor blank = Qt::transparent;
76 for (const QRect &rect : region) {
77 p.fillRect(rect, blank);
78 }
79 }
80}
81
83{
84 m_bufferView.reset();
85}
86
87void BackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
88{
89 Window *platformWindow = static_cast<Window *>(window->handle());
90 InternalWindow *internalWindow = platformWindow->internalWindow();
91 if (!internalWindow) {
92 return;
93 }
94
95 const qreal scale = platformWindow->devicePixelRatio();
96 QRegion bufferDamage;
97 for (const QRect &rect : region) {
98 bufferDamage += QRectF(rect.x() * scale, rect.y() * scale, rect.width() * scale, rect.height() * scale).toAlignedRect();
99 }
100
101 internalWindow->present(InternalWindowFrame{
102 .buffer = m_buffer,
103 .bufferDamage = bufferDamage,
104 });
105}
106
107}
108}
void present(const InternalWindowFrame &frame)
BackingStore(QWindow *window)
QPaintDevice * paintDevice() override
void resize(const QSize &size, const QRegion &staticContents) override
void endPaint() override
void beginPaint(const QRegion &region) override
void flush(QWindow *window, const QRegion &region, const QPoint &offset) override
GraphicsBuffer * acquire()
Definition swapchain.cpp:33
InternalWindow * internalWindow() const
Definition window.cpp:135
qreal devicePixelRatio() const override
Definition window.cpp:130
Swapchain * swapchain(const QHash< uint32_t, QList< uint64_t > > &formats)
Definition window.cpp:45