2021-02-04 09:07:20 +00:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "surfaceitem.h"
|
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
|
|
|
SurfaceItem::SurfaceItem(Scene::Window *window, Item *parent)
|
|
|
|
: Item(window, parent)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QRegion SurfaceItem::shape() const
|
|
|
|
{
|
|
|
|
return QRegion();
|
|
|
|
}
|
|
|
|
|
|
|
|
QRegion SurfaceItem::opaque() const
|
|
|
|
{
|
|
|
|
return QRegion();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceItem::addDamage(const QRegion ®ion)
|
|
|
|
{
|
|
|
|
m_damage += region;
|
|
|
|
scheduleRepaint(region);
|
|
|
|
|
|
|
|
Toplevel *toplevel = window()->window();
|
2021-06-08 07:02:14 +00:00
|
|
|
Q_EMIT toplevel->damaged(toplevel, region);
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceItem::resetDamage()
|
|
|
|
{
|
|
|
|
m_damage = QRegion();
|
|
|
|
}
|
|
|
|
|
|
|
|
QRegion SurfaceItem::damage() const
|
|
|
|
{
|
|
|
|
return m_damage;
|
|
|
|
}
|
|
|
|
|
2021-04-09 07:06:04 +00:00
|
|
|
SurfacePixmap *SurfaceItem::pixmap() const
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
2021-04-09 07:06:04 +00:00
|
|
|
if (m_pixmap && m_pixmap->isValid()) {
|
|
|
|
return m_pixmap.data();
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
2021-04-09 07:06:04 +00:00
|
|
|
if (m_previousPixmap && m_previousPixmap->isValid()) {
|
|
|
|
return m_previousPixmap.data();
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-04-09 07:06:04 +00:00
|
|
|
SurfacePixmap *SurfaceItem::previousPixmap() const
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
2021-04-09 07:06:04 +00:00
|
|
|
return m_previousPixmap.data();
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceItem::referencePreviousPixmap()
|
|
|
|
{
|
2021-04-09 07:06:04 +00:00
|
|
|
if (m_previousPixmap && m_previousPixmap->isDiscarded()) {
|
2021-02-04 09:07:20 +00:00
|
|
|
m_referencePixmapCounter++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceItem::unreferencePreviousPixmap()
|
|
|
|
{
|
2021-04-09 07:06:04 +00:00
|
|
|
if (!m_previousPixmap || !m_previousPixmap->isDiscarded()) {
|
2021-02-04 09:07:20 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_referencePixmapCounter--;
|
|
|
|
if (m_referencePixmapCounter == 0) {
|
2021-04-09 07:06:04 +00:00
|
|
|
m_previousPixmap.reset();
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceItem::updatePixmap()
|
|
|
|
{
|
2021-04-09 07:06:04 +00:00
|
|
|
if (m_pixmap.isNull()) {
|
|
|
|
m_pixmap.reset(createPixmap());
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
2021-04-09 07:06:04 +00:00
|
|
|
if (m_pixmap->isValid()) {
|
|
|
|
m_pixmap->update();
|
2021-02-04 09:07:20 +00:00
|
|
|
} else {
|
2021-04-09 07:06:04 +00:00
|
|
|
m_pixmap->create();
|
|
|
|
if (m_pixmap->isValid()) {
|
|
|
|
m_previousPixmap.reset();
|
2021-02-04 09:07:20 +00:00
|
|
|
discardQuads();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceItem::discardPixmap()
|
|
|
|
{
|
2021-04-09 07:06:04 +00:00
|
|
|
if (!m_pixmap.isNull()) {
|
|
|
|
if (m_pixmap->isValid()) {
|
|
|
|
m_previousPixmap.reset(m_pixmap.take());
|
|
|
|
m_previousPixmap->markAsDiscarded();
|
|
|
|
m_referencePixmapCounter++;
|
2021-02-04 09:07:20 +00:00
|
|
|
} else {
|
2021-04-09 07:06:04 +00:00
|
|
|
m_pixmap.reset();
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
addDamage(rect());
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceItem::preprocess()
|
|
|
|
{
|
|
|
|
updatePixmap();
|
|
|
|
}
|
|
|
|
|
2021-05-21 10:51:23 +00:00
|
|
|
WindowQuadList SurfaceItem::buildQuads() const
|
|
|
|
{
|
|
|
|
const QRegion region = shape();
|
|
|
|
|
|
|
|
WindowQuadList quads;
|
|
|
|
quads.reserve(region.rectCount());
|
|
|
|
|
|
|
|
for (const QRectF rect : region) {
|
2021-06-10 09:54:16 +00:00
|
|
|
WindowQuad quad(const_cast<SurfaceItem *>(this));
|
2021-05-21 10:51:23 +00:00
|
|
|
|
|
|
|
const QPointF bufferTopLeft = mapToBuffer(rect.topLeft());
|
|
|
|
const QPointF bufferTopRight = mapToBuffer(rect.topRight());
|
|
|
|
const QPointF bufferBottomRight = mapToBuffer(rect.bottomRight());
|
|
|
|
const QPointF bufferBottomLeft = mapToBuffer(rect.bottomLeft());
|
|
|
|
|
2021-06-10 10:02:10 +00:00
|
|
|
quad[0] = WindowVertex(rect.topLeft(), bufferTopLeft);
|
|
|
|
quad[1] = WindowVertex(rect.topRight(), bufferTopRight);
|
|
|
|
quad[2] = WindowVertex(rect.bottomRight(), bufferBottomRight);
|
|
|
|
quad[3] = WindowVertex(rect.bottomLeft(), bufferBottomLeft);
|
2021-05-21 10:51:23 +00:00
|
|
|
|
|
|
|
quads << quad;
|
|
|
|
}
|
|
|
|
|
|
|
|
return quads;
|
|
|
|
}
|
|
|
|
|
2021-04-09 07:06:04 +00:00
|
|
|
PlatformSurfaceTexture::~PlatformSurfaceTexture()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
SurfacePixmap::SurfacePixmap(PlatformSurfaceTexture *platformTexture, QObject *parent)
|
|
|
|
: QObject(parent)
|
|
|
|
, m_platformTexture(platformTexture)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfacePixmap::update()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
PlatformSurfaceTexture *SurfacePixmap::platformTexture() const
|
|
|
|
{
|
|
|
|
return m_platformTexture.data();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SurfacePixmap::hasAlphaChannel() const
|
|
|
|
{
|
|
|
|
return m_hasAlphaChannel;
|
|
|
|
}
|
|
|
|
|
|
|
|
QSize SurfacePixmap::size() const
|
|
|
|
{
|
|
|
|
return m_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
QRect SurfacePixmap::contentsRect() const
|
|
|
|
{
|
|
|
|
return m_contentsRect;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SurfacePixmap::isDiscarded() const
|
|
|
|
{
|
|
|
|
return m_isDiscarded;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfacePixmap::markAsDiscarded()
|
|
|
|
{
|
|
|
|
m_isDiscarded = true;
|
|
|
|
}
|
|
|
|
|
2021-02-04 09:07:20 +00:00
|
|
|
} // namespace KWin
|