diff --git a/shell/platform/android/android_external_texture_gl.cc b/shell/platform/android/android_external_texture_gl.cc index 41a89ccb9511de7a4174ec423d944a098d1e4ca6..305ee4fd01d1c1034ec37d51f9d2d4c69d6aa043 100644 --- a/shell/platform/android/android_external_texture_gl.cc +++ b/shell/platform/android/android_external_texture_gl.cc @@ -4,7 +4,6 @@ #include "flutter/shell/platform/android/android_external_texture_gl.h" -// #include #include #include "flutter/common/threads.h" #include "flutter/shell/platform/android/platform_view_android_jni.h" @@ -15,7 +14,7 @@ namespace shell { AndroidExternalTextureGL::AndroidExternalTextureGL( int64_t id, const fml::jni::JavaObjectWeakGlobalRef& surfaceTexture) - : Texture(id), surface_texture_(surfaceTexture) {} + : Texture(id), surface_texture_(surfaceTexture), transform(SkMatrix::I()) {} AndroidExternalTextureGL::~AndroidExternalTextureGL() = default; @@ -44,16 +43,42 @@ void AndroidExternalTextureGL::Paint(SkCanvas& canvas, const SkRect& bounds) { new_frame_ready_ = false; } GrGLTextureInfo textureInfo = {GL_TEXTURE_EXTERNAL_OES, texture_name_}; - GrBackendTexture backendTexture(bounds.width(), bounds.height(), - kRGBA_8888_GrPixelConfig, textureInfo); + GrBackendTexture backendTexture(1, 1, kRGBA_8888_GrPixelConfig, textureInfo); sk_sp image = SkImage::MakeFromTexture( canvas.getGrContext(), backendTexture, kTopLeft_GrSurfaceOrigin, SkAlphaType::kPremul_SkAlphaType, nullptr); if (image) { - canvas.drawImage(image, bounds.x(), bounds.y()); + SkAutoCanvasRestore autoRestore(&canvas, true); + canvas.translate(bounds.x(), bounds.y()); + canvas.scale(bounds.width(), bounds.height()); + if (!transform.isIdentity()) { + SkMatrix transformAroundCenter(transform); + + transformAroundCenter.preTranslate(-0.5, -0.5); + transformAroundCenter.postScale(1, -1); + transformAroundCenter.postTranslate(0.5, 0.5); + canvas.concat(transformAroundCenter); + } + canvas.drawImage(image, 0, 0); } } +void AndroidExternalTextureGL::UpdateTransform() { + JNIEnv* env = fml::jni::AttachCurrentThread(); + fml::jni::ScopedJavaLocalRef surfaceTexture = + surface_texture_.get(env); + jfloatArray transformMatrix = env->NewFloatArray(16); + SurfaceTextureGetTransformMatrix(env, surfaceTexture.obj(), transformMatrix); + float* m = env->GetFloatArrayElements(transformMatrix, nullptr); + SkScalar matrix3[] = { + m[0], m[1], m[2], // + m[4], m[5], m[6], // + m[8], m[9], m[10], // + }; + env->ReleaseFloatArrayElements(transformMatrix, m, JNI_ABORT); + transform.set9(matrix3); +} + void AndroidExternalTextureGL::OnGrContextDestroyed() { ASSERT_IS_GPU_THREAD; if (state_ == AttachmentState::attached) { @@ -77,6 +102,7 @@ void AndroidExternalTextureGL::Update() { surface_texture_.get(env); if (!surfaceTexture.is_null()) { SurfaceTextureUpdateTexImage(env, surfaceTexture.obj()); + UpdateTransform(); } } diff --git a/shell/platform/android/android_external_texture_gl.h b/shell/platform/android/android_external_texture_gl.h index 73b1de203b577fc86cc79846affab25d370abcfa..df890b91c827f4a87a6d35a65d82834c93d3dde3 100644 --- a/shell/platform/android/android_external_texture_gl.h +++ b/shell/platform/android/android_external_texture_gl.h @@ -35,6 +35,8 @@ class AndroidExternalTextureGL : public flow::Texture { void Detach(); + void UpdateTransform(); + enum class AttachmentState { uninitialized, attached, detached }; fml::jni::JavaObjectWeakGlobalRef surface_texture_; @@ -45,6 +47,8 @@ class AndroidExternalTextureGL : public flow::Texture { GLuint texture_name_ = 0; + SkMatrix transform; + FXL_DISALLOW_COPY_AND_ASSIGN(AndroidExternalTextureGL); }; diff --git a/shell/platform/android/platform_view_android_jni.cc b/shell/platform/android/platform_view_android_jni.cc index 448e809f6c14d87fe177856213239f1905bdd25b..be70ff4c8bb9ce0fb5f3279bbd931fbc1ecbf53b 100644 --- a/shell/platform/android/platform_view_android_jni.cc +++ b/shell/platform/android/platform_view_android_jni.cc @@ -90,6 +90,15 @@ void SurfaceTextureUpdateTexImage(JNIEnv* env, jobject obj) { FXL_CHECK(CheckException(env)); } +static jmethodID g_get_transform_matrix_method = nullptr; +void SurfaceTextureGetTransformMatrix(JNIEnv* env, + jobject obj, + jfloatArray result) { + ASSERT_IS_GPU_THREAD; + env->CallVoidMethod(obj, g_get_transform_matrix_method, result); + FXL_CHECK(CheckException(env)); +} + static jmethodID g_detach_from_gl_context_method = nullptr; void SurfaceTextureDetachFromGLContext(JNIEnv* env, jobject obj) { ASSERT_IS_GPU_THREAD; @@ -502,6 +511,13 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { return false; } + g_get_transform_matrix_method = env->GetMethodID( + g_surface_texture_class->obj(), "getTransformMatrix", "([F)V"); + + if (g_get_transform_matrix_method == nullptr) { + return false; + } + g_detach_from_gl_context_method = env->GetMethodID( g_surface_texture_class->obj(), "detachFromGLContext", "()V"); diff --git a/shell/platform/android/platform_view_android_jni.h b/shell/platform/android/platform_view_android_jni.h index 76915734f3dfbff27eeb9a35d4c3e2b85472e5ee..65dff978d1a9e07c6918688c8f52bc36b6a83d3c 100644 --- a/shell/platform/android/platform_view_android_jni.h +++ b/shell/platform/android/platform_view_android_jni.h @@ -33,6 +33,10 @@ void SurfaceTextureAttachToGLContext(JNIEnv* env, jobject obj, jint textureId); void SurfaceTextureUpdateTexImage(JNIEnv* env, jobject obj); +void SurfaceTextureGetTransformMatrix(JNIEnv* env, + jobject obj, + jfloatArray result); + void SurfaceTextureDetachFromGLContext(JNIEnv* env, jobject obj); } // namespace shell