kwin/src/scene/scene.cpp
Xaver Hugl e4938297e6 scene: fix texture inversion with the drm backend
Specify the render target to buffer transformation and take that into
account in effects and when calculating the projection matrix.
2023-03-09 13:22:53 +00:00

137 lines
2.5 KiB
C++

/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "scene/scene.h"
#include "core/output.h"
#include "core/renderlayer.h"
#include "scene/itemrenderer.h"
namespace KWin
{
SceneDelegate::SceneDelegate(Scene *scene, Output *output)
: m_scene(scene)
, m_output(output)
{
m_scene->addDelegate(this);
}
SceneDelegate::~SceneDelegate()
{
m_scene->removeDelegate(this);
}
QRegion SceneDelegate::repaints() const
{
return m_scene->damage().translated(-viewport().topLeft());
}
SurfaceItem *SceneDelegate::scanoutCandidate() const
{
return m_scene->scanoutCandidate();
}
void SceneDelegate::prePaint()
{
m_scene->prePaint(this);
}
void SceneDelegate::postPaint()
{
m_scene->postPaint();
}
void SceneDelegate::paint(const RenderTarget &renderTarget, const QRegion &region)
{
m_scene->paint(renderTarget, region == infiniteRegion() ? infiniteRegion() : region.translated(viewport().topLeft()));
}
Output *SceneDelegate::output() const
{
return m_output;
}
QRect SceneDelegate::viewport() const
{
return m_output ? m_output->geometry() : m_scene->geometry();
}
Scene::Scene(std::unique_ptr<ItemRenderer> &&renderer)
: m_renderer(std::move(renderer))
{
}
Scene::~Scene()
{
}
ItemRenderer *Scene::renderer() const
{
return m_renderer.get();
}
void Scene::addRepaintFull()
{
addRepaint(geometry());
}
void Scene::addRepaint(int x, int y, int width, int height)
{
addRepaint(QRegion(x, y, width, height));
}
void Scene::addRepaint(const QRegion &region)
{
for (const auto &delegate : std::as_const(m_delegates)) {
const QRect viewport = delegate->viewport();
QRegion dirtyRegion = region & viewport;
dirtyRegion.translate(-viewport.topLeft());
if (!dirtyRegion.isEmpty()) {
delegate->layer()->addRepaint(dirtyRegion);
}
}
}
QRegion Scene::damage() const
{
return QRegion();
}
QRect Scene::geometry() const
{
return m_geometry;
}
void Scene::setGeometry(const QRect &rect)
{
if (m_geometry != rect) {
m_geometry = rect;
addRepaintFull();
}
}
QList<SceneDelegate *> Scene::delegates() const
{
return m_delegates;
}
void Scene::addDelegate(SceneDelegate *delegate)
{
m_delegates.append(delegate);
}
void Scene::removeDelegate(SceneDelegate *delegate)
{
m_delegates.removeOne(delegate);
Q_EMIT delegateRemoved(delegate);
}
SurfaceItem *Scene::scanoutCandidate() const
{
return nullptr;
}
} // namespace KWin