Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit d69917c

Browse files
authored
Directly use 4x4 matrices with surface textures instead of converting to and from the 3x3 variants. (#54126)
SurfaceTextureGetTransformMatrix returns a col-major 4x4 matrix. We used to convert it to a 3x3 matrix. Then when applying the transformation in the shader, I'd convert it back to a 4x4 matrix. Instead of all this (potentially lossy) flip-flopping, store the matrix just as we get it in 4x4 form and perform the conversion just once if necessary. Today, it is necessary only in the Skia backend. SkM44 already has a converter to convert to and from a 3x3 SkMatrix. So, use that instead of rolling our own. I spent a lot of time debugging these conversions and transformations because we had rolled our own and the printers seemed to dump in row-major order irrespective of storage order. This caused a lot of confusion. No change in functionality. Hopefully, the next person debugging transformations has an easier go at this.
1 parent d941f08 commit d69917c

8 files changed

+25
-51
lines changed

shell/platform/android/android_shell_holder_unittests.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ class MockPlatformViewAndroidJNI : public PlatformViewAndroidJNI {
4848
SurfaceTextureUpdateTexImage,
4949
(JavaLocalRef surface_texture),
5050
(override));
51-
MOCK_METHOD(void,
51+
MOCK_METHOD(SkM44,
5252
SurfaceTextureGetTransformMatrix,
53-
(JavaLocalRef surface_texture, SkMatrix& transform),
53+
(JavaLocalRef surface_texture),
5454
(override));
5555
MOCK_METHOD(void,
5656
SurfaceTextureDetachFromGLContext,

shell/platform/android/jni/jni_mock.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ class JNIMock final : public PlatformViewAndroidJNI {
5959
(JavaLocalRef surface_texture),
6060
(override));
6161

62-
MOCK_METHOD(void,
62+
MOCK_METHOD(SkM44,
6363
SurfaceTextureGetTransformMatrix,
64-
(JavaLocalRef surface_texture, SkMatrix& transform),
64+
(JavaLocalRef surface_texture),
6565
(override));
6666

6767
MOCK_METHOD(JavaLocalRef,

shell/platform/android/jni/platform_view_android_jni.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ class PlatformViewAndroidJNI {
107107
/// Then, it updates the `transform` matrix, so it fill the canvas
108108
/// and preserve the aspect ratio.
109109
///
110-
virtual void SurfaceTextureGetTransformMatrix(JavaLocalRef surface_texture,
111-
SkMatrix& transform) = 0;
110+
virtual SkM44 SurfaceTextureGetTransformMatrix(
111+
JavaLocalRef surface_texture) = 0;
112112

113113
//----------------------------------------------------------------------------
114114
/// @brief Detaches a SurfaceTexture from the OpenGL ES context.

shell/platform/android/platform_view_android_jni_impl.cc

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,20 +1502,19 @@ void PlatformViewAndroidJNIImpl::SurfaceTextureUpdateTexImage(
15021502
FML_CHECK(fml::jni::CheckException(env));
15031503
}
15041504

1505-
void PlatformViewAndroidJNIImpl::SurfaceTextureGetTransformMatrix(
1506-
JavaLocalRef surface_texture,
1507-
SkMatrix& transform) {
1505+
SkM44 PlatformViewAndroidJNIImpl::SurfaceTextureGetTransformMatrix(
1506+
JavaLocalRef surface_texture) {
15081507
JNIEnv* env = fml::jni::AttachCurrentThread();
15091508

15101509
if (surface_texture.is_null()) {
1511-
return;
1510+
return {};
15121511
}
15131512

15141513
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
15151514
env, env->CallObjectMethod(surface_texture.obj(),
15161515
g_java_weak_reference_get_method));
15171516
if (surface_texture_local_ref.is_null()) {
1518-
return;
1517+
return {};
15191518
}
15201519

15211520
fml::jni::ScopedJavaLocalRef<jfloatArray> transformMatrix(
@@ -1527,36 +1526,12 @@ void PlatformViewAndroidJNIImpl::SurfaceTextureGetTransformMatrix(
15271526

15281527
float* m = env->GetFloatArrayElements(transformMatrix.obj(), nullptr);
15291528

1530-
// SurfaceTexture 4x4 Column Major -> Skia 3x3 Row Major
1531-
1532-
// SurfaceTexture 4x4 (Column Major):
1533-
// | m[0] m[4] m[ 8] m[12] |
1534-
// | m[1] m[5] m[ 9] m[13] |
1535-
// | m[2] m[6] m[10] m[14] |
1536-
// | m[3] m[7] m[11] m[15] |
1537-
1538-
// According to Android documentation, the 4x4 matrix returned should be used
1539-
// with texture coordinates in the form (s, t, 0, 1). Since the z component is
1540-
// always 0.0, we are free to ignore any element that multiplies with the z
1541-
// component. Converting this to a 3x3 matrix is easy:
1542-
1543-
// SurfaceTexture 3x3 (Column Major):
1544-
// | m[0] m[4] m[12] |
1545-
// | m[1] m[5] m[13] |
1546-
// | m[3] m[7] m[15] |
1547-
1548-
// Skia (Row Major):
1549-
// | m[0] m[1] m[2] |
1550-
// | m[3] m[4] m[5] |
1551-
// | m[6] m[7] m[8] |
1552-
1553-
SkScalar matrix3[] = {
1554-
m[0], m[4], m[12], //
1555-
m[1], m[5], m[13], //
1556-
m[3], m[7], m[15], //
1557-
};
1529+
static_assert(sizeof(SkScalar) == sizeof(float));
1530+
const auto transform = SkM44::ColMajor(m);
1531+
15581532
env->ReleaseFloatArrayElements(transformMatrix.obj(), m, JNI_ABORT);
1559-
transform.set9(matrix3);
1533+
1534+
return transform;
15601535
}
15611536

15621537
void PlatformViewAndroidJNIImpl::SurfaceTextureDetachFromGLContext(

shell/platform/android/platform_view_android_jni_impl.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ class PlatformViewAndroidJNIImpl final : public PlatformViewAndroidJNI {
4949

5050
void SurfaceTextureUpdateTexImage(JavaLocalRef surface_texture) override;
5151

52-
void SurfaceTextureGetTransformMatrix(JavaLocalRef surface_texture,
53-
SkMatrix& transform) override;
52+
SkM44 SurfaceTextureGetTransformMatrix(JavaLocalRef surface_texture) override;
5453

5554
void SurfaceTextureDetachFromGLContext(JavaLocalRef surface_texture) override;
5655

shell/platform/android/surface_texture_external_texture.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void SurfaceTextureExternalTexture::DrawFrame(
6767
PaintContext& context,
6868
const SkRect& bounds,
6969
const DlImageSampling sampling) const {
70-
auto transform = GetCurrentUVTransformation();
70+
auto transform = GetCurrentUVTransformation().asM33();
7171

7272
// Android's SurfaceTexture transform matrix works on texture coordinate
7373
// lookups in the range 0.0-1.0, while Skia's Shader transform matrix works on
@@ -136,12 +136,11 @@ bool SurfaceTextureExternalTexture::ShouldUpdate() {
136136
void SurfaceTextureExternalTexture::Update() {
137137
jni_facade_->SurfaceTextureUpdateTexImage(
138138
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_));
139-
jni_facade_->SurfaceTextureGetTransformMatrix(
140-
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_), transform_);
139+
transform_ = jni_facade_->SurfaceTextureGetTransformMatrix(
140+
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_));
141141
}
142142

143-
const SkMatrix& SurfaceTextureExternalTexture::GetCurrentUVTransformation()
144-
const {
143+
const SkM44& SurfaceTextureExternalTexture::GetCurrentUVTransformation() const {
145144
return transform_;
146145
}
147146

shell/platform/android/surface_texture_external_texture.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "flutter/common/graphics/texture.h"
1111
#include "flutter/shell/platform/android/platform_view_android_jni_impl.h"
12+
#include "flutter/third_party/skia/include/core/SkM44.h"
1213

1314
namespace flutter {
1415

@@ -64,7 +65,7 @@ class SurfaceTextureExternalTexture : public flutter::Texture {
6465
///
6566
/// @return The current uv transformation.
6667
///
67-
const SkMatrix& GetCurrentUVTransformation() const;
68+
const SkM44& GetCurrentUVTransformation() const;
6869

6970
//----------------------------------------------------------------------------
7071
/// @brief Provides an opportunity for the subclasses to sever the
@@ -111,7 +112,7 @@ class SurfaceTextureExternalTexture : public flutter::Texture {
111112
sk_sp<flutter::DlImage> dl_image_;
112113

113114
private:
114-
SkMatrix transform_;
115+
SkM44 transform_;
115116

116117
// |Texture|
117118
void Paint(PaintContext& context,

shell/platform/android/surface_texture_external_texture_vk_impeller.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,9 @@ void SurfaceTextureExternalTextureVKImpeller::ProcessFrame(
148148
vk::ImageLayout::eColorAttachmentOptimal,
149149
LayoutUpdateMode::kSync);
150150

151-
SkM44 transformation(GetCurrentUVTransformation());
152151
impeller::Matrix uv_transformation;
153-
transformation.getColMajor(reinterpret_cast<SkScalar*>(&uv_transformation));
152+
GetCurrentUVTransformation().getColMajor(
153+
reinterpret_cast<SkScalar*>(&uv_transformation));
154154

155155
glvk::Trampoline::GLTextureInfo src_texture;
156156
src_texture.texture = src_gl_texture;

0 commit comments

Comments
 (0)