screencasting: Expose necessary information to implement efficient screencasting
This commit is contained in:
parent
57e19874b7
commit
27ea1b9527
13 changed files with 96 additions and 4 deletions
|
@ -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 ®ion)
|
|||
}
|
||||
}
|
||||
|
||||
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 ®ion);
|
||||
|
||||
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 ®ion, 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 ®ion, 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 ®ion, ScreenPaintData& d
|
|||
paintGenericScreen(mask, data);
|
||||
else
|
||||
paintSimpleScreen(mask, region);
|
||||
|
||||
Q_EMIT frameRendered();
|
||||
}
|
||||
|
||||
// The generic painting code that can handle even transformations.
|
||||
|
|
12
scene.h
12
scene.h
|
@ -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 ®ion, qreal textureScale = 1.0) const;
|
||||
WindowQuadList makeContentsQuads() const;
|
||||
|
|
Loading…
Reference in a new issue