From 2747ea7d17b22716dc4cca528c9debc3f7a91dfa Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Tue, 4 Jan 2022 23:17:32 +0100 Subject: [PATCH 1/6] Fix crash in BackdropFilterLayer::Diff (#30460) * Fix crash in BackdropFilterLayer::Diff * Pass context transform to filterBounds instead of scaling the filter --- flow/layers/backdrop_filter_layer.cc | 8 ++----- .../layers/backdrop_filter_layer_unittests.cc | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/flow/layers/backdrop_filter_layer.cc b/flow/layers/backdrop_filter_layer.cc index 548db3227d72e..8e8ef2628a16b 100644 --- a/flow/layers/backdrop_filter_layer.cc +++ b/flow/layers/backdrop_filter_layer.cc @@ -25,15 +25,11 @@ void BackdropFilterLayer::Diff(DiffContext* context, const Layer* old_layer) { context->AddLayerBounds(paint_bounds); if (filter_) { - // convert paint bounds and filter to screen coordinates context->GetTransform().mapRect(&paint_bounds); auto input_filter_bounds = paint_bounds.roundOut(); - auto filter = filter_->makeWithLocalMatrix(context->GetTransform()); - auto filter_bounds = // in screen coordinates - filter->filterBounds(input_filter_bounds, SkMatrix::I(), - SkImageFilter::kReverse_MapDirection); - + filter_->filterBounds(input_filter_bounds, context->GetTransform(), + SkImageFilter::kReverse_MapDirection); context->AddReadbackRegion(filter_bounds); } diff --git a/flow/layers/backdrop_filter_layer_unittests.cc b/flow/layers/backdrop_filter_layer_unittests.cc index 7a5a066fd7344..667b0dc713d28 100644 --- a/flow/layers/backdrop_filter_layer_unittests.cc +++ b/flow/layers/backdrop_filter_layer_unittests.cc @@ -327,5 +327,29 @@ TEST_F(BackdropLayerDiffTest, BackdropLayer) { EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(0, 0, 190, 190)); } +TEST_F(BackdropLayerDiffTest, BackdropLayerInvalidTransform) { + auto filter = SkImageFilters::Blur(10, 10, SkTileMode::kClamp, nullptr); + + { + // tests later assume 30px readback area, fail early if that's not the case + auto readback = filter->filterBounds(SkIRect::MakeWH(10, 10), SkMatrix::I(), + SkImageFilter::kReverse_MapDirection); + EXPECT_EQ(readback, SkIRect::MakeLTRB(-30, -30, 40, 40)); + } + + MockLayerTree l1(SkISize::Make(100, 100)); + SkMatrix transform; + transform.setPerspX(0.1); + transform.setPerspY(0.1); + + auto transform_layer = std::make_shared(transform); + l1.root()->Add(transform_layer); + transform_layer->Add( + std::make_shared(filter, SkBlendMode::kSrcOver)); + + auto damage = DiffLayerTree(l1, MockLayerTree(SkISize::Make(100, 100))); + EXPECT_EQ(damage.frame_damage, SkIRect::MakeWH(15, 15)); +} + } // namespace testing } // namespace flutter From 433d3155bf04ac0e8892fda51bb9a03287beef68 Mon Sep 17 00:00:00 2001 From: Zachary Anderson Date: Thu, 20 Jan 2022 09:46:23 -0800 Subject: [PATCH 2/6] Disable building examples by default (#30946) This should be paired with a recipe change to enable building the example on CI that I'll prepare shortly. --- examples/examples.gni | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/examples.gni b/examples/examples.gni index 6779ee16b905e..4c267169d37ef 100644 --- a/examples/examples.gni +++ b/examples/examples.gni @@ -4,6 +4,6 @@ declare_args() { # The example embedders may use dependencies not suitable on all platforms. - # Use this GN arg to disable building the examples. - build_embedder_examples = is_mac || is_linux + # Use this GN arg to enable building the examples. + build_embedder_examples = false } From 3c44eeff9184ce6ad5a3c2c90789be0586734fd1 Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Fri, 11 Feb 2022 12:30:04 -0800 Subject: [PATCH 3/6] Detach from GL context before attaching (#31390) --- .../renderer/SurfaceTextureWrapper.java | 25 +++++- .../renderer/SurfaceTextureWrapperTest.java | 82 +++++++++++++++++++ 2 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 shell/platform/android/test/io/flutter/embedding/engine/renderer/SurfaceTextureWrapperTest.java diff --git a/shell/platform/android/io/flutter/embedding/engine/renderer/SurfaceTextureWrapper.java b/shell/platform/android/io/flutter/embedding/engine/renderer/SurfaceTextureWrapper.java index b9a9c57d95de4..55f183c6c6cd6 100644 --- a/shell/platform/android/io/flutter/embedding/engine/renderer/SurfaceTextureWrapper.java +++ b/shell/platform/android/io/flutter/embedding/engine/renderer/SurfaceTextureWrapper.java @@ -19,6 +19,7 @@ public class SurfaceTextureWrapper { private SurfaceTexture surfaceTexture; private boolean released; + private boolean attached; public SurfaceTextureWrapper(@NonNull SurfaceTexture surfaceTexture) { this.surfaceTexture = surfaceTexture; @@ -45,6 +46,7 @@ public void release() { if (!released) { surfaceTexture.release(); released = true; + attached = false; } } } @@ -53,16 +55,33 @@ public void release() { @SuppressWarnings("unused") public void attachToGLContext(int texName) { synchronized (this) { - if (!released) { - surfaceTexture.attachToGLContext(texName); + if (released) { + return; + } + // When the rasterizer tasks run on a different thread, the GrContext is re-created. + // This causes the texture to be in an uninitialized state. + // This should *not* be an issue once platform views are always rendered as TextureLayers + // since thread merging will be always disabled on Android. + // For more see: AndroidExternalTextureGL::OnGrContextCreated in + // android_external_texture_gl.cc, and + // https://github.com/flutter/flutter/issues/98155 + if (attached) { + surfaceTexture.detachFromGLContext(); } + surfaceTexture.attachToGLContext(texName); + attached = true; } } // Called by native. @SuppressWarnings("unused") public void detachFromGLContext() { - surfaceTexture.detachFromGLContext(); + synchronized (this) { + if (attached && !released) { + surfaceTexture.detachFromGLContext(); + attached = false; + } + } } // Called by native. diff --git a/shell/platform/android/test/io/flutter/embedding/engine/renderer/SurfaceTextureWrapperTest.java b/shell/platform/android/test/io/flutter/embedding/engine/renderer/SurfaceTextureWrapperTest.java new file mode 100644 index 0000000000000..a9395f675235a --- /dev/null +++ b/shell/platform/android/test/io/flutter/embedding/engine/renderer/SurfaceTextureWrapperTest.java @@ -0,0 +1,82 @@ +package io.flutter.embedding.engine.renderer; + +import static junit.framework.TestCase.*; +import static org.mockito.Mockito.*; + +import android.graphics.SurfaceTexture; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class SurfaceTextureWrapperTest { + + @Test + public void attachToGLContext() { + final SurfaceTexture tx = mock(SurfaceTexture.class); + final SurfaceTextureWrapper wrapper = new SurfaceTextureWrapper(tx); + + wrapper.attachToGLContext(0); + verify(tx, times(1)).attachToGLContext(0); + verifyNoMoreInteractions(tx); + } + + @Test + public void attachToGLContext_detachesFromCurrentContext() { + final SurfaceTexture tx = mock(SurfaceTexture.class); + final SurfaceTextureWrapper wrapper = new SurfaceTextureWrapper(tx); + + wrapper.attachToGLContext(0); + + reset(tx); + + wrapper.attachToGLContext(0); + verify(tx, times(1)).detachFromGLContext(); + verify(tx, times(1)).attachToGLContext(0); + verifyNoMoreInteractions(tx); + } + + @Test + public void attachToGLContext_doesNotDetacheFromCurrentContext() { + final SurfaceTexture tx = mock(SurfaceTexture.class); + final SurfaceTextureWrapper wrapper = new SurfaceTextureWrapper(tx); + + wrapper.attachToGLContext(0); + + wrapper.detachFromGLContext(); + + reset(tx); + + wrapper.attachToGLContext(0); + verify(tx, times(1)).attachToGLContext(0); + verifyNoMoreInteractions(tx); + } + + @Test + public void detachFromGLContext() { + final SurfaceTexture tx = mock(SurfaceTexture.class); + final SurfaceTextureWrapper wrapper = new SurfaceTextureWrapper(tx); + + wrapper.attachToGLContext(0); + reset(tx); + + wrapper.detachFromGLContext(); + verify(tx, times(1)).detachFromGLContext(); + verifyNoMoreInteractions(tx); + } + + @Test + public void release() { + final SurfaceTexture tx = mock(SurfaceTexture.class); + final SurfaceTextureWrapper wrapper = new SurfaceTextureWrapper(tx); + + wrapper.release(); + + verify(tx, times(1)).release(); + reset(tx); + + wrapper.detachFromGLContext(); + wrapper.attachToGLContext(0); + verifyNoMoreInteractions(tx); + } +} From 230a8b0fe1b2a3a767e423684f27f8a03c41769b Mon Sep 17 00:00:00 2001 From: Kevin Chisholm Date: Thu, 17 Feb 2022 15:28:02 -0600 Subject: [PATCH 4/6] 'add branch flutter-2.8-candidate.16 to enabled_branches in .ci.yaml' --- .ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci.yaml b/.ci.yaml index 55abd5a4e951d..d488429fae467 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -6,6 +6,7 @@ # More information at: # * https://github.com/flutter/cocoon/blob/main/CI_YAML.md enabled_branches: + - flutter-2.8-candidate.16 - main - flutter-\d+\.\d+-candidate\.\d+ From 75ae4a4d982575c92253004f14e8a73c6f6781ee Mon Sep 17 00:00:00 2001 From: Kevin Chisholm Date: Thu, 17 Feb 2022 15:29:11 -0600 Subject: [PATCH 5/6] remove ref to branch --- .ci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci.yaml b/.ci.yaml index d488429fae467..55abd5a4e951d 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -6,7 +6,6 @@ # More information at: # * https://github.com/flutter/cocoon/blob/main/CI_YAML.md enabled_branches: - - flutter-2.8-candidate.16 - main - flutter-\d+\.\d+-candidate\.\d+ From 449256d1ac8b4954b0e12c78faed6b442f838297 Mon Sep 17 00:00:00 2001 From: Kevin Chisholm Date: Thu, 17 Feb 2022 19:45:14 -0600 Subject: [PATCH 6/6] add junit dependency to gradle.build --- shell/platform/android/test_runner/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/platform/android/test_runner/build.gradle b/shell/platform/android/test_runner/build.gradle index bb9a1fc781375..826c1f8dba3cb 100644 --- a/shell/platform/android/test_runner/build.gradle +++ b/shell/platform/android/test_runner/build.gradle @@ -46,6 +46,7 @@ android { testImplementation "com.ibm.icu:icu4j:69.1" testImplementation "org.robolectric:robolectric:4.6.1" testImplementation "junit:junit:4.13" + testImplementation "androidx.test.ext:junit:1.1.3" def mockitoVersion = "4.1.0" testImplementation "org.mockito:mockito-core:$mockitoVersion"