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>
152 if (!threadContext) {
154 qWarning(
"No QTLS available. currentContext won't work");
158 qwindow_context_storage()->setLocalData(threadContext);
174#if !QT_CONFIG(opengles2)
175 if (!
q->isOpenGLES()) {
233 return d->platformGLContext;
246 return d->shareContext->handle();
310 q->setScreen(
nullptr);
352 if (
d->platformGLContext)
356 if (!platformContext)
359 d->adopt(platformContext);
400void QOpenGLContext::destroy()
406 if (
d->platformGLContext)
410 if (
d->textureFunctionsDestroyCallback) {
411 d->textureFunctionsDestroyCallback();
412 d->textureFunctionsDestroyCallback =
nullptr;
414 d->textureFunctions =
nullptr;
416 delete d->versionFunctions;
417 d->versionFunctions =
nullptr;
419 if (
d->vaoHelperDestroyCallback) {
421 d->vaoHelperDestroyCallback(
d->vaoHelper);
422 d->vaoHelperDestroyCallback =
nullptr;
424 d->vaoHelper =
nullptr;
427 delete d->versionFunctions;
428 d->versionFunctions =
nullptr;
431 d->functions =
nullptr;
438 d->shareGroup->d_func()->removeContext(
this);
440 d->shareGroup =
nullptr;
442 delete d->platformGLContext;
443 d->platformGLContext =
nullptr;
496 return d->platformGLContext &&
d->platformGLContext->isValid();
550 if (
d->extensionNames.isEmpty()) {
552 d->extensionNames =
matcher.extensions();
555 return d->extensionNames;
601 if (!
d->surface || !
d->surface->surfaceHandle())
604 if (
d->defaultFboRedirect)
605 return d->defaultFboRedirect;
607 return d->platformGLContext->defaultFramebufferObject(
d->surface->surfaceHandle());
641 qFatal(
"Cannot make QOpenGLContext current in a different thread");
652 qWarning() <<
"QOpenGLContext::makeCurrent() called with non-opengl surface" <<
surface;
666 static bool needsWorkaroundSet =
false;
667 static bool needsWorkaround =
false;
669 if (!needsWorkaroundSet) {
677 needsWorkaround =
true;
679 if (!needsWorkaround) {
680 const char *rendererString =
reinterpret_cast<const char *
>(
functions()->
glGetString(GL_RENDERER));
683 qstrncmp(rendererString,
"Mali-4xx", 6) == 0
684 ||
qstrcmp(rendererString,
"Mali-T880") == 0
685 ||
qstrncmp(rendererString,
"Adreno (TM) 2xx", 13) == 0
686 ||
qstrncmp(rendererString,
"Adreno 2xx", 8) == 0
687 ||
qstrncmp(rendererString,
"Adreno (TM) 3xx", 13) == 0
688 ||
qstrncmp(rendererString,
"Adreno 3xx", 8) == 0
689 ||
qstrncmp(rendererString,
"Adreno (TM) 4xx", 13) == 0
690 ||
qstrncmp(rendererString,
"Adreno 4xx", 8) == 0
691 ||
qstrncmp(rendererString,
"Adreno (TM) 5xx", 13) == 0
692 ||
qstrncmp(rendererString,
"Adreno 5xx", 8) == 0
693 ||
qstrncmp(rendererString,
"Adreno (TM) 6xx", 13) == 0
694 ||
qstrncmp(rendererString,
"Adreno 6xx", 8) == 0
695 ||
qstrcmp(rendererString,
"GC800 core") == 0
696 ||
qstrcmp(rendererString,
"GC1000 core") == 0
697 || strstr(rendererString,
"GC2000") !=
nullptr
698 ||
qstrcmp(rendererString,
"Immersion.16") == 0
699 ||
qstrncmp(rendererString,
"Apple Mx", 7) == 0;
701 needsWorkaroundSet =
true;
705 d->workaround_brokenFBOReadBack =
true;
707 d->shareGroup->d_func()->deletePendingResources(
this);
726 d->shareGroup->d_func()->deletePendingResources(
this);
728 d->platformGLContext->doneCurrent();
731 d->surface =
nullptr;
760 qWarning(
"QOpenGLContext::swapBuffers() called with null argument");
765 qWarning(
"QOpenGLContext::swapBuffers() called with non-opengl surface");
773#if !defined(QT_NO_DEBUG)
775 qWarning(
"QOpenGLContext::swapBuffers() called without corresponding makeCurrent()");
779 d->platformGLContext->swapBuffers(surfaceHandle);
799 if (!
d->platformGLContext)
801 return d->platformGLContext->getProcAddress(procName);
826 if (!
d->platformGLContext)
827 return d->requestedFormat;
828 return d->platformGLContext->format();
837 return d->shareGroup;
849 return d->shareContext;
889#if defined(QT_OPENGL_DYNAMIC)
892#elif QT_CONFIG(opengles2)
960 return d->textureFunctions;
966void QOpenGLContext::setTextureFunctions(
QOpenGLTextureHelper* textureFuncs, std::function<
void()> destroyCallback)
969 d->textureFunctions = textureFuncs;
970 d->textureFunctionsDestroyCallback = destroyCallback;
986QOpenGLContextGroup::QOpenGLContextGroup()
1017 return current ? current->
shareGroup() :
nullptr;
1025 const auto locker = qt_scoped_lock(
m_mutex);
1034 bool deleteObject =
false;
1037 const auto locker = qt_scoped_lock(
m_mutex);
1045 deleteObject =
true;
1064 it.key()->cleanup(
q,
it.value());
1072 (*it)->invalidateResource();
1073 (*it)->m_group =
nullptr;
1085 const auto locker = qt_scoped_lock(
m_mutex);
1093 (*it)->freeResource(
ctx);
1126 const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
1127 m_group->d_func()->m_sharedResources <<
this;
1142 const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
1143 m_group->d_func()->m_sharedResources.removeOne(
this);
1144 m_group->d_func()->m_pendingDeletion <<
this;
1148 if (current && current->
shareGroup() == m_group) {
1149 m_group->d_func()->deletePendingResources(current);
1172 m_func(&functions, m_id);
1196#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
1197 qDebug(
"Creating context group resource object %p.",
this);
1203#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
1204 qDebug(
"Deleting context group resource %p. Group size: %d.",
this, m_groups.
size());
1206 for (
int i = 0;
i < m_groups.
size(); ++
i) {
1213 m_groups.
at(
i)->d_func()->m_resources.remove(
this);
1218 qWarning(
"QtGui: Resources are still available at program shutdown.\n"
1219 " This is possibly caused by a leaked QOpenGLWidget, \n"
1220 " QOpenGLFramebufferObject or QOpenGLPixelBuffer.");
1227#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
1228 qDebug(
"Inserting context group resource %p for context %p, managed by %p.",
value,
context,
this);
1232 group->d_func()->m_resources.insert(
this,
value);
1240 return group->d_func()->m_resources.value(
this,
nullptr);
1256#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
1259 value->invalidateResource();
1270#ifndef QT_NO_DEBUG_STREAM
1276 debug <<
"QOpenGLContext(";
1278 debug << static_cast<const void *>(
ctx);
1279 if (
ctx->isValid()) {
1280 debug <<
", format=" <<
ctx->format();
1282 debug <<
", surface=" << sf;
1284 debug <<
", screen=\"" <<
s->name() <<
'"';
1286 debug <<
", invalid";
1299 debug <<
"QOpenGLContextGroup(";
1311void *QOpenGLContext::resolveInterface(
const char *
name,
int revision)
const
1315 auto *platformContext =
handle();
1318#if defined(Q_OS_MACOS)
1321#if defined(Q_OS_WIN)
1324#if QT_CONFIG(xcb_glx_plugin)
1336#include "moc_qopenglcontext.cpp"
T loadRelaxed() const noexcept
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
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
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent