Qt 6.x
The Qt SDK
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 <qpa/qplatformnativeinterface.h>
8#include <QtOpenGL/QOpenGLTexture>
9#include <QtGui/QGuiApplication>
10#include <QtGui/QOpenGLContext>
11#include <QtGui/QOffscreenSurface>
12#include <qpa/qplatformscreen.h>
13#include <QtGui/QWindow>
14#include <QtCore/QPointer>
15#include <QDebug>
16
17#include <QMutex>
18#include <QMutexLocker>
19#include <QVarLengthArray>
20#include <QtCore/private/qcore_unix_p.h>
21#include <QtGui/private/qeglstreamconvenience_p.h>
22
23#ifndef GL_TEXTURE_EXTERNAL_OES
24#define GL_TEXTURE_EXTERNAL_OES 0x8D65
25#endif
26
27#ifndef EGL_WAYLAND_BUFFER_WL
28#define EGL_WAYLAND_BUFFER_WL 0x31D5
29#endif
30
31#ifndef EGL_WAYLAND_EGLSTREAM_WL
32#define EGL_WAYLAND_EGLSTREAM_WL 0x334B
33#endif
34
35#ifndef EGL_WAYLAND_PLANE_WL
36#define EGL_WAYLAND_PLANE_WL 0x31D6
37#endif
38
39#ifndef EGL_WAYLAND_Y_INVERTED_WL
40#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB
41#endif
42
43#ifndef EGL_TEXTURE_RGB
44#define EGL_TEXTURE_RGB 0x305D
45#endif
46
47#ifndef EGL_TEXTURE_RGBA
48#define EGL_TEXTURE_RGBA 0x305E
49#endif
50
51#ifndef EGL_TEXTURE_EXTERNAL_WL
52#define EGL_TEXTURE_EXTERNAL_WL 0x31DA
53#endif
54
55#ifndef EGL_TEXTURE_Y_U_V_WL
56#define EGL_TEXTURE_Y_U_V_WL 0x31D7
57#endif
58
59#ifndef EGL_TEXTURE_Y_UV_WL
60#define EGL_TEXTURE_Y_UV_WL 0x31D8
61#endif
62
63#ifndef EGL_TEXTURE_Y_XUXV_WL
64#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
65#endif
66
67#ifndef EGL_PLATFORM_X11_KHR
68#define EGL_PLATFORM_X11_KHR 0x31D5
69#endif
70
71/* Needed for compatibility with Mesa older than 10.0. */
72typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL_compat) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
73
74#ifndef EGL_WL_bind_wayland_display
75typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
76typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
77#endif
78
79#ifndef EGL_KHR_image
80typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
81typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
82#endif
83
84#ifndef GL_OES_EGL_image
85typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
86typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
87#endif
88
90
91static const char *
92egl_error_string(EGLint code)
93{
94#define MYERRCODE(x) case x: return #x;
95 switch (code) {
96 MYERRCODE(EGL_SUCCESS)
97 MYERRCODE(EGL_NOT_INITIALIZED)
98 MYERRCODE(EGL_BAD_ACCESS)
99 MYERRCODE(EGL_BAD_ALLOC)
100 MYERRCODE(EGL_BAD_ATTRIBUTE)
101 MYERRCODE(EGL_BAD_CONTEXT)
102 MYERRCODE(EGL_BAD_CONFIG)
103 MYERRCODE(EGL_BAD_CURRENT_SURFACE)
104 MYERRCODE(EGL_BAD_DISPLAY)
105 MYERRCODE(EGL_BAD_SURFACE)
106 MYERRCODE(EGL_BAD_MATCH)
107 MYERRCODE(EGL_BAD_PARAMETER)
108 MYERRCODE(EGL_BAD_NATIVE_PIXMAP)
109 MYERRCODE(EGL_BAD_NATIVE_WINDOW)
110 MYERRCODE(EGL_CONTEXT_LOST)
111 default:
112 return "unknown";
113 }
114#undef MYERRCODE
115}
116
118{
119 BufferState() = default;
120
121 enum EglMode {
125 };
126
129 QOpenGLTexture *textures[3] = {nullptr, nullptr, nullptr};
130 QOpenGLContext *texturesContext[3] = {nullptr, nullptr, nullptr};
133
135
136 bool isYInverted = true;
139};
140
142{
143public:
145
148 bool ensureContext();
149 bool initEglStream(WaylandEglClientBuffer *buffer, struct ::wl_resource *bufferHandle);
151 void handleEglstreamTexture(WaylandEglClientBuffer *buffer, wl_resource *bufferHandle);
152 void registerBuffer(struct ::wl_resource *buffer, BufferState state);
156
157 EGLDisplay egl_display = EGL_NO_DISPLAY;
158 bool display_bound = false;
159 ::wl_display *wlDisplay = nullptr;
162
166
167
168 PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display = nullptr;
169 PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display = nullptr;
170 PFNEGLQUERYWAYLANDBUFFERWL_compat egl_query_wayland_buffer = nullptr;
171
172 PFNEGLCREATEIMAGEKHRPROC egl_create_image = nullptr;
173 PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image = nullptr;
174
175 PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d = nullptr;
176
179 return shuttingDown ? nullptr : integration->d_ptr.data();
180 }
181
182 static bool shuttingDown;
183};
184
186
188{
189}
190
192{
193 EGLint format;
194
195 if (egl_query_wayland_buffer(egl_display, buffer->waylandBufferHandle(), EGL_TEXTURE_FORMAT, &format))
197}
198
200{
201// Non-streaming case
202
203 // Resolving GL functions may need a context current, so do it only here.
205 gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
206
208 qCWarning(qLcWaylandCompositorHardwareIntegration)
209 << "BindTextureToBuffer() failed. Could not find glEGLImageTargetTexture2DOES.";
210 return;
211 }
212
213 BufferState &state = *buffer->d;
214 state.egl_format = format;
216
217#if defined(EGL_WAYLAND_Y_INVERTED_WL)
218 EGLint isYInverted;
219 EGLBoolean ret = egl_query_wayland_buffer(egl_display, buffer->waylandBufferHandle(), EGL_WAYLAND_Y_INVERTED_WL, &isYInverted);
220 // Yes, this looks strange, but the specification says that EGL_FALSE return
221 // value (not supported) should be treated the same as EGL_TRUE return value
222 // and EGL_TRUE in value.
223 state.isYInverted = (ret == EGL_FALSE || isYInverted == EGL_TRUE);
224#endif
225
226 int planes = 1;
227
228 switch (format) {
229 default:
230 case EGL_TEXTURE_RGB:
231 case EGL_TEXTURE_RGBA:
233 planes = 1;
234 break;
236 planes = 2;
237 break;
239 planes = 3;
240 break;
242 planes = 2;
243 break;
244 }
245
246 for (int i = 0; i < planes; i++) {
247 EGLint attribs[5] = { EGL_WAYLAND_PLANE_WL, i, EGL_NONE };
248#ifdef EGL_EXT_protected_content
249 if (buffer->isProtected()) {
250 attribs[2] = EGL_PROTECTED_CONTENT_EXT;
251 attribs[3] = EGL_TRUE;
252 attribs[4] = EGL_NONE;
253 }
254#endif
256 EGL_NO_CONTEXT,
258 buffer->waylandBufferHandle(),
259 attribs);
260
261 if (image == EGL_NO_IMAGE_KHR) {
262 qCWarning(qLcWaylandCompositorHardwareIntegration)
263 << "Failed to create EGL image for plane" << i;
264 }
265
266 state.egl_images << image;
267
268 QMutexLocker locker(&state.texturesLock);
269 state.textures[i] = nullptr;
270 }
271}
272
274{
275 bool localContextNeeded = false;
281 }
282 if (localContext) {
283 if (!offscreenSurface) {
287 }
289 localContextNeeded = true;
290 }
291 }
292 return localContextNeeded;
293}
294
295
297{
298 QMutexLocker locker(&bs->texturesLock);
299
300 bs->textures[plane] = texture;
302
303 Q_ASSERT(bs->texturesContext[plane] != nullptr);
304
305 qCDebug(qLcWaylandCompositorHardwareIntegration)
306 << Q_FUNC_INFO
307 << "(egl) creating a cleanup-lambda for QOpenGLContext::aboutToBeDestroyed!"
308 << ", texture: " << bs->textures[plane]
309 << ", ctx: " << (void*)bs->texturesContext[plane];
310
313 bs->texturesContext[plane], [bs, plane]() {
314
315 QMutexLocker locker(&bs->texturesLock);
316
317 // See above lock - there is a chance that this has already been removed from textures[plane]!
318 // Furthermore, we can trust that all the rest (e.g. disconnect) has also been properly executed!
319 if (bs->textures[plane] == nullptr)
320 return;
321
322 delete bs->textures[plane];
323
324 qCDebug(qLcWaylandCompositorHardwareIntegration)
325 << Q_FUNC_INFO
326 << "texture deleted due to QOpenGLContext::aboutToBeDestroyed!"
327 << "Pointer (now dead) was:" << (void*)(bs->textures[plane])
328 << " Associated context (about to die too) is: " << (void*)(bs->texturesContext[plane]);
329
330 bs->textures[plane] = nullptr;
331 bs->texturesContext[plane] = nullptr;
332
333 QObject::disconnect(bs->texturesAboutToBeDestroyedConnection[plane]);
334 bs->texturesAboutToBeDestroyedConnection[plane] = QMetaObject::Connection();
335
337}
338
340{
341 BufferState &state = *buffer->d;
342 state.egl_format = EGL_TEXTURE_EXTERNAL_WL;
343 state.isYInverted = false;
344
346
347 if (egl_query_wayland_buffer(egl_display, bufferHandle, EGL_WAYLAND_BUFFER_WL, &streamFd)) {
349 close(streamFd);
350 } else {
351 EGLAttrib stream_attribs[] = {
352 EGL_WAYLAND_EGLSTREAM_WL, (EGLAttrib)bufferHandle,
353 EGL_NONE
354 };
355 state.egl_stream = funcs->create_stream_attrib_nv(egl_display, stream_attribs);
356 }
357
358 if (state.egl_stream == EGL_NO_STREAM_KHR) {
359 qCWarning(qLcWaylandCompositorHardwareIntegration, "%s:%d: eglCreateStreamFromFileDescriptorKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError());
360 return false;
361 }
363
365 qCWarning(qLcWaylandCompositorHardwareIntegration)
366 << "EglClientBufferIntegration: creating texture with no current context";
367 return false;
368 }
369
371 texture->create();
373
374 qCDebug(qLcWaylandCompositorHardwareIntegration)
375 << " NEW texture! It's pointer and ctx pointer: "
376 << (void*)state.textures[0] << "; " << (void*)state.texturesContext[0];
377
378 texture->bind();
379
380 auto newStream = funcs->stream_consumer_gltexture(egl_display, state.egl_stream);
381 if (!newStream) {
382 EGLint code = eglGetError();
383 qCWarning(qLcWaylandCompositorHardwareIntegration) << "Could not initialize EGLStream:" << egl_error_string(code) << Qt::hex << (long)code;
385 state.egl_stream = EGL_NO_STREAM_KHR;
386 return false;
387 }
388 return true;
389}
390
392{
393 bool usingLocalContext = ensureContext();
394
395 if (buffer->d->eglMode == BufferState::ModeUninitialized) {
396 bool streamOK = initEglStream(buffer, bufferHandle);
397 if (!streamOK)
398 return;
399 }
400
401 BufferState &state = *buffer->d;
402 auto texture = state.textures[0];
403
404 // EGLStream requires calling acquire on every frame.
405 texture->bind();
406 EGLint stream_state;
407 funcs->query_stream(egl_display, state.egl_stream, EGL_STREAM_STATE_KHR, &stream_state);
408
409 if (stream_state == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR) {
410 if (funcs->stream_consumer_acquire(egl_display, state.egl_stream) != EGL_TRUE)
411 qCWarning(qLcWaylandCompositorHardwareIntegration,
412 "%s:%d: eglStreamConsumerAcquireKHR failed: 0x%x", Q_FUNC_INFO, __LINE__,
413 eglGetError());
414 }
415
416 if (usingLocalContext)
418}
419
422
423 Q_ASSERT(ctx != nullptr);
425
426 qCDebug(qLcWaylandCompositorHardwareIntegration)
427 << Q_FUNC_INFO << " got texture and ctx to be deleted!"
428 << (void*)texture << "; " << (void*)ctx;
429
432 ctx, [this, texture]() {
433 this->deleteSpecificOrphanedTexture(texture);
435}
436
438{
440
442
443 for (int i=0; i < orphanedTextures.size(); i++) {
444 qCDebug(qLcWaylandCompositorHardwareIntegration)
445 << Q_FUNC_INFO << " about to delete a texture: "
446 << (void*)orphanedTextures[i];
447 }
448
450
453
456}
457
459{
461
463
464 // In this case, deleteOrphanedTextures was called while we entered (see lock!) this function!
465 if (orphanedTextures.length()==0) {
466 qCWarning(qLcWaylandCompositorHardwareIntegration)
467 << Q_FUNC_INFO
468 << "Looks like deleteOrphanedTextures() and this function where called simultaneously!"
469 << "This might cause issues!";
470 return;
471 }
472
474 Q_ASSERT(i!=-1); // If it isn't empty (see above if), then it should be guaranteed to still contain this texture
475
478
480 delete texture;
481
482 qCDebug(qLcWaylandCompositorHardwareIntegration)
483 << Q_FUNC_INFO
484 << "texture deleted due to QOpenGLContext::aboutToBeDestroyed!"
485 << "Pointer (now dead) was:" << (void*)texture;
486}
487
490{
491}
492
494{
497 if (d->egl_unbind_wayland_display && d->display_bound) {
498 Q_ASSERT(d->wlDisplay);
499 if (!d->egl_unbind_wayland_display(d->egl_display, d->wlDisplay))
500 qCWarning(qLcWaylandCompositorHardwareIntegration) << "eglUnbindWaylandDisplayWL failed";
501 }
502}
503
505{
507
508 const bool ignoreBindDisplay = !qgetenv("QT_WAYLAND_IGNORE_BIND_DISPLAY").isEmpty();
509
511 if (!nativeInterface) {
512 qCWarning(qLcWaylandCompositorHardwareIntegration)
513 << "Failed to initialize EGL display. No native platform interface available.";
514 return;
515 }
516
517 d->egl_display = nativeInterface->nativeResourceForIntegration("EglDisplay");
518 if (!d->egl_display) {
519 qCWarning(qLcWaylandCompositorHardwareIntegration)
520 << "Failed to initialize EGL display. Could not get EglDisplay for window.";
521 return;
522 }
523
524 const char *extensionString = eglQueryString(d->egl_display, EGL_EXTENSIONS);
525 if ((!extensionString || !strstr(extensionString, "EGL_WL_bind_wayland_display")) && !ignoreBindDisplay) {
526 qCWarning(qLcWaylandCompositorHardwareIntegration)
527 << "Failed to initialize EGL display. There is no EGL_WL_bind_wayland_display extension.";
528 return;
529 }
530
531 d->egl_bind_wayland_display = reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL"));
532 d->egl_unbind_wayland_display = reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL"));
533 if ((!d->egl_bind_wayland_display || !d->egl_unbind_wayland_display) && !ignoreBindDisplay) {
534 qCWarning(qLcWaylandCompositorHardwareIntegration)
535 << "Failed to initialize EGL display. Could not find eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL.";
536 return;
537 }
538
539 d->egl_query_wayland_buffer = reinterpret_cast<PFNEGLQUERYWAYLANDBUFFERWL_compat>(eglGetProcAddress("eglQueryWaylandBufferWL"));
540 if (!d->egl_query_wayland_buffer) {
541 qCWarning(qLcWaylandCompositorHardwareIntegration)
542 << "Failed to initialize EGL display. Could not find eglQueryWaylandBufferWL.";
543 return;
544 }
545
546 d->egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
547 d->egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
548 if (!d->egl_create_image || !d->egl_destroy_image) {
549 qCWarning(qLcWaylandCompositorHardwareIntegration)
550 << "Failed to initialize EGL display. Could not find eglCreateImageKHR and eglDestroyImageKHR.";
551 return;
552 }
553
554 if (d->egl_bind_wayland_display && d->egl_unbind_wayland_display) {
555 d->display_bound = d->egl_bind_wayland_display(d->egl_display, display);
556 if (!d->display_bound)
557 qCDebug(qLcWaylandCompositorHardwareIntegration) << "Wayland display already bound by other client buffer integration.";
558 d->wlDisplay = display;
559 }
560
561 d->funcs = new QEGLStreamConvenience;
562 d->funcs->initialize(d->egl_display);
563}
564
566{
568 int w = -1;
569 bool q = d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WIDTH, &w);
570 if (!q || w <= 0)
571 return nullptr;
572 return new WaylandEglClientBuffer(this, buffer);
573}
574
576 : ClientBuffer(buffer)
577 , m_integration(integration)
578{
580 d = new BufferState;
581 if (buffer && !wl_shm_buffer_get(buffer)) {
582 EGLint width, height;
583 p->egl_query_wayland_buffer(p->egl_display, buffer, EGL_WIDTH, &width);
584 p->egl_query_wayland_buffer(p->egl_display, buffer, EGL_HEIGHT, &height);
585 d->size = QSize(width, height);
586
587 p->initBuffer(this);
588 }
589}
590
591
593{
595
596 if (p) {
597 for (auto image : d->egl_images)
598 p->egl_destroy_image(p->egl_display, image);
599
600 if (d->egl_stream)
601 p->funcs->destroy_stream(p->egl_display, d->egl_stream);
602
603
604 QMutexLocker locker(&d->texturesLock);
605
606 for (int i=0; i<3; i++) {
607 if (d->textures[i] != nullptr) {
608
609 qCDebug(qLcWaylandCompositorHardwareIntegration)
610 << Q_FUNC_INFO << " handing over texture!"
611 << (void*)d->textures[i] << "; " << (void*)d->texturesContext[i]
612 << " ... current context might be the same: " << QOpenGLContext::currentContext();
613
614 p->deleteGLTextureWhenPossible(d->textures[i], d->texturesContext[i]);
615 d->textures[i] = nullptr; // in case the aboutToBeDestroyed lambda is called while we where here
616 d->texturesContext[i] = nullptr;
619 }
620 }
621 }
622
623 delete d;
624}
625
627 switch (format) {
628 case EGL_TEXTURE_RGB:
630 case EGL_TEXTURE_RGBA:
640 }
641
643}
644
646 switch (format) {
647 case EGL_TEXTURE_RGB:
649 case EGL_TEXTURE_RGBA:
651 default:
653 }
654}
655
657{
659}
660
662{
664 // At this point we should have a valid OpenGL context, so it's safe to destroy textures
665 p->deleteOrphanedTextures();
666
667 if (!m_buffer)
668 return nullptr;
669
670 auto texture = d->textures[plane];
672 return texture; // EGLStreams texture is maintained by handle_eglstream_texture()
673
675 : GL_TEXTURE_2D);
676 if (!texture) {
679 texture->setSize(d->size.width(), d->size.height());
680 texture->create();
681 p->setupBufferAndCleanup(this->d, texture, plane);
682 }
683
684 if (m_textureDirty) {
685 m_textureDirty = false;
686 texture->bind();
687 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
688 p->gl_egl_image_target_texture_2d(target, d->egl_images[plane]);
689#ifdef GL_EXT_protected_textures
690 if (isProtected())
691 glTexParameteri(target, GL_TEXTURE_PROTECTED_EXT, GL_TRUE);
692#endif
693 }
694 return texture;
695}
696
698{
699 ClientBuffer::setCommitted(damage);
702 p->handleEglstreamTexture(this, waylandBufferHandle());
703 }
704}
705
707{
708 if (m_integration && m_buffer)
709 return m_integration->isProtected(m_buffer);
710
711 return false;
712}
713
714
716{
718}
719
721{
723
725 return 0;
726
727 EGLImageKHR image = p->egl_create_image(p->egl_display, EGL_NO_CONTEXT,
729 m_buffer, nullptr);
730 return reinterpret_cast<quintptr>(image);
731}
732
734{
735 if (!native_buffer)
736 return;
737
739
740 EGLImageKHR image = reinterpret_cast<EGLImageKHR>(native_buffer);
741 p->egl_destroy_image(p->egl_display, image);
742}
743
745{
746 return d->size;
747}
748
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:106
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()
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
void removeAt(qsizetype i)
Definition qlist.h:573
T takeAt(qsizetype i)
Definition qlist.h:592
qsizetype length() const noexcept
Definition qlist.h:388
void clear()
Definition qlist.h:417
\inmodule QtCore Represents a handle to a signal-slot (or signal-functor) connection.
\inmodule QtCore
Definition qmutex.h:317
\inmodule QtCore
Definition qmutex.h:285
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3099
\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.
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:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
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
void handleEglstreamTexture(WaylandEglClientBuffer *buffer, wl_resource *bufferHandle)
static WaylandEglClientBufferIntegrationPrivate * get(WaylandEglClientBufferIntegration *integration)
QList< QMetaObject::Connection > orphanedTexturesAboutToBeDestroyedConnection
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 deleteGLTextureWhenPossible(QOpenGLTexture *texture, QOpenGLContext *ctx)
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
qDeleteAll(list.begin(), list.end())
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:72
QObject::connect nullptr
BufferState()=default
QVarLengthArray< EGLImageKHR, 3 > egl_images
QMetaObject::Connection texturesAboutToBeDestroyedConnection[3]
QOpenGLContext * texturesContext[3]
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
Definition qlist.h:955
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