11#include <QtGui/QGuiApplication>
12#include <QtGui/QOpenGLContext>
14#import <OpenGLES/EAGL.h>
15#import <OpenGLES/ES2/glext.h>
16#import <QuartzCore/CAEAGLLayer.h>
30 EAGLSharegroup *shareGroup = m_sharedContext ? [m_sharedContext->m_eaglContext sharegroup] : nil;
31 const int preferredVersion = m_format.
majorVersion() == 1 ? kEAGLRenderingAPIOpenGLES1 : kEAGLRenderingAPIOpenGLES3;
32 for (
int version = preferredVersion; !m_eaglContext && version >= m_format.
majorVersion(); --version)
33 m_eaglContext = [[EAGLContext alloc] initWithAPI:EAGLRenderingAPI(version) sharegroup:shareGroup];
35 if (m_eaglContext != nil) {
36 EAGLContext *originalContext = [EAGLContext currentContext];
37 [EAGLContext setCurrentContext:m_eaglContext];
38 const GLubyte *
s = glGetString(GL_VERSION);
47 [EAGLContext setCurrentContext:originalContext];
56 qCDebug(lcQpaGLContext) <<
"created context with format" << m_format <<
"shared with" << m_sharedContext;
61 [EAGLContext setCurrentContext:m_eaglContext];
63 foreach (
const FramebufferObject &framebufferObject, m_framebufferObjects)
64 deleteBuffers(framebufferObject);
66 [EAGLContext setCurrentContext:nil];
70void QIOSContext::deleteBuffers(
const FramebufferObject &framebufferObject)
72 if (framebufferObject.handle)
73 glDeleteFramebuffers(1, &framebufferObject.handle);
74 if (framebufferObject.colorRenderbuffer)
75 glDeleteRenderbuffers(1, &framebufferObject.colorRenderbuffer);
76 if (framebufferObject.depthRenderbuffer)
77 glDeleteRenderbuffers(1, &framebufferObject.depthRenderbuffer);
85#define QT_IOS_GL_STATUS_CASE(val) case val: return QLatin1StringView(#val)
99#define Q_ASSERT_IS_GL_SURFACE(surface) \
100 Q_ASSERT(surface && (surface->surface()->surfaceType() & (QSurface::OpenGLSurface | QSurface::RasterGLSurface)))
106 if (!verifyGraphicsHardwareAvailability())
109 [EAGLContext setCurrentContext:m_eaglContext];
116 FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface);
118 if (!framebufferObject.handle) {
120 glGenFramebuffers(1, &framebufferObject.handle);
123 glGenRenderbuffers(1, &framebufferObject.colorRenderbuffer);
124 glBindRenderbuffer(
GL_RENDERBUFFER, framebufferObject.colorRenderbuffer);
126 framebufferObject.colorRenderbuffer);
129 glGenRenderbuffers(1, &framebufferObject.depthRenderbuffer);
130 glBindRenderbuffer(
GL_RENDERBUFFER, framebufferObject.depthRenderbuffer);
132 framebufferObject.depthRenderbuffer);
136 framebufferObject.depthRenderbuffer);
142 if (needsRenderbufferResize(surface)) {
145 qCDebug(lcQpaGLContext,
"Reallocating renderbuffer storage - current: %dx%d, layer: %gx%g",
146 framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight,
149 glBindRenderbuffer(
GL_RENDERBUFFER, framebufferObject.colorRenderbuffer);
155 if (framebufferObject.depthRenderbuffer) {
156 glBindRenderbuffer(
GL_RENDERBUFFER, framebufferObject.depthRenderbuffer);
161 framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight);
164 framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight);
169 if (!framebufferObject.isComplete) {
170 qCWarning(lcQpaGLContext,
"QIOSContext failed to make complete framebuffer object (%s)",
175 return framebufferObject.isComplete;
180 [EAGLContext setCurrentContext:nil];
187 if (!verifyGraphicsHardwareAvailability())
193 FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface);
194 Q_ASSERT_X(framebufferObject.isComplete,
"QIOSContext",
"swapBuffers on incomplete FBO");
196 if (needsRenderbufferResize(surface)) {
197 qCWarning(lcQpaGLContext,
"CAEAGLLayer was resized between makeCurrent and swapBuffers, skipping flush");
201 [EAGLContext setCurrentContext:m_eaglContext];
202 glBindRenderbuffer(
GL_RENDERBUFFER, framebufferObject.colorRenderbuffer);
206QIOSContext::FramebufferObject &QIOSContext::backingFramebufferObjectFor(
QPlatformSurface *surface)
const
213 return m_sharedContext->backingFramebufferObjectFor(surface);
215 if (!m_framebufferObjects.
contains(surface)) {
220 return m_framebufferObjects[surface];
232 FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface);
233 Q_ASSERT_X(framebufferObject.handle,
"QIOSContext",
"can't resolve default FBO before makeCurrent");
235 return framebufferObject.handle;
242 FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface);
245 if (framebufferObject.renderbufferWidth != (
layer.frame.size.width *
layer.contentsScale))
248 if (framebufferObject.renderbufferHeight != (
layer.frame.size.height *
layer.contentsScale))
254bool QIOSContext::verifyGraphicsHardwareAvailability()
265 static dispatch_once_t onceToken = 0;
266 dispatch_once(&onceToken, ^{
272 qCDebug(lcQpaGLContext) <<
"app no longer backgrounded, rendering enabled";
273 applicationBackgrounded =
false;
283 qCDebug(lcQpaGLContext) <<
"app backgrounded, rendering disabled";
284 applicationBackgrounded =
true;
291 qCWarning(lcQpaGLContext) <<
"explicitly glFinishing and deactivating" << currentContext;
293 currentContext->doneCurrent();
299 if (applicationBackgrounded)
300 qCWarning(lcQpaGLContext,
"OpenGL ES calls are not allowed while an application is backgrounded");
302 return !applicationBackgrounded;
305void QIOSContext::windowDestroyed(
QObject *
object)
311 qCDebug(lcQpaGLContext) <<
object <<
"destroyed, deleting corresponding FBO";
313 EAGLContext *originalContext = [EAGLContext currentContext];
314 [EAGLContext setCurrentContext:m_eaglContext];
315 deleteBuffers(m_framebufferObjects[
window]);
317 [EAGLContext setCurrentContext:originalContext];
322 return QFunctionPointer(dlsym(RTLD_DEFAULT, functionName));
327 return m_eaglContext;
332 return m_sharedContext;
337#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)
QIOSApplicationState applicationState
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.
#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)