From a4f50269f82695fbd0dd344f87b4b355feff4333 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 20 Aug 2014 11:48:02 +0200 Subject: Support QOpenGLWidget and QQuickWidget on Android It gets somewhat complicated due to the fact that a RasterGLSurface window (i.e. any widget window since 5.3) may behave either like an OpenGLSurface or a RasterSurface, and the expected behavior may change on each backingstore sync. This does not fit designs where the platform window implementation is separated and there is different behavior for raster and GL windows. Therefore QAndroidPlatformOpenGLWindow is now made capable of behaving like the raster one, based on a flag communicated from the widget stack via QWindowPrivate (since the plugin knows nothing about widgets). This means that widget windows that do not have renderToTexture children (QOpenGLWidget, QQuickWidget) will go through the raster path, while the ones that have will behave like an OpenGL window with the actual rendering happening in QPlatformBackingStore::composeAndFlush(). The surface type is RasterGLSurface in both cases nonetheless. Task-number: QTBUG-37907 Change-Id: I6f9261fc0fd993afcda7f30d379c5410069033d3 Reviewed-by: Paul Olav Tvete --- .../android/qandroidplatformopenglwindow.cpp | 39 +++++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'src/plugins/platforms/android/qandroidplatformopenglwindow.cpp') diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp index d821145973c..73c0a76dd75 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp @@ -42,9 +42,11 @@ #include "qandroidplatformopenglwindow.h" +#include "qandroidplatformscreen.h" #include "androidjnimain.h" #include +#include #include #include @@ -69,25 +71,52 @@ QAndroidPlatformOpenGLWindow::~QAndroidPlatformOpenGLWindow() unlockSurface(); } +void QAndroidPlatformOpenGLWindow::repaint(const QRegion ®ion) +{ + // This is only for real raster top-level windows. Stop in all other cases. + if ((window()->surfaceType() == QSurface::RasterGLSurface && qt_window_private(window())->compositing) + || window()->surfaceType() == QSurface::OpenGLSurface + || QAndroidPlatformWindow::parent()) + return; + + QRect currentGeometry = geometry(); + + QRect dirtyClient = region.boundingRect(); + QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(), + currentGeometry.top() + dirtyClient.top(), + dirtyClient.width(), + dirtyClient.height()); + QRect mOldGeometryLocal = m_oldGeometry; + m_oldGeometry = currentGeometry; + // If this is a move, redraw the previous location + if (mOldGeometryLocal != currentGeometry) + platformScreen()->setDirty(mOldGeometryLocal); + platformScreen()->setDirty(dirtyRegion); +} + void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect) { if (rect == geometry()) return; - QRect oldGeometry = geometry(); + m_oldGeometry = geometry(); QAndroidPlatformWindow::setGeometry(rect); - QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect); + if (m_nativeSurfaceId != -1) + QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect); QRect availableGeometry = screen()->availableGeometry(); - if (oldGeometry.width() == 0 - && oldGeometry.height() == 0 + if (m_oldGeometry.width() == 0 + && m_oldGeometry.height() == 0 && rect.width() > 0 && rect.height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0) { QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size())); } + + if (rect.topLeft() != m_oldGeometry.topLeft()) + repaint(QRegion(rect)); } EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config) @@ -162,8 +191,8 @@ QSurfaceFormat QAndroidPlatformOpenGLWindow::format() const void QAndroidPlatformOpenGLWindow::clearEgl() { - eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); if (m_eglSurface != EGL_NO_SURFACE) { + eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroySurface(m_eglDisplay, m_eglSurface); m_eglSurface = EGL_NO_SURFACE; } -- cgit v1.2.3