summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/platforms/ios/qioscontext.h21
-rw-r--r--src/plugins/platforms/ios/qioscontext.mm100
-rw-r--r--src/plugins/platforms/ios/qioswindow.h11
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm65
4 files changed, 113 insertions, 84 deletions
diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h
index b45917832c..082ec4794c 100644
--- a/src/plugins/platforms/ios/qioscontext.h
+++ b/src/plugins/platforms/ios/qioscontext.h
@@ -48,8 +48,10 @@
QT_BEGIN_NAMESPACE
-class QIOSContext : public QPlatformOpenGLContext
+class QIOSContext : public QObject, public QPlatformOpenGLContext
{
+ Q_OBJECT
+
public:
QIOSContext(QOpenGLContext *context);
~QIOSContext();
@@ -62,15 +64,26 @@ public:
void doneCurrent();
GLuint defaultFramebufferObject(QPlatformSurface *) const;
- GLuint defaultColorRenderbuffer(QPlatformSurface *) const;
-
QFunctionPointer getProcAddress(const QByteArray &procName);
- EAGLContext *nativeContext() const;
+private Q_SLOTS:
+ void windowDestroyed(QObject *object);
private:
EAGLContext *m_eaglContext;
QSurfaceFormat m_format;
+
+ struct FramebufferObject {
+ GLuint handle;
+ GLuint colorRenderbuffer;
+ GLuint depthRenderbuffer;
+ GLint renderbufferWidth;
+ GLint renderbufferHeight;
+ };
+
+ static void deleteBuffers(const FramebufferObject &framebufferObject);
+
+ mutable QHash<QWindow *, FramebufferObject> m_framebufferObjects;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm
index 00629a84ab..dc431b57dd 100644
--- a/src/plugins/platforms/ios/qioscontext.mm
+++ b/src/plugins/platforms/ios/qioscontext.mm
@@ -70,12 +70,25 @@ QIOSContext::QIOSContext(QOpenGLContext *context)
QIOSContext::~QIOSContext()
{
- if ([EAGLContext currentContext] == m_eaglContext)
- doneCurrent();
+ [EAGLContext setCurrentContext:m_eaglContext];
+
+ foreach (const FramebufferObject &framebufferObject, m_framebufferObjects)
+ deleteBuffers(framebufferObject);
+ [EAGLContext setCurrentContext:nil];
[m_eaglContext release];
}
+void QIOSContext::deleteBuffers(const FramebufferObject &framebufferObject)
+{
+ if (framebufferObject.handle)
+ glDeleteFramebuffers(1, &framebufferObject.handle);
+ if (framebufferObject.colorRenderbuffer)
+ glDeleteRenderbuffers(1, &framebufferObject.colorRenderbuffer);
+ if (framebufferObject.depthRenderbuffer)
+ glDeleteRenderbuffers(1, &framebufferObject.depthRenderbuffer);
+}
+
QSurfaceFormat QIOSContext::format() const
{
return m_format;
@@ -88,8 +101,7 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface)
[EAGLContext setCurrentContext:m_eaglContext];
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface));
- // Ensures render buffers are set up and match the size of the window
- return defaultColorRenderbuffer(surface) != 0;
+ return true;
}
void QIOSContext::doneCurrent()
@@ -100,20 +112,86 @@ void QIOSContext::doneCurrent()
void QIOSContext::swapBuffers(QPlatformSurface *surface)
{
Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface);
+ Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window);
+ QWindow *window = static_cast<QWindow *>(surface->surface());
+ Q_ASSERT(m_framebufferObjects.contains(window));
[EAGLContext setCurrentContext:m_eaglContext];
- glBindRenderbuffer(GL_RENDERBUFFER, defaultColorRenderbuffer(surface));
+ glBindRenderbuffer(GL_RENDERBUFFER, m_framebufferObjects[window].colorRenderbuffer);
[m_eaglContext presentRenderbuffer:GL_RENDERBUFFER];
}
GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const
{
- return static_cast<QIOSWindow *>(surface)->framebufferObject(*this);
+ Q_ASSERT(surface && surface->surface()->surfaceClass() == QSurface::Window);
+ QWindow *window = static_cast<QWindow *>(surface->surface());
+
+ FramebufferObject &framebufferObject = m_framebufferObjects[window];
+
+ // Set up an FBO for the window if it hasn't been created yet
+ if (!framebufferObject.handle) {
+ [EAGLContext setCurrentContext:m_eaglContext];
+
+ glGenFramebuffers(1, &framebufferObject.handle);
+ glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject.handle);
+
+ glGenRenderbuffers(1, &framebufferObject.colorRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+ framebufferObject.colorRenderbuffer);
+
+ if (m_format.depthBufferSize() > 0 || m_format.stencilBufferSize() > 0) {
+ glGenRenderbuffers(1, &framebufferObject.depthRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.depthRenderbuffer);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
+ framebufferObject.depthRenderbuffer);
+
+ if (m_format.stencilBufferSize() > 0)
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
+ framebufferObject.depthRenderbuffer);
+ }
+
+ connect(window, SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*)));
+ }
+
+ // Ensure that the FBO's buffers match the size of the window
+ QIOSWindow *platformWindow = static_cast<QIOSWindow *>(surface);
+ if (framebufferObject.renderbufferWidth != platformWindow->effectiveWidth() ||
+ framebufferObject.renderbufferHeight != platformWindow->effectiveHeight()) {
+
+ glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer);
+ CAEAGLLayer *layer = static_cast<CAEAGLLayer *>(platformWindow->nativeView().layer);
+ [m_eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer];
+
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferObject.renderbufferWidth);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferObject.renderbufferHeight);
+
+ if (framebufferObject.depthRenderbuffer) {
+ glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.depthRenderbuffer);
+
+ // FIXME: Support more fine grained control over depth/stencil buffer sizes
+ if (m_format.stencilBufferSize() > 0)
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES,
+ framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight);
+ else
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
+ framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight);
+ }
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
+ }
+
+ return framebufferObject.handle;
}
-GLuint QIOSContext::defaultColorRenderbuffer(QPlatformSurface *surface) const
+void QIOSContext::windowDestroyed(QObject *object)
{
- return static_cast<QIOSWindow *>(surface)->colorRenderbuffer(*this);
+ QWindow *window = static_cast<QWindow *>(object);
+ if (m_framebufferObjects.contains(window)) {
+ deleteBuffers(m_framebufferObjects[window]);
+ m_framebufferObjects.remove(window);
+ }
}
QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName)
@@ -121,7 +199,5 @@ QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName)
return reinterpret_cast<QFunctionPointer>(dlsym(RTLD_NEXT, functionName.constData()));
}
-EAGLContext *QIOSContext::nativeContext() const
-{
- return m_eaglContext;
-}
+#include "moc_qioscontext.cpp"
+
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index 63099682f1..1f36c525ce 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -67,9 +67,9 @@ public:
void handleContentOrientationChange(Qt::ScreenOrientation orientation);
void setVisible(bool visible);
- GLuint framebufferObject(const QIOSContext &context) const;
- GLuint colorRenderbuffer(const QIOSContext &context) const;
qreal devicePixelRatio() const;
+ int effectiveWidth() const;
+ int effectiveHeight() const;
UIView *nativeView() const { return m_view; }
@@ -77,13 +77,6 @@ private:
UIView *m_view;
QRect m_requestedGeometry;
- mutable struct GLData {
- GLuint framebufferObject;
- GLuint colorRenderbuffer;
- GLuint depthRenderbuffer;
- GLint renderbufferWidth;
- GLint renderbufferHeight;
- } m_glData;
qreal m_devicePixelRatio;
};
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 9c814ac924..88debb7c33 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -229,7 +229,6 @@ QIOSWindow::QIOSWindow(QWindow *window)
: QPlatformWindow(window)
, m_view([[EAGLView alloc] initWithQIOSWindow:this])
, m_requestedGeometry(QPlatformWindow::geometry())
- , m_glData()
, m_devicePixelRatio(1.0)
{
if (isQtApplication())
@@ -249,13 +248,6 @@ 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 removeFromSuperview];
[m_view release];
}
@@ -325,64 +317,19 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio
[[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO];
}
-GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const
+qreal QIOSWindow::devicePixelRatio() const
{
- if (!m_glData.framebufferObject) {
- [EAGLContext setCurrentContext:context.nativeContext()];
-
- glGenFramebuffers(1, &m_glData.framebufferObject);
- glBindFramebuffer(GL_FRAMEBUFFER, m_glData.framebufferObject);
-
- glGenRenderbuffers(1, &m_glData.colorRenderbuffer);
- glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_glData.colorRenderbuffer);
-
- 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);
-
- if (requestedFormat.stencilBufferSize() > 0)
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer);
- }
- }
-
- return m_glData.framebufferObject;
+ return m_devicePixelRatio;
}
-GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const
+int QIOSWindow::effectiveWidth() const
{
- if (!m_glData.colorRenderbuffer ||
- m_glData.renderbufferWidth != geometry().width() * m_devicePixelRatio ||
- m_glData.renderbufferHeight != geometry().height() * m_devicePixelRatio) {
-
- 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 (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 m_glData.colorRenderbuffer;
+ return geometry().width() * m_devicePixelRatio;
}
-qreal QIOSWindow::devicePixelRatio() const
+int QIOSWindow::effectiveHeight() const
{
- return m_devicePixelRatio;
+ return geometry().height() * m_devicePixelRatio;
}
QT_END_NAMESPACE