Flutter Engine
The Flutter Engine
SurfaceTexturePlatformViewRenderTarget.java
Go to the documentation of this file.
1package io.flutter.plugin.platform;
2
3import static android.content.ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
4import static io.flutter.Build.API_LEVELS;
5
6import android.annotation.TargetApi;
7import android.graphics.SurfaceTexture;
8import android.os.Build;
9import android.view.Surface;
10import io.flutter.view.TextureRegistry;
11import io.flutter.view.TextureRegistry.SurfaceTextureEntry;
12
13@TargetApi(API_LEVELS.API_26)
15 private static final String TAG = "SurfaceTexturePlatformViewRenderTarget";
16
17 private final SurfaceTextureEntry surfaceTextureEntry;
18
19 private SurfaceTexture surfaceTexture;
20 private Surface surface;
21 private int bufferWidth = 0;
22 private int bufferHeight = 0;
23
24 private boolean shouldRecreateSurfaceForLowMemory = false;
25 private final TextureRegistry.OnTrimMemoryListener trimMemoryListener =
27 @Override
28 public void onTrimMemory(int level) {
29 // When a memory pressure warning is received and the level equal {@code
30 // ComponentCallbacks2.TRIM_MEMORY_COMPLETE}, the Android system releases the underlying
31 // surface. If we continue to use the surface (e.g., call lockHardwareCanvas), a crash
32 // occurs, and we found that this crash appeared on Android 10 and above.
33 // See https://github.com/flutter/flutter/issues/103870 for more details.
34 //
35 // Here our workaround is to recreate the surface before using it.
36 if (level == TRIM_MEMORY_COMPLETE && Build.VERSION.SDK_INT >= API_LEVELS.API_29) {
37 shouldRecreateSurfaceForLowMemory = true;
38 }
39 }
40 };
41
42 private void recreateSurfaceIfNeeded() {
43 if (surface != null && !shouldRecreateSurfaceForLowMemory) {
44 // No need to recreate the surface.
45 return;
46 }
47 if (surface != null) {
48 surface.release();
49 surface = null;
50 }
51 surface = createSurface();
52 shouldRecreateSurfaceForLowMemory = false;
53 }
54
55 protected Surface createSurface() {
56 return new Surface(surfaceTexture);
57 }
58
59 /** Implementation of PlatformViewRenderTarget */
61 if (Build.VERSION.SDK_INT < API_LEVELS.API_23) {
62 throw new UnsupportedOperationException(
63 "Platform views cannot be displayed below API level 23"
64 + "You can prevent this issue by setting `minSdkVersion: 23` in build.gradle.");
65 }
66 this.surfaceTextureEntry = surfaceTextureEntry;
67 this.surfaceTexture = surfaceTextureEntry.surfaceTexture();
68 surfaceTextureEntry.setOnTrimMemoryListener(trimMemoryListener);
69 }
70
71 public void resize(int width, int height) {
72 bufferWidth = width;
73 bufferHeight = height;
74 if (surfaceTexture != null) {
75 surfaceTexture.setDefaultBufferSize(bufferWidth, bufferHeight);
76 }
77 }
78
79 public int getWidth() {
80 return bufferWidth;
81 }
82
83 public int getHeight() {
84 return bufferHeight;
85 }
86
87 public long getId() {
88 return this.surfaceTextureEntry.id();
89 }
90
91 public boolean isReleased() {
92 return surfaceTexture == null;
93 }
94
95 public void release() {
96 // Don't release the texture, let the GC finalize it.
97 surfaceTexture = null;
98 if (surface != null) {
99 surface.release();
100 surface = null;
101 }
102 }
103
104 public Surface getSurface() {
105 recreateSurfaceIfNeeded();
106 if (surfaceTexture == null || surfaceTexture.isReleased()) {
107 return null;
108 }
109 return surface;
110 }
111}
static final int API_29
Definition: Build.java:19
static final int API_23
Definition: Build.java:13
VkSurfaceKHR surface
Definition: main.cc:49
default void setOnTrimMemoryListener(@Nullable OnTrimMemoryListener listener)
def Build(configs, env, options)
Definition: build.py:232
#define TAG()
int32_t height
int32_t width