Fixes for surface creation/destruction

- After reset a surface we must call makeCurrent before we are usign
swapBuffers.

 - No need to set the surface in QPA when surfaceCreated are called in
QtSurface.java, some time the OpenGL surface is not fully initialized at
this stage. Is better to wait for surfaceChanged which is always fired
at least once.

 - DO NOT reset m_surfaceId to 1 when there is no surface. The problem
is that if we have one surface and when we distory it we don't (need to)
wait for its surfaceChanged/surfaceDestroyed notifications, and if we
create another one quicly it will have the same id (1).

Task-number: QTBUG-39712
Change-Id: I2aa31e5b59d81ef3b03624d4636a4381eea6d543
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
This commit is contained in:
BogDan Vatra 2015-01-08 17:11:43 +02:00
parent 05d39ec9c0
commit a0737f65a6
6 changed files with 19 additions and 17 deletions

View File

@ -45,7 +45,6 @@ package org.qtproject.qt5.android;
import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
@ -87,7 +86,6 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
@Override
public void surfaceCreated(SurfaceHolder holder)
{
QtNative.setSurface(getId(), holder.getSurface(), getWidth(), getHeight());
}
@Override

View File

@ -376,8 +376,6 @@ namespace QtAndroid
const auto &it = m_surfaces.find(surfaceId);
if (it != m_surfaces.end())
m_surfaces.remove(surfaceId);
if (m_surfaces.isEmpty())
m_surfaceId = 1;
QJNIEnvironmentPrivate env;
if (!env)

View File

@ -50,8 +50,10 @@ QAndroidPlatformOpenGLContext::QAndroidPlatformOpenGLContext(const QSurfaceForma
void QAndroidPlatformOpenGLContext::swapBuffers(QPlatformSurface *surface)
{
if (surface->surface()->surfaceClass() == QSurface::Window)
static_cast<QAndroidPlatformOpenGLWindow *>(surface)->checkNativeSurface(eglConfig());
if (surface->surface()->surfaceClass() == QSurface::Window &&
static_cast<QAndroidPlatformOpenGLWindow *>(surface)->checkNativeSurface(eglConfig())) {
QEGLPlatformContext::makeCurrent(surface);
}
QEGLPlatformContext::swapBuffers(surface);
}

View File

@ -138,19 +138,19 @@ EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
return m_eglSurface;
}
void QAndroidPlatformOpenGLWindow::checkNativeSurface(EGLConfig config)
bool QAndroidPlatformOpenGLWindow::checkNativeSurface(EGLConfig config)
{
QMutexLocker lock(&m_surfaceMutex);
if (m_nativeSurfaceId == -1 || !m_androidSurfaceObject.isValid())
return;
return false; // makeCurrent is NOT needed.
createEgl(config);
// we've create another surface, the window should be repainted
QRect availableGeometry = screen()->availableGeometry();
if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
QWindowSystemInterface::handleExposeEvent(window(), QRegion(QRect(QPoint(), geometry().size())));
return true; // makeCurrent is needed!
}
void QAndroidPlatformOpenGLWindow::applicationStateChanged(Qt::ApplicationState state)
@ -209,15 +209,19 @@ void QAndroidPlatformOpenGLWindow::surfaceChanged(JNIEnv *jniEnv, jobject surfac
Q_UNUSED(jniEnv);
Q_UNUSED(w);
Q_UNUSED(h);
lockSurface();
m_androidSurfaceObject = surface;
if (surface) // wait until we have a valid surface to draw into
m_surfaceWaitCondition.wakeOne();
unlockSurface();
// repaint the window
if (surface) {
// repaint the window, when we have a valid surface
QRect availableGeometry = screen()->availableGeometry();
if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
QWindowSystemInterface::handleExposeEvent(window(), QRegion(QRect(QPoint(), geometry().size())));
}
}
QT_END_NAMESPACE

View File

@ -54,7 +54,7 @@ public:
EGLSurface eglSurface(EGLConfig config);
QSurfaceFormat format() const;
void checkNativeSurface(EGLConfig config);
bool checkNativeSurface(EGLConfig config);
void applicationStateChanged(Qt::ApplicationState);
@ -66,7 +66,7 @@ protected:
void clearEgl();
private:
EGLDisplay m_eglDisplay;
EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
EGLSurface m_eglSurface = EGL_NO_SURFACE;
EGLNativeWindowType m_nativeWindow = nullptr;

View File

@ -391,7 +391,7 @@ Qt::ScreenOrientation QAndroidPlatformScreen::nativeOrientation() const
void QAndroidPlatformScreen::surfaceChanged(JNIEnv *env, jobject surface, int w, int h)
{
lockSurface();
if (surface && w && h) {
if (surface && w > 0 && h > 0) {
releaseSurface();
m_nativeSurface = ANativeWindow_fromSurface(env, surface);
QMetaObject::invokeMethod(this, "setDirty", Qt::QueuedConnection, Q_ARG(QRect, QRect(0, 0, w, h)));