diff --git a/filament/backend/include/backend/platforms/OpenGLPlatform.h b/filament/backend/include/backend/platforms/OpenGLPlatform.h index a64278dab2..121039ea31 100644 --- a/filament/backend/include/backend/platforms/OpenGLPlatform.h +++ b/filament/backend/include/backend/platforms/OpenGLPlatform.h @@ -27,6 +27,7 @@ #include #include +#include namespace filament::backend { @@ -319,6 +320,13 @@ public: virtual void updateTexImage(Stream* UTILS_NONNULL stream, int64_t* UTILS_NONNULL timestamp) noexcept; + /** + * Returns the transform matrix of the texture attached to the stream. + * @param stream Stream to get the transform matrix from + * @param uvTransform Output parameter: Transform matrix of the image bound to the texture. Returns identity if not supported. + */ + virtual math::mat3f getTransformMatrix(Stream* UTILS_NONNULL stream) noexcept; + // -------------------------------------------------------------------------------------------- // External Image support diff --git a/filament/backend/include/backend/platforms/PlatformEGLAndroid.h b/filament/backend/include/backend/platforms/PlatformEGLAndroid.h index b56d30880b..ecd8fc8ab4 100644 --- a/filament/backend/include/backend/platforms/PlatformEGLAndroid.h +++ b/filament/backend/include/backend/platforms/PlatformEGLAndroid.h @@ -86,6 +86,7 @@ protected: void attach(Stream* stream, intptr_t tname) noexcept override; void detach(Stream* stream) noexcept override; void updateTexImage(Stream* stream, int64_t* timestamp) noexcept override; + math::mat3f getTransformMatrix(Stream* stream) noexcept override; /** * Converts a AHardwareBuffer to EGLImage diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index 81436e4dc9..6f79963cac 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -58,6 +58,7 @@ #include #include +#include #include #include @@ -2163,6 +2164,14 @@ int64_t OpenGLDriver::getStreamTimestamp(Handle sh) { return 0; } +math::mat3f OpenGLDriver::getStreamTransformMatrix(Handle sh) { + if (sh) { + GLStream* s = handle_cast(sh); + return mPlatform.getTransformMatrix(s->stream); + } + return math::mat3f(); +} + void OpenGLDriver::destroyFence(Handle fh) { if (fh) { GLFence* f = handle_cast(fh); diff --git a/filament/backend/src/opengl/OpenGLDriver.h b/filament/backend/src/opengl/OpenGLDriver.h index 5a3f8050a6..8cb735fac4 100644 --- a/filament/backend/src/opengl/OpenGLDriver.h +++ b/filament/backend/src/opengl/OpenGLDriver.h @@ -367,6 +367,7 @@ private: void attachStream(GLTexture* t, GLStream* stream) noexcept; void detachStream(GLTexture* t) noexcept; void replaceStream(GLTexture* t, GLStream* stream) noexcept; + math::mat3f getStreamTransformMatrix(Handle sh); #ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2 // tasks executed on the main thread after the fence signaled diff --git a/filament/backend/src/opengl/OpenGLPlatform.cpp b/filament/backend/src/opengl/OpenGLPlatform.cpp index 57d021cf0d..4506223aa9 100644 --- a/filament/backend/src/opengl/OpenGLPlatform.cpp +++ b/filament/backend/src/opengl/OpenGLPlatform.cpp @@ -141,6 +141,10 @@ void OpenGLPlatform::updateTexImage( UTILS_UNUSED int64_t* timestamp) noexcept { } +math::mat3f OpenGLPlatform::getTransformMatrix( + UTILS_UNUSED Stream* stream) noexcept { +return math::mat3f(); +} OpenGLPlatform::ExternalTexture* OpenGLPlatform::createExternalImageTexture() noexcept { return nullptr; diff --git a/filament/backend/src/opengl/platforms/ExternalStreamManagerAndroid.cpp b/filament/backend/src/opengl/platforms/ExternalStreamManagerAndroid.cpp index 88b929d8bb..f3291c7ebb 100644 --- a/filament/backend/src/opengl/platforms/ExternalStreamManagerAndroid.cpp +++ b/filament/backend/src/opengl/platforms/ExternalStreamManagerAndroid.cpp @@ -38,6 +38,7 @@ typedef struct ASurfaceTexture ASurfaceTexture; #include #include +#include using namespace utils; @@ -73,6 +74,7 @@ JNIEnv* ExternalStreamManagerAndroid::getEnvironmentSlow() noexcept { mSurfaceTextureClass_attachToGLContext = env->GetMethodID(SurfaceTextureClass, "attachToGLContext", "(I)V"); mSurfaceTextureClass_detachFromGLContext = env->GetMethodID(SurfaceTextureClass, "detachFromGLContext", "()V"); mSurfaceTextureClass_getTimestamp = env->GetMethodID(SurfaceTextureClass, "getTimestamp", "()J"); + mSurfaceTextureClass_getTransformMatrix = env->GetMethodID(SurfaceTextureClass, "getTransformMatrix", "([F)V"); return env; } @@ -167,4 +169,25 @@ void ExternalStreamManagerAndroid::updateTexImage(Stream* handle, int64_t* times } } +math::mat3f ExternalStreamManagerAndroid::getTransformMatrix(Stream* handle) noexcept { + EGLStream const* stream = static_cast(handle); + math::mat4f out = math::mat4f(); + if (__builtin_available(android 28, *)) { + ASurfaceTexture_getTransformMatrix(stream->nSurfaceTexture, &out[0][0]); + } else { + JNIEnv* const env = getEnvironment(); + assert_invariant(env); // we should have called attach() by now + auto jout = env->NewFloatArray(16); + env->CallVoidMethod(stream->jSurfaceTexture, mSurfaceTextureClass_getTransformMatrix, jout); + env->GetFloatArrayRegion(jout, 0, 16, &out[0][0]); + env->DeleteLocalRef(jout); + VirtualMachineEnv::handleException(env); + } + return math::mat3f { + out[0][0], out[0][1], out[0][3], + out[1][0], out[1][1], out[1][3], + out[3][0], out[3][1], out[3][3], + }; +} + } // namespace filament::backend diff --git a/filament/backend/src/opengl/platforms/ExternalStreamManagerAndroid.h b/filament/backend/src/opengl/platforms/ExternalStreamManagerAndroid.h index d1257269c3..610cea0ee7 100644 --- a/filament/backend/src/opengl/platforms/ExternalStreamManagerAndroid.h +++ b/filament/backend/src/opengl/platforms/ExternalStreamManagerAndroid.h @@ -33,6 +33,7 @@ typedef struct ASurfaceTexture ASurfaceTexture; #include #include +#include namespace filament::backend { @@ -63,6 +64,9 @@ public: // must be called on GLES context thread, updates the stream content void updateTexImage(Stream* stream, int64_t* timestamp) noexcept; + // must be called on GLES context thread, returns the transform matrix + math::mat3f getTransformMatrix(Stream* stream) noexcept; + private: ExternalStreamManagerAndroid() noexcept; ~ExternalStreamManagerAndroid() noexcept; @@ -88,6 +92,7 @@ private: jmethodID mSurfaceTextureClass_updateTexImage{}; jmethodID mSurfaceTextureClass_getTimestamp{}; + jmethodID mSurfaceTextureClass_getTransformMatrix{}; jmethodID mSurfaceTextureClass_attachToGLContext{}; jmethodID mSurfaceTextureClass_detachFromGLContext{}; }; diff --git a/filament/backend/src/opengl/platforms/PlatformEGLAndroid.cpp b/filament/backend/src/opengl/platforms/PlatformEGLAndroid.cpp index 73828f74ca..e32adb864e 100644 --- a/filament/backend/src/opengl/platforms/PlatformEGLAndroid.cpp +++ b/filament/backend/src/opengl/platforms/PlatformEGLAndroid.cpp @@ -283,6 +283,10 @@ void PlatformEGLAndroid::updateTexImage(Stream* stream, int64_t* timestamp) noex mExternalStreamManager.updateTexImage(stream, timestamp); } +math::mat3f PlatformEGLAndroid::getTransformMatrix(Stream* stream) noexcept { + return mExternalStreamManager.getTransformMatrix(stream); +} + int PlatformEGLAndroid::getOSVersion() const noexcept { return mOSVersion; }