You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

120 lines
2.8 KiB

/*
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "outputscreencastsource.h"
#include "screencastutils.h"
#include "compositor.h"
#include "core/output.h"
#include "core/renderloop.h"
#include "opengl/gltexture.h"
#include "opengl/glutils.h"
#include "scene/workspacescene.h"
#include <drm_fourcc.h>
namespace KWin
{
OutputScreenCastSource::OutputScreenCastSource(Output *output, QObject *parent)
: ScreenCastSource(parent)
, m_output(output)
{
connect(m_output, &QObject::destroyed, this, &ScreenCastSource::closed);
connect(m_output, &Output::enabledChanged, this, [this] {
if (!m_output->isEnabled()) {
Q_EMIT closed();
}
});
}
OutputScreenCastSource::~OutputScreenCastSource()
{
pause();
}
quint32 OutputScreenCastSource::drmFormat() const
{
return DRM_FORMAT_ARGB8888;
}
QSize OutputScreenCastSource::textureSize() const
{
return m_output->pixelSize();
}
void OutputScreenCastSource::render(QImage *target)
{
const auto [outputTexture, colorDescription] = Compositor::self()->scene()->textureForOutput(m_output);
if (outputTexture) {
grabTexture(outputTexture.get(), target);
}
}
void OutputScreenCastSource::render(GLFramebuffer *target)
{
const auto [outputTexture, colorDescription] = Compositor::self()->scene()->textureForOutput(m_output);
if (!outputTexture) {
return;
}
ShaderBinder shaderBinder(ShaderTrait::MapTexture | ShaderTrait::TransformColorspace);
QMatrix4x4 projectionMatrix;
projectionMatrix.scale(1, -1);
projectionMatrix.ortho(QRect(QPoint(), textureSize()));
shaderBinder.shader()->setUniform(GLShader::Mat4Uniform::ModelViewProjectionMatrix, projectionMatrix);
shaderBinder.shader()->setColorspaceUniformsToSRGB(colorDescription);
GLFramebuffer::pushFramebuffer(target);
outputTexture->render(textureSize());
GLFramebuffer::popFramebuffer();
}
std::chrono::nanoseconds OutputScreenCastSource::clock() const
{
return m_output->renderLoop()->lastPresentationTimestamp();
}
uint OutputScreenCastSource::refreshRate() const
{
return m_output->refreshRate();
}
void OutputScreenCastSource::report(const QRegion &damage)
{
if (!damage.isEmpty()) {
Q_EMIT frame(scaleRegion(damage, m_output->scale()));
}
}
void OutputScreenCastSource::resume()
{
if (m_active) {
return;
}
connect(m_output, &Output::outputChange, this, &OutputScreenCastSource::report);
report(m_output->rect());
m_active = true;
}
void OutputScreenCastSource::pause()
{
if (!m_active) {
return;
}
if (m_output) {
disconnect(m_output, &Output::outputChange, this, &OutputScreenCastSource::report);
}
m_active = false;
}
} // namespace KWin
#include "moc_outputscreencastsource.cpp"