diff options
author | Christian Strømme <christian.stromme@qt.io> | 2016-07-04 17:32:24 +0200 |
---|---|---|
committer | Christian Stromme <christian.stromme@qt.io> | 2016-07-05 14:24:40 +0000 |
commit | 443ed0be093b2d8e78d111a59eca97f2eba5b0fe (patch) | |
tree | 919aa0796073c7f5a515e204d0562c588566c0d1 /src | |
parent | 7fb7f278fff2c407f8c0fe8165c60a934f95cd91 (diff) | |
download | qtmultimedia-443ed0be093b2d8e78d111a59eca97f2eba5b0fe.tar.gz |
Android: Fix attach- and detachFromGLContext()
This fixes a regression caused by ba8127639857232d8a. The change
assumed that the AndroidSurfaceTexture class could cope with changing
textures, but since the callback from the SurfaceTextureListener was
tied to the initial, invalid, texture handle, it would only work as
long as there were only one texture; all textures would register
the callback to the same invalid handle.
This change maps the callback directly to the android texture object,
instead of the texture handle.
Task-number: QTBUG-54340
Change-Id: I39568d0f97fa6b9cb1182efaca568b16a26f0d09
Reviewed-by: Yoann Lopes <yoann.lopes@qt.io>
Diffstat (limited to 'src')
3 files changed, 37 insertions, 19 deletions
diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener.java index bd076bd43..a9ec4b5ae 100644 --- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener.java +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener.java @@ -37,18 +37,18 @@ import android.graphics.SurfaceTexture; public class QtSurfaceTextureListener implements SurfaceTexture.OnFrameAvailableListener { - private final int texID; + private final long m_id; - public QtSurfaceTextureListener(int texName) + public QtSurfaceTextureListener(long id) { - texID = texName; + m_id = id; } @Override public void onFrameAvailable(SurfaceTexture surfaceTexture) { - notifyFrameAvailable(texID); + notifyFrameAvailable(m_id); } - private static native void notifyFrameAvailable(int id); + private static native void notifyFrameAvailable(long id); } diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp index 2cea896e1..bc7187e9c 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp @@ -34,24 +34,32 @@ #include "androidsurfacetexture.h" #include <QtCore/private/qjni_p.h> #include <QtCore/private/qjnihelpers_p.h> +#include <QtCore/qmutex.h> QT_BEGIN_NAMESPACE static const char QtSurfaceTextureListenerClassName[] = "org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener"; -static QMap<int, AndroidSurfaceTexture*> g_objectMap; +typedef QVector<jlong> SurfaceTextures; +Q_GLOBAL_STATIC(SurfaceTextures, g_surfaceTextures); +Q_GLOBAL_STATIC(QMutex, g_textureMutex); // native method for QtSurfaceTexture.java -static void notifyFrameAvailable(JNIEnv* , jobject, int id) +static void notifyFrameAvailable(JNIEnv* , jobject, jlong id) { - AndroidSurfaceTexture *obj = g_objectMap.value(id, 0); + const QMutexLocker lock(g_textureMutex); + const int idx = g_surfaceTextures->indexOf(id); + if (idx == -1) + return; + + AndroidSurfaceTexture *obj = reinterpret_cast<AndroidSurfaceTexture *>(g_surfaceTextures->at(idx)); if (obj) Q_EMIT obj->frameAvailable(); } AndroidSurfaceTexture::AndroidSurfaceTexture(unsigned int texName) : QObject() - , m_texID(int(texName)) { + Q_STATIC_ASSERT(sizeof (jlong) >= sizeof (void *)); // API level 11 or higher is required if (QtAndroidPrivate::androidSdkVersion() < 11) { qWarning("Camera preview and video playback require Android 3.0 (API level 11) or later."); @@ -67,13 +75,13 @@ AndroidSurfaceTexture::AndroidSurfaceTexture(unsigned int texName) env->ExceptionClear(); } - if (m_surfaceTexture.isValid()) - g_objectMap.insert(int(texName), this); + if (!m_surfaceTexture.isValid()) + return; - QJNIObjectPrivate listener(QtSurfaceTextureListenerClassName, "(I)V", jint(texName)); - m_surfaceTexture.callMethod<void>("setOnFrameAvailableListener", - "(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V", - listener.object()); + const QMutexLocker lock(g_textureMutex); + g_surfaceTextures->append(jlong(this)); + QJNIObjectPrivate listener(QtSurfaceTextureListenerClassName, "(J)V", jlong(this)); + setOnFrameAvailableListener(listener); } AndroidSurfaceTexture::~AndroidSurfaceTexture() @@ -83,7 +91,10 @@ AndroidSurfaceTexture::~AndroidSurfaceTexture() if (m_surfaceTexture.isValid()) { release(); - g_objectMap.remove(m_texID); + const QMutexLocker lock(g_textureMutex); + const int idx = g_surfaceTextures->indexOf(jlong(this)); + if (idx != -1) + g_surfaceTextures->remove(idx); } } @@ -172,7 +183,7 @@ bool AndroidSurfaceTexture::initJNI(JNIEnv *env) env); static const JNINativeMethod methods[] = { - {"notifyFrameAvailable", "(I)V", (void *)notifyFrameAvailable} + {"notifyFrameAvailable", "(J)V", (void *)notifyFrameAvailable} }; if (clazz && env->RegisterNatives(clazz, @@ -184,4 +195,11 @@ bool AndroidSurfaceTexture::initJNI(JNIEnv *env) return true; } +void AndroidSurfaceTexture::setOnFrameAvailableListener(const QJNIObjectPrivate &listener) +{ + m_surfaceTexture.callMethod<void>("setOnFrameAvailableListener", + "(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V", + listener.object()); +} + QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h index a08483e5e..3c41bf51d 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h @@ -48,7 +48,6 @@ public: explicit AndroidSurfaceTexture(unsigned int texName); ~AndroidSurfaceTexture(); - int textureID() const { return m_texID; } jobject surfaceTexture(); jobject surface(); jobject surfaceHolder(); @@ -67,7 +66,8 @@ Q_SIGNALS: void frameAvailable(); private: - int m_texID; + void setOnFrameAvailableListener(const QJNIObjectPrivate &listener); + QJNIObjectPrivate m_surfaceTexture; QJNIObjectPrivate m_surface; QJNIObjectPrivate m_surfaceHolder; |