11
11
import android .view .Surface ;
12
12
import io .flutter .view .TextureRegistry .ImageTextureEntry ;
13
13
14
- @ TargetApi (29 )
14
+ @ TargetApi (26 )
15
15
public class ImageReaderPlatformViewRenderTarget implements PlatformViewRenderTarget {
16
16
private ImageTextureEntry textureEntry ;
17
+ private boolean mustRecreateImageReader = false ;
17
18
private ImageReader reader ;
18
19
private int bufferWidth = 0 ;
19
20
private int bufferHeight = 0 ;
20
21
private static final String TAG = "ImageReaderPlatformViewRenderTarget" ;
21
22
22
23
private void closeReader () {
23
24
if (this .reader != null ) {
24
- // Push a null image, forcing the texture entry to close any cached images.
25
- textureEntry .pushImage (null );
26
- // Close the reader, which also closes any produced images.
27
25
this .reader .close ();
28
26
this .reader = null ;
29
27
}
30
28
}
31
29
30
+ private void recreateImageReaderIfNeeded () {
31
+ if (!mustRecreateImageReader ) {
32
+ return ;
33
+ }
34
+ mustRecreateImageReader = false ;
35
+ closeReader ();
36
+ this .reader = createImageReader ();
37
+ }
38
+
32
39
private final Handler onImageAvailableHandler = new Handler ();
33
40
private final ImageReader .OnImageAvailableListener onImageAvailableListener =
34
41
new ImageReader .OnImageAvailableListener () {
@@ -48,12 +55,9 @@ protected ImageReader createImageReader33() {
48
55
// Allow for double buffering.
49
56
builder .setMaxImages (3 );
50
57
// Use PRIVATE image format so that we can support video decoding.
51
- // TODO(johnmccutchan): Should we always use PRIVATE here? It may impact our
52
- // ability to read back texture data. If we don't always want to use it, how do we
53
- // decide when to use it or not? Perhaps PlatformViews can indicate if they may contain
54
- // DRM'd content.
55
- // I need to investigate how PRIVATE impacts our ability to take screenshots or capture
56
- // the output of Flutter application.
58
+ // TODO(johnmccutchan): Should we always use PRIVATE here? It may impact our ability
59
+ // to read back texture data. If we don't always want to use it, how do we decide when
60
+ // to use it or not? Perhaps PlatformViews can indicate if they may contain DRM'd content.
57
61
builder .setImageFormat (ImageFormat .PRIVATE );
58
62
// Hint that consumed images will only be read by GPU.
59
63
builder .setUsage (HardwareBuffer .USAGE_GPU_SAMPLED_IMAGE );
@@ -64,31 +68,29 @@ protected ImageReader createImageReader33() {
64
68
65
69
@ TargetApi (29 )
66
70
protected ImageReader createImageReader29 () {
67
- final ImageReader reader =
68
- ImageReader .newInstance (
69
- bufferWidth ,
70
- bufferHeight ,
71
- ImageFormat .PRIVATE ,
72
- 2 ,
73
- HardwareBuffer .USAGE_GPU_SAMPLED_IMAGE );
74
- reader .setOnImageAvailableListener (this .onImageAvailableListener , onImageAvailableHandler );
75
- return reader ;
71
+ return ImageReader .newInstance (
72
+ bufferWidth , bufferHeight , ImageFormat .PRIVATE , 2 , HardwareBuffer .USAGE_GPU_SAMPLED_IMAGE );
73
+ }
74
+
75
+ @ TargetApi (26 )
76
+ protected ImageReader createImageReader26 () {
77
+ return ImageReader .newInstance (bufferWidth , bufferHeight , ImageFormat .PRIVATE , 2 );
76
78
}
77
79
78
80
protected ImageReader createImageReader () {
79
81
if (Build .VERSION .SDK_INT >= 33 ) {
80
82
return createImageReader33 ();
81
83
} else if (Build .VERSION .SDK_INT >= 29 ) {
82
84
return createImageReader29 ();
85
+ } else {
86
+ return createImageReader26 ();
83
87
}
84
- throw new UnsupportedOperationException (
85
- "ImageReaderPlatformViewRenderTarget requires API version 29+" );
86
88
}
87
89
88
90
public ImageReaderPlatformViewRenderTarget (ImageTextureEntry textureEntry ) {
89
- if (Build .VERSION .SDK_INT < 29 ) {
91
+ if (Build .VERSION .SDK_INT < 26 ) {
90
92
throw new UnsupportedOperationException (
91
- "ImageReaderPlatformViewRenderTarget requires API version 29 +" );
93
+ "ImageReaderPlatformViewRenderTarget requires API version 26 +" );
92
94
}
93
95
this .textureEntry = textureEntry ;
94
96
}
@@ -125,16 +127,17 @@ public long getId() {
125
127
}
126
128
127
129
public void release () {
128
- closeReader ();
129
130
// textureEntry has a finalizer attached.
130
131
textureEntry = null ;
132
+ closeReader ();
131
133
}
132
134
133
135
public boolean isReleased () {
134
136
return this .textureEntry == null ;
135
137
}
136
138
137
139
public Surface getSurface () {
140
+ recreateImageReaderIfNeeded ();
138
141
return this .reader .getSurface ();
139
142
}
140
143
}
0 commit comments