Commit 27ea1b95 authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧
Browse files

screencasting: Expose necessary information to implement efficient screencasting

parent 57e19874
......@@ -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)
};
......
......@@ -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,
......
......@@ -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)
}
}
......@@ -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);
......
......@@ -116,4 +116,10 @@ void OpenGLBackend::copyPixels(const QRegion &region)
}
}
QSharedPointer<KWin::GLTexture> OpenGLBackend::textureForOutput(AbstractOutput* output) const
{
Q_UNUSED(output)
return {};
}
}
......@@ -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.
......
......@@ -98,4 +98,9 @@ void X11Output::setPhysicalSize(const QSize &size)
m_physicalSize = size;
}
QSize X11Output::pixelSize() const
{
return geometry().size();
}
}
......@@ -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);
......
......@@ -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
......
......@@ -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;
......
......@@ -149,8 +149,6 @@ qint64 SceneQPainter::paint(const QRegion &_damage, const QList<Toplevel *> &top
// do cleanup
clearStackingOrder();
emit frameRendered();
return renderTimer.nsecsElapsed();
}
......
......@@ -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.
......
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment