KWin
Loading...
Searching...
No Matches
itemrenderer_qpainter.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
9#include "effect/effect.h"
11#include "scene/imageitem.h"
13#include "window.h"
14
15#include <QPainter>
16
17namespace KWin
18{
19
21 : m_painter(std::make_unique<QPainter>())
22{
23}
24
28
29std::unique_ptr<ImageItem> ItemRendererQPainter::createImageItem(Scene *scene, Item *parent)
30{
31 return std::make_unique<ImageItem>(scene, parent);
32}
33
35{
36 return m_painter.get();
37}
38
39void ItemRendererQPainter::beginFrame(const RenderTarget &renderTarget, const RenderViewport &viewport)
40{
41 QImage *buffer = renderTarget.image();
42 m_painter->begin(buffer);
43 m_painter->setWindow(viewport.renderRect().toRect());
44}
45
47{
48 m_painter->end();
49}
50
51void ItemRendererQPainter::renderBackground(const RenderTarget &renderTarget, const RenderViewport &viewport, const QRegion &region)
52{
53 m_painter->setCompositionMode(QPainter::CompositionMode_Source);
54 for (const QRect &rect : region) {
55 m_painter->fillRect(rect, Qt::transparent);
56 }
57 m_painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
58}
59
60void ItemRendererQPainter::renderItem(const RenderTarget &renderTarget, const RenderViewport &viewport, Item *item, int mask, const QRegion &_region, const WindowPaintData &data)
61{
62 QRegion region = _region;
63
64 const QRect boundingRect = item->mapToGlobal(item->boundingRect()).toAlignedRect();
66 region &= boundingRect;
67 }
68
69 if (region.isEmpty()) {
70 return;
71 }
72
73 m_painter->save();
74 m_painter->setClipRegion(region);
75 m_painter->setClipping(true);
76 m_painter->setOpacity(data.opacity());
77
79 m_painter->translate(data.xTranslation(), data.yTranslation());
80 m_painter->scale(data.xScale(), data.yScale());
81 }
82
83 renderItem(m_painter.get(), item);
84
85 m_painter->restore();
86}
87
88void ItemRendererQPainter::renderItem(QPainter *painter, Item *item) const
89{
90 const QList<Item *> sortedChildItems = item->sortedChildItems();
91
92 painter->save();
93 painter->translate(item->position());
94 painter->setOpacity(painter->opacity() * item->opacity());
95
96 for (Item *childItem : sortedChildItems) {
97 if (childItem->z() >= 0) {
98 break;
99 }
100 if (childItem->explicitVisible()) {
101 renderItem(painter, childItem);
102 }
103 }
104
105 item->preprocess();
106 if (auto surfaceItem = qobject_cast<SurfaceItem *>(item)) {
107 renderSurfaceItem(painter, surfaceItem);
108 } else if (auto decorationItem = qobject_cast<DecorationItem *>(item)) {
109 renderDecorationItem(painter, decorationItem);
110 } else if (auto imageItem = qobject_cast<ImageItem *>(item)) {
111 renderImageItem(painter, imageItem);
112 }
113
114 for (Item *childItem : sortedChildItems) {
115 if (childItem->z() < 0) {
116 continue;
117 }
118 if (childItem->explicitVisible()) {
119 renderItem(painter, childItem);
120 }
121 }
122
123 painter->restore();
124}
125
126void ItemRendererQPainter::renderSurfaceItem(QPainter *painter, SurfaceItem *surfaceItem) const
127{
128 const SurfacePixmap *surfaceTexture = surfaceItem->pixmap();
129 if (!surfaceTexture || !surfaceTexture->isValid()) {
130 return;
131 }
132
133 QPainterSurfaceTexture *platformSurfaceTexture =
134 static_cast<QPainterSurfaceTexture *>(surfaceTexture->texture());
135 if (!platformSurfaceTexture->isValid()) {
136 platformSurfaceTexture->create();
137 } else {
138 platformSurfaceTexture->update(surfaceItem->damage());
139 }
140 surfaceItem->resetDamage();
141
142 const OutputTransform surfaceToBufferTransform = surfaceItem->bufferTransform();
143 const QSizeF transformedSize = surfaceToBufferTransform.map(surfaceItem->destinationSize());
144
145 painter->save();
146 switch (surfaceToBufferTransform.kind()) {
148 break;
150 painter->translate(transformedSize.height(), 0);
151 painter->rotate(90);
152 break;
154 painter->translate(transformedSize.width(), transformedSize.height());
155 painter->rotate(180);
156 break;
158 painter->translate(0, transformedSize.width());
159 painter->rotate(270);
160 break;
162 painter->translate(transformedSize.width(), 0);
163 painter->scale(-1, 1);
164 break;
166 painter->scale(-1, 1);
167 painter->rotate(90);
168 break;
170 painter->translate(0, transformedSize.height());
171 painter->scale(-1, 1);
172 painter->rotate(180);
173 break;
175 painter->translate(transformedSize.height(), transformedSize.width());
176 painter->scale(-1, 1);
177 painter->rotate(270);
178 break;
179 }
180
181 const QRectF sourceBox = surfaceItem->bufferSourceBox();
182 const qreal xSourceBoxScale = sourceBox.width() / transformedSize.width();
183 const qreal ySourceBoxScale = sourceBox.height() / transformedSize.height();
184
185 const QList<QRectF> shape = surfaceItem->shape();
186 for (const QRectF rect : shape) {
187 const QRectF target = surfaceToBufferTransform.map(rect, surfaceItem->size());
188 const QRectF source(sourceBox.x() + target.x() * xSourceBoxScale,
189 sourceBox.y() + target.y() * ySourceBoxScale,
190 target.width() * xSourceBoxScale,
191 target.height() * ySourceBoxScale);
192
193 painter->drawImage(target, platformSurfaceTexture->image(), source);
194 }
195
196 painter->restore();
197}
198
199void ItemRendererQPainter::renderDecorationItem(QPainter *painter, DecorationItem *decorationItem) const
200{
201 const auto renderer = static_cast<const SceneQPainterDecorationRenderer *>(decorationItem->renderer());
202 QRectF dtr, dlr, drr, dbr;
203 decorationItem->window()->layoutDecorationRects(dlr, dtr, drr, dbr);
204
205 painter->drawImage(dtr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Top));
206 painter->drawImage(dlr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Left));
207 painter->drawImage(drr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Right));
209}
210
211void ItemRendererQPainter::renderImageItem(QPainter *painter, ImageItem *imageItem) const
212{
213 painter->drawImage(imageItem->rect(), imageItem->image());
214}
215
216} // namespace KWin
virtual void preprocess()
Definition item.cpp:341
QPointF position() const
Definition item.cpp:117
qreal opacity() const
Definition item.cpp:37
QList< Item * > sortedChildItems() const
Definition item.cpp:430
QRectF boundingRect() const
Definition item.cpp:157
QRegion mapToGlobal(const QRegion &region) const
Definition item.cpp:210
void renderBackground(const RenderTarget &renderTarget, const RenderViewport &viewport, const QRegion &region) override
void renderItem(const RenderTarget &renderTarget, const RenderViewport &viewport, Item *item, int mask, const QRegion &region, const WindowPaintData &data) override
QPainter * painter() const override
std::unique_ptr< ImageItem > createImageItem(Scene *scene, Item *parent=nullptr) override
void beginFrame(const RenderTarget &renderTarget, const RenderViewport &viewport) override
QImage * image() const
QRectF renderRect() const
@ PAINT_SCREEN_TRANSFORMED
Definition scene.h:60
@ PAINT_WINDOW_TRANSFORMED
Definition scene.h:55
qreal yTranslation() const
Definition effect.cpp:131
qreal yScale() const
Definition effect.cpp:61
qreal xScale() const
Definition effect.cpp:56
qreal xTranslation() const
Definition effect.cpp:126
qreal opacity() const
Definition effect.cpp:259