7#include <QtWaylandCompositor/QWaylandCompositor>
8#include <QtOpenGL/QOpenGLTexture>
9#include <QtGui/QGuiApplication>
10#include <QtGui/QOpenGLContext>
11#include <QtGui/QOffscreenSurface>
12#include <QtCore/QMutexLocker>
14#include <QtGui/private/qeglstreamconvenience_p.h>
15#include <qpa/qplatformnativeinterface.h>
17#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
18#include <QtWaylandCompositor/private/qwlbuffermanager_p.h>
19#include <QtWaylandCompositor/private/qwltextureorphanage_p.h>
22#include <EGL/eglext.h>
25#ifndef GL_TEXTURE_EXTERNAL_OES
26#define GL_TEXTURE_EXTERNAL_OES 0x8D65
29#ifndef EGL_WAYLAND_BUFFER_WL
30#define EGL_WAYLAND_BUFFER_WL 0x31D5
33#ifndef EGL_WAYLAND_EGLSTREAM_WL
34#define EGL_WAYLAND_EGLSTREAM_WL 0x334B
37#ifndef EGL_WAYLAND_PLANE_WL
38#define EGL_WAYLAND_PLANE_WL 0x31D6
41#ifndef EGL_WAYLAND_Y_INVERTED_WL
42#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB
45#ifndef EGL_TEXTURE_RGB
46#define EGL_TEXTURE_RGB 0x305D
49#ifndef EGL_TEXTURE_RGBA
50#define EGL_TEXTURE_RGBA 0x305E
53#ifndef EGL_TEXTURE_EXTERNAL_WL
54#define EGL_TEXTURE_EXTERNAL_WL 0x31DA
57#ifndef EGL_TEXTURE_Y_U_V_WL
58#define EGL_TEXTURE_Y_U_V_WL 0x31D7
61#ifndef EGL_TEXTURE_Y_UV_WL
62#define EGL_TEXTURE_Y_UV_WL 0x31D8
65#ifndef EGL_TEXTURE_Y_XUXV_WL
66#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
69#ifndef EGL_PLATFORM_X11_KHR
70#define EGL_PLATFORM_X11_KHR 0x31D5
78#ifndef EGL_WL_bind_wayland_display
86#define MYERRCODE(x) case x: return #x;
159 bool localContextNeeded =
false;
173 localContextNeeded =
true;
176 return localContextNeeded;
187 Q_ASSERT(bs->texturesContext[plane] !=
nullptr);
189 qCDebug(qLcWaylandCompositorHardwareIntegration)
191 <<
"(eglstream) creating a cleanup-lambda for QOpenGLContext::aboutToBeDestroyed!"
192 <<
", texture: " << bs->textures[plane]
193 <<
", ctx: " << (
void*)bs->texturesContext[plane];
195 bs->texturesAboutToBeDestroyedConnection[plane] =
197 bs->texturesContext[plane], [bs, plane]() {
199 QMutexLocker locker(&bs->texturesLock);
203 if (bs->textures[plane] == nullptr)
206 delete bs->textures[plane];
208 qCDebug(qLcWaylandCompositorHardwareIntegration)
210 <<
"texture deleted due to QOpenGLContext::aboutToBeDestroyed!"
211 <<
"Pointer (now dead) was:" << (void*)(bs->textures[plane])
212 <<
" Associated context (about to die too) is: " << (void*)(bs->texturesContext[plane]);
214 bs->textures[plane] = nullptr;
215 bs->texturesContext[plane] = nullptr;
217 QObject::disconnect(bs->texturesAboutToBeDestroyedConnection[plane]);
218 bs->texturesAboutToBeDestroyedConnection[plane] = QMetaObject::Connection();
227 state.isYInverted =
false;
243 qWarning(
"%s:%d: eglCreateStreamFromFileDescriptorKHR failed: 0x%x",
Q_FUNC_INFO, __LINE__, eglGetError());
258 if (usingLocalContext)
262 EGLint code = eglGetError();
285 qWarning(
"%s:%d: eglStreamConsumerAcquireKHR failed: 0x%x",
Q_FUNC_INFO, __LINE__, eglGetError());
288 if (usingLocalContext)
302 if (
d->egl_unbind_wayland_display !=
nullptr &&
d->display_bound) {
304 if (!
d->egl_unbind_wayland_display(
d->egl_display,
d->wlDisplay))
305 qCWarning(qLcWaylandCompositorHardwareIntegration) <<
"eglUnbindWaylandDisplayWL failed";
325 const bool ignoreBindDisplay = !
qgetenv(
"QT_WAYLAND_IGNORE_BIND_DISPLAY").isEmpty();
328 if (!nativeInterface) {
329 qWarning(
"QtCompositor: Failed to initialize EGL display. No native platform interface available.");
334 if (!
d->egl_display) {
335 qWarning(
"QtCompositor: Failed to initialize EGL display. Could not get EglDisplay for window.");
339 const char *extensionString = eglQueryString(
d->egl_display, EGL_EXTENSIONS);
340 if ((!extensionString || !strstr(extensionString,
"EGL_WL_bind_wayland_display")) && !ignoreBindDisplay) {
341 qWarning(
"QtCompositor: Failed to initialize EGL display. There is no EGL_WL_bind_wayland_display extension.");
345 d->egl_bind_wayland_display =
reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL
>(eglGetProcAddress(
"eglBindWaylandDisplayWL"));
346 d->egl_unbind_wayland_display =
reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL
>(eglGetProcAddress(
"eglUnbindWaylandDisplayWL"));
347 if ((!
d->egl_bind_wayland_display || !
d->egl_unbind_wayland_display) && !ignoreBindDisplay) {
348 qWarning(
"QtCompositor: Failed to initialize EGL display. Could not find eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL.");
352 d->egl_query_wayland_buffer =
reinterpret_cast<PFNEGLQUERYWAYLANDBUFFERWL_compat
>(eglGetProcAddress(
"eglQueryWaylandBufferWL"));
353 if (!
d->egl_query_wayland_buffer) {
354 qWarning(
"QtCompositor: Failed to initialize EGL display. Could not find eglQueryWaylandBufferWL.");
358 if (
d->egl_bind_wayland_display &&
d->egl_unbind_wayland_display) {
359 d->display_bound =
d->egl_bind_wayland_display(
d->egl_display,
display);
360 if (!
d->display_bound)
361 qCDebug(qLcWaylandCompositorHardwareIntegration) <<
"Wayland display already bound by other client buffer integration.";
374 if (wl_shm_buffer_get(
buffer))
383 , m_integration(integration)
389 p->egl_query_wayland_buffer(
p->egl_display,
buffer, EGL_WIDTH, &
width);
390 p->egl_query_wayland_buffer(
p->egl_display,
buffer, EGL_HEIGHT, &
height);
401 p->funcs->destroy_stream(
p->egl_display, d->
egl_stream);
407 for (
int i=0;
i<3;
i++) {
410 qCDebug(qLcWaylandCompositorHardwareIntegration)
458 ClientBuffer::setCommitted(damage);
460 p->handleEglstreamTexture(
this);
void initialize(EGLDisplay dpy)
PFNEGLQUERYSTREAMKHRPROC query_stream
PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC create_stream_from_file_descriptor
PFNEGLDESTROYSTREAMKHRPROC destroy_stream
PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC stream_consumer_gltexture
PFNEGLCREATESTREAMATTRIBNVPROC create_stream_attrib_nv
PFNEGLSTREAMCONSUMERACQUIREKHRPROC stream_consumer_acquire
static QPlatformNativeInterface * platformNativeInterface()
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
void create()
Allocates the platform resources associated with the offscreen surface.
void setFormat(const QSurfaceFormat &format)
Sets the offscreen surface format.
bool create()
Attempts to create the OpenGL context with the current configuration.
bool makeCurrent(QSurface *surface)
Makes the context current in the current thread, against the given surface.
QSurfaceFormat format() const
Returns the format of the underlying platform context, if create() has been called.
void setShareContext(QOpenGLContext *shareContext)
Makes this context share textures, shaders, and other OpenGL resources with shareContext.
void aboutToBeDestroyed()
This signal is emitted before the underlying native OpenGL context is destroyed, such that users may ...
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
void doneCurrent()
Convenience function for calling makeCurrent with a 0 surface.
static QOpenGLContext * globalShareContext()
Target
This enum defines the texture target of a QOpenGLTexture object.
void bind()
Binds this texture to the currently active texture unit ready for rendering.
The QRegion class specifies a clip region for a painter.
T * data() const noexcept
Returns the value of the pointer referenced by this object.
@ BufferFormatEgl_EXTERNAL_OES
static QWaylandCompositorPrivate * get(QWaylandCompositor *compositor)
Origin
This enum type is used to specify the origin of a QWaylandSurface's buffer.
QWaylandCompositor * m_compositor
struct::wl_resource * m_buffer
static QWaylandTextureOrphanage * instance()
QOffscreenSurface * offscreenSurface
WaylandEglStreamController * eglStreamController
QOpenGLContext * localContext
WaylandEglStreamClientBufferIntegrationPrivate()=default
bool initEglStream(WaylandEglStreamClientBuffer *buffer, struct ::wl_resource *bufferHandle)
PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display
PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display
void setupBufferAndCleanup(BufferState *bs, QOpenGLTexture *texture, int plane)
void handleEglstreamTexture(WaylandEglStreamClientBuffer *buffer)
PFNEGLQUERYWAYLANDBUFFERWL_compat egl_query_wayland_buffer
QEGLStreamConvenience * funcs
static WaylandEglStreamClientBufferIntegrationPrivate * get(WaylandEglStreamClientBufferIntegration *integration)
void initializeHardware(struct ::wl_display *display) override
void attachEglStreamConsumer(struct ::wl_resource *wl_surface, struct ::wl_resource *wl_buffer)
QtWayland::ClientBuffer * createBufferFor(wl_resource *buffer) override
WaylandEglStreamClientBufferIntegration()
~WaylandEglStreamClientBufferIntegration() override
QOpenGLTexture * toOpenGlTexture(int plane) override
QWaylandSurface::Origin origin() const override
~WaylandEglStreamClientBuffer() override
void setCommitted(QRegion &damage) override
QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const override
QSize size() const override
struct wl_display * display
Combined button and popup list for selecting options.
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
int EGLNativeFileDescriptorKHR
#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR
typedef EGLDisplay(EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform
#define EGL_STREAM_STATE_KHR
#define EGL_NO_STREAM_KHR
#define EGL_NO_FILE_DESCRIPTOR_KHR
#define qCWarning(category,...)
#define qCDebug(category,...)
GLint GLsizei GLsizei height
GLuint const GLuint GLuint const GLuint * textures
GLintptr GLsizeiptr GLeglClientBufferEXT clientBuffer
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QMetaObject::Connection texturesAboutToBeDestroyedConnection[3]
QOpenGLContext * texturesContext[3]
QOpenGLTexture * textures[3]
#define EGL_TEXTURE_EXTERNAL_WL
QT_BEGIN_NAMESPACE typedef struct wl_resource EGLint attribute
static const char * egl_error_string(EGLint code)
QT_BEGIN_NAMESPACE typedef EGLBoolean(EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL_compat)(EGLDisplay dpy
#define EGL_WAYLAND_BUFFER_WL
struct wl_display * display
QT_BEGIN_NAMESPACE typedef struct wl_resource * buffer
QT_BEGIN_NAMESPACE typedef struct wl_resource EGLint EGLint * value
#define GL_TEXTURE_EXTERNAL_OES
#define EGL_WAYLAND_EGLSTREAM_WL