kwin/src/decorationitem.h
Vlad Zahorodnii bb935aa5de Fix decoration rendering with scale factor < 1
QPainter won't let paint with a device pixel ratio less than 1. There
are used to be workarounds to force a device pixel ratio of 1, but they
were removed with fractional scaling corner fix.

This change makes sure that the decoration renderer forces a device
pixel ratio of 1 if the output's scale factor is less than 1 so
calculated texture coordinates match where window borders are rendered
in the texture atlas.

BUG: 449681
2022-02-07 11:45:31 +00:00

101 lines
2.2 KiB
C++

/*
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "item.h"
namespace KDecoration2
{
class Decoration;
}
namespace KWin
{
class AbstractClient;
class Deleted;
class Toplevel;
namespace Decoration
{
class DecoratedClientImpl;
}
class KWIN_EXPORT DecorationRenderer : public QObject
{
Q_OBJECT
public:
virtual void render(const QRegion &region) = 0;
void invalidate();
// TODO: Move damage tracking inside DecorationItem.
QRegion damage() const;
void addDamage(const QRegion &region);
void resetDamage();
qreal effectiveDevicePixelRatio() const;
qreal devicePixelRatio() const;
void setDevicePixelRatio(qreal dpr);
// Reserve some space for padding. We pad decoration parts to avoid texture bleeding.
static const int TexturePad = 1;
Q_SIGNALS:
void damaged(const QRegion &region);
protected:
explicit DecorationRenderer(Decoration::DecoratedClientImpl *client);
Decoration::DecoratedClientImpl *client() const;
bool areImageSizesDirty() const {
return m_imageSizesDirty;
}
void resetImageSizesDirty() {
m_imageSizesDirty = false;
}
QImage renderToImage(const QRect &geo);
void renderToPainter(QPainter *painter, const QRect &rect);
private:
QPointer<Decoration::DecoratedClientImpl> m_client;
QRegion m_damage;
qreal m_devicePixelRatio = 1;
bool m_imageSizesDirty;
};
/**
* The DecorationItem class represents a server-side decoration.
*/
class KWIN_EXPORT DecorationItem : public Item
{
Q_OBJECT
public:
explicit DecorationItem(KDecoration2::Decoration *decoration, AbstractClient *window, Item *parent = nullptr);
DecorationRenderer *renderer() const;
private Q_SLOTS:
void handleFrameGeometryChanged();
void handleWindowClosed(Toplevel *original, Deleted *deleted);
void handleOutputChanged();
void handleOutputScaleChanged();
protected:
void preprocess() override;
WindowQuadList buildQuads() const override;
private:
Toplevel *m_window;
QPointer<AbstractOutput> m_output;
QPointer<KDecoration2::Decoration> m_decoration;
QScopedPointer<DecorationRenderer> m_renderer;
};
} // namespace KWin