Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
waylandeglclientbufferintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5
6#include <QtWaylandCompositor/QWaylandCompositor>
7#include <QtWaylandCompositor/private/qwltextureorphanage_p.h>
8#include <qpa/qplatformnativeinterface.h>
9#include <QtOpenGL/QOpenGLTexture>
10#include <QtGui/QGuiApplication>
11#include <QtGui/QOpenGLContext>
12#include <QtGui/QOffscreenSurface>
13#include <qpa/qplatformscreen.h>
14#include <QtGui/QWindow>
15#include <QtCore/QPointer>
16#include <QDebug>
17
18#include <QMutex>
19#include <QMutexLocker>
20#include <QVarLengthArray>
21#include <QtCore/private/qcore_unix_p.h>
22#include <QtGui/private/qeglstreamconvenience_p.h>
23
24#ifndef GL_TEXTURE_EXTERNAL_OES
25#define GL_TEXTURE_EXTERNAL_OES 0x8D65
26#endif
27
28#ifndef EGL_WAYLAND_BUFFER_WL
29#define EGL_WAYLAND_BUFFER_WL 0x31D5
30#endif
31
32#ifndef EGL_WAYLAND_EGLSTREAM_WL
33#define EGL_WAYLAND_EGLSTREAM_WL 0x334B
34#endif
35
36#ifndef EGL_WAYLAND_PLANE_WL
37#define EGL_WAYLAND_PLANE_WL 0x31D6
38#endif
39
40#ifndef EGL_WAYLAND_Y_INVERTED_WL
41#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB
42#endif
43
44#ifndef EGL_TEXTURE_RGB
45#define EGL_TEXTURE_RGB 0x305D
46#endif
47
48#ifndef EGL_TEXTURE_RGBA
49#define EGL_TEXTURE_RGBA 0x305E
50#endif
51
52#ifndef EGL_TEXTURE_EXTERNAL_WL
53#define EGL_TEXTURE_EXTERNAL_WL 0x31DA
54#endif
55
56#ifndef EGL_TEXTURE_Y_U_V_WL
57#define EGL_TEXTURE_Y_U_V_WL 0x31D7
58#endif
59
60#ifndef EGL_TEXTURE_Y_UV_WL
61#define EGL_TEXTURE_Y_UV_WL 0x31D8
62#endif
63
64#ifndef EGL_TEXTURE_Y_XUXV_WL
65#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
66#endif
67
68#ifndef EGL_PLATFORM_X11_KHR
69#define EGL_PLATFORM_X11_KHR 0x31D5
70#endif
71
72/* Needed for compatibility with Mesa older than 10.0. */
73typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL_compat) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
74
75#ifndef EGL_WL_bind_wayland_display
76typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
77typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
78#endif
79
80#ifndef EGL_KHR_image
81typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
82typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
83#endif
84
85#ifndef GL_OES_EGL_image
86typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
87typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
88#endif
89
91
92static const char *
93egl_error_string(EGLint code)
94{
95#define MYERRCODE(x) case x: return #x;
96 switch (code) {
97 MYERRCODE(EGL_SUCCESS)
98 MYERRCODE(EGL_NOT_INITIALIZED)
99 MYERRCODE(EGL_BAD_ACCESS)
100 MYERRCODE(EGL_BAD_ALLOC)
101 MYERRCODE(EGL_BAD_ATTRIBUTE)
102 MYERRCODE(EGL_BAD_CONTEXT)
103 MYERRCODE(EGL_BAD_CONFIG)
104 MYERRCODE(EGL_BAD_CURRENT_SURFACE)
105 MYERRCODE(EGL_BAD_DISPLAY)
106 MYERRCODE(EGL_BAD_SURFACE)
107 MYERRCODE(EGL_BAD_MATCH)
108 MYERRCODE(EGL_BAD_PARAMETER)
109 MYERRCODE(EGL_BAD_NATIVE_PIXMAP)
110 MYERRCODE(EGL_BAD_NATIVE_WINDOW)
111 MYERRCODE(EGL_CONTEXT_LOST)
112 default:
113 return "unknown";
114 }
115#undef MYERRCODE
116}
117
141
143{
144public:
146
149 bool ensureContext();
150 bool initEglStream(WaylandEglClientBuffer *buffer, struct ::wl_resource *bufferHandle);
152 void handleEglstreamTexture(WaylandEglClientBuffer *buffer, wl_resource *bufferHandle);
153 void registerBuffer(struct ::wl_resource *buffer, BufferState state);
154
155 EGLDisplay egl_display = EGL_NO_DISPLAY;
156 bool display_bound = false;
157 ::wl_display *wlDisplay = nullptr;
160
161 PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display = nullptr;
162 PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display = nullptr;
163 PFNEGLQUERYWAYLANDBUFFERWL_compat egl_query_wayland_buffer = nullptr;
164
165 PFNEGLCREATEIMAGEKHRPROC egl_create_image = nullptr;
166 PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image = nullptr;
167
168 PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d = nullptr;
169
172 return shuttingDown ? nullptr : integration->d_ptr.data();
173 }
174
175 static bool shuttingDown;
176};
177
179
183
191
193{
194// Non-streaming case
195
196 // Resolving GL functions may need a context current, so do it only here.
198 gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
199
201 qCWarning(qLcWaylandCompositorHardwareIntegration)
202 << "BindTextureToBuffer() failed. Could not find glEGLImageTargetTexture2DOES.";
203 return;
204 }
205
206 BufferState &state = *buffer->d;
209
210#if defined(EGL_WAYLAND_Y_INVERTED_WL)
211 EGLint isYInverted;
212 EGLBoolean ret = egl_query_wayland_buffer(egl_display, buffer->waylandBufferHandle(), EGL_WAYLAND_Y_INVERTED_WL, &isYInverted);
213 // Yes, this looks strange, but the specification says that EGL_FALSE return
214 // value (not supported) should be treated the same as EGL_TRUE return value
215 // and EGL_TRUE in value.
216 state.isYInverted = (ret == EGL_FALSE || isYInverted == EGL_TRUE);
217#endif
218
219 int planes = 1;
220
221 switch (format) {
222 default:
223 case EGL_TEXTURE_RGB:
224 case EGL_TEXTURE_RGBA:
226 planes = 1;
227 break;
229 planes = 2;
230 break;
232 planes = 3;
233 break;
235 planes = 2;
236 break;
237 }
238
239 for (int i = 0; i < planes; i++) {
240 EGLint attribs[5] = { EGL_WAYLAND_PLANE_WL, i, EGL_NONE };
241#ifdef EGL_EXT_protected_content
242 if (buffer->isProtected()) {
243 attribs[2] = EGL_PROTECTED_CONTENT_EXT;
244 attribs[3] = EGL_TRUE;
245 attribs[4] = EGL_NONE;
246 }
247#endif
249 EGL_NO_CONTEXT,
251 buffer->waylandBufferHandle(),
252 attribs);
253
254 if (image == EGL_NO_IMAGE_KHR) {
255 qCWarning(qLcWaylandCompositorHardwareIntegration)
256 << "Failed to create EGL image for plane" << i;
257 }
258
259 state.egl_images << image;
260
261 QMutexLocker locker(&state.texturesLock);
262 state.textures[i] = nullptr;
263 }
264}
265
267{
268 bool localContextNeeded = false;
274 }
275 if (localContext) {
276 if (!offscreenSurface) {
280 }
282 localContextNeeded = true;
283 }
284 }
285 return localContextNeeded;
286}
287
288
290{
291 QMutexLocker locker(&bs->texturesLock);
292
293 bs->textures[plane] = texture;
294 bs->texturesContext[plane] = QOpenGLContext::currentContext();
295
296 Q_ASSERT(bs->texturesContext[plane] != nullptr);
297
298 qCDebug(qLcWaylandCompositorHardwareIntegration)
299 << Q_FUNC_INFO
300 << "(egl) creating a cleanup-lambda for QOpenGLContext::aboutToBeDestroyed!"
301 << ", texture: " << bs->textures[plane]
302 << ", ctx: " << (void*)bs->texturesContext[plane];
303
304 bs->texturesAboutToBeDestroyedConnection[plane] =
305 QObject::connect(bs->texturesContext[plane], &QOpenGLContext::aboutToBeDestroyed,
306 bs->texturesContext[plane], [bs, plane]() {
307
308 QMutexLocker locker(&bs->texturesLock);
309
310 // See above lock - there is a chance that this has already been removed from textures[plane]!
311 // Furthermore, we can trust that all the rest (e.g. disconnect) has also been properly executed!
312 if (bs->textures[plane] == nullptr)
313 return;
314
315 delete bs->textures[plane];
316
317 qCDebug(qLcWaylandCompositorHardwareIntegration)
318 << Q_FUNC_INFO
319 << "texture deleted due to QOpenGLContext::aboutToBeDestroyed!"
320 << "Pointer (now dead) was:" << (void*)(bs->textures[plane])
321 << " Associated context (about to die too) is: " << (void*)(bs->texturesContext[plane]);
322
323 bs->textures[plane] = nullptr;
324 bs->texturesContext[plane] = nullptr;
325
326 QObject::disconnect(bs->texturesAboutToBeDestroyedConnection[plane]);
327 bs->texturesAboutToBeDestroyedConnection[plane] = QMetaObject::Connection();
328
330}
331
333{
334 BufferState &state = *buffer->d;
336 state.isYInverted = false;
337
339
340 if (egl_query_wayland_buffer(egl_display, bufferHandle, EGL_WAYLAND_BUFFER_WL, &streamFd)) {
342 close(streamFd);
343 } else {
344 EGLAttrib stream_attribs[] = {
345 EGL_WAYLAND_EGLSTREAM_WL, (EGLAttrib)bufferHandle,
346 EGL_NONE
347 };
348 state.egl_stream = funcs->create_stream_attrib_nv(egl_display, stream_attribs);
349 }
350
351 if (state.egl_stream == EGL_NO_STREAM_KHR) {
352 qCWarning(qLcWaylandCompositorHardwareIntegration, "%s:%d: eglCreateStreamFromFileDescriptorKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError());
353 return false;
354 }
356
358 qCWarning(qLcWaylandCompositorHardwareIntegration)
359 << "EglClientBufferIntegration: creating texture with no current context";
360 return false;
361 }
362
364 texture->create();
366
367 qCDebug(qLcWaylandCompositorHardwareIntegration)
368 << " NEW texture! It's pointer and ctx pointer: "
369 << (void*)state.textures[0] << "; " << (void*)state.texturesContext[0];
370
371 texture->bind();
372
373 auto newStream = funcs->stream_consumer_gltexture(egl_display, state.egl_stream);
374 if (!newStream) {
375 EGLint code = eglGetError();
376 qCWarning(qLcWaylandCompositorHardwareIntegration) << "Could not initialize EGLStream:" << egl_error_string(code) << Qt::hex << (long)code;
378 state.egl_stream = EGL_NO_STREAM_KHR;
379 return false;
380 }
381 return true;
382}
383
385{
386 bool usingLocalContext = ensureContext();
387
388 if (buffer->d->eglMode == BufferState::ModeUninitialized) {
389 bool streamOK = initEglStream(buffer, bufferHandle);
390 if (!streamOK)
391 return;
392 }
393
394 BufferState &state = *buffer->d;
395 auto texture = state.textures[0];
396
397 // EGLStream requires calling acquire on every frame.
398 texture->bind();
399 EGLint stream_state;
400 funcs->query_stream(egl_display, state.egl_stream, EGL_STREAM_STATE_KHR, &stream_state);
401
402 if (stream_state == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR) {
403 if (funcs->stream_consumer_acquire(egl_display, state.egl_stream) != EGL_TRUE)
404 qCWarning(qLcWaylandCompositorHardwareIntegration,
405 "%s:%d: eglStreamConsumerAcquireKHR failed: 0x%x", Q_FUNC_INFO, __LINE__,
406 eglGetError());
407 }
408
409 if (usingLocalContext)
411}
412
417
419{
422 if (d->egl_unbind_wayland_display && d->display_bound) {
423 Q_ASSERT(d->wlDisplay);
424 if (!d->egl_unbind_wayland_display(d->egl_display, d->wlDisplay))
425 qCWarning(qLcWaylandCompositorHardwareIntegration) << "eglUnbindWaylandDisplayWL failed";
426 }
427}
428
430{
432
433 const bool ignoreBindDisplay = !qgetenv("QT_WAYLAND_IGNORE_BIND_DISPLAY").isEmpty();
434
436 if (!nativeInterface) {
437 qCWarning(qLcWaylandCompositorHardwareIntegration)
438 << "Failed to initialize EGL display. No native platform interface available.";
439 return;
440 }
441
442 d->egl_display = nativeInterface->nativeResourceForIntegration("EglDisplay");
443 if (!d->egl_display) {
444 qCWarning(qLcWaylandCompositorHardwareIntegration)
445 << "Failed to initialize EGL display. Could not get EglDisplay for window.";
446 return;
447 }
448
449 const char *extensionString = eglQueryString(d->egl_display, EGL_EXTENSIONS);
450 if ((!extensionString || !strstr(extensionString, "EGL_WL_bind_wayland_display")) && !ignoreBindDisplay) {
451 qCWarning(qLcWaylandCompositorHardwareIntegration)
452 << "Failed to initialize EGL display. There is no EGL_WL_bind_wayland_display extension.";
453 return;
454 }
455
456 d->egl_bind_wayland_display = reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL"));
457 d->egl_unbind_wayland_display = reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL"));
458 if ((!d->egl_bind_wayland_display || !d->egl_unbind_wayland_display) && !ignoreBindDisplay) {
459 qCWarning(qLcWaylandCompositorHardwareIntegration)
460 << "Failed to initialize EGL display. Could not find eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL.";
461 return;
462 }
463
464 d->egl_query_wayland_buffer = reinterpret_cast<PFNEGLQUERYWAYLANDBUFFERWL_compat>(eglGetProcAddress("eglQueryWaylandBufferWL"));
465 if (!d->egl_query_wayland_buffer) {
466 qCWarning(qLcWaylandCompositorHardwareIntegration)
467 << "Failed to initialize EGL display. Could not find eglQueryWaylandBufferWL.";
468 return;
469 }
470
471 d->egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
472 d->egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
473 if (!d->egl_create_image || !d->egl_destroy_image) {
474 qCWarning(qLcWaylandCompositorHardwareIntegration)
475 << "Failed to initialize EGL display. Could not find eglCreateImageKHR and eglDestroyImageKHR.";
476 return;
477 }
478
479 if (d->egl_bind_wayland_display && d->egl_unbind_wayland_display) {
480 d->display_bound = d->egl_bind_wayland_display(d->egl_display, display);
481 if (!d->display_bound)
482 qCDebug(qLcWaylandCompositorHardwareIntegration) << "Wayland display already bound by other client buffer integration.";
483 d->wlDisplay = display;
484 }
485
486 d->funcs = new QEGLStreamConvenience;
487 d->funcs->initialize(d->egl_display);
488}
489
491{
493 int w = -1;
494 bool q = d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WIDTH, &w);
495 if (!q || w <= 0)
496 return nullptr;
497 return new WaylandEglClientBuffer(this, buffer);
498}
499
501 : ClientBuffer(buffer)
502 , m_integration(integration)
503{
505 d = new BufferState;
506 if (buffer && !wl_shm_buffer_get(buffer)) {
507 EGLint width, height;
508 p->egl_query_wayland_buffer(p->egl_display, buffer, EGL_WIDTH, &width);
509 p->egl_query_wayland_buffer(p->egl_display, buffer, EGL_HEIGHT, &height);
510 d->size = QSize(width, height);
511
512 p->initBuffer(this);
513 }
514}
515
516
518{
520
521 if (p) {
522 for (auto image : d->egl_images)
523 p->egl_destroy_image(p->egl_display, image);
524
525 if (d->egl_stream)
526 p->funcs->destroy_stream(p->egl_display, d->egl_stream);
527
528 }
529
530 {
531 QMutexLocker locker(&d->texturesLock);
532
533 for (int i=0; i<3; i++) {
534 if (d->textures[i] != nullptr) {
535
536 qCDebug(qLcWaylandCompositorHardwareIntegration)
537 << Q_FUNC_INFO << " handing over texture!"
538 << (void*)d->textures[i] << "; " << (void*)d->texturesContext[i]
539 << " ... current context might be the same: " << QOpenGLContext::currentContext();
540
542 d->textures[i], d->texturesContext[i]);
543 d->textures[i] = nullptr; // in case the aboutToBeDestroyed lambda is called while we where here
544 d->texturesContext[i] = nullptr;
547 }
548 }
549 }
550
551 delete d;
552}
553
572
574 switch (format) {
575 case EGL_TEXTURE_RGB:
577 case EGL_TEXTURE_RGBA:
579 default:
581 }
582}
583
588
590{
592 // At this point we should have a valid OpenGL context, so it's safe to destroy textures
594
595 if (!m_buffer)
596 return nullptr;
597
598 auto texture = d->textures[plane];
600 return texture; // EGLStreams texture is maintained by handle_eglstream_texture()
601
603 : GL_TEXTURE_2D);
604 if (!texture) {
607 texture->setSize(d->size.width(), d->size.height());
608 texture->create();
609 p->setupBufferAndCleanup(this->d, texture, plane);
610 }
611
612 if (m_textureDirty) {
613 m_textureDirty = false;
614 texture->bind();
615 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
616 p->gl_egl_image_target_texture_2d(target, d->egl_images[plane]);
617#ifdef GL_EXT_protected_textures
618 if (isProtected())
619 glTexParameteri(target, GL_TEXTURE_PROTECTED_EXT, GL_TRUE);
620#endif
621 }
622 return texture;
623}
624
626{
627 ClientBuffer::setCommitted(damage);
630 p->handleEglstreamTexture(this, waylandBufferHandle());
631 }
632}
633
635{
636 if (m_integration && m_buffer)
637 return m_integration->isProtected(m_buffer);
638
639 return false;
640}
641
642
647
649{
651
653 return 0;
654
655 EGLImageKHR image = p->egl_create_image(p->egl_display, EGL_NO_CONTEXT,
657 m_buffer, nullptr);
658 return reinterpret_cast<quintptr>(image);
659}
660
662{
663 if (!native_buffer)
664 return;
665
667
668 EGLImageKHR image = reinterpret_cast<EGLImageKHR>(native_buffer);
669 p->egl_destroy_image(p->egl_display, image);
670}
671
673{
674 return d->size;
675}
676
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()
\inmodule QtCore Represents a handle to a signal-slot (or signal-functor) connection.
\inmodule QtCore
Definition qmutex.h:313
\inmodule QtCore
Definition qmutex.h:281
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3236
\inmodule QtGui
void create()
Allocates the platform resources associated with the offscreen surface.
void setFormat(const QSurfaceFormat &format)
Sets the offscreen surface format.
\inmodule QtGui
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()
\inmodule QtGui
TextureFormat
This enum defines the possible texture formats.
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 QPlatformNativeInterface class provides an abstraction for retrieving native resource handles.
virtual void * nativeResourceForIntegration(const QByteArray &resource)
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
T * data() const noexcept
Returns the value of the pointer referenced by this object.
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
Origin
This enum type is used to specify the origin of a QWaylandSurface's buffer.
virtual bool isProtected(struct ::wl_resource *buffer)
virtual QImage image() const
struct::wl_resource * m_buffer
struct::wl_resource * waylandBufferHandle() const
static QWaylandTextureOrphanage * instance()
void handleEglstreamTexture(WaylandEglClientBuffer *buffer, wl_resource *bufferHandle)
static WaylandEglClientBufferIntegrationPrivate * get(WaylandEglClientBufferIntegration *integration)
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d
void initEglTexture(WaylandEglClientBuffer *buffer, EGLint format)
bool initEglStream(WaylandEglClientBuffer *buffer, struct ::wl_resource *bufferHandle)
void registerBuffer(struct ::wl_resource *buffer, BufferState state)
void setupBufferAndCleanup(BufferState *bs, QOpenGLTexture *texture, int plane)
void initializeHardware(struct ::wl_display *display) override
QtWayland::ClientBuffer * createBufferFor(wl_resource *buffer) override
QOpenGLTexture * toOpenGlTexture(int plane) override
WaylandEglClientBuffer(WaylandEglClientBufferIntegration *integration, wl_resource *bufferResource)
void unlockNativeBuffer(quintptr native_buffer) const override
QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const override
QWaylandSurface::Origin origin() const override
void setCommitted(QRegion &damage) override
else opt state
[0]
struct wl_display * display
Definition linuxdmabuf.h:41
Combined button and popup list for selecting options.
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
@ DirectConnection
Definition image.cpp:4
#define Q_FUNC_INFO
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
int EGLNativeFileDescriptorKHR
intptr_t EGLAttrib
#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
void * EGLStreamKHR
#define qCWarning(category,...)
#define qCDebug(category,...)
return ret
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLuint const GLuint GLuint const GLuint * textures
GLenum GLuint buffer
GLint GLsizei width
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLenum target
#define GL_TEXTURE_PROTECTED_EXT
GLenum GLuint texture
#define GL_APIENTRYP
#define GL_TEXTURE_EXTERNAL_OES
GLint GLsizei GLsizei GLenum format
void * GLeglImageOES
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
const GLint * attribs
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
size_t quintptr
Definition qtypes.h:167
QObject::connect nullptr
BufferState()=default
QVarLengthArray< EGLImageKHR, 3 > egl_images
QMetaObject::Connection texturesAboutToBeDestroyedConnection[3]
QOpenGLContext * texturesContext[3]
static QOpenGLTexture::TextureFormat openGLFormatFromEglFormat(EGLint format)
#define EGL_TEXTURE_EXTERNAL_WL
struct wl_resource EGLint EGLint * value
EGLContext EGLenum EGLClientBuffer const EGLint * attrib_list
typedef EGLBoolean(EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL_compat)(EGLDisplay dpy
struct wl_display * display
struct wl_resource * buffer
#define EGL_WAYLAND_Y_INVERTED_WL
#define MYERRCODE(x)
static QT_BEGIN_NAMESPACE const char * egl_error_string(EGLint code)
static QWaylandBufferRef::BufferFormatEgl formatFromEglFormat(EGLint format)
EGLContext EGLenum target
#define GL_TEXTURE_EXTERNAL_OES
#define EGL_WAYLAND_EGLSTREAM_WL
struct wl_resource EGLint attribute
#define EGL_TEXTURE_RGBA