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); virtual bool setGammaRamp(const GammaRamp &gamma);
/** Returns the resolution of the output. */
virtual QSize pixelSize() const = 0;
private: private:
Q_DISABLE_COPY(AbstractOutput) Q_DISABLE_COPY(AbstractOutput)
}; };

View File

@ -73,7 +73,7 @@ public:
QSize modeSize() const; QSize modeSize() const;
// TODO: The name is ambiguous. Rename this function. // TODO: The name is ambiguous. Rename this function.
QSize pixelSize() const; QSize pixelSize() const override;
qreal scale() const override; qreal scale() const override;
@ -125,6 +125,7 @@ public:
Q_SIGNALS: Q_SIGNALS:
void modeChanged(); void modeChanged();
void outputChange(const QRegion &damagedRegion);
protected: protected:
void initInterfaces(const QString &model, const QString &manufacturer, 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 "platform.h"
#include "scene.h" #include "scene.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "abstract_wayland_output.h"
#include <KWaylandServer/buffer_interface.h> #include <KWaylandServer/buffer_interface.h>
#include <KWaylandServer/display.h> #include <KWaylandServer/display.h>
#include <KWaylandServer/surface_interface.h> #include <KWaylandServer/surface_interface.h>
@ -316,6 +317,17 @@ void AbstractEglBackend::setSurface(const EGLSurface &surface)
kwinApp()->platform()->setSceneEglSurface(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) AbstractEglTexture::AbstractEglTexture(SceneOpenGLTexture *texture, AbstractEglBackend *backend)
: SceneOpenGLTexturePrivate() : SceneOpenGLTexturePrivate()
, q(texture) , q(texture)
@ -630,4 +642,3 @@ bool AbstractEglTexture::updateFromInternalImageObject(WindowPixmap *pixmap)
} }
} }

View File

@ -37,6 +37,7 @@ namespace KWin
{ {
class EglDmabuf; class EglDmabuf;
class AbstractOutput;
class KWIN_EXPORT AbstractEglBackend : public QObject, public OpenGLBackend class KWIN_EXPORT AbstractEglBackend : public QObject, public OpenGLBackend
{ {
@ -59,6 +60,8 @@ public:
return m_config; return m_config;
} }
QSharedPointer<GLTexture> textureForOutput(AbstractOutput *output) const override;
protected: protected:
AbstractEglBackend(); AbstractEglBackend();
void setEglDisplay(const EGLDisplay &display); 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 namespace KWin
{ {
class AbstractOutput;
class OpenGLBackend; class OpenGLBackend;
class OverlayWindow; class OverlayWindow;
class SceneOpenGL; class SceneOpenGL;
class SceneOpenGLTexture; class SceneOpenGLTexture;
class SceneOpenGLTexturePrivate; class SceneOpenGLTexturePrivate;
class WindowPixmap; class WindowPixmap;
class GLTexture;
/** /**
* @brief The OpenGLBackend creates and holds the OpenGL context and is responsible for Texture from Pixmap. * @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); void copyPixels(const QRegion &region);
virtual QSharedPointer<GLTexture> textureForOutput(AbstractOutput *output) const;
protected: protected:
/** /**
* @brief Backend specific flushing of frame to screen. * @brief Backend specific flushing of frame to screen.

View File

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

View File

@ -57,6 +57,8 @@ public:
QSize physicalSize() const override; QSize physicalSize() const override;
void setPhysicalSize(const QSize &size); void setPhysicalSize(const QSize &size);
QSize pixelSize() const override;
private: private:
void setCrtc(xcb_randr_crtc_t crtc); void setCrtc(xcb_randr_crtc_t crtc);
void setGammaRampSize(int size); 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 "decorations/decoratedclient.h"
#include <logging.h> #include <logging.h>
#include "abstract_wayland_output.h"
#include "abstract_egl_backend.h"
#include <KWaylandServer/buffer_interface.h> #include <KWaylandServer/buffer_interface.h>
#include <KWaylandServer/subcompositor_interface.h> #include <KWaylandServer/subcompositor_interface.h>
#include <KWaylandServer/surface_interface.h> #include <KWaylandServer/surface_interface.h>
@ -889,6 +891,11 @@ QVector<QByteArray> SceneOpenGL::openGLPlatformInterfaceExtensions() const
return m_backend->extensions().toVector(); return m_backend->extensions().toVector();
} }
QSharedPointer<GLTexture> SceneOpenGL::textureForOutput(AbstractOutput* output) const
{
return m_backend->textureForOutput(output);
}
//**************************************** //****************************************
// SceneOpenGL2 // SceneOpenGL2
//**************************************** //****************************************
@ -1531,6 +1538,41 @@ void OpenGLWindow::performPaint(int mask, const QRegion &region, const WindowPai
endRenderWindow(); 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 // OpenGLWindowPixmap

View File

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

View File

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

12
scene.h
View File

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