diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/platforms/ios/qioscontext.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioscontext.mm | 16 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.h | 9 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.mm | 82 |
4 files changed, 66 insertions, 43 deletions
diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h index 102aaaa387..b45917832c 100644 --- a/src/plugins/platforms/ios/qioscontext.h +++ b/src/plugins/platforms/ios/qioscontext.h @@ -62,6 +62,8 @@ public: void doneCurrent(); GLuint defaultFramebufferObject(QPlatformSurface *) const; + GLuint defaultColorRenderbuffer(QPlatformSurface *) const; + QFunctionPointer getProcAddress(const QByteArray &procName); EAGLContext *nativeContext() const; diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 8beb588b03..68db28212b 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -88,7 +88,8 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface) [EAGLContext setCurrentContext:m_eaglContext]; glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); - return true; + // Ensures render buffers are set up and match the size of the window + return defaultColorRenderbuffer(surface) != 0; } void QIOSContext::doneCurrent() @@ -101,13 +102,7 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface) Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); [EAGLContext setCurrentContext:m_eaglContext]; - - GLint renderbuffer; - glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &renderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); - + glBindRenderbuffer(GL_RENDERBUFFER, defaultColorRenderbuffer(surface)); [m_eaglContext presentRenderbuffer:GL_RENDERBUFFER]; } @@ -116,6 +111,11 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const return static_cast<QIOSWindow *>(surface)->framebufferObject(*const_cast<const QIOSContext*>(this)); } +GLuint QIOSContext::defaultColorRenderbuffer(QPlatformSurface *surface) const +{ + return static_cast<QIOSWindow *>(surface)->colorRenderbuffer(*const_cast<const QIOSContext*>(this)); +} + QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) { return reinterpret_cast<QFunctionPointer>(dlsym(RTLD_NEXT, functionName.constData())); diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 2a762d2bdc..4c55249046 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -88,12 +88,21 @@ public: void handleContentOrientationChange(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; + GLuint colorRenderbuffer(const QIOSContext &context) const; EAGLView *nativeView() const { return m_view; } private: EAGLView *m_view; QRect m_requestedGeometry; + + mutable struct GLData { + GLuint framebufferObject; + GLuint colorRenderbuffer; + GLuint depthRenderbuffer; + GLint renderbufferWidth; + GLint renderbufferHeight; + } m_glData; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index b209bbc159..90734e58e8 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -116,6 +116,10 @@ static QRect fromCGRect(const CGRect &rect) QRect geometry = fromCGRect(self.frame); m_qioswindow->QPlatformWindow::setGeometry(geometry); QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry); + + // If we have a new size here we need to resize the FBO's corresponding buffers, + // but we defer that to when the application calls makeCurrent. + [super layoutSubviews]; } @@ -200,6 +204,7 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_requestedGeometry(QPlatformWindow::geometry()) + , m_glData() { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; @@ -209,6 +214,13 @@ QIOSWindow::QIOSWindow(QWindow *window) QIOSWindow::~QIOSWindow() { + if (m_glData.framebufferObject) + glDeleteFramebuffers(1, &m_glData.framebufferObject); + if (m_glData.colorRenderbuffer) + glDeleteRenderbuffers(1, &m_glData.colorRenderbuffer); + if (m_glData.depthRenderbuffer) + glDeleteRenderbuffers(1, &m_glData.depthRenderbuffer); + [m_view release]; } @@ -259,56 +271,56 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { - static GLuint framebuffer = 0; + if (!m_glData.framebufferObject) { + [EAGLContext setCurrentContext:context.nativeContext()]; - // FIXME: Cache context and recreate framebuffer if window - // is used with a different context then last time. + glGenFramebuffers(1, &m_glData.framebufferObject); + glBindFramebuffer(GL_FRAMEBUFFER, m_glData.framebufferObject); - if (!framebuffer) { - EAGLContext* eaglContext = context.nativeContext(); + glGenRenderbuffers(1, &m_glData.colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_glData.colorRenderbuffer); - [EAGLContext setCurrentContext:eaglContext]; + QSurfaceFormat requestedFormat = context.format(); + if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { + glGenRenderbuffers(1, &m_glData.depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); - // Create the framebuffer and bind it - glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + if (requestedFormat.stencilBufferSize() > 0) + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); + } + } - GLint width; - GLint height; + return m_glData.framebufferObject; +} - // Create a color renderbuffer, allocate storage for it, - // and attach it to the framebuffer’s color attachment point. - GLuint colorRenderbuffer; - glGenRenderbuffers(1, &colorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); - [eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast<CAEAGLLayer *>(m_view.layer)]; - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); +GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const +{ + if (!m_glData.colorRenderbuffer || + m_glData.renderbufferWidth != geometry().width() || m_glData.renderbufferHeight != geometry().height()) { - QSurfaceFormat requestedFormat = context.format(); - if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { - // Create a depth or depth/stencil renderbuffer, allocate storage for it, - // and attach it to the framebuffer’s depth attachment point. - GLuint depthRenderbuffer; - glGenRenderbuffers(1, &depthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); + [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast<CAEAGLLayer *>(m_view.layer)]; + + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_glData.renderbufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_glData.renderbufferHeight); + + if (m_glData.depthRenderbuffer) { + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); // FIXME: Support more fine grained control over depth/stencil buffer sizes - if (requestedFormat.stencilBufferSize() > 0) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); - } else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); - } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); + if (context.format().stencilBufferSize() > 0) + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_glData.renderbufferWidth, m_glData.renderbufferHeight); + else + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_glData.renderbufferWidth, m_glData.renderbufferHeight); } if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); } - return framebuffer; + return m_glData.colorRenderbuffer; } QT_END_NAMESPACE |