screencasting: Expose necessary information to implement efficient screencasting

icc-effect-master
Aleix Pol 2020-07-22 19:22:36 +02:00
parent 57e19874b7
commit 27ea1b9527
13 changed files with 96 additions and 4 deletions

View File

@ -172,6 +172,9 @@ public:
*/
virtual bool setGammaRamp(const GammaRamp &gamma);
/** Returns the resolution of the output. */
virtual QSize pixelSize() const = 0;
private:
Q_DISABLE_COPY(AbstractOutput)
};

View File

@ -73,7 +73,7 @@ public:
QSize modeSize() const;
// TODO: The name is ambiguous. Rename this function.
QSize pixelSize() const;
QSize pixelSize() const override;
qreal scale() const override;
@ -125,6 +125,7 @@ public:
Q_SIGNALS:
void modeChanged();
void outputChange(const QRegion &damagedRegion);
protected:
void initInterfaces(const QString &model, const QString &manufacturer,

View File

@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "platform.h"
#include "scene.h"
#include "wayland_server.h"
#include "abstract_wayland_output.h"
#include <KWaylandServer/buffer_interface.h>
#include <KWaylandServer/display.h>
#include <KWaylandServer/surface_interface.h>
@ -316,6 +317,17 @@ void AbstractEglBackend::setSurface(const EGLSurface &surface)
kwinApp()->platform()->setSceneEglSurface(surface);
}
QSharedPointer<GLTexture> AbstractEglBackend::textureForOutput(AbstractOutput *requestedOutput) const
{
QSharedPointer<GLTexture> texture(new GLTexture(GL_RGBA8, requestedOutput->pixelSize()));
GLRenderTarget renderTarget(*texture);
const QRect geo = requestedOutput->geometry();
QRect invGeo(geo.left(), geo.bottom(), geo.width(), -geo.height());
renderTarget.blitFromFramebuffer(invGeo);
return texture;
}
AbstractEglTexture::AbstractEglTexture(SceneOpenGLTexture *texture, AbstractEglBackend *backend)
: SceneOpenGLTexturePrivate()
, q(texture)
@ -630,4 +642,3 @@ bool AbstractEglTexture::updateFromInternalImageObject(WindowPixmap *pixmap)
}
}

View File

@ -37,6 +37,7 @@ namespace KWin
{
class EglDmabuf;
class AbstractOutput;
class KWIN_EXPORT AbstractEglBackend : public QObject, public OpenGLBackend
{
@ -59,6 +60,8 @@ public:
return m_config;
}
QSharedPointer<GLTexture> textureForOutput(AbstractOutput *output) const override;
protected:
AbstractEglBackend();
void setEglDisplay(const EGLDisplay &display);

View File

@ -116,4 +116,10 @@ void OpenGLBackend::copyPixels(const QRegion &region)
}
}
QSharedPointer<KWin::GLTexture> OpenGLBackend::textureForOutput(AbstractOutput* output) const
{
Q_UNUSED(output)
return {};
}
}

View File

