summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/android/src/opengl
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>2013-04-15 11:23:04 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-18 09:18:43 +0200
commiteb95685556143eb71323742bfcdaa20541b01375 (patch)
treecb54d5314c95aa9eb9b1aa1f272e60aa7f38b702 /src/plugins/platforms/android/src/opengl
parent1770f25857c7cfe21c36c0bda8a80a54b199bafe (diff)
Android: Don't crash when displaying multiple top-levels
While the raster platform plugin supports multiple top level windows, this is not supported on the GL plugin, so if you use GL or QtQuick2 in your app and use several top levels, the app would crash with an error message. A problem is that the top-level SurfaceView is a special overlay View and does not support being stacked in a layout. So instead, we let all windows share the same GL surface and draw on top of each other. This works fine for simple use cases. We implement a new platform capability to make sure no top level windows (even combobox popups and dialogs) get non-fullscreen geometries. That has never worked properly with the eglfs plugin. Task-number: QTBUG-30473 Change-Id: Ia1438019638fc739cc93ffe79b46b81631254df2 Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
Diffstat (limited to 'src/plugins/platforms/android/src/opengl')
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp14
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp58
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h13
-rw-r--r--src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp1
4 files changed, 78 insertions, 8 deletions
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
index aa8ee57341..4d741807d0 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
@@ -62,16 +62,16 @@ void QAndroidOpenGLContext::swapBuffers(QPlatformSurface *surface)
{
QEglFSContext::swapBuffers(surface);
- QAndroidOpenGLPlatformWindow *primaryWindow = m_platformIntegration->primaryWindow();
- if (primaryWindow == surface) {
- primaryWindow->lock();
- QSize size = primaryWindow->scheduledResize();
+ if (surface->surface()->surfaceClass() == QSurface::Window) {
+ QAndroidOpenGLPlatformWindow *window = static_cast<QAndroidOpenGLPlatformWindow *>(surface);
+ window->lock();
+ QSize size = window->scheduledResize();
if (size.isValid()) {
QRect geometry(QPoint(0, 0), size);
- primaryWindow->setGeometry(geometry);
- primaryWindow->scheduleResize(QSize());
+ window->setGeometry(geometry);
+ window->scheduleResize(QSize());
}
- primaryWindow->unlock();
+ window->unlock();
}
}
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
index 15c6559157..5362906e0e 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
@@ -45,11 +45,21 @@
QT_BEGIN_NAMESPACE
+EGLSurface QAndroidOpenGLPlatformWindow::m_staticSurface = 0;
+EGLNativeWindowType QAndroidOpenGLPlatformWindow::m_staticNativeWindow = 0;
+QReadWriteLock QAndroidOpenGLPlatformWindow::m_staticSurfaceLock;
+QBasicAtomicInt QAndroidOpenGLPlatformWindow::m_referenceCount = Q_BASIC_ATOMIC_INITIALIZER(0);
+
QAndroidOpenGLPlatformWindow::QAndroidOpenGLPlatformWindow(QWindow *window)
: QEglFSWindow(window)
{
}
+QAndroidOpenGLPlatformWindow::~QAndroidOpenGLPlatformWindow()
+{
+ destroy();
+}
+
bool QAndroidOpenGLPlatformWindow::isExposed() const
{
return QtAndroid::nativeWindow(false) != 0 && QEglFSWindow::isExposed();
@@ -60,11 +70,57 @@ void QAndroidOpenGLPlatformWindow::invalidateSurface()
QWindowSystemInterface::handleExposeEvent(window(), QRegion()); // Obscure event
QWindowSystemInterface::flushWindowSystemEvents();
QEglFSWindow::invalidateSurface();
+
+ m_window = 0;
+ m_surface = 0;
+
+ if (!m_referenceCount.deref()){
+ QWriteLocker locker(&m_staticSurfaceLock);
+
+ EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display();
+ eglDestroySurface(display, m_staticSurface);
+
+ m_staticSurface = 0;
+ m_staticNativeWindow = 0;
+ }
}
void QAndroidOpenGLPlatformWindow::resetSurface()
{
- QEglFSWindow::resetSurface();
+ m_referenceCount.ref();
+ if (m_staticSurface == 0) {
+ QWriteLocker locker(&m_staticSurfaceLock);
+ QEglFSWindow::resetSurface();
+ m_staticSurface = m_surface;
+ m_staticNativeWindow = m_window;
+ } else {
+ QReadLocker locker(&m_staticSurfaceLock);
+ Q_ASSERT(m_staticSurface != m_surface);
+ m_window = m_staticNativeWindow;
+ m_surface = m_staticSurface;
+ }
+
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
+ QWindowSystemInterface::flushWindowSystemEvents();
+}
+
+void QAndroidOpenGLPlatformWindow::destroy()
+{
+ if (!m_referenceCount.deref()) {
+ QEglFSWindow::destroy();
+ } else {
+ m_window = 0;
+ m_surface = 0;
+ }
+}
+
+void QAndroidOpenGLPlatformWindow::raise()
+{
+}
+
+void QAndroidOpenGLPlatformWindow::setVisible(bool visible)
+{
+ QEglFSWindow::setVisible(visible);
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
QWindowSystemInterface::flushWindowSystemEvents();
}
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
index b835cb3246..36a110e1a8 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
@@ -44,6 +44,7 @@
#include "qeglfswindow.h"
#include <QtCore/qmutex.h>
+#include <QtCore/qreadwritelock.h>
QT_BEGIN_NAMESPACE
@@ -51,6 +52,7 @@ class QAndroidOpenGLPlatformWindow : public QEglFSWindow
{
public:
QAndroidOpenGLPlatformWindow(QWindow *window);
+ ~QAndroidOpenGLPlatformWindow();
QSize scheduledResize() const { return m_scheduledResize; }
void scheduleResize(const QSize &size) { m_scheduledResize = size; }
@@ -60,12 +62,23 @@ public:
bool isExposed() const;
+ void raise();
+
void invalidateSurface();
void resetSurface();
+ void setVisible(bool visible);
+
+ void destroy();
+
private:
QSize m_scheduledResize;
QMutex m_lock;
+
+ static QReadWriteLock m_staticSurfaceLock;
+ static EGLSurface m_staticSurface;
+ static EGLNativeWindowType m_staticNativeWindow;
+ static QBasicAtomicInt m_referenceCount;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
index 4734d47eb3..005758d83d 100644
--- a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
+++ b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
@@ -96,6 +96,7 @@ QDpi QEglFSAndroidHooks::logicalDpi() const
EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(const QSize &size, const QSurfaceFormat &format)
{
+ Q_UNUSED(size);
ANativeWindow *window = QtAndroid::nativeWindow();
if (window != 0)
ANativeWindow_acquire(window);