Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwaylandquickcompositor.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2// Copyright (C) 2017 Jolla Ltd, author: <giulio.camuffo@jollamobile.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
5#include <QtQml/QQmlEngine>
6#include <QQuickWindow>
7#if QT_CONFIG(opengl)
8# include <QOpenGLTextureBlitter>
9# include <QOpenGLTexture>
10# include <QOpenGLFramebufferObject>
11#endif
12#include <QMatrix4x4>
13#include <QRunnable>
14
15#include "qwaylandclient.h"
20#include "qwaylandoutput.h"
21#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
22#include <QtWaylandCompositor/QWaylandViewporter>
24
26
28{
29public:
30 explicit QWaylandQuickCompositorPrivate(QWaylandCompositor *compositor)
33 {
34 }
35protected:
36 QWaylandSurface *createDefaultSurface() override
37 {
38 return new QWaylandQuickSurface();
39 }
40private:
41 QScopedPointer<QWaylandViewporter> m_viewporter;
42};
43
44QWaylandQuickCompositor::QWaylandQuickCompositor(QObject *parent)
45 : QWaylandCompositor(*new QWaylandQuickCompositorPrivate(this), parent)
46{
47}
48
49/*!
50 * \qmlproperty list QtWayland.Compositor::WaylandCompositor::extensions
51 *
52 * A list of extensions that the compositor advertises to its clients. For
53 * any Wayland extension the compositor should support, instantiate its component,
54 * and add it to the list of extensions.
55 *
56 * For instance, the following code would allow the clients to request \c wl_shell
57 * surfaces in the compositor using the \c wl_shell interface.
58 *
59 * \qml
60 * import QtWayland.Compositor
61 *
62 * WaylandCompositor {
63 * WlShell {
64 * // ...
65 * }
66 * }
67 * \endqml
68 */
69
70void QWaylandQuickCompositor::create()
71{
72 QWaylandCompositor::create();
73}
74
75
76void QWaylandQuickCompositor::classBegin()
77{
78 QWaylandCompositorPrivate::get(this)->preInit();
79}
80
81void QWaylandQuickCompositor::componentComplete()
82{
83 create();
84}
85
86/*!
87 * Grab the surface content from the given \a buffer.
88 * Reimplemented from QWaylandCompositor::grabSurface.
89 */
90void QWaylandQuickCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const QWaylandBufferRef &buffer)
91{
92 if (buffer.isSharedMemory()) {
93 QWaylandCompositor::grabSurface(grabber, buffer);
94 return;
95 }
96
97#if QT_CONFIG(opengl)
98 QWaylandQuickOutput *output = static_cast<QWaylandQuickOutput *>(defaultOutput());
99 if (!output) {
100 emit grabber->failed(QWaylandSurfaceGrabber::RendererNotReady);
101 return;
102 }
103
104 // We cannot grab the surface now, we need to have a current opengl context, so we
105 // need to be in the render thread
106 class GrabState : public QRunnable
107 {
108 public:
109 QWaylandSurfaceGrabber *grabber = nullptr;
110 QWaylandBufferRef buffer;
111
112 void run() override
113 {
114 QOpenGLFramebufferObject fbo(buffer.size());
115 fbo.bind();
116 QOpenGLTextureBlitter blitter;
117 blitter.create();
118
119 glViewport(0, 0, buffer.size().width(), buffer.size().height());
120
121 QOpenGLTextureBlitter::Origin surfaceOrigin =
122 buffer.origin() == QWaylandSurface::OriginTopLeft
123 ? QOpenGLTextureBlitter::OriginTopLeft
124 : QOpenGLTextureBlitter::OriginBottomLeft;
125
126 auto texture = buffer.toOpenGLTexture();
127 blitter.bind(texture->target());
128 blitter.blit(texture->textureId(), QMatrix4x4(), surfaceOrigin);
129 blitter.release();
130
131 emit grabber->success(fbo.toImage());
132 }
133 };
134
135 GrabState *state = new GrabState;
136 state->grabber = grabber;
137 state->buffer = buffer;
138 static_cast<QQuickWindow *>(output->window())->scheduleRenderJob(state, QQuickWindow::AfterRenderingStage);
139#else
140 emit grabber->failed(QWaylandSurfaceGrabber::UnknownBufferType);
141#endif
142}
143
144QT_END_NAMESPACE
145
146#include "moc_qwaylandquickcompositor.cpp"
QWaylandSurface * createDefaultSurface() override
QWaylandQuickCompositorPrivate(QWaylandCompositor *compositor)