@ -28,12 +28,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace KWin
{
class AbstractOutput;
class OpenGLBackend;
class OverlayWindow;
class SceneOpenGL;
class SceneOpenGLTexture;
class SceneOpenGLTexturePrivate;
class WindowPixmap;
class GLTexture;
/**
* @brief The OpenGLBackend creates and holds the OpenGL context and is responsible for Texture from Pixmap.
@ -197,6 +199,8 @@ public:
*/
void copyPixels(const QRegion &region);
virtual QSharedPointer<GLTexture> textureForOutput(AbstractOutput *output) const;
protected:
/**
* @brief Backend specific flushing of frame to screen.

View File

@ -98,4 +98,9 @@ void X11Output::setPhysicalSize(const QSize &size)
m_physicalSize = size;
}
QSize X11Output::pixelSize() const
{
return geometry().size();
}
}

View File

@ -57,6 +57,8 @@ public:
QSize physicalSize() const override;
void setPhysicalSize(const QSize &size);
QSize pixelSize() const override;
private:
void setCrtc(xcb_randr_crtc_t crtc);
void setGammaRampSize(int size);

View File

@ -49,6 +49,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "decorations/decoratedclient.h"
#include <logging.h>
#include "abstract_wayland_output.h"
#include "abstract_egl_backend.h"
#include <KWaylandServer/buffer_interface.h>
#include <KWaylandServer/subcompositor_interface.h>
#include <KWaylandServer/surface_interface.h>
@ -889,6 +891,11 @@ QVector<QByteArray> SceneOpenGL::openGLPlatformInterfaceExtensions() const
return m_backend->extensions().toVector();
}
QSharedPointer<GLTexture> SceneOpenGL::textureForOutput(AbstractOutput* output) const
{
return m_backend->textureForOutput(output);
}
//****************************************
// SceneOpenGL2
//****************************************
@ -1531,6 +1538,41 @@ void OpenGLWindow::performPaint(int mask, const QRegion &region, const WindowPai
endRenderWindow();
}
QSharedPointer<GLTexture> OpenGLWindow::windowTexture()
{
auto frame = windowPixmap<OpenGLWindowPixmap>();
if (frame->children().isEmpty()) {
return QSharedPointer<GLTexture>(new GLTexture(*frame->texture()));
} else {
auto effectWindow = window()->effectWindow();
QRect geo(pos(), window()->clientSize());
QSharedPointer<GLTexture> texture(new GLTexture(GL_RGBA8, geo.size()));
QScopedPointer<GLRenderTarget> framebuffer(new KWin::GLRenderTarget(*texture));
GLRenderTarget::pushRenderTarget(framebuffer.data());
auto renderVSG = GLRenderTarget::virtualScreenGeometry();
GLVertexBuffer::setVirtualScreenGeometry(geo);
GLRenderTarget::setVirtualScreenGeometry(geo);
QMatrix4x4 mvp;
mvp.ortho(geo);
WindowPaintData data(effectWindow);
data.setProjectionMatrix(mvp);
QSizeF size(geo.size());
data.setYScale(-1);
data.setXTranslation(bufferOffset().x());
data.setYTranslation(geo.height() + bufferOffset().y());
performPaint(Scene::PAINT_WINDOW_TRANSFORMED | Scene::PAINT_WINDOW_LANCZOS, geo, data);
GLRenderTarget::popRenderTarget();
GLVertexBuffer::setVirtualScreenGeometry(renderVSG);
GLRenderTarget::setVirtualScreenGeometry(renderVSG);
return texture;
}
}
//****************************************
// OpenGLWindowPixmap

View File

@ -80,6 +80,7 @@ public:
}
QVector<QByteArray> openGLPlatformInterfaceExtensions() const override;
QSharedPointer<GLTexture> textureForOutput(AbstractOutput *output) const override;
static SceneOpenGL *createScene(QObject *parent);
@ -100,6 +101,7 @@ protected:
bool init_ok;
private:
bool viewportLimitsMatched(const QSize &size) const;
private:
bool m_debug;
OpenGLBackend *m_backend;
@ -189,6 +191,7 @@ public:
WindowPixmap *createWindowPixmap() override;
void performPaint(int mask, const QRegion &region, const WindowPaintData &data) override;
QSharedPointer<GLTexture> windowTexture() override;
private:
QMatrix4x4 transformation(int mask, const WindowPaintData &data) const;

View File

@ -149,8 +149,6 @@ qint64 SceneQPainter::paint(const QRegion &_damage, const QList<Toplevel *> &top
// do cleanup
clearStackingOrder();
emit frameRendered();
return renderTimer.nsecsElapsed();
}

View File

@ -198,6 +198,8 @@ void Scene::finalPaintScreen(int mask, const QRegion &region, ScreenPaintData& d
paintGenericScreen(mask, data);
else
paintSimpleScreen(mask, region);
Q_EMIT frameRendered();
}
// The generic painting code that can handle even transformations.

12
scene.h
View File

@ -52,6 +52,8 @@ class EffectWindowImpl;
class OverlayWindow;
class Shadow;
class WindowPixmap;
class GLTexture;
class AbstractOutput;
// The base class for compositing backends.
class KWIN_EXPORT Scene : public QObject
@ -195,6 +197,11 @@ public:
*/
virtual QVector<QByteArray> openGLPlatformInterfaceExtensions() const;
virtual QSharedPointer<GLTexture> textureForOutput(AbstractOutput *output) const {
Q_UNUSED(output);
return {};
}
Q_SIGNALS:
void frameRendered();
void resetCompositing();
@ -347,6 +354,11 @@ public:
void unreferencePreviousPixmap();
void discardQuads();
void preprocess();
virtual QSharedPointer<GLTexture> windowTexture() {
return {};
}
protected:
WindowQuadList makeDecorationQuads(const QRect *rects, const QRegion &region, qreal textureScale = 1.0) const;
WindowQuadList makeContentsQuads() const;