13#include <QtGui/QGuiApplication>
14#include <QtGui/QOpenGLContext>
16#import <OpenGLES/EAGL.h>
17#import <OpenGLES/ES2/glext.h>
18#import <QuartzCore/CAEAGLLayer.h>
32 EAGLSharegroup *shareGroup = m_sharedContext ? [m_sharedContext->m_eaglContext sharegroup] : nil;
33 const int preferredVersion = m_format.
majorVersion() == 1 ? kEAGLRenderingAPIOpenGLES1 : kEAGLRenderingAPIOpenGLES3;
34 for (
int version = preferredVersion; !m_eaglContext && version >= m_format.
majorVersion(); --version)
35 m_eaglContext = [[EAGLContext alloc] initWithAPI:EAGLRenderingAPI(version) sharegroup:shareGroup];
37 if (m_eaglContext != nil) {
38 EAGLContext *originalContext = [EAGLContext currentContext];
39 [EAGLContext setCurrentContext:m_eaglContext];
40 const GLubyte *
s = glGetString(GL_VERSION);
49 [EAGLContext setCurrentContext:originalContext];
58 qCDebug(lcQpaGLContext) <<
"created context with format" << m_format <<
"shared with" << m_sharedContext;
63 [EAGLContext setCurrentContext:m_eaglContext];
65 foreach (
const FramebufferObject &framebufferObject, m_framebufferObjects)
66 deleteBuffers(framebufferObject);
68 [EAGLContext setCurrentContext:nil];
72void QIOSContext::deleteBuffers(
const FramebufferObject &framebufferObject)
74 if (framebufferObject.handle)
75 glDeleteFramebuffers(1, &framebufferObject.handle);
76 if (framebufferObject.colorRenderbuffer)
77 glDeleteRenderbuffers(1, &framebufferObject.colorRenderbuffer);
78 if (framebufferObject.depthRenderbuffer)
79 glDeleteRenderbuffers(1, &framebufferObject.depthRenderbuffer);
87#define QT_IOS_GL_STATUS_CASE(val) case val: return QLatin1StringView(#val)
101#define Q_ASSERT_IS_GL_SURFACE(surface) \
102 Q_ASSERT(surface && (surface->surface()->surfaceType() & (QSurface::OpenGLSurface | QSurface::RasterGLSurface)))
108 if (!verifyGraphicsHardwareAvailability())
111 [EAGLContext setCurrentContext:m_eaglContext];
118 FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface);
120 if (!framebufferObject.handle) {
122 glGenFramebuffers(1, &framebufferObject.handle);
125 glGenRenderbuffers(1, &framebufferObject.colorRenderbuffer);
126 glBindRenderbuffer(
GL_RENDERBUFFER, framebufferObject.colorRenderbuffer);
128 framebufferObject.colorRenderbuffer);
131 glGenRenderbuffers(1, &framebufferObject.depthRenderbuffer);
132 glBindRenderbuffer(
GL_RENDERBUFFER, framebufferObject.depthRenderbuffer);
134 framebufferObject.depthRenderbuffer);
138 framebufferObject.depthRenderbuffer);
144 if (needsRenderbufferResize(surface)) {
147 qCDebug(lcQpaGLContext,
"Reallocating renderbuffer storage - current: %dx%d, layer: %gx%g",
148 framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight,
151 glBindRenderbuffer(
GL_RENDERBUFFER, framebufferObject.colorRenderbuffer);
157 if (framebufferObject.depthRenderbuffer) {
158 glBindRenderbuffer(
GL_RENDERBUFFER, framebufferObject.depthRenderbuffer);
163 framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight);
166 framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight);
171 if (!framebufferObject.isComplete) {
172 qCWarning(lcQpaGLContext,
"QIOSContext failed to make complete framebuffer object (%s)",
177 return framebufferObject.isComplete;
182 [EAGLContext setCurrentContext:nil];
189 if (!verifyGraphicsHardwareAvailability())
195 FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface);
196 Q_ASSERT_X(framebufferObject.isComplete,
"QIOSContext",
"swapBuffers on incomplete FBO");
198 if (needsRenderbufferResize(surface)) {
199 qCWarning(lcQpaGLContext,
"CAEAGLLayer was resized between makeCurrent and swapBuffers, skipping flush");
203 [EAGLContext setCurrentContext:m_eaglContext];
204 glBindRenderbuffer(
GL_RENDERBUFFER, framebufferObject.colorRenderbuffer);
208QIOSContext::FramebufferObject &QIOSContext::backingFramebufferObjectFor(
QPlatformSurface *surface)
const
215 return m_sharedContext->backingFramebufferObjectFor(surface);
217 if (!m_framebufferObjects.
contains(surface)) {
222 return m_framebufferObjects[surface];
234 FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface);
235 Q_ASSERT_X(framebufferObject.handle,
"QIOSContext",
"can't resolve default FBO before makeCurrent");
237 return framebufferObject.handle;
244 FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface);
247 if (framebufferObject.renderbufferWidth != (
layer.frame.size.width *
layer.contentsScale))
250 if (framebufferObject.renderbufferHeight != (
layer.frame.size.height *
layer.contentsScale))
256bool QIOSContext::verifyGraphicsHardwareAvailability()
267 static dispatch_once_t onceToken = 0;
268 dispatch_once(&onceToken, ^{
274 qCDebug(lcQpaGLContext) <<
"app no longer backgrounded, rendering enabled";
275 applicationBackgrounded =
false;
285 qCDebug(lcQpaGLContext) <<
"app backgrounded, rendering disabled";
286 applicationBackgrounded =
true;
293 qCWarning(lcQpaGLContext) <<
"explicitly glFinishing and deactivating" << currentContext;
295 currentContext->doneCurrent();
301 if (applicationBackgrounded)
302 qCWarning(lcQpaGLContext,
"OpenGL ES calls are not allowed while an application is backgrounded");
304 return !applicationBackgrounded;
307void QIOSContext::windowDestroyed(
QObject *
object)
313 qCDebug(lcQpaGLContext) <<
object <<
"destroyed, deleting corresponding FBO";
315 EAGLContext *originalContext = [EAGLContext currentContext];
316 [EAGLContext setCurrentContext:m_eaglContext];
317 deleteBuffers(m_framebufferObjects[
window]);
319 [EAGLContext setCurrentContext:originalContext];
324 return QFunctionPointer(dlsym(RTLD_DEFAULT, functionName));
329 return m_eaglContext;
334 return m_sharedContext;
339#include "moc_qioscontext.cpp"
static Qt::ApplicationState applicationState()
bool remove(const Key &key)
Removes the item that has the key from the hash.
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
void applicationStateWillChange(Qt::ApplicationState oldState, Qt::ApplicationState newState)
void applicationStateDidChange(Qt::ApplicationState oldState, Qt::ApplicationState newState)
QSurfaceFormat format() const override
void doneCurrent() override
bool isSharing() const override
void swapBuffers(QPlatformSurface *surface) override
Reimplement in subclass to native swap buffers calls.
GLuint defaultFramebufferObject(QPlatformSurface *) const override
Reimplement in subclass if your platform uses framebuffer objects for surfaces.
bool isValid() const override
QFunctionPointer getProcAddress(const char *procName) override
Reimplement in subclass to allow dynamic querying of OpenGL symbols.
bool makeCurrent(QPlatformSurface *surface) override
QIOSContext(QOpenGLContext *context)
static QIOSIntegration * instance()
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
The QPlatformOpenGLContext class provides an abstraction for native GL contexts.
static bool parseOpenGLVersion(const QByteArray &versionString, int &major, int &minor)
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
SurfaceClass surfaceClass() const
Returns the surface class of this surface.
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
Combined button and popup list for selecting options.
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define Q_ASSERT_IS_GL_SURFACE(surface)
#define QT_IOS_GL_STATUS_CASE(val)
static QString fboStatusString(GLenum status)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
#define GL_DEPTH24_STENCIL8_OES
GLint GLsizei GLsizei GLenum format
#define GL_DEPTH_COMPONENT16
#define GL_RENDERBUFFER_WIDTH
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
#define GL_COLOR_ATTACHMENT0
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
#define GL_RENDERBUFFER_HEIGHT
#define GL_FRAMEBUFFER_COMPLETE
#define GL_FRAMEBUFFER_UNSUPPORTED
#define GL_DEPTH_ATTACHMENT
#define GL_STENCIL_ATTACHMENT
#define Q_ASSERT_X(cond, x, msg)
#define qPrintable(string)
#define QStringLiteral(str)