4#include <qpa/qplatformopenglcontext.h>
5#include <qpa/qplatformintegration.h>
10#include <QtCore/QThreadStorage>
11#include <QtCore/QThread>
12#include <QtCore/private/qlocking_p.h>
14#include <QtGui/private/qguiapplication_p.h>
15#include <QtGui/private/qopengl_p.h>
16#include <QtGui/private/qwindow_p.h>
17#include <QtGui/QScreen>
18#include <qpa/qplatformnativeinterface.h>
20#include <private/qopenglextensions_p.h>
168 if (!threadContext) {
170 qWarning(
"No QTLS available. currentContext won't work");
177 qwindow_context_storage()->setLocalData(threadContext);
180 threadContext->context =
context;
193#if !QT_CONFIG(opengles2)
194 if (!
q->isOpenGLES()) {
252 return d->platformGLContext;
265 return d->shareContext->handle();
329 q->setScreen(
nullptr);
371 if (
d->platformGLContext)
375 if (!platformContext)
378 d->adopt(platformContext);
419void QOpenGLContext::destroy()
425 if (
d->platformGLContext)
429 if (
d->textureFunctionsDestroyCallback) {
430 d->textureFunctionsDestroyCallback();
431 d->textureFunctionsDestroyCallback =
nullptr;
433 d->textureFunctions =
nullptr;
435 delete d->versionFunctions;
436 d->versionFunctions =
nullptr;
438 if (
d->vaoHelperDestroyCallback) {
440 d->vaoHelperDestroyCallback(
d->vaoHelper);
441 d->vaoHelperDestroyCallback =
nullptr;
443 d->vaoHelper =
nullptr;
446 delete d->versionFunctions;
447 d->versionFunctions =
nullptr;
450 d->functions =
nullptr;
457 d->shareGroup->d_func()->removeContext(
this);
459 d->shareGroup =
nullptr;
461 delete d->platformGLContext;
462 d->platformGLContext =
nullptr;
520 return d->platformGLContext &&
d->platformGLContext->isValid();
574 if (
d->extensionNames.isEmpty()) {
576 d->extensionNames =
matcher.extensions();
579 return d->extensionNames;
625 if (!
d->surface || !
d->surface->surfaceHandle())
628 if (
d->defaultFboRedirect)
629 return d->defaultFboRedirect;
631 return d->platformGLContext->defaultFramebufferObject(
d->surface->surfaceHandle());
665 qFatal(
"Cannot make QOpenGLContext current in a different thread");
676 qWarning() <<
"QOpenGLContext::makeCurrent() called with non-opengl surface" <<
surface;
690 static bool needsWorkaroundSet =
false;
691 static bool needsWorkaround =
false;
693 if (!needsWorkaroundSet) {
701 needsWorkaround =
true;
703 if (!needsWorkaround) {
704 const char *rendererString =
reinterpret_cast<const char *
>(
functions()->
glGetString(GL_RENDERER));
707 qstrncmp(rendererString,
"Mali-4xx", 6) == 0
708 ||
qstrcmp(rendererString,
"Mali-T880") == 0
709 ||
qstrncmp(rendererString,
"Adreno (TM) 2xx", 13) == 0
710 ||
qstrncmp(rendererString,
"Adreno 2xx", 8) == 0
711 ||
qstrncmp(rendererString,
"Adreno (TM) 3xx", 13) == 0
712 ||
qstrncmp(rendererString,
"Adreno 3xx", 8) == 0
713 ||
qstrncmp(rendererString,
"Adreno (TM) 4xx", 13) == 0
714 ||
qstrncmp(rendererString,
"Adreno 4xx", 8) == 0
715 ||
qstrncmp(rendererString,
"Adreno (TM) 5xx", 13) == 0
716 ||
qstrncmp(rendererString,
"Adreno 5xx", 8) == 0
717 ||
qstrncmp(rendererString,
"Adreno (TM) 6xx", 13) == 0
718 ||
qstrncmp(rendererString,
"Adreno 6xx", 8) == 0
719 ||
qstrcmp(rendererString,
"GC800 core") == 0
720 ||
qstrcmp(rendererString,
"GC1000 core") == 0
721 || strstr(rendererString,
"GC2000") !=
nullptr
722 ||
qstrcmp(rendererString,
"Immersion.16") == 0
723 ||
qstrncmp(rendererString,
"Apple Mx", 7) == 0;
725 needsWorkaroundSet =
true;
729 d->workaround_brokenFBOReadBack =
true;
731 d->shareGroup->d_func()->deletePendingResources(
this);
750 d->shareGroup->d_func()->deletePendingResources(
this);
752 d->platformGLContext->doneCurrent();
755 d->surface =
nullptr;
784 qWarning(
"QOpenGLContext::swapBuffers() called with null argument");
789 qWarning(
"QOpenGLContext::swapBuffers() called with non-opengl surface");
797#if !defined(QT_NO_DEBUG)
799 qWarning(
"QOpenGLContext::swapBuffers() called without corresponding makeCurrent()");
803 d->platformGLContext->swapBuffers(surfaceHandle);
823 if (!
d->platformGLContext)
825 return d->platformGLContext->getProcAddress(procName);
850 if (!
d->platformGLContext)
851 return d->requestedFormat;
852 return d->platformGLContext->format();
861 return d->shareGroup;
873 return d->shareContext;
913#if defined(QT_OPENGL_DYNAMIC)
916#elif QT_CONFIG(opengles2)
984 return d->textureFunctions;
990void QOpenGLContext::setTextureFunctions(
QOpenGLTextureHelper* textureFuncs, std::function<
void()> destroyCallback)
993 d->textureFunctions = textureFuncs;
994 d->textureFunctionsDestroyCallback = destroyCallback;
1010QOpenGLContextGroup::QOpenGLContextGroup()
1041 return current ? current->
shareGroup() :
nullptr;
1049 const auto locker = qt_scoped_lock(
m_mutex);
1058 bool deleteObject =
false;
1061 const auto locker = qt_scoped_lock(
m_mutex);
1069 deleteObject =
true;
1088 it.key()->cleanup(
q,
it.value());
1096 (*it)->invalidateResource();
1097 (*it)->m_group =
nullptr;
1109 const auto locker = qt_scoped_lock(
m_mutex);
1117 (*it)->freeResource(
ctx);
1150 const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
1151 m_group->d_func()->m_sharedResources <<
this;
1166 const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
1167 m_group->d_func()->m_sharedResources.removeOne(
this);
1168 m_group->d_func()->m_pendingDeletion <<
this;
1172 if (current && current->
shareGroup() == m_group) {
1173 m_group->d_func()->deletePendingResources(current);
1196 m_func(&functions, m_id);
1220#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
1221 qDebug(
"Creating context group resource object %p.",
this);
1227#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
1228 qDebug(
"Deleting context group resource %p. Group size: %d.",
this, m_groups.
size());
1230 for (
int i = 0;
i < m_groups.
size(); ++
i) {
1237 m_groups.
at(
i)->d_func()->m_resources.remove(
this);
1242 qWarning(
"QtGui: Resources are still available at program shutdown.\n"
1243 " This is possibly caused by a leaked QOpenGLWidget, \n"
1244 " QOpenGLFramebufferObject or QOpenGLPixelBuffer.");
1251#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
1252 qDebug(
"Inserting context group resource %p for context %p, managed by %p.",
value,
context,
this);
1256 group->d_func()->m_resources.insert(
this,
value);
1264 return group->d_func()->m_resources.value(
this,
nullptr);
1269 QList<QOpenGLSharedResource *>
result;
1280#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
1283 value->invalidateResource();
1294#ifndef QT_NO_DEBUG_STREAM
1300 debug <<
"QOpenGLContext(";
1302 debug << static_cast<const void *>(
ctx);
1303 if (
ctx->isValid()) {
1304 debug <<
", format=" <<
ctx->format();
1306 debug <<
", surface=" << sf;
1308 debug <<
", screen=\"" <<
s->name() <<
'"';
1310 debug <<
", invalid";
1323 debug <<
"QOpenGLContextGroup(";
1335void *QOpenGLContext::resolveInterface(
const char *
name,
int revision)
const
1339 auto *platformContext =
handle();
1342#if defined(Q_OS_MACOS)
1345#if defined(Q_OS_WIN)
1348#if QT_CONFIG(xcb_glx_plugin)
1360#include "moc_qopenglcontext.cpp"
T loadRelaxed() const noexcept
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static QPlatformIntegration * platformIntegration()
static QGuiApplicationPrivate * instance()
QScreen * primaryScreen
the primary (or default) screen of the application.
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
const_iterator constBegin() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
qsizetype size() const noexcept
bool isEmpty() const noexcept
bool removeOne(const AT &t)
const_reference at(qsizetype i) const noexcept
const_iterator constBegin() const noexcept
const T & constFirst() const noexcept
void append(parameter_type t)
const_iterator constEnd() const noexcept
\inheaderfile QOpenGLContext
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
QThread * thread() const
Returns the thread in which the object lives.
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
QHash< QOpenGLMultiGroupSharedResource *, QOpenGLSharedResource * > m_resources
void removeContext(QOpenGLContext *ctx)
~QOpenGLContextGroupPrivate() override
void deletePendingResources(QOpenGLContext *ctx)
QList< QOpenGLSharedResource * > m_sharedResources
QList< QOpenGLContext * > m_shares
QList< QOpenGLSharedResource * > m_pendingDeletion
QOpenGLContext * m_context
void addContext(QOpenGLContext *ctx)
The QOpenGLContextGroup class represents a group of contexts sharing OpenGL resources....
static QOpenGLContextGroup * currentContextGroup()
Returns the QOpenGLContextGroup corresponding to the current context.
QList< QOpenGLContext * > shares() const
Returns all the QOpenGLContext objects in this share group.
QOpenGLContextGroup * shareGroup
static void cleanMakeCurrentTracker(QOpenGLContext *context)
void _q_screenDestroyed(QObject *object)
QOpenGLContext * shareContext
QPlatformOpenGLContext * platformGLContext
static QOpenGLContext * setCurrentContext(QOpenGLContext *context)
~QOpenGLContextPrivate() override
static QMutex makeCurrentTrackerMutex
void adopt(QPlatformOpenGLContext *)
static bool toggleMakeCurrentTracker(QOpenGLContext *context, bool value)
static QHash< QOpenGLContext *, bool > makeCurrentTracker
virtual ~QOpenGLContextVersionFunctionHelper()
QFunctionPointer getProcAddress(const QByteArray &procName) const
Resolves the function pointer to an OpenGL extension function, identified by procName.
bool create()
Attempts to create the OpenGL context with the current configuration.
void setScreen(QScreen *screen)
Sets the screen the OpenGL context should be valid for.
bool isValid() const
Returns if this context is valid, i.e.
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.
QOpenGLContext(QObject *parent=nullptr)
Creates a new OpenGL context instance with parent object parent.
QOpenGLContext * shareContext() const
Returns the share context this context was created with.
QSet< QByteArray > extensions() const
Returns the set of OpenGL extensions supported by this context.
QPlatformOpenGLContext * handle() const
Returns the underlying platform context.
QOpenGLContextGroup * shareGroup() const
Returns the share group this context belongs to.
QOpenGLExtraFunctions * extraFunctions() const
Get the QOpenGLExtraFunctions instance for this context.
static OpenGLModuleType openGLModuleType()
Returns the underlying OpenGL implementation type.
void setShareContext(QOpenGLContext *shareContext)
Makes this context share textures, shaders, and other OpenGL resources with shareContext.
OpenGLModuleType
This enum defines the type of the underlying OpenGL implementation.
void aboutToBeDestroyed()
This signal is emitted before the underlying native OpenGL context is destroyed, such that users may ...
GLuint defaultFramebufferObject() const
Call this to get the default framebuffer object for the current surface.
void setFormat(const QSurfaceFormat &format)
Sets the format the OpenGL context should be compatible with.
bool hasExtension(const QByteArray &extension) const
Returns true if this OpenGL context supports the specified OpenGL extension, false otherwise.
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 bool areSharing(QOpenGLContext *first, QOpenGLContext *second)
Returns true if the first and second contexts are sharing OpenGL resources.
static QOpenGLContext * globalShareContext()
QScreen * screen() const
Returns the screen the context was created for.
QPlatformOpenGLContext * shareHandle() const
Returns the underlying platform context with which this context is sharing.
QOpenGLFunctions * functions() const
Get the QOpenGLFunctions instance for this context.
QSurface * surface() const
Returns the surface the context has been made current with.
static bool supportsThreadedOpenGL()
Returns true if the platform supports OpenGL rendering outside the main (gui) thread.
void swapBuffers(QSurface *surface)
Swap the back and front buffers of surface.
bool isOpenGLES() const
Returns true if the context is an OpenGL ES context.
~QOpenGLContext()
Destroys the QOpenGLContext object.
The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.
const GLubyte * glGetString(GLenum name)
Convenience function that calls glGetString(name).
void glFlush()
Convenience function that calls glFlush().
The QOpenGLMultiGroupSharedResource keeps track of a shared resource that might be needed from multip...
void cleanup(QOpenGLContextGroup *group, QOpenGLSharedResource *value)
~QOpenGLMultiGroupSharedResource()
QOpenGLMultiGroupSharedResource()
QList< QOpenGLSharedResource * > resources() const
QOpenGLSharedResource * value(QOpenGLContext *context)
void insert(QOpenGLContext *context, QOpenGLSharedResource *value)
~QOpenGLSharedResourceGuard() override
void freeResource(QOpenGLContext *context) override
The QOpenGLSharedResource class is used to keep track of resources that are shared between OpenGL con...
QOpenGLSharedResource(QOpenGLContextGroup *group)
virtual ~QOpenGLSharedResource()=0
The QPlatformOpenGLContext class provides an abstraction for native GL contexts.
virtual void initialize()
Called after a new instance is constructed.
virtual bool isSharing() const
The QScreen class is used to query screen properties. \inmodule QtGui.
bool contains(const T &value) const
virtual QPlatformSurface * surfaceHandle() const =0
Returns a handle to the platform-specific implementation of the surface.
bool supportsOpenGL() const
Returns true if the surface is OpenGL compatible and can be used in conjunction with QOpenGLContext; ...
virtual QSurfaceFormat format() const =0
Returns the format of the surface.
static QThread * currentThread()
static VulkanServerBufferGlFunctions * funcs
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
Combined button and popup list for selecting options.
@ AA_DontCheckOpenGLContextThreadAffinity
#define QByteArrayLiteral(str)
int qstrncmp(const char *str1, const char *str2, size_t len)
Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2)
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 return DBusPendingCall * pending
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define QT_NATIVE_INTERFACE_RETURN_IF(NativeInterface, baseType)
QOpenGLContext * qt_gl_global_share_context()
void qt_gl_set_global_share_context(QOpenGLContext *context)
static QOpenGLContext * global_share_context
QDebug operator<<(QDebug debug, const QOpenGLContext *ctx)
typedef GLint(GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC)(GLuint program
GLenum GLuint GLintptr GLsizeiptr size
[1]
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLint GLsizei GLsizei GLenum format
const void * getProcAddress
GLdouble GLdouble GLdouble GLdouble q
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
myObject disconnect()
[26]
static const auto matcher
[0]
bool contains(const AT &t) const noexcept