Skip to content

Commit 036e7cb

Browse files
jason-simmonsflutteractionsbot
authored andcommitted
[Android] Close FlutterRenderer texture image SyncFence objects immediately after waiting on them (flutter#188313)
Each SyncFence may use a file descriptor. But the SyncFences were not being closed promptly and their file descriptors were not being deleted until the SyncFences were garbage collected. If the process is rendering video and creating a SyncFence for each frame, then it may run out of file descriptor capacity before Java GC happens. Fixes flutter#188161
1 parent ee80f08 commit 036e7cb

2 files changed

Lines changed: 17 additions & 5 deletions

File tree

engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -785,9 +785,9 @@ private void cleanup() {
785785
}
786786

787787
@RequiresApi(API_LEVELS.API_33)
788-
private void waitOnFence(Image image) {
789-
try {
790-
SyncFence fence = image.getFence();
788+
@VisibleForTesting
789+
void waitOnFence(Image image) {
790+
try (SyncFence fence = image.getFence()) {
791791
fence.awaitForever();
792792
} catch (IOException e) {
793793
// Drop.
@@ -1066,8 +1066,7 @@ public void pushImage(Image image) {
10661066

10671067
@RequiresApi(API_LEVELS.API_33)
10681068
private void waitOnFence(Image image) {
1069-
try {
1070-
SyncFence fence = image.getFence();
1069+
try (SyncFence fence = image.getFence()) {
10711070
fence.awaitForever();
10721071
} catch (IOException e) {
10731072
// Drop.

engine/src/flutter/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import android.graphics.Canvas;
2929
import android.graphics.Rect;
3030
import android.graphics.SurfaceTexture;
31+
import android.hardware.SyncFence;
3132
import android.media.Image;
3233
import android.media.ImageReader;
3334
import android.os.Looper;
@@ -1074,4 +1075,16 @@ public void restoreSurfaceProducers_restoresImageReaderSurfaceProducersAsIfAppli
10741075
assertFalse(imageReaderProducer1.notifiedDestroy);
10751076
assertFalse(imageReaderProducer2.notifiedDestroy);
10761077
}
1078+
1079+
@Test
1080+
public void waitOnFence_closesFence() throws Exception {
1081+
FlutterRenderer.ImageReaderSurfaceProducer producer =
1082+
(FlutterRenderer.ImageReaderSurfaceProducer)
1083+
engineRule.getFlutterEngine().getRenderer().createSurfaceProducer();
1084+
Image image = mock(Image.class);
1085+
SyncFence fence = mock(SyncFence.class);
1086+
when(image.getFence()).thenReturn(fence);
1087+
producer.waitOnFence(image);
1088+
verify(fence, times(1)).close();
1089+
}
10771090
}

0 commit comments

Comments
 (0)