diff options
author | Giulio Camuffo <giulio.camuffo@kdab.com> | 2016-03-28 12:12:04 +0300 |
---|---|---|
committer | Giulio Camuffo <giulio.camuffo@kdab.com> | 2016-04-18 10:48:11 +0000 |
commit | 68f40f95972b857433df424cc16809eebfd77b8f (patch) | |
tree | 815ad8e49e25d4c19a3b3d20395b3e89fa30df51 /src/compositor/compositor_api/qwaylandcompositor.cpp | |
parent | 95d2bff24bc2678da91cfbd210382c3a5af6af8a (diff) |
Add API to grab a surface's content
This patch adds a new QWaylandSurfaceGrabber class. The user can use it
to grab a surface's content, and get a QImage with the data.
Change-Id: I25dd72a8ba39201cd91addbfc976b93ca1e05112
Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
Diffstat (limited to 'src/compositor/compositor_api/qwaylandcompositor.cpp')
-rw-r--r-- | src/compositor/compositor_api/qwaylandcompositor.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 57e8397b9..17b089dcf 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -46,6 +46,7 @@ #include <QtWaylandCompositor/qwaylandkeyboard.h> #include <QtWaylandCompositor/qwaylandpointer.h> #include <QtWaylandCompositor/qwaylandtouch.h> +#include <QtWaylandCompositor/qwaylandsurfacegrabber.h> #include <QtWaylandCompositor/private/qwaylandkeyboard_p.h> #include <QtWaylandCompositor/private/qwaylandsurface_p.h> @@ -75,6 +76,13 @@ #include <QtGui/qpa/qplatformnativeinterface.h> #include <QtGui/private/qguiapplication_p.h> +#ifdef QT_COMPOSITOR_WAYLAND_GL +# include <QtGui/private/qopengltextureblitter_p.h> +# include <QOpenGLContext> +# include <QOpenGLFramebufferObject> +# include <QMatrix4x4> +#endif + QT_BEGIN_NAMESPACE namespace QtWayland { @@ -819,4 +827,50 @@ void QWaylandCompositor::setUseHardwareIntegrationExtension(bool use) useHardwareIntegrationExtensionChanged(); } +/*! + * Grab the surface content from the given \a buffer. + * The default implementation requires a OpenGL context to be bound to the current thread + * to work. If this is not possible reimplement this function in your compositor subclass + * to implement custom logic. + * The default implementation only grabs SHM and OpenGL buffers, reimplement this in your + * compositor subclass to handle more buffer types. + * You should not call this manually, but rather use \a QWaylandSurfaceGrabber. + */ +void QWaylandCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const QWaylandBufferRef &buffer) +{ + if (buffer.isShm()) { + emit grabber->success(buffer.image()); + } else { +#ifdef QT_COMPOSITOR_WAYLAND_GL + if (QOpenGLContext::currentContext()) { + QOpenGLFramebufferObject fbo(buffer.size()); + fbo.bind(); + QOpenGLTextureBlitter blitter; + blitter.create(); + blitter.bind(); + + glViewport(0, 0, buffer.size().width(), buffer.size().height()); + + QOpenGLTextureBlitter::Origin surfaceOrigin = + buffer.origin() == QWaylandSurface::OriginTopLeft + ? QOpenGLTextureBlitter::OriginTopLeft + : QOpenGLTextureBlitter::OriginBottomLeft; + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + buffer.bindToTexture(); + blitter.blit(texture, QMatrix4x4(), surfaceOrigin); + + blitter.release(); + glDeleteTextures(1, &texture); + + emit grabber->success(fbo.toImage()); + } else +#endif + emit grabber->failed(QWaylandSurfaceGrabber::UnknownBufferType); + } +} + QT_END_NAMESPACE |