Skip to content

Commit

Permalink
Apply transform to textures on android (flutter#4486)
Browse files Browse the repository at this point in the history
* Apply transform to textures on android

* Use RAII canvas save
  • Loading branch information
sigurdm authored Dec 22, 2017
1 parent 7c12600 commit eee4a1e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 5 deletions.
36 changes: 31 additions & 5 deletions shell/platform/android/android_external_texture_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include "flutter/shell/platform/android/android_external_texture_gl.h"

// #include <GLES/gl.h>
#include <GLES/glext.h>
#include "flutter/common/threads.h"
#include "flutter/shell/platform/android/platform_view_android_jni.h"
Expand All @@ -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;

Expand Down Expand Up @@ -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<SkImage> 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<jobject> 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) {
Expand All @@ -77,6 +102,7 @@ void AndroidExternalTextureGL::Update() {
surface_texture_.get(env);
if (!surfaceTexture.is_null()) {
SurfaceTextureUpdateTexImage(env, surfaceTexture.obj());
UpdateTransform();
}
}

Expand Down
4 changes: 4 additions & 0 deletions shell/platform/android/android_external_texture_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class AndroidExternalTextureGL : public flow::Texture {

void Detach();

void UpdateTransform();

enum class AttachmentState { uninitialized, attached, detached };

fml::jni::JavaObjectWeakGlobalRef surface_texture_;
Expand All @@ -45,6 +47,8 @@ class AndroidExternalTextureGL : public flow::Texture {

GLuint texture_name_ = 0;

SkMatrix transform;

FXL_DISALLOW_COPY_AND_ASSIGN(AndroidExternalTextureGL);
};

Expand Down
16 changes: 16 additions & 0 deletions shell/platform/android/platform_view_android_jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");

Expand Down
4 changes: 4 additions & 0 deletions shell/platform/android/platform_view_android_jni.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit eee4a1e

Please sign in to comment.