iOS: Tie QIOSContext FBOs to corresponding QPlatformWindow, not QWindow

A QWindow may be created() and destroyed() multiple times in the lifetime
of the window, each time resulting in a new platform window (QIOSWindow)
being created. This QIOSWindow is backed by a new UIView each time, hence
it needs a new FBO and renderbuffer-mapping, since the previous
renderbuffer was mapped to the old UIView.

This fixes a bug where a QWindow would not render after a destroy()
unless it was resized (which triggered new FBO/renderbuffers).

We need to inherit QObject so that we can watch the destroyed() signal.

Change-Id: I93172dd6280b86b49755bf7abddf061d7e6b66f1
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
This commit is contained in:
Tor Arne Vestbø 2013-11-11 15:17:56 +01:00 committed by The Qt Project
parent 18182a6275
commit bb1225f5ba
4 changed files with 13 additions and 8 deletions

View File

@ -48,6 +48,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QIOSWindow;
class QIOSContext : public QObject, public QPlatformOpenGLContext class QIOSContext : public QObject, public QPlatformOpenGLContext
{ {
Q_OBJECT Q_OBJECT
@ -87,7 +89,7 @@ private:
static void deleteBuffers(const FramebufferObject &framebufferObject); static void deleteBuffers(const FramebufferObject &framebufferObject);
mutable QHash<QWindow *, FramebufferObject> m_framebufferObjects; mutable QHash<QIOSWindow *, FramebufferObject> m_framebufferObjects;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -113,7 +113,7 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface)
{ {
Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface);
Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window); Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window);
QWindow *window = static_cast<QWindow *>(surface->surface()); QIOSWindow *window = static_cast<QIOSWindow *>(surface);
Q_ASSERT(m_framebufferObjects.contains(window)); Q_ASSERT(m_framebufferObjects.contains(window));
[EAGLContext setCurrentContext:m_eaglContext]; [EAGLContext setCurrentContext:m_eaglContext];
@ -124,7 +124,7 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface)
GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const
{ {
Q_ASSERT(surface && surface->surface()->surfaceClass() == QSurface::Window); Q_ASSERT(surface && surface->surface()->surfaceClass() == QSurface::Window);
QWindow *window = static_cast<QWindow *>(surface->surface()); QIOSWindow *window = static_cast<QIOSWindow *>(surface);
FramebufferObject &framebufferObject = m_framebufferObjects[window]; FramebufferObject &framebufferObject = m_framebufferObjects[window];
@ -155,8 +155,7 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const
} }
// Ensure that the FBO's buffers match the size of the layer // Ensure that the FBO's buffers match the size of the layer
QIOSWindow *platformWindow = static_cast<QIOSWindow *>(surface); UIView *view = reinterpret_cast<UIView *>(window->winId());
UIView *view = reinterpret_cast<UIView *>(platformWindow->winId());
CAEAGLLayer *layer = static_cast<CAEAGLLayer *>(view.layer); CAEAGLLayer *layer = static_cast<CAEAGLLayer *>(view.layer);
if (framebufferObject.renderbufferWidth != (layer.frame.size.width * layer.contentsScale) || if (framebufferObject.renderbufferWidth != (layer.frame.size.width * layer.contentsScale) ||
framebufferObject.renderbufferHeight != (layer.frame.size.height * layer.contentsScale)) { framebufferObject.renderbufferHeight != (layer.frame.size.height * layer.contentsScale)) {
@ -191,7 +190,7 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const
void QIOSContext::windowDestroyed(QObject *object) void QIOSContext::windowDestroyed(QObject *object)
{ {
QWindow *window = static_cast<QWindow *>(object); QIOSWindow *window = static_cast<QIOSWindow *>(object);
if (m_framebufferObjects.contains(window)) { if (m_framebufferObjects.contains(window)) {
EAGLContext *originalContext = [EAGLContext currentContext]; EAGLContext *originalContext = [EAGLContext currentContext];
[EAGLContext setCurrentContext:m_eaglContext]; [EAGLContext setCurrentContext:m_eaglContext];

View File

@ -58,8 +58,10 @@ QT_BEGIN_NAMESPACE
@class QUIView; @class QUIView;
class QIOSWindow : public QPlatformWindow class QIOSWindow : public QObject, public QPlatformWindow
{ {
Q_OBJECT
public: public:
explicit QIOSWindow(QWindow *window); explicit QIOSWindow(QWindow *window);
~QIOSWindow(); ~QIOSWindow();

View File

@ -342,7 +342,7 @@ QIOSWindow::QIOSWindow(QWindow *window)
, m_normalGeometry(QPlatformWindow::geometry()) , m_normalGeometry(QPlatformWindow::geometry())
, m_windowLevel(0) , m_windowLevel(0)
{ {
setParent(parent()); setParent(QPlatformWindow::parent());
setWindowState(window->windowState()); setWindowState(window->windowState());
} }
@ -527,4 +527,6 @@ qreal QIOSWindow::devicePixelRatio() const
return m_view.contentScaleFactor; return m_view.contentScaleFactor;
} }
#include "moc_qioswindow.cpp"
QT_END_NAMESPACE QT_END_NAMESPACE