From 10cee612bb1d3abeef0497329d508c2ddf760bc9 Mon Sep 17 00:00:00 2001 From: Amir Hardon Date: Fri, 15 Feb 2019 13:11:49 -0800 Subject: [PATCH] Delete GL textures when they are released from the texture registry. (#7836) On Android we were never deleting the textures allocated for the texture registry, which resulted in a memory leak, see: https://github.com/flutter/flutter/issues/24145 --- shell/platform/android/android_external_texture_gl.cc | 6 +++++- .../flutter/embedding/engine/renderer/FlutterRenderer.java | 2 +- shell/platform/android/io/flutter/view/FlutterView.java | 7 ++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/shell/platform/android/android_external_texture_gl.cc b/shell/platform/android/android_external_texture_gl.cc index ead73ccddef79..0d21841338a37 100644 --- a/shell/platform/android/android_external_texture_gl.cc +++ b/shell/platform/android/android_external_texture_gl.cc @@ -16,7 +16,11 @@ AndroidExternalTextureGL::AndroidExternalTextureGL( const fml::jni::JavaObjectWeakGlobalRef& surfaceTexture) : Texture(id), surface_texture_(surfaceTexture), transform(SkMatrix::I()) {} -AndroidExternalTextureGL::~AndroidExternalTextureGL() = default; +AndroidExternalTextureGL::~AndroidExternalTextureGL() { + if (state_ == AttachmentState::attached) { + glDeleteTextures(1, &texture_name_); + } +} void AndroidExternalTextureGL::OnGrContextCreated() { state_ = AttachmentState::uninitialized; diff --git a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java index 6048cd4ab59aa..130f04d6e4551 100644 --- a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java +++ b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java @@ -134,8 +134,8 @@ public void release() { if (released) { return; } - unregisterTexture(id); surfaceTexture.release(); + unregisterTexture(id); released = true; } } diff --git a/shell/platform/android/io/flutter/view/FlutterView.java b/shell/platform/android/io/flutter/view/FlutterView.java index 14c4c42cefba4..6fcdc0a3850b1 100644 --- a/shell/platform/android/io/flutter/view/FlutterView.java +++ b/shell/platform/android/io/flutter/view/FlutterView.java @@ -1128,11 +1128,16 @@ public void release() { return; } released = true; - mNativeView.getFlutterJNI().unregisterTexture(id); + + // The ordering of the next 3 calls is important: + // First we remove the frame listener, then we release the SurfaceTexture, and only after we unregister + // the texture which actually deletes the GL texture. + // Otherwise onFrameAvailableListener might be called after mNativeView==null // (https://github.com/flutter/flutter/issues/20951). See also the check in onFrameAvailable. surfaceTexture.setOnFrameAvailableListener(null); surfaceTexture.release(); + mNativeView.getFlutterJNI().unregisterTexture(id); } } }