├── README.md ├── patches ├── alf_stable_v1.5.4 │ ├── engine#src#flutter │ │ ├── 0001-Add-external-surface-texture-support-By-lujunchen.patch │ │ ├── 0002-Fix-a-tap-failure-problem-when-double-click-on-FlutterViewController.patch │ │ ├── 0003-A-workaround-for-libgpu-related-crash-in-background.patch │ │ ├── 0004-Workaround-for-android-eglCreateContext-fail.patch │ │ ├── 0005-iphone_simulator_image_invisible_by_lujunchen.patch │ │ ├── 0006-fix-engine-transform_layer-crash-by-SanLi.patch │ │ ├── 0007-get-context-android-by-lujunchen.patch │ │ └── 0008-fix-crash-in-AccessibilityBridge-by-sanli.patch │ ├── engine#src#third_party#boringssl#src │ │ └── 0001-Add-intel-emulation-layer-logic-for-arm.patch │ ├── engine#src#third_party#skia │ │ └── 0001-Workaround-for-Flutter-related-black-screen-in-some-.patch │ └── flutter │ │ ├── 0001-Enable-git-track-for-bin-cache.patch │ │ ├── 0002-Disable-pod-install-in-flutter-tools.patch │ │ ├── 0003-FocusNode-adds-api-to-disableKeyboard.patch │ │ ├── 0004-Add-flutter-tools-hook-by-JiangXiu.patch │ │ ├── 0005-LaunchActivity-android-by-SanLi.patch │ │ └── 0006-Android-cursor-by-SanLi.patch └── stable_v1.0 │ ├── engine#src#flutter │ ├── 0001-Add-external-surface-texture-support-By-luj.patch │ ├── 0002-Fix-a-tap-failure-problem-when-double-click.patch │ ├── 0003-A-workaround-for-libgpu-related-crash-in-ba.patch │ ├── 0004-Add-notify-idle-api-for-engine-by-Fuju.patch │ ├── 0005-Workaround-for-android-eglCreateContext-fai.patch │ └── 0006-Fix-accessibility-dealloc-resulted-crash.patch │ ├── engine#src#third_party#boringssl#src │ └── 0001-Add-intel-emulation-layer-logic-for-arm.patch │ └── engine#src#third_party#skia │ └── 0001-Workaround-for-Flutter-related-black-screen.patch └── script ├── android_engine_symbolicate.py └── get_dartsdk_for_flutter.py /README.md: -------------------------------------------------------------------------------- 1 | # 内容归档 2 | 3 | ## 构建相关 4 | ### Xcode10上如何自定义引擎构建 5 | 6 | [Supporting legacy platforms](https://github.com/flutter/flutter/wiki/Supporting-legacy-platforms) 7 | 8 | ## 工具链 9 | 10 | ## 文档 11 | 12 | ## C++支持 13 | 14 | ## 反射支持 15 | 16 | ## 包大小优化 17 | 18 | ## 性能调优 19 | 20 | ## 符号化 21 | 22 | Android: 23 | 24 | 参见:[Symbolicate the crash](https://github.com/flutter/flutter/wiki/Crashes) 25 | 26 | ## 自定义构建替换flutter自带的snapshots 27 | 目前在flutter/bin/cache/dart-sdk/bin/snapshots目录下,存在多个flutter自带的snapshots。 28 | ``` 29 | 如用于分析的analysis_server.dart.snapshot,dartanalyzer.dart.snapshot; 30 | 用于文档的dartfmt.dart.snapshot; 31 | 用于格式化的dartfmt.dart.snapshot; 32 | 用于kernel-service的kernel-service.dart.snapshot; 33 | 用于依赖获取的pub.dart.snapshot; 34 | ``` 35 | 那么当我们需要去修改的时候,如何处理呢? 36 | 请使用: script/get_dartsdk_for_flutter.py 37 | 38 | 例如,需要修改用于IDE代码分析的analysis_server.dart.snapshot,则可以通过 39 | ``` 40 | get_dartsdk_for_flutter.py -fp your-flutter-root-path 41 | ``` 42 | 这个脚本将会根据你的flutter环境中的依赖关系,获取具体的dartsdk依赖,然后重新生成相应的snapshot,替换即可。 43 | 当需要编辑相应源代码的时候,找到对应的package,fork出来修改,替换,使用脚本重新编译(修改会被保留,因而生效)重新编译构建snapshot,替换即可。 44 | 45 | ## Patches (stable_v1.0) 46 | 47 | 兼容性问题 48 | 49 | ### HUAWEI P6-T00 Android 4.2.2, API 17 50 | #### 问题 51 | Flutter页面黑并且Crash 52 | #### 错误日志: 53 | ``` 54 | [ERROR:flutter/shell/platform/android/android_context_gl.cc(187)] Could not create an EGL context[ERROR:flutter/shell/platform/android/android_context_gl.cc(53)] EGL Error: EGL_BAD_MATCH (12297) 55 | ``` 56 | #### 问题分析: 57 | 此款设备上OpenGL driver支持有问题,造成share context创建失败。 58 | 59 | #### 解决方案: 60 | 在engine(engine/src/flutter)中添加错误时的容错逻辑(不会影响之前正常的设备)。参见: 61 | patches/stable_v1.0/engine#src#flutter/0005-Workaround-for-android-eglCreateContext-fai.patch 62 | 63 | #### 问题跟踪: 64 | https://github.com/flutter/engine/pull/6358 65 | 66 | ### Xiaomi MI PAD 2 Android5.1 API 22 67 | #### 问题1 68 | 黑屏并且Crash 69 | #### 错误日志 70 | ``` 71 | [ERROR:flutter/shell/gpu/gpu_surface_gl.cc(55)] Failed to setup Skia Gr context. 72 | ``` 73 | #### 问题分析: 74 | 此款设备上OpenGL driver支持有问题,造成skia中的验证逻辑因为GL_EXT_texture_buffer支持不完备而失败。 75 | 76 | #### 解决方案: 77 | 移除skia(engine/src/third_party/skia)中对于GL_EXT_texture_buffer的判断逻辑,因为flutter中已不需要。参见: 78 | patches/stable_v1.0/engine#src#third_party#skia/0001-Workaround-for-Flutter-related-black-screen.patch 79 | 80 | #### 问题跟踪 81 | https://github.com/flutter/flutter/issues/22353 82 | 83 | #### 问题2 84 | 页面内容部分展示后,图片下载网络请求过程中奔溃 85 | 86 | #### 错误日志 87 | ``` 88 | 00 pc 00c20310 /data/app/xxx/lib/arm/libflutter.so 89 | --- --- --- 90 | 00 pc 00c20310 /data/app/com.taobao.idlefish.debug-1/lib/arm/libflutter.so 91 | 01 pc 00bc6ee7 /data/app/com.taobao.idlefish.debug-1/lib/arm/libflutter.so 92 | 符号化:src kylewong$ ./third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line -e ./out/android_release_unopt/libflutter.so 93 | 00c20310 94 | linux-atomic.c:? 95 | 00c20310 96 | linux-atomic.c:? 97 | 00bc6ee7 98 | /Users/kylewong/Codes/Flutter/beta/engine/src/out/android_release_unopt/../../third_party/boringssl/src/crypto/fipsmodule/cipher/e_aes.c:312 99 | ``` 100 | #### 问题分析: 101 | 此款设备是Intel的Atom处理器,openSSL中的相关逻辑对其判断有问题,导致指令集支持判断失败导致奔溃。 102 | #### 解决方案 103 | 在openssl中(engine/src/third_party/boringssl/src)添加对于此种处理器的处理逻辑。参见: 104 | patches/stable_v1.0/engine#src#third_party#boringssl#src/0001-Add-intel-emulation-layer-logic-for-arm.patch 105 | 106 | ### HUAWEI H30-T00 Android 4.2.2 API 17 107 | #### 问题 108 | Flutter页面黑并且Crash 109 | #### 错误日志: 110 | ``` 111 | [ERROR:flutter/shell/gpu/gpu_surface_gl.cc(55)] Failed to setup Skia Gr context. 112 | ``` 113 | #### 问题分析: 114 | 此款设备上OpenGL driver支持有问题,造成skia中的验证逻辑因为GL_EXT_debug_marker支持不完备而失败。参阅https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_debug_marker.txt 115 | GL_EXT_debug_marker用于debug/profile时,用来改善OpenGL & OpenGL ES 开发工具中的用户体验。去除此段逻辑,对于Release模式没有影响,对于Debug/Profile模式,最多是性能诊断的时候,部分机型,可能会发生部分API在被调用时不支持导致异常的问题。 116 | 117 | #### 解决方案: 118 | 移除skia(engine/src/third_party/skia)中对于GL_EXT_debug_marker的判断逻辑。参见: 119 | patches/stable_v1.0/engine#src#third_party#skia/0001-Workaround-for-Flutter-related-black-screen.patch 120 | 121 | ### iOS上手势问题引起的flutter状态异常 122 | #### 问题 123 | Flutter页面点击事件在某些场景下失效 124 | #### 错误现象 125 | 在某些场景下,如当Flutter页面与Native嵌套使用的时候,Flutter页面ListView中带小图可以点击查看大图(Push Native的ViewController展示),大图上单击可以退出Native页面。这种场景下,连续两个手指点击会造成Flutter页面最后滑动异常,表现为页面卡顿或者点击事件不生效。 126 | 127 | #### 问题分析 128 | Flutter在iOS上的手势处理,数据来源于FlutterViewController的touchesBegan/touchesMoved/touchesEnded/touchesCancelled这四个函数。一个触摸事件的正常与结束,取决于开始(touchesBegan)同结束(touchesEnded/touchesCancelled)的对称关系。然而,在此种场景下,这种对称关系被破坏了。 129 | 130 | #### 解决方案: 131 | 在engine(engine/src/flutter)中添加容错逻辑。参见: 132 | patches/stable_v1.0/engine#src#flutter/0002-Fix-a-tap-failure-problem-when-double-click.patch 133 | 134 | #### 问题跟踪 135 | https://github.com/flutter/engine/pull/6145 136 | 137 | 稳定性问题 138 | 139 | ### iOS上后台GPU渲染crash 140 | #### 崩溃日志 141 | ``` 142 | Exception Type: SIGSEGV 143 | Exception Codes: SEGV_ACCERR at 0x1 144 | Triggered by Thread: 24 145 | 146 | Thread 24 Crashed: 147 | 0 libGPUSupportMercury.dylib 0x000000018b1d1f90 _gpus_ReturnNotPermittedKillClient :12 (in libGPUSupportMercury.dylib) 148 | 1 GLEngine 0x0000000185d691f4 0x0000000185c78000 + 987636 149 | 2 GLEngine 0x0000000185d690f8 0x0000000185c78000 + 987384 150 | 3 OpenGLES 0x0000000185d77c58 -[EAGLContext presentRenderbuffer:] :72 (in OpenGLES) 151 | 4 Flutter 0x0000000103a75de8 0x0000000103a54000 + 138728 152 | 5 Flutter 0x0000000103a7880c 0x0000000103a54000 + 149516 153 | 6 Flutter 0x0000000103aa7744 0x0000000103a54000 + 341828 154 | 7 Flutter 0x0000000103aa7c34 0x0000000103a54000 + 343092 155 | 8 Flutter 0x0000000103aa7fd0 0x0000000103a54000 + 344016 156 | 9 Flutter 0x0000000103aa7acc 0x0000000103a54000 + 342732 157 | 10 Flutter 0x0000000103aab4a0 0x0000000103a54000 + 357536 158 | 11 Flutter 0x0000000103a82968 0x0000000103a54000 + 190824 159 | 12 Flutter 0x0000000103a83884 0x0000000103a54000 + 194692 160 | ``` 161 | #### 问题分析: 162 | Flutter Engine实例对应了四个TaskRunner:Platform, UI, GPU 和IO,涉及到直接GPU操作的是GPU和IO,目前的Message Loop下未能彻底保证后台无GPU/IO操作。 163 | 164 | #### 解决方案: 165 | 在engine(engine/src/flutter)中添加前后台切换时对于TaskRunner的暂停/开始操作(从灰度/上线效果看,有效降低了其造成的crash率)。参见: 166 | patches/stable_v1.0/engine#src#flutter/0003-A-workaround-for-libgpu-related-crash-in-ba.patch 167 | 168 | ###iOS上内存abort问题 169 | #### 崩溃现象: 170 | 连续打开多个Flutter页面(页面上有大量的图片视频等内存占用高的对象)时,iPhone 6Plus等设备上很容易因为内存原因崩溃。 171 | 172 | #### 解决方案: 173 | 在engine(engine/src/flutter)中添加页面切换时dart垃圾收集的调用机制。参见: 174 | patches/stable_v1.0/engine#src#flutter/0004-Add-notify-idle-api-for-engine-by-Fuju.patch 175 | 176 | ###iOS上accessibility析构相关crash(最新master已修复) 177 | #### 崩溃日志: 178 | ``` 179 | Exception Type: SIGSEGV 180 | Exception Codes: SEGV_ACCERR at 0x9e65bee10 181 | Triggered by Thread: 0 182 | Thread 0 Crashed: 183 | 0 libobjc.A.dylib 0x0000000187587ca8 _objc_release 184 | 1 libobjc.A.dylib 0x0000000187589b9c __ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv 185 | 2 CoreFoundation 0x00000001883268f4 ___CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ 186 | 3 CoreFoundation 0x0000000188326624 ___CFRunLoopDoTimer 187 | 4 CoreFoundation 0x0000000188325e58 ___CFRunLoopDoTimers 188 | 5 CoreFoundation 0x0000000188320da8 ___CFRunLoopRun 189 | 6 CoreFoundation 0x0000000188320354 _CFRunLoopRunSpecific 190 | 7 GraphicsServices 0x000000018a52079c _GSEventRunModal 191 | 8 UIKitCore 0x00000001b47c9b68 _UIApplicationMain 192 | 9 Runner 0x0000000106457c70 main main.m 193 | 10 libdyld.dylib 0x0000000187de68e0 _start 194 | ``` 195 | #### 解决方案: 196 | 在engine(engine/src/flutter)中accessibility_bridge.mm添加bugfix代码。参见: 197 | patches/stable_v1.0/engine#src#flutter/0006-Fix-accessibility-dealloc-resulted-crash.patch 198 | 199 | 功能优化 200 | ### Flutter拍摄视频等使用场景下的多余内存拷贝问题 201 | #### 问题: 202 | 之前在视频拍摄的应用场景下,摄像头数据先会被拷贝到GPU中生成GPU纹理,然后基于纹理去实现美颜/滤镜等纹理操作,处理完成后如果需要给Flutter端显示预览数据,则需要将GPU数据拷贝到CPU中,再由Flutte Engine本身的纹理机制拷贝到GPU中生成纹理用于渲染。 203 | 修改后则将美颜/滤镜等纹理操作生成的纹理直接提供给Flutter Engine用于渲染。 204 | #### 解决方案: 205 | 在engine(engine/src/flutter)中添加patch代码。参见: 206 | patches/stable_v1.0/engine#src#flutter/0001-Add-external-surface-texture-support-By-luj.patch 207 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/engine#src#flutter/0001-Add-external-surface-texture-support-By-lujunchen.patch: -------------------------------------------------------------------------------- 1 | From 94b6af93d8fe5c69b66cdf7a8c213dba3d0855b0 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Fri, 21 Dec 2018 23:51:36 +0800 4 | Subject: [PATCH] Add external surface texture support By lujunchen 5 | 6 | --- 7 | shell/platform/android/android_context_gl.cc | 4 + 8 | shell/platform/android/android_context_gl.h | 2 + 9 | .../android/android_external_texture_gl.cc | 28 +++- 10 | .../android/android_external_texture_gl.h | 3 + 11 | shell/platform/android/android_surface.h | 2 + 12 | shell/platform/android/android_surface_gl.cc | 4 + 13 | shell/platform/android/android_surface_gl.h | 2 + 14 | .../android/android_surface_software.cc | 4 + 15 | .../android/android_surface_software.h | 2 + 16 | .../android/io/flutter/view/FlutterView.java | 129 +++++++++++++++++- 17 | .../io/flutter/view/TextureRegistry.java | 50 +++++++ 18 | .../platform/android/platform_view_android.cc | 10 ++ 19 | .../platform/android/platform_view_android.h | 4 + 20 | .../android/platform_view_android_jni.cc | 40 ++++++ 21 | .../ios/framework/Headers/FlutterTexture.h | 3 + 22 | .../ios/framework/Source/FlutterEngine.mm | 3 + 23 | .../framework/Source/FlutterViewController.mm | 5 + 24 | .../darwin/ios/ios_external_texture_gl.mm | 67 +++++---- 25 | shell/platform/darwin/ios/ios_gl_context.h | 2 + 26 | shell/platform/darwin/ios/ios_gl_context.mm | 9 +- 27 | shell/platform/darwin/ios/ios_surface.h | 2 + 28 | shell/platform/darwin/ios/ios_surface_gl.h | 2 + 29 | shell/platform/darwin/ios/ios_surface_gl.mm | 4 + 30 | .../darwin/ios/ios_surface_software.h | 2 + 31 | .../darwin/ios/ios_surface_software.mm | 4 + 32 | shell/platform/darwin/ios/platform_view_ios.h | 2 + 33 | .../platform/darwin/ios/platform_view_ios.mm | 6 + 34 | 27 files changed, 359 insertions(+), 36 deletions(-) 35 | 36 | diff --git a/shell/platform/android/android_context_gl.cc b/shell/platform/android/android_context_gl.cc 37 | index 8ac43b403..bb4e7b653 100644 38 | --- a/shell/platform/android/android_context_gl.cc 39 | +++ b/shell/platform/android/android_context_gl.cc 40 | @@ -143,6 +143,10 @@ bool AndroidContextGL::CreatePBufferSurface() { 41 | return surface_ != EGL_NO_SURFACE; 42 | } 43 | 44 | +void* AndroidContextGL::GetContext() { 45 | + return context_; 46 | +} 47 | + 48 | AndroidContextGL::AndroidContextGL(fml::RefPtr env, 49 | const AndroidContextGL* share_context) 50 | : environment_(env), 51 | diff --git a/shell/platform/android/android_context_gl.h b/shell/platform/android/android_context_gl.h 52 | index e29dc7ac4..9a0be6d42 100644 53 | --- a/shell/platform/android/android_context_gl.h 54 | +++ b/shell/platform/android/android_context_gl.h 55 | @@ -35,6 +35,8 @@ class AndroidContextGL : public fml::RefCountedThreadSafe { 56 | 57 | bool Resize(const SkISize& size); 58 | 59 | + void* GetContext(); 60 | + 61 | private: 62 | fml::RefPtr environment_; 63 | fml::RefPtr window_; 64 | diff --git a/shell/platform/android/android_external_texture_gl.cc b/shell/platform/android/android_external_texture_gl.cc 65 | index c587becd6..f8580fdbe 100644 66 | --- a/shell/platform/android/android_external_texture_gl.cc 67 | +++ b/shell/platform/android/android_external_texture_gl.cc 68 | @@ -16,7 +16,18 @@ AndroidExternalTextureGL::AndroidExternalTextureGL( 69 | const fml::jni::JavaObjectWeakGlobalRef& surfaceTexture) 70 | : Texture(id), surface_texture_(surfaceTexture), transform(SkMatrix::I()) {} 71 | 72 | -AndroidExternalTextureGL::~AndroidExternalTextureGL() = default; 73 | +AndroidExternalTextureGL::AndroidExternalTextureGL(int64_t id, 74 | + int64_t texture_id) 75 | + : Texture(id), texture_name_(texture_id) { 76 | + use_out_texture_ = true; 77 | +} 78 | + 79 | +AndroidExternalTextureGL::~AndroidExternalTextureGL() { 80 | + if (texture_name_ != 0 && !use_out_texture_) { 81 | + glDeleteTextures(1, &texture_name_); 82 | + texture_name_ = 0; 83 | + } 84 | +}; 85 | 86 | void AndroidExternalTextureGL::OnGrContextCreated() { 87 | state_ = AttachmentState::uninitialized; 88 | @@ -33,16 +44,25 @@ void AndroidExternalTextureGL::Paint(SkCanvas& canvas, 89 | return; 90 | } 91 | if (state_ == AttachmentState::uninitialized) { 92 | - glGenTextures(1, &texture_name_); 93 | - Attach(static_cast(texture_name_)); 94 | + if (!use_out_texture_) { 95 | + glGenTextures(1, &texture_name_); 96 | + Attach(static_cast(texture_name_)); 97 | + } 98 | state_ = AttachmentState::attached; 99 | } 100 | if (!freeze && new_frame_ready_) { 101 | - Update(); 102 | + if (!use_out_texture_) { 103 | + Update(); 104 | + } 105 | new_frame_ready_ = false; 106 | } 107 | GrGLTextureInfo textureInfo = {GL_TEXTURE_EXTERNAL_OES, texture_name_, 108 | GL_RGBA8_OES}; 109 | + if (use_out_texture_) { 110 | + textureInfo.fTarget = GL_TEXTURE_2D; 111 | + transform.setIdentity(); 112 | + } 113 | + 114 | GrBackendTexture backendTexture(1, 1, GrMipMapped::kNo, textureInfo); 115 | sk_sp image = SkImage::MakeFromTexture( 116 | canvas.getGrContext(), backendTexture, kTopLeft_GrSurfaceOrigin, 117 | diff --git a/shell/platform/android/android_external_texture_gl.h b/shell/platform/android/android_external_texture_gl.h 118 | index 09a56766e..936efec81 100644 119 | --- a/shell/platform/android/android_external_texture_gl.h 120 | +++ b/shell/platform/android/android_external_texture_gl.h 121 | @@ -16,6 +16,7 @@ class AndroidExternalTextureGL : public flow::Texture { 122 | AndroidExternalTextureGL( 123 | int64_t id, 124 | const fml::jni::JavaObjectWeakGlobalRef& surfaceTexture); 125 | + AndroidExternalTextureGL(int64_t id, int64_t texture_id); 126 | 127 | ~AndroidExternalTextureGL() override; 128 | 129 | @@ -44,6 +45,8 @@ class AndroidExternalTextureGL : public flow::Texture { 130 | 131 | bool new_frame_ready_ = false; 132 | 133 | + bool use_out_texture_ = false; 134 | + 135 | GLuint texture_name_ = 0; 136 | 137 | SkMatrix transform; 138 | diff --git a/shell/platform/android/android_surface.h b/shell/platform/android/android_surface.h 139 | index 0ecc9ffc7..0c2557698 100644 140 | --- a/shell/platform/android/android_surface.h 141 | +++ b/shell/platform/android/android_surface.h 142 | @@ -36,6 +36,8 @@ class AndroidSurface { 143 | virtual bool ResourceContextClearCurrent() = 0; 144 | 145 | virtual bool SetNativeWindow(fml::RefPtr window) = 0; 146 | + 147 | + virtual void* GetContext() = 0; 148 | }; 149 | 150 | } // namespace shell 151 | diff --git a/shell/platform/android/android_surface_gl.cc b/shell/platform/android/android_surface_gl.cc 152 | index 4e1ff9f41..a4d6fecc2 100644 153 | --- a/shell/platform/android/android_surface_gl.cc 154 | +++ b/shell/platform/android/android_surface_gl.cc 155 | @@ -87,6 +87,10 @@ bool AndroidSurfaceGL::ResourceContextClearCurrent() { 156 | return offscreen_context_->ClearCurrent(); 157 | } 158 | 159 | +void* AndroidSurfaceGL::GetContext() { 160 | + return offscreen_context_->GetContext(); 161 | +} 162 | + 163 | bool AndroidSurfaceGL::SetNativeWindow( 164 | fml::RefPtr window) { 165 | // In any case, we want to get rid of our current onscreen context. 166 | diff --git a/shell/platform/android/android_surface_gl.h b/shell/platform/android/android_surface_gl.h 167 | index 11badede1..638a81b0c 100644 168 | --- a/shell/platform/android/android_surface_gl.h 169 | +++ b/shell/platform/android/android_surface_gl.h 170 | @@ -58,6 +58,8 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate, 171 | // |shell::GPUSurfaceGLDelegate| 172 | intptr_t GLContextFBO() const override; 173 | 174 | + void* GetContext() override; 175 | + 176 | private: 177 | fml::RefPtr onscreen_context_; 178 | fml::RefPtr offscreen_context_; 179 | diff --git a/shell/platform/android/android_surface_software.cc b/shell/platform/android/android_surface_software.cc 180 | index 475c1de26..c492caf78 100644 181 | --- a/shell/platform/android/android_surface_software.cc 182 | +++ b/shell/platform/android/android_surface_software.cc 183 | @@ -139,6 +139,10 @@ bool AndroidSurfaceSoftware::OnScreenSurfaceResize(const SkISize& size) const { 184 | return true; 185 | } 186 | 187 | +void* AndroidSurfaceSoftware::GetContext() { 188 | + return 0; 189 | +} 190 | + 191 | bool AndroidSurfaceSoftware::SetNativeWindow( 192 | fml::RefPtr window) { 193 | native_window_ = std::move(window); 194 | diff --git a/shell/platform/android/android_surface_software.h b/shell/platform/android/android_surface_software.h 195 | index c7410642c..110e2db7c 100644 196 | --- a/shell/platform/android/android_surface_software.h 197 | +++ b/shell/platform/android/android_surface_software.h 198 | @@ -47,6 +47,8 @@ class AndroidSurfaceSoftware final : public AndroidSurface, 199 | // |shell::GPUSurfaceSoftwareDelegate| 200 | bool PresentBackingStore(sk_sp backing_store) override; 201 | 202 | + void* GetContext() override; 203 | + 204 | private: 205 | sk_sp sk_surface_; 206 | fml::RefPtr native_window_; 207 | diff --git a/shell/platform/android/io/flutter/view/FlutterView.java b/shell/platform/android/io/flutter/view/FlutterView.java 208 | index 759b2744c..a85670700 100644 209 | --- a/shell/platform/android/io/flutter/view/FlutterView.java 210 | +++ b/shell/platform/android/io/flutter/view/FlutterView.java 211 | @@ -25,6 +25,8 @@ import android.view.accessibility.AccessibilityNodeProvider; 212 | import android.view.inputmethod.EditorInfo; 213 | import android.view.inputmethod.InputConnection; 214 | import android.view.inputmethod.InputMethodManager; 215 | +import android.opengl.EGLContext; 216 | +import io.flutter.app.FlutterActivity; 217 | import io.flutter.app.FlutterPluginRegistry; 218 | import io.flutter.plugin.common.*; 219 | import io.flutter.plugin.editing.TextInputPlugin; 220 | @@ -790,10 +792,15 @@ public class FlutterView extends SurfaceView 221 | 222 | private static native void nativeRegisterTexture(long nativePlatformViewAndroid, long textureId, 223 | SurfaceTexture surfaceTexture); 224 | + 225 | + private static native void nativeGLRegisterTexture(long nativePlatformViewAndroid, long textureIndex, long textureId); 226 | 227 | private static native void nativeMarkTextureFrameAvailable(long nativePlatformViewAndroid, long textureId); 228 | + 229 | 230 | private static native void nativeUnregisterTexture(long nativePlatformViewAndroid, long textureId); 231 | + 232 | + private static native EGLContext nativeGetContext(long nativePlatformViewAndroid); 233 | 234 | private void updateViewportMetrics() { 235 | if (!isAttached()) 236 | @@ -1076,11 +1083,85 @@ public class FlutterView extends SurfaceView 237 | nativeRegisterTexture(mNativeView.get(), entry.id(), surfaceTexture); 238 | return entry; 239 | } 240 | + 241 | + @Override 242 | + public void onGLFrameAvaliable(int textureIndex) { 243 | + nativeMarkTextureFrameAvailable(mNativeView.get(), textureIndex); 244 | + } 245 | + 246 | + @Override 247 | + public long registerGLTexture(long textureID) { 248 | + long texIndex = nextTextureId.getAndIncrement(); 249 | + nativeGLRegisterTexture(mNativeView.get(), texIndex, textureID); 250 | + return texIndex; 251 | + } 252 | + 253 | + @Override 254 | + public TextureRegistry.GLTextureEntry createGLTexture(long textureID) { 255 | + long texIndex = nextTextureId.getAndIncrement(); 256 | + final GLTextureRegistryEntry entry = new GLTextureRegistryEntry(texIndex,textureID); 257 | + nativeGLRegisterTexture(mNativeView.get(), texIndex, textureID); 258 | + return entry; 259 | + } 260 | 261 | + @Override 262 | + public EGLContext getGLContext() { 263 | + return nativeGetContext(mNativeView.get()); 264 | + } 265 | + 266 | + final class GLTextureRegistryEntry implements TextureRegistry.GLTextureEntry { 267 | + private final long id; 268 | + private final long textureID; 269 | + private boolean released; 270 | + private boolean suspended; 271 | + GLTextureRegistryEntry(long id, long textureID) { 272 | + this.id = id; 273 | + this.textureID = textureID; 274 | + } 275 | + 276 | + @Override 277 | + public long id() { 278 | + return id; 279 | + } 280 | + 281 | + @Override 282 | + public void release() { 283 | + if (released) { 284 | + return; 285 | + } 286 | + if (suspended) { 287 | + return; 288 | + } 289 | + released = true; 290 | + nativeGLRegisterTexture(mNativeView.get(), id, textureID); 291 | + } 292 | + 293 | + @Override 294 | + public void suspend() { 295 | + if (released) { 296 | + return; 297 | + } 298 | + if (suspended) { 299 | + return; 300 | + } 301 | + suspended = true; 302 | + nativeUnregisterTexture(mNativeView.get(), id); 303 | + } 304 | + 305 | + @Override 306 | + public void resume(long textureID) { 307 | + if(released) return; 308 | + if(!suspended) return; 309 | + suspended = false; 310 | + nativeGLRegisterTexture(mNativeView.get(), id, textureID); 311 | + } 312 | + } 313 | + 314 | final class SurfaceTextureRegistryEntry implements TextureRegistry.SurfaceTextureEntry { 315 | private final long id; 316 | - private final SurfaceTexture surfaceTexture; 317 | + private SurfaceTexture surfaceTexture; 318 | private boolean released; 319 | + private boolean suspended; 320 | 321 | SurfaceTextureRegistryEntry(long id, SurfaceTexture surfaceTexture) { 322 | this.id = id; 323 | @@ -1127,12 +1208,58 @@ public class FlutterView extends SurfaceView 324 | if (released) { 325 | return; 326 | } 327 | + if (suspended) { 328 | + return; 329 | + } 330 | released = true; 331 | nativeUnregisterTexture(mNativeView.get(), id); 332 | // Otherwise onFrameAvailableListener might be called after mNativeView==null 333 | // (https://github.com/flutter/flutter/issues/20951). See also the check in onFrameAvailable. 334 | surfaceTexture.setOnFrameAvailableListener(null); 335 | surfaceTexture.release(); 336 | + surfaceTexture = null; 337 | + } 338 | + 339 | + @Override 340 | + public void suspend() { 341 | + if (released) { 342 | + return; 343 | + } 344 | + if (suspended) { 345 | + return; 346 | + } 347 | + 348 | + suspended = true; 349 | + nativeUnregisterTexture(mNativeView.get(), id); 350 | + // Otherwise onFrameAvailableListener might be called after mNativeView==null 351 | + // (https://github.com/flutter/flutter/issues/20951). See also the check in 352 | + // onFrameAvailable. 353 | + surfaceTexture.setOnFrameAvailableListener(null); 354 | + surfaceTexture.release(); 355 | + surfaceTexture = null; 356 | + } 357 | + 358 | + @Override 359 | + public void resume() { 360 | + if(released) return; 361 | + if(!suspended) return; 362 | + suspended = false; 363 | + if(surfaceTexture == null){ 364 | + surfaceTexture = new SurfaceTexture(0); 365 | + surfaceTexture.detachFromGLContext(); 366 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 367 | + // The callback relies on being executed on the UI thread (unsynchronised read of mNativeView 368 | + // and also the engine code check for platform thread in Shell::OnPlatformViewMarkTextureFrameAvailable), 369 | + // so we explicitly pass a Handler for the current thread. 370 | + surfaceTexture.setOnFrameAvailableListener(onFrameListener, new Handler()); 371 | + } else { 372 | + // Android documentation states that the listener can be called on an arbitrary thread. 373 | + // But in practice, versions of Android that predate the newer API will call the listener 374 | + // on the thread where the SurfaceTexture was constructed. 375 | + surfaceTexture.setOnFrameAvailableListener(onFrameListener); 376 | + } 377 | + } 378 | + nativeRegisterTexture(mNativeView.get(), id, surfaceTexture); 379 | } 380 | } 381 | } 382 | diff --git a/shell/platform/android/io/flutter/view/TextureRegistry.java b/shell/platform/android/io/flutter/view/TextureRegistry.java 383 | index ed3134bb0..1b1045f01 100644 384 | --- a/shell/platform/android/io/flutter/view/TextureRegistry.java 385 | +++ b/shell/platform/android/io/flutter/view/TextureRegistry.java 386 | @@ -5,6 +5,7 @@ 387 | package io.flutter.view; 388 | 389 | import android.graphics.SurfaceTexture; 390 | +import android.opengl.EGLContext; 391 | 392 | /** 393 | * Registry of backend textures used with a single {@link FlutterView} instance. 394 | @@ -19,6 +20,42 @@ public interface TextureRegistry { 395 | * @return A SurfaceTextureEntry. 396 | */ 397 | SurfaceTextureEntry createSurfaceTexture(); 398 | + 399 | + void onGLFrameAvaliable(int index); 400 | + 401 | + long registerGLTexture(long textureID); 402 | + 403 | + EGLContext getGLContext(); 404 | + 405 | + GLTextureEntry createGLTexture(long textureID); 406 | + 407 | + /** 408 | + * A registry entry for a managed SurfaceTexture. 409 | + */ 410 | + interface GLTextureEntry { 411 | + 412 | + /** 413 | + * @return The identity of this SurfaceTexture. 414 | + */ 415 | + long id(); 416 | + 417 | + /** 418 | + * Deregisters and releases this SurfaceTexture. 419 | + */ 420 | + void release(); 421 | + 422 | + /** 423 | + * suspend the SurfaceTexture 424 | + * this will unregister the texture and release the existed surfaceeTexture,but 425 | + * the id will be reserved 426 | + */ 427 | + void suspend(); 428 | + 429 | + /** 430 | + * this will create a new SurfaceTexture, and register texture 431 | + */ 432 | + void resume(long textureID); 433 | + } 434 | 435 | /** 436 | * A registry entry for a managed SurfaceTexture. 437 | @@ -38,5 +75,18 @@ public interface TextureRegistry { 438 | * Deregisters and releases this SurfaceTexture. 439 | */ 440 | void release(); 441 | + 442 | + /** 443 | + * suspend the SurfaceTexture 444 | + * this will unregister the texture and release the existed surfaceeTexture,but 445 | + * the id will be reserved 446 | + */ 447 | + void suspend(); 448 | + 449 | + /** 450 | + * this will create a new SurfaceTexture, and register texture 451 | + */ 452 | + void resume(); 453 | + 454 | } 455 | } 456 | diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc 457 | index 034c05969..d70cd5be3 100644 458 | --- a/shell/platform/android/platform_view_android.cc 459 | +++ b/shell/platform/android/platform_view_android.cc 460 | @@ -355,6 +355,16 @@ void PlatformViewAndroid::RegisterExternalTexture( 461 | std::make_shared(texture_id, surface_texture)); 462 | } 463 | 464 | +void PlatformViewAndroid::RegisterGLExternalTexture(int64_t texture_index, 465 | + int64_t texture_id) { 466 | + RegisterTexture( 467 | + std::make_shared(texture_index, texture_id)); 468 | +} 469 | + 470 | +void* PlatformViewAndroid::GetContext() { 471 | + return android_surface_->GetContext(); 472 | +} 473 | + 474 | // |shell::PlatformView| 475 | std::unique_ptr PlatformViewAndroid::CreateVSyncWaiter() { 476 | return std::make_unique(task_runners_); 477 | diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h 478 | index c162ac5a2..b325d166f 100644 479 | --- a/shell/platform/android/platform_view_android.h 480 | +++ b/shell/platform/android/platform_view_android.h 481 | @@ -73,6 +73,10 @@ class PlatformViewAndroid final : public PlatformView { 482 | int64_t texture_id, 483 | const fml::jni::JavaObjectWeakGlobalRef& surface_texture); 484 | 485 | + void RegisterGLExternalTexture(int64_t texture_index, int64_t texture_id); 486 | + 487 | + void* GetContext(); 488 | + 489 | private: 490 | const fml::jni::JavaObjectWeakGlobalRef java_object_; 491 | const std::unique_ptr android_surface_; 492 | diff --git a/shell/platform/android/platform_view_android_jni.cc b/shell/platform/android/platform_view_android_jni.cc 493 | index be42414b6..50d93f1b1 100644 494 | --- a/shell/platform/android/platform_view_android_jni.cc 495 | +++ b/shell/platform/android/platform_view_android_jni.cc 496 | @@ -24,6 +24,9 @@ 497 | #include "flutter/shell/platform/android/apk_asset_provider.h" 498 | #include "flutter/shell/platform/android/flutter_main.h" 499 | 500 | +#include 501 | +#include 502 | + 503 | #define ANDROID_SHELL_HOLDER \ 504 | (reinterpret_cast(shell_holder)) 505 | 506 | @@ -502,6 +505,31 @@ static void RegisterTexture(JNIEnv* env, 507 | ); 508 | } 509 | 510 | +static void RegisterGLTexture(JNIEnv* env, 511 | + jobject jcaller, 512 | + jlong shell_holder, 513 | + jlong texture_index, 514 | + jlong texture_id) { 515 | + ANDROID_SHELL_HOLDER->GetPlatformView()->RegisterGLExternalTexture( 516 | + static_cast(texture_index), static_cast(texture_id)); 517 | +} 518 | + 519 | +static jobject GetContext(JNIEnv* env, jobject jcaller, jlong shell_holder) { 520 | + jclass eglcontextClassLocal = env->FindClass("android/opengl/EGLContext"); 521 | + jmethodID eglcontextConstructor = 522 | + env->GetMethodID(eglcontextClassLocal, "", "(J)V"); 523 | + 524 | + void* cxt = ANDROID_SHELL_HOLDER->GetPlatformView()->GetContext(); 525 | + 526 | + if ((EGLContext)cxt == EGL_NO_CONTEXT) { 527 | + return env->NewObject(eglcontextClassLocal, eglcontextConstructor, 528 | + reinterpret_cast(EGL_NO_CONTEXT)); 529 | + } 530 | + 531 | + return env->NewObject(eglcontextClassLocal, eglcontextConstructor, 532 | + reinterpret_cast(cxt)); 533 | +} 534 | + 535 | static void MarkTextureFrameAvailable(JNIEnv* env, 536 | jobject jcaller, 537 | jlong shell_holder, 538 | @@ -688,6 +716,12 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { 539 | .signature = "(JJLandroid/graphics/SurfaceTexture;)V", 540 | .fnPtr = reinterpret_cast(&shell::RegisterTexture), 541 | }, 542 | + { 543 | + .name = "nativeGLRegisterTexture", 544 | + .signature = "(JJJ)V", 545 | + .fnPtr = reinterpret_cast(&shell::RegisterGLTexture), 546 | + }, 547 | + 548 | { 549 | .name = "nativeMarkTextureFrameAvailable", 550 | .signature = "(JJ)V", 551 | @@ -698,6 +732,12 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { 552 | .signature = "(JJ)V", 553 | .fnPtr = reinterpret_cast(&shell::UnregisterTexture), 554 | }, 555 | + { 556 | + .name = "nativeGetContext", 557 | + .signature = "(J)Landroid/opengl/EGLContext;", 558 | + .fnPtr = reinterpret_cast(&shell::GetContext), 559 | + }, 560 | + 561 | }; 562 | 563 | static const JNINativeMethod callback_info_methods[] = { 564 | diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h b/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h 565 | index e7cd01337..4abccee96 100644 566 | --- a/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h 567 | +++ b/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h 568 | @@ -7,6 +7,7 @@ 569 | 570 | #import 571 | #import 572 | +#import 573 | 574 | #include "FlutterMacros.h" 575 | 576 | @@ -15,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN 577 | FLUTTER_EXPORT 578 | @protocol FlutterTexture 579 | - (CVPixelBufferRef _Nullable)copyPixelBuffer; 580 | +- (GLuint)copyTextureID; 581 | @end 582 | 583 | FLUTTER_EXPORT 584 | @@ -22,6 +24,7 @@ FLUTTER_EXPORT 585 | - (int64_t)registerTexture:(NSObject*)texture; 586 | - (void)textureFrameAvailable:(int64_t)textureId; 587 | - (void)unregisterTexture:(int64_t)textureId; 588 | +- (EAGLSharegroup*)glShareGroup; 589 | @end 590 | 591 | NS_ASSUME_NONNULL_END 592 | diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm 593 | index c5f3b8d9a..c6c4f1af6 100644 594 | --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm 595 | +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm 596 | @@ -459,6 +459,9 @@ - (void)setMessageHandlerOnChannel:(NSString*)channel 597 | } 598 | 599 | #pragma mark - FlutterTextureRegistry 600 | +- (EAGLSharegroup*)glShareGroup { 601 | + return (EAGLSharegroup*)(self.iosPlatformView -> GetGLShareGroup()); 602 | +} 603 | 604 | - (int64_t)registerTexture:(NSObject*)texture { 605 | int64_t textureId = _nextTextureId++; 606 | diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 607 | index 5a367bdea..9f01c4002 100644 608 | --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 609 | +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 610 | @@ -953,6 +953,11 @@ - (void)setMessageHandlerOnChannel:(NSString*)channel 611 | } 612 | 613 | #pragma mark - FlutterTextureRegistry 614 | +- (EAGLSharegroup*)glShareGroup { 615 | + shell::PlatformViewIOS* platformViewIOS = 616 | + static_cast([_engine.get() platformView].get()); 617 | + return (EAGLSharegroup*)(platformViewIOS->GetGLShareGroup()); 618 | +} 619 | 620 | - (int64_t)registerTexture:(NSObject*)texture { 621 | return [_engine.get() registerTexture:texture]; 622 | diff --git a/shell/platform/darwin/ios/ios_external_texture_gl.mm b/shell/platform/darwin/ios/ios_external_texture_gl.mm 623 | index e77970697..b1480efae 100644 624 | --- a/shell/platform/darwin/ios/ios_external_texture_gl.mm 625 | +++ b/shell/platform/darwin/ios/ios_external_texture_gl.mm 626 | @@ -25,39 +25,48 @@ 627 | IOSExternalTextureGL::~IOSExternalTextureGL() = default; 628 | 629 | void IOSExternalTextureGL::Paint(SkCanvas& canvas, const SkRect& bounds, bool freeze) { 630 | - if (!cache_ref_) { 631 | - CVOpenGLESTextureCacheRef cache; 632 | - CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, 633 | - [EAGLContext currentContext], NULL, &cache); 634 | - if (err == noErr) { 635 | - cache_ref_.Reset(cache); 636 | - } else { 637 | - FML_LOG(WARNING) << "Failed to create GLES texture cache: " << err; 638 | - return; 639 | - } 640 | - } 641 | - fml::CFRef bufferRef; 642 | - if (!freeze) { 643 | - bufferRef.Reset([external_texture_ copyPixelBuffer]); 644 | - if (bufferRef != nullptr) { 645 | - CVOpenGLESTextureRef texture; 646 | - CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage( 647 | - kCFAllocatorDefault, cache_ref_, bufferRef, nullptr, GL_TEXTURE_2D, GL_RGBA, 648 | - static_cast(CVPixelBufferGetWidth(bufferRef)), 649 | - static_cast(CVPixelBufferGetHeight(bufferRef)), GL_BGRA, GL_UNSIGNED_BYTE, 0, 650 | - &texture); 651 | - texture_ref_.Reset(texture); 652 | - if (err != noErr) { 653 | - FML_LOG(WARNING) << "Could not create texture from pixel buffer: " << err; 654 | + GrGLTextureInfo textureInfo; 655 | + if ([external_texture_ respondsToSelector:@selector(copyTextureID)]) { 656 | + textureInfo.fFormat = GL_RGBA8_OES; 657 | + textureInfo.fID = [external_texture_ copyTextureID]; 658 | + textureInfo.fTarget = GL_TEXTURE_2D; 659 | + } else { 660 | + if (!cache_ref_) { 661 | + CVOpenGLESTextureCacheRef cache; 662 | + CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, 663 | + [EAGLContext currentContext], NULL, &cache); 664 | + if (err == noErr) { 665 | + cache_ref_.Reset(cache); 666 | + } else { 667 | + FML_LOG(WARNING) << "Failed to create GLES texture cache: " << err; 668 | return; 669 | } 670 | } 671 | + if (!freeze) { 672 | + fml::CFRef bufferRef; 673 | + bufferRef.Reset([external_texture_ copyPixelBuffer]); 674 | + if (bufferRef != nullptr) { 675 | + CVOpenGLESTextureRef texture; 676 | + CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage( 677 | + kCFAllocatorDefault, cache_ref_, bufferRef, nullptr, GL_TEXTURE_2D, GL_RGBA, 678 | + static_cast(CVPixelBufferGetWidth(bufferRef)), 679 | + static_cast(CVPixelBufferGetHeight(bufferRef)), GL_BGRA, GL_UNSIGNED_BYTE, 0, 680 | + &texture); 681 | + texture_ref_.Reset(texture); 682 | + if (err != noErr) { 683 | + FML_LOG(WARNING) << "Could not create texture from pixel buffer: " << err; 684 | + return; 685 | + } 686 | + } 687 | + } 688 | + 689 | + if (!texture_ref_) { 690 | + return; 691 | + } 692 | + textureInfo.fFormat = GL_RGBA8_OES; 693 | + textureInfo.fID = CVOpenGLESTextureGetName(texture_ref_); 694 | + textureInfo.fTarget = CVOpenGLESTextureGetTarget(texture_ref_); 695 | } 696 | - if (!texture_ref_) { 697 | - return; 698 | - } 699 | - GrGLTextureInfo textureInfo = {CVOpenGLESTextureGetTarget(texture_ref_), 700 | - CVOpenGLESTextureGetName(texture_ref_), GL_RGBA8_OES}; 701 | GrBackendTexture backendTexture(bounds.width(), bounds.height(), GrMipMapped::kNo, textureInfo); 702 | sk_sp image = 703 | SkImage::MakeFromTexture(canvas.getGrContext(), backendTexture, kTopLeft_GrSurfaceOrigin, 704 | diff --git a/shell/platform/darwin/ios/ios_gl_context.h b/shell/platform/darwin/ios/ios_gl_context.h 705 | index 08778d213..6758c93cd 100644 706 | --- a/shell/platform/darwin/ios/ios_gl_context.h 707 | +++ b/shell/platform/darwin/ios/ios_gl_context.h 708 | @@ -30,6 +30,8 @@ class IOSGLContext { 709 | 710 | bool ResourceMakeCurrent(); 711 | 712 | + void* GetGLShareGroup(); 713 | + 714 | sk_sp ColorSpace() const { return color_space_; } 715 | 716 | private: 717 | diff --git a/shell/platform/darwin/ios/ios_gl_context.mm b/shell/platform/darwin/ios/ios_gl_context.mm 718 | index c8819a78b..276d330f9 100644 719 | --- a/shell/platform/darwin/ios/ios_gl_context.mm 720 | +++ b/shell/platform/darwin/ios/ios_gl_context.mm 721 | @@ -13,9 +13,9 @@ 722 | namespace shell { 723 | 724 | IOSGLContext::IOSGLContext() { 725 | - context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]); 726 | + context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]); 727 | if (context_ != nullptr) { 728 | - resource_context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3 729 | + resource_context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 730 | sharegroup:context_.get().sharegroup]); 731 | } else { 732 | context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]); 733 | @@ -61,4 +61,9 @@ 734 | return [EAGLContext setCurrentContext:resource_context_.get()]; 735 | } 736 | 737 | +void* IOSGLContext::GetGLShareGroup() { 738 | + EAGLSharegroup* shareGroup = context_.get().sharegroup; 739 | + return (void*)shareGroup; 740 | +} 741 | + 742 | } // namespace shell 743 | diff --git a/shell/platform/darwin/ios/ios_surface.h b/shell/platform/darwin/ios/ios_surface.h 744 | index 1fc6a4218..e8bb37c84 100644 745 | --- a/shell/platform/darwin/ios/ios_surface.h 746 | +++ b/shell/platform/darwin/ios/ios_surface.h 747 | @@ -33,6 +33,8 @@ class IOSSurface { 748 | 749 | virtual std::unique_ptr CreateGPUSurface() = 0; 750 | 751 | + virtual void* GetGLShareGroup() = 0; 752 | + 753 | protected: 754 | FlutterPlatformViewsController* GetPlatformViewsController(); 755 | 756 | diff --git a/shell/platform/darwin/ios/ios_surface_gl.h b/shell/platform/darwin/ios/ios_surface_gl.h 757 | index 93fcc0f51..8d6515db5 100644 758 | --- a/shell/platform/darwin/ios/ios_surface_gl.h 759 | +++ b/shell/platform/darwin/ios/ios_surface_gl.h 760 | @@ -39,6 +39,8 @@ class IOSSurfaceGL : public IOSSurface, 761 | 762 | bool GLContextMakeCurrent() override; 763 | 764 | + void* GetGLShareGroup() override; 765 | + 766 | bool GLContextClearCurrent() override; 767 | 768 | bool GLContextPresent() override; 769 | diff --git a/shell/platform/darwin/ios/ios_surface_gl.mm b/shell/platform/darwin/ios/ios_surface_gl.mm 770 | index cd0bb093d..914bf2a33 100644 771 | --- a/shell/platform/darwin/ios/ios_surface_gl.mm 772 | +++ b/shell/platform/darwin/ios/ios_surface_gl.mm 773 | @@ -50,6 +50,10 @@ 774 | return IsValid() ? render_target_->framebuffer() : GL_NONE; 775 | } 776 | 777 | +void* IOSSurfaceGL::GetGLShareGroup() { 778 | + return context_.get()->GetGLShareGroup(); 779 | +} 780 | + 781 | bool IOSSurfaceGL::UseOffscreenSurface() const { 782 | // The onscreen surface wraps a GL renderbuffer, which is extremely slow to read. 783 | // Certain filter effects require making a copy of the current destination, so we 784 | diff --git a/shell/platform/darwin/ios/ios_surface_software.h b/shell/platform/darwin/ios/ios_surface_software.h 785 | index 79695b3a2..ecc640dbb 100644 786 | --- a/shell/platform/darwin/ios/ios_surface_software.h 787 | +++ b/shell/platform/darwin/ios/ios_surface_software.h 788 | @@ -36,6 +36,8 @@ class IOSSurfaceSoftware final : public IOSSurface, 789 | // |shell::IOSSurface| 790 | std::unique_ptr CreateGPUSurface() override; 791 | 792 | + void* GetGLShareGroup() override; 793 | + 794 | // |shell::GPUSurfaceSoftwareDelegate| 795 | sk_sp AcquireBackingStore(const SkISize& size) override; 796 | 797 | diff --git a/shell/platform/darwin/ios/ios_surface_software.mm b/shell/platform/darwin/ios/ios_surface_software.mm 798 | index 5d120ef47..0c467853b 100644 799 | --- a/shell/platform/darwin/ios/ios_surface_software.mm 800 | +++ b/shell/platform/darwin/ios/ios_surface_software.mm 801 | @@ -52,6 +52,10 @@ 802 | return surface; 803 | } 804 | 805 | +void* IOSSurfaceSoftware::GetGLShareGroup() { 806 | + return nullptr; 807 | +} 808 | + 809 | sk_sp IOSSurfaceSoftware::AcquireBackingStore(const SkISize& size) { 810 | TRACE_EVENT0("flutter", "IOSSurfaceSoftware::AcquireBackingStore"); 811 | if (!IsValid()) { 812 | diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h 813 | index a0d85a7ff..294885c15 100644 814 | --- a/shell/platform/darwin/ios/platform_view_ios.h 815 | +++ b/shell/platform/darwin/ios/platform_view_ios.h 816 | @@ -36,6 +36,8 @@ class PlatformViewIOS final : public PlatformView { 817 | 818 | void RegisterExternalTexture(int64_t id, NSObject* texture); 819 | 820 | + void* GetGLShareGroup(); 821 | + 822 | fml::scoped_nsprotocol GetTextInputPlugin() const; 823 | 824 | void SetTextInputPlugin(fml::scoped_nsprotocol plugin); 825 | diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm 826 | index f3371a983..3231c1736 100644 827 | --- a/shell/platform/darwin/ios/platform_view_ios.mm 828 | +++ b/shell/platform/darwin/ios/platform_view_ios.mm 829 | @@ -63,6 +63,12 @@ 830 | RegisterTexture(std::make_shared(texture_id, texture)); 831 | } 832 | 833 | +void* PlatformViewIOS::GetGLShareGroup() { 834 | + if (ios_surface_.get() == NULL) 835 | + return NULL; 836 | + return ios_surface_->GetGLShareGroup(); 837 | +} 838 | + 839 | // |shell::PlatformView| 840 | std::unique_ptr PlatformViewIOS::CreateRenderingSurface() { 841 | if (!ios_surface_) { 842 | -- 843 | 2.17.2 (Apple Git-113) 844 | 845 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/engine#src#flutter/0002-Fix-a-tap-failure-problem-when-double-click-on-FlutterViewController.patch: -------------------------------------------------------------------------------- 1 | From 5a6564b9f8ea73c85372e356f566ea6e3f28fdfd Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sat, 22 Dec 2018 22:32:41 +0800 4 | Subject: [PATCH] Fix a tap failure problem when double click on 5 | FlutterViewController. 6 | 7 | --- 8 | .../framework/Source/FlutterViewController.mm | 74 ++++++++++++++++--- 9 | 1 file changed, 65 insertions(+), 9 deletions(-) 10 | 11 | diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 12 | index 9f01c4002..ea8beaaa0 100644 13 | --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 14 | +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 15 | @@ -22,6 +22,8 @@ 16 | #include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" 17 | #include "flutter/shell/platform/darwin/ios/platform_view_ios.h" 18 | 19 | +static double kTouchTrackerCheckInterval = 1.f; 20 | + 21 | @implementation FlutterViewController { 22 | std::unique_ptr> _weakFactory; 23 | fml::scoped_nsobject _engine; 24 | @@ -37,6 +39,8 @@ @implementation FlutterViewController { 25 | BOOL _initialized; 26 | BOOL _viewOpaque; 27 | BOOL _engineNeedsLaunch; 28 | + NSMutableSet* _touchTrackerSet; 29 | + NSMutableDictionary* _touchTrackerDict; 30 | } 31 | 32 | #pragma mark - Manage and override all designated initializers 33 | @@ -113,6 +117,8 @@ - (void)performCommonViewControllerInitialization { 34 | _orientationPreferences = UIInterfaceOrientationMaskAll; 35 | _statusBarStyle = UIStatusBarStyleDefault; 36 | 37 | + _touchTrackerSet = [[NSMutableSet set] retain]; 38 | + _touchTrackerDict = [[NSMutableDictionary dictionary] retain]; 39 | [self setupNotificationCenterObservers]; 40 | } 41 | 42 | @@ -429,6 +435,8 @@ - (void)viewDidDisappear:(BOOL)animated { 43 | 44 | - (void)dealloc { 45 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 46 | + [_touchTrackerSet release]; 47 | + [_touchTrackerDict release]; 48 | [super dealloc]; 49 | } 50 | 51 | @@ -498,18 +506,40 @@ - (void)applicationWillEnterForeground:(NSNotification*)notification { 52 | // in the status bar area are available to framework code. The change type (optional) of the faked 53 | // touch is specified in the second argument. 54 | - (void)dispatchTouches:(NSSet*)touches 55 | - pointerDataChangeOverride:(blink::PointerData::Change*)overridden_change { 56 | + pointerDataChangeOverride:(blink::PointerData::Change*)overridden_change 57 | + trackTouches:(BOOL)bTrack { 58 | const CGFloat scale = [UIScreen mainScreen].scale; 59 | auto packet = std::make_unique(touches.count); 60 | - 61 | + NSTimeInterval tsNow = [[NSDate date] timeIntervalSinceReferenceDate]; 62 | size_t pointer_index = 0; 63 | 64 | for (UITouch* touch in touches) { 65 | CGPoint windowCoordinates = [touch locationInView:self.view]; 66 | - 67 | + UITouchPhase phase = touch.phase; 68 | + NSValue* key = [NSValue valueWithPointer:(void*)touch]; 69 | blink::PointerData pointer_data; 70 | pointer_data.Clear(); 71 | 72 | + switch (phase) { 73 | + case UITouchPhaseBegan: 74 | + case UITouchPhaseMoved: 75 | + case UITouchPhaseStationary: 76 | + if (bTrack) { 77 | + [_touchTrackerSet addObject:touch]; 78 | + _touchTrackerDict[key] = @(tsNow + kTouchTrackerCheckInterval); 79 | + } 80 | + break; 81 | + case UITouchPhaseEnded: 82 | + case UITouchPhaseCancelled: 83 | + if (bTrack) { 84 | + [_touchTrackerDict removeObjectForKey:key]; 85 | + [_touchTrackerSet removeObject:touch]; 86 | + } 87 | + break; 88 | + default: 89 | + break; 90 | + } 91 | + 92 | constexpr int kMicrosecondsPerSecond = 1000 * 1000; 93 | pointer_data.time_stamp = touch.timestamp * kMicrosecondsPerSecond; 94 | 95 | @@ -584,19 +614,45 @@ - (void)dispatchTouches:(NSSet*)touches 96 | } 97 | 98 | - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { 99 | - [self dispatchTouches:touches pointerDataChangeOverride:nullptr]; 100 | + [self dispatchTouches:touches pointerDataChangeOverride:nullptr trackTouches:TRUE]; 101 | + [self checkIfCompleteTouches]; 102 | } 103 | 104 | - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { 105 | - [self dispatchTouches:touches pointerDataChangeOverride:nullptr]; 106 | + [self dispatchTouches:touches pointerDataChangeOverride:nullptr trackTouches:TRUE]; 107 | } 108 | 109 | - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { 110 | - [self dispatchTouches:touches pointerDataChangeOverride:nullptr]; 111 | + [self dispatchTouches:touches pointerDataChangeOverride:nullptr trackTouches:TRUE]; 112 | } 113 | 114 | - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { 115 | - [self dispatchTouches:touches pointerDataChangeOverride:nullptr]; 116 | + [self dispatchTouches:touches pointerDataChangeOverride:nullptr trackTouches:TRUE]; 117 | +} 118 | + 119 | +- (BOOL)checkIfCompleteTouches { 120 | + NSInteger cnt = _touchTrackerSet.count; 121 | + if (cnt <= 0) 122 | + return FALSE; 123 | + NSTimeInterval tsNow = [[NSDate date] timeIntervalSinceReferenceDate]; 124 | + NSSet* tmpTrackingTouches = [_touchTrackerSet copy]; 125 | + NSMutableSet* set = [NSMutableSet set]; 126 | + for (UITouch* touch in tmpTrackingTouches) { 127 | + NSValue* key = [NSValue valueWithPointer:(void*)touch]; 128 | + NSNumber* expiredTime = [_touchTrackerDict objectForKey:key]; 129 | + if (expiredTime.doubleValue <= tsNow) { 130 | + [touch setValue:@(UITouchPhaseEnded) forKey:@"phase"]; 131 | + [set addObject:touch]; 132 | + [_touchTrackerDict removeObjectForKey:key]; 133 | + [_touchTrackerSet removeObject:touch]; 134 | + } 135 | + } 136 | + if (set.count > 0) { 137 | + [self dispatchTouches:set pointerDataChangeOverride:nullptr trackTouches:FALSE]; 138 | + [self dispatchTouches:set pointerDataChangeOverride:nullptr trackTouches:FALSE]; 139 | + return TRUE; 140 | + } 141 | + return FALSE; 142 | } 143 | 144 | #pragma mark - Handle view resizing 145 | @@ -892,9 +948,9 @@ - (void)handleStatusBarTouches:(UIEvent*)event { 146 | NSSet* statusbarTouches = [NSSet setWithObject:touch]; 147 | 148 | blink::PointerData::Change change = blink::PointerData::Change::kDown; 149 | - [self dispatchTouches:statusbarTouches pointerDataChangeOverride:&change]; 150 | + [self dispatchTouches:statusbarTouches pointerDataChangeOverride:&change trackTouches:TRUE]; 151 | change = blink::PointerData::Change::kUp; 152 | - [self dispatchTouches:statusbarTouches pointerDataChangeOverride:&change]; 153 | + [self dispatchTouches:statusbarTouches pointerDataChangeOverride:&change trackTouches:TRUE]; 154 | return; 155 | } 156 | } 157 | -- 158 | 2.17.2 (Apple Git-113) 159 | 160 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/engine#src#flutter/0003-A-workaround-for-libgpu-related-crash-in-background.patch: -------------------------------------------------------------------------------- 1 | From fe6790122d8f61b15f0a5b17a90ff62ca0a99f16 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sat, 22 Dec 2018 23:25:10 +0800 4 | Subject: [PATCH] A workaround for libgpu related crash in background . 5 | 6 | --- 7 | fml/message_loop_impl.cc | 26 ++++++-- 8 | fml/message_loop_impl.h | 17 ++++- 9 | fml/task_runner.cc | 8 +++ 10 | fml/task_runner.h | 2 + 11 | shell/common/shell.cc | 8 +++ 12 | .../framework/Source/FlutterViewController.mm | 62 +++++++++++++++++++ 13 | 6 files changed, 116 insertions(+), 7 deletions(-) 14 | 15 | diff --git a/fml/message_loop_impl.cc b/fml/message_loop_impl.cc 16 | index 4d2c5bf4f..dd2b05cd1 100644 17 | --- a/fml/message_loop_impl.cc 18 | +++ b/fml/message_loop_impl.cc 19 | @@ -39,7 +39,8 @@ fml::RefPtr MessageLoopImpl::Create() { 20 | #endif 21 | } 22 | 23 | -MessageLoopImpl::MessageLoopImpl() : order_(0), terminated_(false) {} 24 | +MessageLoopImpl::MessageLoopImpl() 25 | + : order_(0), terminated_(false), task_limit_per_looprun_(10000) {} 26 | 27 | MessageLoopImpl::~MessageLoopImpl() = default; 28 | 29 | @@ -116,25 +117,34 @@ void MessageLoopImpl::RunExpiredTasks() { 30 | TRACE_EVENT0("fml", "MessageLoop::RunExpiredTasks"); 31 | std::vector invocations; 32 | 33 | + int i_tasks_cnt = 0; 34 | + bool need_call_run_again = false; 35 | + auto now = fml::TimePoint::Now(); 36 | + 37 | { 38 | std::lock_guard lock(delayed_tasks_mutex_); 39 | 40 | - if (delayed_tasks_.empty()) { 41 | + if (delayed_tasks_.empty() || !IsMessageLoopEnabled()) { 42 | return; 43 | } 44 | 45 | - auto now = fml::TimePoint::Now(); 46 | - while (!delayed_tasks_.empty()) { 47 | + is_runninging_expired_tasks_ = true; 48 | + while (!delayed_tasks_.empty() && i_tasks_cnt < task_limit_per_looprun_) { 49 | const auto& top = delayed_tasks_.top(); 50 | if (top.target_time > now) { 51 | break; 52 | } 53 | invocations.emplace_back(std::move(top.task)); 54 | delayed_tasks_.pop(); 55 | + i_tasks_cnt++; 56 | } 57 | 58 | - WakeUp(delayed_tasks_.empty() ? fml::TimePoint::Max() 59 | - : delayed_tasks_.top().target_time); 60 | + if (i_tasks_cnt >= task_limit_per_looprun_ && !delayed_tasks_.empty()) { 61 | + need_call_run_again = true; 62 | + } else { 63 | + WakeUp(delayed_tasks_.empty() ? fml::TimePoint::Max() 64 | + : delayed_tasks_.top().target_time); 65 | + } 66 | } 67 | 68 | for (const auto& invocation : invocations) { 69 | @@ -143,6 +153,10 @@ void MessageLoopImpl::RunExpiredTasks() { 70 | observer.second(); 71 | } 72 | } 73 | + is_runninging_expired_tasks_ = false; 74 | + if (need_call_run_again) { 75 | + RunExpiredTasks(); 76 | + } 77 | } 78 | 79 | MessageLoopImpl::DelayedTask::DelayedTask(size_t p_order, 80 | diff --git a/fml/message_loop_impl.h b/fml/message_loop_impl.h 81 | index 9dab218d0..0a89161cb 100644 82 | --- a/fml/message_loop_impl.h 83 | +++ b/fml/message_loop_impl.h 84 | @@ -42,6 +42,18 @@ class MessageLoopImpl : public fml::RefCountedThreadSafe { 85 | 86 | void DoTerminate(); 87 | 88 | + void EnableMessageLoop(bool isEnable) { is_loop_enabled_ = isEnable; } 89 | + 90 | + void SetTaskLimitPerLoopRun(int task_limit_per_looprun) { 91 | + task_limit_per_looprun_ = task_limit_per_looprun; 92 | + } 93 | + 94 | + inline bool IsMessageLoopEnabled() { return is_loop_enabled_; } 95 | + 96 | + inline bool IsRunningingExpiredTasks() { 97 | + return is_runninging_expired_tasks_; 98 | + } 99 | + 100 | // Exposed for the embedder shell which allows clients to poll for events 101 | // instead of dedicating a thread to the message loop. 102 | void RunExpiredTasksNow(); 103 | @@ -73,13 +85,16 @@ class MessageLoopImpl : public fml::RefCountedThreadSafe { 104 | 105 | using DelayedTaskQueue = std:: 106 | priority_queue, DelayedTaskCompare>; 107 | - 108 | + bool is_loop_enabled_ = true; 109 | std::map task_observers_; 110 | std::mutex delayed_tasks_mutex_; 111 | DelayedTaskQueue delayed_tasks_; 112 | size_t order_; 113 | std::atomic_bool terminated_; 114 | 115 | + bool is_runninging_expired_tasks_; 116 | + int task_limit_per_looprun_; 117 | + 118 | void RegisterTask(fml::closure task, fml::TimePoint target_time); 119 | 120 | void RunExpiredTasks(); 121 | diff --git a/fml/task_runner.cc b/fml/task_runner.cc 122 | index 2c4cfe4b6..58b1bad46 100644 123 | --- a/fml/task_runner.cc 124 | +++ b/fml/task_runner.cc 125 | @@ -39,6 +39,14 @@ bool TaskRunner::RunsTasksOnCurrentThread() { 126 | return MessageLoop::GetCurrent().GetLoopImpl() == loop_; 127 | } 128 | 129 | +void TaskRunner::EnableMessageLoop(bool isEnable) { 130 | + loop_->EnableMessageLoop(isEnable); 131 | +} 132 | + 133 | +MessageLoopImpl* TaskRunner::getMessageLoop() { 134 | + return loop_.get(); 135 | +} 136 | + 137 | void TaskRunner::RunNowOrPostTask(fml::RefPtr runner, 138 | fml::closure task) { 139 | FML_DCHECK(runner); 140 | diff --git a/fml/task_runner.h b/fml/task_runner.h 141 | index 04696752c..60a23c1ea 100644 142 | --- a/fml/task_runner.h 143 | +++ b/fml/task_runner.h 144 | @@ -24,6 +24,8 @@ class TaskRunner : public fml::RefCountedThreadSafe { 145 | virtual void PostDelayedTask(fml::closure task, fml::TimeDelta delay); 146 | 147 | virtual bool RunsTasksOnCurrentThread(); 148 | + void EnableMessageLoop(bool isEnable); 149 | + MessageLoopImpl* getMessageLoop(); 150 | 151 | virtual ~TaskRunner(); 152 | 153 | diff --git a/shell/common/shell.cc b/shell/common/shell.cc 154 | index 4adf55a3f..4503059be 100644 155 | --- a/shell/common/shell.cc 156 | +++ b/shell/common/shell.cc 157 | @@ -981,6 +981,14 @@ Rasterizer::Screenshot Shell::Screenshot( 158 | Rasterizer::ScreenshotType screenshot_type, 159 | bool base64_encode) { 160 | TRACE_EVENT0("flutter", "Shell::Screenshot"); 161 | + fml::TaskRunner* taskRunner = 162 | + (fml::TaskRunner*)this->GetTaskRunners().GetUITaskRunner().get(); 163 | + taskRunner->EnableMessageLoop(true); 164 | + 165 | + taskRunner = 166 | + (fml::TaskRunner*)this->GetTaskRunners().GetGPUTaskRunner().get(); 167 | + taskRunner->EnableMessageLoop(true); 168 | + 169 | fml::AutoResetWaitableEvent latch; 170 | Rasterizer::Screenshot screenshot; 171 | fml::TaskRunner::RunNowOrPostTask( 172 | diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 173 | index ea8beaaa0..43f74c8ee 100644 174 | --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 175 | +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 176 | @@ -9,8 +9,10 @@ 177 | 178 | #include 179 | 180 | +#include "flutter/common/task_runners.h" 181 | #include "flutter/fml/memory/weak_ptr.h" 182 | #include "flutter/fml/message_loop.h" 183 | +#include "flutter/fml/message_loop_impl.h" 184 | #include "flutter/fml/platform/darwin/platform_version.h" 185 | #include "flutter/fml/platform/darwin/scoped_nsobject.h" 186 | #include "flutter/shell/common/thread_host.h" 187 | @@ -119,6 +121,14 @@ - (void)performCommonViewControllerInitialization { 188 | 189 | _touchTrackerSet = [[NSMutableSet set] retain]; 190 | _touchTrackerDict = [[NSMutableDictionary dictionary] retain]; 191 | + 192 | + fml::MessageLoopImpl* gpuLoop = 193 | + ((fml::TaskRunner*)[self getTaskRunners].GetGPUTaskRunner().get())->getMessageLoop(); 194 | + gpuLoop->SetTaskLimitPerLoopRun(10); 195 | + fml::MessageLoopImpl* ioLoop = 196 | + ((fml::TaskRunner*)[self getTaskRunners].GetIOTaskRunner().get())->getMessageLoop(); 197 | + ioLoop->SetTaskLimitPerLoopRun(10); 198 | + 199 | [self setupNotificationCenterObservers]; 200 | } 201 | 202 | @@ -378,6 +388,7 @@ - (void)setFlutterViewDidRenderCallback:(void (^)(void))callback { 203 | 204 | - (void)surfaceUpdated:(BOOL)appeared { 205 | // NotifyCreated/NotifyDestroyed are synchronous and require hops between the UI and GPU thread. 206 | + [self setEnableForRunnersBatch:YES]; 207 | if (appeared) { 208 | [self installSplashScreenViewCallback]; 209 | [_engine.get() platformViewsController] -> SetFlutterView(_flutterView.get()); 210 | @@ -385,6 +396,7 @@ - (void)surfaceUpdated:(BOOL)appeared { 211 | } else { 212 | [_engine.get() platformView] -> NotifyDestroyed(); 213 | [_engine.get() platformViewsController] -> SetFlutterView(nullptr); 214 | + [self disableGPUOperation]; 215 | } 216 | } 217 | 218 | @@ -465,6 +477,56 @@ - (void)applicationWillEnterForeground:(NSNotification*)notification { 219 | [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.inactive"]; 220 | } 221 | 222 | +- (blink::TaskRunners)getTaskRunners { 223 | + return ([_engine.get() shell].GetTaskRunners()); 224 | +} 225 | + 226 | +- (void)disableGPUOperation { 227 | + [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.paused"]; 228 | + //暂时通过延时来等待GL操作结束(否则进入后台后的GL操作会闪退) 229 | + NSDate* date = [NSDate date]; 230 | + double delayMax = 8; //最多等8S 231 | + fml::MessageLoopImpl* gpuLoop = 232 | + ((fml::TaskRunner*)[self getTaskRunners].GetGPUTaskRunner().get())->getMessageLoop(); 233 | + fml::MessageLoopImpl* ioLoop = 234 | + ((fml::TaskRunner*)[self getTaskRunners].GetIOTaskRunner().get())->getMessageLoop(); 235 | + while (true) { 236 | + //两个TaskRunner没内容了,好,可以退出 237 | + if (!gpuLoop->IsRunningingExpiredTasks() && !ioLoop->IsRunningingExpiredTasks()) 238 | + break; 239 | + //超时退出 240 | + if ([[NSDate date] timeIntervalSinceDate:date] > delayMax) 241 | + break; 242 | + [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]]; 243 | + } 244 | + [self setEnableForRunnersBatch:FALSE]; 245 | +} 246 | + 247 | +- (void)enableMessageLoop:(bool)isEnable forTaskRunner:(NSString*)aTaskRunnerId { 248 | + if ([@"io.flutter.io" caseInsensitiveCompare:aTaskRunnerId] == NSOrderedSame) { 249 | + fml::TaskRunner* taskRunner = (fml::TaskRunner*)[self getTaskRunners].GetIOTaskRunner().get(); 250 | + taskRunner->EnableMessageLoop(isEnable); 251 | + } 252 | + if ([@"io.flutter.ui" caseInsensitiveCompare:aTaskRunnerId] == NSOrderedSame) { 253 | + fml::TaskRunner* taskRunner = (fml::TaskRunner*)[self getTaskRunners].GetUITaskRunner().get(); 254 | + taskRunner->EnableMessageLoop(isEnable); 255 | + } 256 | + if ([@"io.flutter.gpu" caseInsensitiveCompare:aTaskRunnerId] == NSOrderedSame) { 257 | + fml::TaskRunner* taskRunner = (fml::TaskRunner*)[self getTaskRunners].GetGPUTaskRunner().get(); 258 | + taskRunner->EnableMessageLoop(isEnable); 259 | + } 260 | + if ([@"io.flutter.platform" caseInsensitiveCompare:aTaskRunnerId] == NSOrderedSame) { 261 | + fml::TaskRunner* taskRunner = 262 | + (fml::TaskRunner*)[self getTaskRunners].GetPlatformTaskRunner().get(); 263 | + taskRunner->EnableMessageLoop(isEnable); 264 | + } 265 | +} 266 | + 267 | +- (void)setEnableForRunnersBatch:(BOOL)enable { 268 | + [self enableMessageLoop:enable forTaskRunner:@"io.flutter.gpu"]; 269 | + [self enableMessageLoop:enable forTaskRunner:@"io.flutter.io"]; 270 | +} 271 | + 272 | #pragma mark - Touch event handling 273 | 274 | static blink::PointerData::Change PointerDataChangeFromUITouchPhase(UITouchPhase phase) { 275 | -- 276 | 2.17.2 (Apple Git-113) 277 | 278 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/engine#src#flutter/0004-Workaround-for-android-eglCreateContext-fail.patch: -------------------------------------------------------------------------------- 1 | From fa208b164fffe02af542be012c1c199a3bcc35b3 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sun, 23 Dec 2018 16:50:29 +0800 4 | Subject: [PATCH] Workaround for android eglCreateContext fail. 5 | 6 | --- 7 | shell/platform/android/android_context_gl.cc | 6 ++++++ 8 | 1 file changed, 6 insertions(+) 9 | 10 | diff --git a/shell/platform/android/android_context_gl.cc b/shell/platform/android/android_context_gl.cc 11 | index bb4e7b653..2878d1087 100644 12 | --- a/shell/platform/android/android_context_gl.cc 13 | +++ b/shell/platform/android/android_context_gl.cc 14 | @@ -65,6 +65,12 @@ static EGLResult CreateContext(EGLDisplay display, 15 | EGLint attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; 16 | 17 | EGLContext context = eglCreateContext(display, config, share, attributes); 18 | + if (context == EGL_NO_CONTEXT) { 19 | + EGLint last_error = eglGetError(); 20 | + if (last_error == EGL_BAD_MATCH && share != EGL_NO_CONTEXT) { 21 | + context = eglCreateContext(display, config, EGL_NO_CONTEXT, attributes); 22 | + } 23 | + } 24 | 25 | return {context != EGL_NO_CONTEXT, context}; 26 | } 27 | -- 28 | 2.17.2 (Apple Git-113) 29 | 30 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/engine#src#flutter/0005-iphone_simulator_image_invisible_by_lujunchen.patch: -------------------------------------------------------------------------------- 1 | From f5c7a26e5ab6595f49e5fec3d4cdd5f7cb1a6512 Mon Sep 17 00:00:00 2001 2 | From: lujunchen 3 | Date: Tue, 19 Mar 2019 22:23:38 +0800 4 | Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E5=99=A8=E5=9B=BE=E7=89=87?= 5 | =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D=E3=80=82?= 6 | MIME-Version: 1.0 7 | Content-Type: text/plain; charset=UTF-8 8 | Content-Transfer-Encoding: 8bit 9 | 10 | --- 11 | shell/platform/darwin/ios/framework/Source/FlutterView.mm | 8 ++++---- 12 | 1 file changed, 4 insertions(+), 4 deletions(-) 13 | 14 | diff --git a/shell/platform/darwin/ios/framework/Source/FlutterView.mm b/shell/platform/darwin/ios/framework/Source/FlutterView.mm 15 | index 32c54f632..a21809de7 100644 16 | --- a/shell/platform/darwin/ios/framework/Source/FlutterView.mm 17 | +++ b/shell/platform/darwin/ios/framework/Source/FlutterView.mm 18 | @@ -55,11 +55,11 @@ 19 | } 20 | 21 | + (Class)layerClass { 22 | -#if TARGET_IPHONE_SIMULATOR 23 | - return [CALayer class]; 24 | -#else // TARGET_IPHONE_SIMULATOR 25 | +//#if TARGET_IPHONE_SIMULATOR 26 | +// return [CALayer class]; 27 | +//#else // TARGET_IPHONE_SIMULATOR 28 | return [CAEAGLLayer class]; 29 | -#endif // TARGET_IPHONE_SIMULATOR 30 | +//#endif // TARGET_IPHONE_SIMULATOR 31 | } 32 | 33 | - (std::unique_ptr)createSurface { 34 | -- 35 | 2.18.0 36 | 37 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/engine#src#flutter/0006-fix-engine-transform_layer-crash-by-SanLi.patch: -------------------------------------------------------------------------------- 1 | From 18a6a3a5c87120f7e2eecd473fa829738ab4d02a Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?=E4=B8=89=E8=8E=85?= 3 | Date: Thu, 27 Jun 2019 10:21:32 +0800 4 | Subject: [PATCH] fix #21270273: fix 5 | crash:https://github.com/flutter/flutter/issues/31650 6 | 7 | --- 8 | flow/layers/transform_layer.cc | 9 ++++++++- 9 | 1 file changed, 8 insertions(+), 1 deletion(-) 10 | 11 | diff --git a/flow/layers/transform_layer.cc b/flow/layers/transform_layer.cc 12 | index 9a9a7d486..543fd754a 100644 13 | --- a/flow/layers/transform_layer.cc 14 | +++ b/flow/layers/transform_layer.cc 15 | @@ -25,7 +25,14 @@ void TransformLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { 16 | // 17 | // We have to write this flaky test because there is no reliable way to test 18 | // whether a variable is initialized or not in C++. 19 | - FML_CHECK(transform_.isFinite()); 20 | + 21 | + //fix crash:https://github.com/flutter/flutter/issues/31650 22 | + // FML_CHECK(transform_.isFinite()); 23 | + FML_DCHECK(transform_.isFinite()); 24 | + if (!transform_.isFinite()) { 25 | + FML_LOG(ERROR) << "TransformLayer is constructed with an invalid matrix."; 26 | + transform_.setIdentity(); 27 | + } 28 | 29 | SkMatrix child_matrix; 30 | child_matrix.setConcat(matrix, transform_); 31 | -- 32 | 2.18.0 33 | 34 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/engine#src#flutter/0007-get-context-android-by-lujunchen.patch: -------------------------------------------------------------------------------- 1 | From 337f7e18189c54920735eeb949db29f3e0e5af72 Mon Sep 17 00:00:00 2001 2 | From: lujunchen 3 | Date: Tue, 18 Jun 2019 10:31:21 +0800 4 | Subject: [PATCH] =?UTF-8?q?=E4=BD=8E=E7=AB=AF=E6=9C=BA=E4=B8=8Acontext?= 5 | =?UTF-8?q?=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= 6 | MIME-Version: 1.0 7 | Content-Type: text/plain; charset=UTF-8 8 | Content-Transfer-Encoding: 8bit 9 | 10 | --- 11 | .../android/platform_view_android_jni.cc | 35 ++++++++++++++----- 12 | 1 file changed, 27 insertions(+), 8 deletions(-) 13 | 14 | diff --git a/shell/platform/android/platform_view_android_jni.cc b/shell/platform/android/platform_view_android_jni.cc 15 | index e34626005..28e9e13c5 100644 16 | --- a/shell/platform/android/platform_view_android_jni.cc 17 | +++ b/shell/platform/android/platform_view_android_jni.cc 18 | @@ -25,6 +25,7 @@ 19 | #include "flutter/shell/platform/android/flutter_main.h" 20 | #include 21 | #include 22 | +#include 23 | 24 | #define ANDROID_SHELL_HOLDER \ 25 | (reinterpret_cast(shell_holder)) 26 | @@ -506,19 +507,37 @@ static void RegisterGLTexture(JNIEnv* env, 27 | } 28 | 29 | static jobject GetContext(JNIEnv* env, jobject jcaller, jlong shell_holder) { 30 | - jclass eglcontextClassLocal = env->FindClass("android/opengl/EGLContext"); 31 | - jmethodID eglcontextConstructor = 32 | - env->GetMethodID(eglcontextClassLocal, "", "(J)V"); 33 | 34 | void* cxt = ANDROID_SHELL_HOLDER->GetPlatformView()->GetContext(); 35 | 36 | - if ((EGLContext)cxt == EGL_NO_CONTEXT) { 37 | - return env->NewObject(eglcontextClassLocal, eglcontextConstructor, 38 | - reinterpret_cast(EGL_NO_CONTEXT)); 39 | + 40 | + jclass versionClass = env->FindClass("android/os/Build$VERSION" ); 41 | + jfieldID sdkIntFieldID = env->GetStaticFieldID(versionClass, "SDK_INT", "I" ); 42 | + int sdkInt = env->GetStaticIntField(versionClass, sdkIntFieldID ); 43 | + __android_log_print(ANDROID_LOG_ERROR, "andymao", "sdkInt %d",sdkInt); 44 | + jclass eglcontextClassLocal = env->FindClass("android/opengl/EGLContext"); 45 | + jmethodID eglcontextConstructor; 46 | + jobject eglContext; 47 | + if (sdkInt >= 21) { 48 | + //5.0and above 49 | + eglcontextConstructor=env->GetMethodID(eglcontextClassLocal, "", "(J)V"); 50 | + if ((EGLContext)cxt == EGL_NO_CONTEXT) { 51 | + return env->NewObject(eglcontextClassLocal, eglcontextConstructor, 52 | + reinterpret_cast(EGL_NO_CONTEXT)); 53 | + } 54 | + eglContext = env->NewObject(eglcontextClassLocal, eglcontextConstructor, 55 | + reinterpret_cast(jlong(cxt))); 56 | + }else{ 57 | + eglcontextConstructor=env->GetMethodID(eglcontextClassLocal, "", "(I)V"); 58 | + if ((EGLContext)cxt == EGL_NO_CONTEXT) { 59 | + return env->NewObject(eglcontextClassLocal, eglcontextConstructor, 60 | + reinterpret_cast(EGL_NO_CONTEXT)); 61 | + } 62 | + eglContext = env->NewObject(eglcontextClassLocal, eglcontextConstructor, 63 | + reinterpret_cast(jint(cxt))); 64 | } 65 | 66 | - return env->NewObject(eglcontextClassLocal, eglcontextConstructor, 67 | - reinterpret_cast(cxt)); 68 | + return eglContext; 69 | } 70 | 71 | static void MarkTextureFrameAvailable(JNIEnv* env, 72 | -- 73 | 2.18.0 74 | 75 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/engine#src#flutter/0008-fix-crash-in-AccessibilityBridge-by-sanli.patch: -------------------------------------------------------------------------------- 1 | From 006755f191e30190ac35cfff588ee6f8b9bd6cf2 Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?=E4=B8=89=E8=8E=85?= 3 | Date: Mon, 3 Jun 2019 14:02:26 +0800 4 | Subject: [PATCH] fix crash 5 | 6 | --- 7 | .../platform/android/io/flutter/view/AccessibilityBridge.java | 4 +++- 8 | 1 file changed, 3 insertions(+), 1 deletion(-) 9 | 10 | diff --git a/shell/platform/android/io/flutter/view/AccessibilityBridge.java b/shell/platform/android/io/flutter/view/AccessibilityBridge.java 11 | index c0035399d..6e6d5338f 100644 12 | --- a/shell/platform/android/io/flutter/view/AccessibilityBridge.java 13 | +++ b/shell/platform/android/io/flutter/view/AccessibilityBridge.java 14 | @@ -1453,7 +1453,9 @@ public class AccessibilityBridge extends AccessibilityNodeProvider { 15 | return; 16 | } 17 | // TODO(mattcarroll): why are we explicitly talking to the root view's parent? 18 | - rootAccessibilityView.getParent().requestSendAccessibilityEvent(rootAccessibilityView, event); 19 | + if (rootAccessibilityView.getParent()!=null) { 20 | + rootAccessibilityView.getParent().requestSendAccessibilityEvent(rootAccessibilityView, event); 21 | + } 22 | } 23 | 24 | /** 25 | -- 26 | 27 | 28 | @@ -2045,7 +2045,9 @@ public class AccessibilityBridge extends AccessibilityNodeProvider { 29 | if (globalTransform == null) { 30 | globalTransform = new float[16]; 31 | } 32 | - Matrix.multiplyMM(globalTransform, 0, ancestorTransform, 0, transform, 0); 33 | + if (globalTransform!=null && ancestorTransform!=null && transform!=null) { 34 | + Matrix.multiplyMM(globalTransform, 0, ancestorTransform, 0, transform, 0); 35 | + } 36 | 37 | final float[] sample = new float[4]; 38 | sample[2] = 0; 39 | -- 40 | 41 | 42 | @@ -1125,10 +1125,13 @@ public class AccessibilityBridge extends AccessibilityNodeProvider { 43 | return false; 44 | } 45 | 46 | - SemanticsNode semanticsNodeUnderCursor = getRootSemanticsNode().hitTest(new float[] {event.getX(), event.getY(), 0, 1}); 47 | - if (semanticsNodeUnderCursor.platformViewId != -1) { 48 | - return accessibilityViewEmbedder.onAccessibilityHoverEvent(semanticsNodeUnderCursor.id, event); 49 | + if (getRootSemanticsNode()!=null){ 50 | + SemanticsNode semanticsNodeUnderCursor = getRootSemanticsNode().hitTest(new float[] {event.getX(), event.getY(), 0, 1}); 51 | + if (semanticsNodeUnderCursor.platformViewId != -1) { 52 | + return accessibilityViewEmbedder.onAccessibilityHoverEvent(semanticsNodeUnderCursor.id, event); 53 | + } 54 | } 55 | + 56 | 57 | if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER || event.getAction() == MotionEvent.ACTION_HOVER_MOVE) { 58 | handleTouchExploration(event.getX(), event.getY()); 59 | -- 60 | 61 | 62 | @@ -507,7 +507,9 @@ public class AccessibilityBridge extends AccessibilityNodeProvider { 63 | // For platform views we delegate the node creation to the accessibility view embedder. 64 | View embeddedView = platformViewsAccessibilityDelegate.getPlatformViewById(semanticsNode.platformViewId); 65 | Rect bounds = semanticsNode.getGlobalRect(); 66 | - return accessibilityViewEmbedder.getRootNode(embeddedView, semanticsNode.id, bounds); 67 | + if (embeddedView!=null && bounds!=null) { 68 | + return accessibilityViewEmbedder.getRootNode(embeddedView, semanticsNode.id, bounds); 69 | + } 70 | } 71 | 72 | AccessibilityNodeInfo result = AccessibilityNodeInfo.obtain(rootAccessibilityView, virtualViewId); 73 | -- 74 | 2.18.0 75 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/engine#src#third_party#boringssl#src/0001-Add-intel-emulation-layer-logic-for-arm.patch: -------------------------------------------------------------------------------- 1 | From bb40b72c6ba1c6db2218b8cdb2d58f37d31551f9 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sun, 23 Dec 2018 16:29:05 +0800 4 | Subject: [PATCH] Add intel emulation layer logic for arm. 5 | 6 | --- 7 | crypto/cpu-arm-linux.c | 16 ++++++++++++++++ 8 | 1 file changed, 16 insertions(+) 9 | 10 | diff --git a/crypto/cpu-arm-linux.c b/crypto/cpu-arm-linux.c 11 | index 839b632b0..18a1d747d 100644 12 | --- a/crypto/cpu-arm-linux.c 13 | +++ b/crypto/cpu-arm-linux.c 14 | @@ -276,6 +276,12 @@ static unsigned long get_hwcap2_cpuinfo(const STRING_PIECE *cpuinfo) { 15 | return ret; 16 | } 17 | 18 | +// is_intel returns true if /proc/cpuinfo reports that it is for an intel CPU. 19 | +static int is_intel(const STRING_PIECE *cpuinfo) { 20 | + return cpuinfo_field_equals(cpuinfo, "Hardware", "placeholder"); 21 | +} 22 | + 23 | + 24 | // has_broken_neon returns one if |in| matches a CPU known to have a broken 25 | // NEON unit. See https://crbug.com/341598. 26 | static int has_broken_neon(const STRING_PIECE *cpuinfo) { 27 | @@ -300,6 +306,16 @@ void OPENSSL_cpuid_setup(void) { 28 | cpuinfo.data = cpuinfo_data; 29 | cpuinfo.len = cpuinfo_len; 30 | 31 | + // If we are in a broken emulation environment, and the CPU reports that it is 32 | + // not an ARM CPU, then we should not trust the values reported by 33 | + // getauxval(), etc., and so bail out here. 34 | + if (is_intel(&cpuinfo)) { 35 | + g_has_broken_neon = 1; 36 | + OPENSSL_free(cpuinfo_data); 37 | + return; 38 | + } 39 | + 40 | + 41 | // |getauxval| is not available on Android until API level 20. If it is 42 | // unavailable, read from /proc/self/auxv as a fallback. This is unreadable 43 | // on some versions of Android, so further fall back to /proc/cpuinfo. 44 | -- 45 | 2.17.2 (Apple Git-113) 46 | 47 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/engine#src#third_party#skia/0001-Workaround-for-Flutter-related-black-screen-in-some-.patch: -------------------------------------------------------------------------------- 1 | From 4a93f740f7d80939654f0a9f9683b7c068669538 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sun, 23 Dec 2018 16:20:42 +0800 4 | Subject: [PATCH] Workaround for Flutter related black screen in some android 5 | devices found in China market. 6 | 7 | --- 8 | src/gpu/gl/GrGLInterface.cpp | 4 ++-- 9 | 1 file changed, 2 insertions(+), 2 deletions(-) 10 | 11 | diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp 12 | index f63f483d40..d1643e5b77 100644 13 | --- a/src/gpu/gl/GrGLInterface.cpp 14 | +++ b/src/gpu/gl/GrGLInterface.cpp 15 | @@ -370,7 +370,7 @@ bool GrGLInterface::validate() const { 16 | fExtensions.has("GL_EXT_texture_buffer")) { 17 | if (!fFunctions.fTexBuffer || 18 | !fFunctions.fTexBufferRange) { 19 | - RETURN_FALSE_INTERFACE; 20 | +// RETURN_FALSE_INTERFACE; 21 | } 22 | } 23 | } 24 | @@ -397,7 +397,7 @@ bool GrGLInterface::validate() const { 25 | if (!fFunctions.fInsertEventMarker || 26 | !fFunctions.fPushGroupMarker || 27 | !fFunctions.fPopGroupMarker) { 28 | - RETURN_FALSE_INTERFACE 29 | +// RETURN_FALSE_INTERFACE 30 | } 31 | } 32 | 33 | -- 34 | 2.17.2 (Apple Git-113) 35 | 36 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/flutter/0001-Enable-git-track-for-bin-cache.patch: -------------------------------------------------------------------------------- 1 | From 89cee4b62569b9138425443f67b6f126246bd641 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Fri, 21 Dec 2018 21:16:56 +0800 4 | Subject: [PATCH] Enable git track for bin/cache. 5 | 6 | --- 7 | .gitignore | 2 +- 8 | 1 file changed, 1 insertion(+), 1 deletion(-) 9 | 10 | diff --git a/.gitignore b/.gitignore 11 | index c130db31f..978225f3a 100644 12 | --- a/.gitignore 13 | +++ b/.gitignore 14 | @@ -20,7 +20,7 @@ 15 | .vscode/ 16 | 17 | # Flutter repo-specific 18 | -/bin/cache/ 19 | +# /bin/cache/ 20 | /bin/mingit/ 21 | /dev/benchmarks/mega_gallery/ 22 | /dev/bots/.recipe_deps 23 | -- 24 | 2.17.2 (Apple Git-113) 25 | 26 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/flutter/0002-Disable-pod-install-in-flutter-tools.patch: -------------------------------------------------------------------------------- 1 | From 74ddacc496cb592f5fd89f0ef7f9fc9f40a521e7 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Fri, 21 Dec 2018 23:42:46 +0800 4 | Subject: [PATCH] Disable `pod install` in flutter tools. 5 | 6 | --- 7 | packages/flutter_tools/lib/src/ios/cocoapods.dart | 1 + 8 | 1 file changed, 1 insertion(+) 9 | 10 | diff --git a/packages/flutter_tools/lib/src/ios/cocoapods.dart b/packages/flutter_tools/lib/src/ios/cocoapods.dart 11 | index 26a903d28..8aeaf830a 100644 12 | --- a/packages/flutter_tools/lib/src/ios/cocoapods.dart 13 | +++ b/packages/flutter_tools/lib/src/ios/cocoapods.dart 14 | @@ -206,6 +206,7 @@ class CocoaPods { 15 | // 3. Pods/Manifest.lock doesn't exist (It is deleted when plugins change) 16 | // 4. Podfile.lock doesn't match Pods/Manifest.lock. 17 | bool _shouldRunPodInstall(IosProject iosProject, bool dependenciesChanged) { 18 | + return false; 19 | if (dependenciesChanged) 20 | return true; 21 | 22 | -- 23 | 2.17.2 (Apple Git-113) 24 | 25 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/flutter/0003-FocusNode-adds-api-to-disableKeyboard.patch: -------------------------------------------------------------------------------- 1 | From fab9ee0a73dbe31ce9d90953fd8c327598409f42 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sat, 22 Dec 2018 11:09:59 +0800 4 | Subject: [PATCH] FocusNode adds api to disableKeyboard. 5 | 6 | --- 7 | packages/flutter/lib/src/widgets/editable_text.dart | 2 +- 8 | packages/flutter/lib/src/widgets/focus_manager.dart | 5 ++++- 9 | 2 files changed, 5 insertions(+), 2 deletions(-) 10 | 11 | diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart 12 | index e4ed2b0d1..fd5a5c5a7 100644 13 | --- a/packages/flutter/lib/src/widgets/editable_text.dart 14 | +++ b/packages/flutter/lib/src/widgets/editable_text.dart 15 | @@ -696,7 +696,7 @@ class EditableTextState extends State with AutomaticKeepAliveClien 16 | /// focus, the control will then attach to the keyboard and request that the 17 | /// keyboard become visible. 18 | void requestKeyboard() { 19 | - if (_hasFocus) 20 | + if (_hasFocus && !widget.focusNode.disableKeyboard) 21 | _openInputConnection(); 22 | else 23 | FocusScope.of(context).requestFocus(widget.focusNode); 24 | diff --git a/packages/flutter/lib/src/widgets/focus_manager.dart b/packages/flutter/lib/src/widgets/focus_manager.dart 25 | index 3453c2641..2bb9a13fe 100644 26 | --- a/packages/flutter/lib/src/widgets/focus_manager.dart 27 | +++ b/packages/flutter/lib/src/widgets/focus_manager.dart 28 | @@ -43,6 +43,9 @@ class FocusNode extends ChangeNotifier { 29 | FocusManager _manager; 30 | bool _hasKeyboardToken = false; 31 | 32 | + /// Whether the keyboard is disabled especially when there is a custom keyboard 33 | + bool disableKeyboard = false; 34 | + 35 | /// Whether this node has the overall focus. 36 | /// 37 | /// A [FocusNode] has the overall focus when the node is focused in its 38 | @@ -74,7 +77,7 @@ class FocusNode extends ChangeNotifier { 39 | /// 40 | /// Returns whether this function successfully consumes a keyboard token. 41 | bool consumeKeyboardToken() { 42 | - if (!_hasKeyboardToken) 43 | + if (!_hasKeyboardToken || disableKeyboard) 44 | return false; 45 | _hasKeyboardToken = false; 46 | return true; 47 | -- 48 | 2.17.2 (Apple Git-113) 49 | 50 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/flutter/0004-Add-flutter-tools-hook-by-JiangXiu.patch: -------------------------------------------------------------------------------- 1 | From af7dd219564adaceee62a68d4d6bd5bc4949d3c6 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sun, 23 Dec 2018 17:34:11 +0800 4 | Subject: [PATCH] Add flutter tools hook by JiangXiu. 5 | 6 | --- 7 | .gitignore | 3 +++ 8 | packages/flutter_tools/bin/flutter_tools.dart | 17 +++++++++++++++++ 9 | .../flutter_tools/lib/src/commands/clean.dart | 7 +++++++ 10 | 3 files changed, 27 insertions(+) 11 | 12 | diff --git a/.gitignore b/.gitignore 13 | index 978225f3a..d48db7628 100644 14 | --- a/.gitignore 15 | +++ b/.gitignore 16 | @@ -86,3 +86,6 @@ unlinked_spec.ds 17 | !**/ios/**/default.pbxuser 18 | !**/ios/**/default.perspectivev3 19 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 20 | + 21 | +/bin/cache/flutter_tools.snapshot 22 | +/bin/cache/flutter_tools.stamp 23 | \ No newline at end of file 24 | diff --git a/packages/flutter_tools/bin/flutter_tools.dart b/packages/flutter_tools/bin/flutter_tools.dart 25 | index 762e6a5e9..50f020476 100644 26 | --- a/packages/flutter_tools/bin/flutter_tools.dart 27 | +++ b/packages/flutter_tools/bin/flutter_tools.dart 28 | @@ -3,7 +3,24 @@ 29 | // found in the LICENSE file. 30 | 31 | import 'package:flutter_tools/executable.dart' as executable; 32 | +import 'package:flutter_tools/src/base/io.dart'; 33 | +import 'package:flutter_tools/src/base/process_manager.dart'; 34 | 35 | void main(List args) { 36 | + print('[KWLM]:' + args.toString()); 37 | + 38 | + if (args != null && args.isNotEmpty) { 39 | + if ('run' == args.first || 'build' == args.first) { 40 | + final ProcessResult rlt = processManager 41 | + .runSync(['build_exts/build_hooks.sh'], runInShell: true); 42 | + print('build_hooks:${rlt.stdout}\n${rlt.stderr}'); 43 | + } else if ('delSelf' == args.first) { 44 | + final ProcessResult rlt = processManager.runSync( 45 | + ['build_exts/del_flutter_tool.sh'], 46 | + runInShell: true); 47 | + print('${rlt.stdout}\n${rlt.stderr}'); 48 | + return; 49 | + } 50 | + } 51 | executable.main(args); 52 | } 53 | diff --git a/packages/flutter_tools/lib/src/commands/clean.dart b/packages/flutter_tools/lib/src/commands/clean.dart 54 | index 740f108c8..70721b993 100644 55 | --- a/packages/flutter_tools/lib/src/commands/clean.dart 56 | +++ b/packages/flutter_tools/lib/src/commands/clean.dart 57 | @@ -6,6 +6,8 @@ import 'dart:async'; 58 | 59 | import '../base/common.dart'; 60 | import '../base/file_system.dart'; 61 | +import '../base/io.dart'; 62 | +import '../base/process_manager.dart'; 63 | import '../build_info.dart'; 64 | import '../globals.dart'; 65 | import '../runner/flutter_command.dart'; 66 | @@ -26,6 +28,11 @@ class CleanCommand extends FlutterCommand { 67 | final Directory buildDir = fs.directory(getBuildDirectory()); 68 | printStatus("Deleting '${buildDir.path}${fs.path.separator}'."); 69 | 70 | + final ProcessResult rlt = processManager.runSync( 71 | + ['build_exts/clean_hooks.sh'], 72 | + runInShell: true); 73 | + print('clean_hooks:${rlt.stdout}\n${rlt.stderr}'); 74 | + 75 | if (!buildDir.existsSync()) 76 | return null; 77 | 78 | -- 79 | 2.17.2 (Apple Git-113) 80 | 81 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/flutter/0005-LaunchActivity-android-by-SanLi.patch: -------------------------------------------------------------------------------- 1 | From 4d252c84bb4fa2f0dee4d4c0cb892f8d5bdfa771 Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?=E4=B8=89=E8=8E=85?= 3 | Date: Tue, 2 Apr 2019 14:45:53 +0800 4 | Subject: [PATCH] =?UTF-8?q?fix=20#19808027=20=E9=98=B2=E6=AD=A2launchActiv?= 5 | =?UTF-8?q?ity=E8=AE=BE=E7=BD=AE=E6=88=90DebugActivity=E5=AF=BC=E8=87=B4de?= 6 | =?UTF-8?q?bug=E6=A8=A1=E5=BC=8F=E4=B8=8B=E6=97=A0=E6=B3=95=E6=8B=89?= 7 | =?UTF-8?q?=E8=B5=B7android=20app?= 8 | MIME-Version: 1.0 9 | Content-Type: text/plain; charset=UTF-8 10 | Content-Transfer-Encoding: 8bit 11 | 12 | --- 13 | packages/flutter_tools/lib/src/application_package.dart | 5 ++++- 14 | 1 file changed, 4 insertions(+), 1 deletion(-) 15 | 16 | diff --git a/packages/flutter_tools/lib/src/application_package.dart b/packages/flutter_tools/lib/src/application_package.dart 17 | index fc168971e..67b5f8669 100644 18 | --- a/packages/flutter_tools/lib/src/application_package.dart 19 | +++ b/packages/flutter_tools/lib/src/application_package.dart 20 | @@ -429,7 +429,10 @@ class ApkManifestData { 21 | _Element launchActivity; 22 | for (_Element activity in activities) { 23 | final _Attribute enabled = activity.firstAttribute('android:enabled'); 24 | - if (enabled == null || enabled.value.contains('0xffffffff')) { 25 | + final _Attribute activityName = activity.firstAttribute('android:name'); 26 | + if ((enabled == null || enabled.value.contains('0xffffffff') ) 27 | + && !activityName.value.toLowerCase().contains('debug') 28 | + && !activityName.value.toLowerCase().contains('devtest')) { 29 | launchActivity = activity; 30 | break; 31 | } 32 | -- 33 | 2.18.0 34 | 35 | -------------------------------------------------------------------------------- /patches/alf_stable_v1.5.4/flutter/0006-Android-cursor-by-SanLi.patch: -------------------------------------------------------------------------------- 1 | From 5635c4685efb894df6f12c983550093757e6efa2 Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?=E4=B8=89=E8=8E=85?= 3 | Date: Mon, 24 Jun 2019 10:35:22 +0800 4 | Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9android=E5=85=89=E6=A0=87?= 5 | =?UTF-8?q?=E9=95=BF=E5=BA=A6?= 6 | MIME-Version: 1.0 7 | Content-Type: text/plain; charset=UTF-8 8 | Content-Transfer-Encoding: 8bit 9 | 10 | --- 11 | .../flutter/lib/src/rendering/editable.dart | 22 +++++++++++++++++-- 12 | 1 files changed, 13 insertions(+), 2 deletions(-) 13 | 14 | diff --git a/packages/flutter/lib/src/rendering/editable.dart b/packages/flutter/lib/src/rendering/editable.dart 15 | index a3e12d26c..389dc6d5f 100644 16 | --- a/packages/flutter/lib/src/rendering/editable.dart 17 | +++ b/packages/flutter/lib/src/rendering/editable.dart 18 | @@ -1506,13 +1506,15 @@ class RenderEditable extends RenderBox { 19 | /// of the cursor for iOS is approximate and obtained through an eyeball 20 | /// comparison. 21 | Rect get _getCaretPrototype { 22 | switch(defaultTargetPlatform){ 23 | case TargetPlatform.iOS: 24 | return Rect.fromLTWH(0.0, -_kCaretHeightOffset + .5, cursorWidth, preferredLineHeight + 2); 25 | default: 26 | - return Rect.fromLTWH(0.0, _kCaretHeightOffset, cursorWidth, preferredLineHeight - 2.0 * _kCaretHeightOffset); 27 | + return Rect.fromLTWH(0.0, _kCaretHeightOffset, cursorWidth, preferredLineHeight); 28 | } 29 | } 30 | + 31 | @override 32 | void performLayout() { 33 | _layoutText(constraints.maxWidth); 34 | @@ -1544,6 +1546,7 @@ class RenderEditable extends RenderBox { 35 | return Offset(pixelPerfectOffsetX, pixelPerfectOffsetY); 36 | } 37 | 38 | + //这里是光标位置的重点 39 | void _paintCaret(Canvas canvas, Offset effectiveOffset, TextPosition textPosition) { 40 | assert(_textLayoutLastWidth == constraints.maxWidth); 41 | 42 | @@ -1552,7 +1555,9 @@ class RenderEditable extends RenderBox { 43 | final Paint paint = Paint() 44 | ..color = _floatingCursorOn ? backgroundCursorColor : _cursorColor; 45 | final Offset caretOffset = _textPainter.getOffsetForCaret(textPosition, _caretPrototype) + effectiveOffset; 46 | Rect caretRect = _caretPrototype.shift(caretOffset); 47 | if (_cursorOffset != null) 48 | caretRect = caretRect.shift(_cursorOffset); 49 | 50 | @@ -1569,10 +1574,23 @@ class RenderEditable extends RenderBox { 51 | caretRect.width, 52 | _textPainter.getFullHeightForCaret(textPosition, _caretPrototype), 53 | ); 54 | + }else if (defaultTargetPlatform != TargetPlatform.iOS && _textPainter.getFullHeightForCaret(textPosition, _caretPrototype) == null){ 55 | + caretRect = Rect.fromLTWH( 56 | + caretRect.left, 57 | + // Offset by _kCaretHeightOffset to counteract the same value added in 58 | + // _getCaretPrototype. This prevents this from scaling poorly for small 59 | + // font sizes. 60 | + caretRect.top - _kCaretHeightOffset, 61 | + caretRect.width, 62 | + caretRect.height, 63 | + ); 64 | } 65 | 66 | caretRect = caretRect.shift(_getPixelPerfectCursorOffset(caretRect)); 67 | - 68 | if (cursorRadius == null) { 69 | canvas.drawRect(caretRect, paint); 70 | } else { 71 | -- 72 | 2.18.0 73 | -------------------------------------------------------------------------------- /patches/stable_v1.0/engine#src#flutter/0001-Add-external-surface-texture-support-By-luj.patch: -------------------------------------------------------------------------------- 1 | From 55f59bc560711b15ec443a73001692a1c5901d91 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sat, 22 Dec 2018 21:09:43 +0800 4 | Subject: [PATCH] alfpatch:Add external surface texture support By lujunchen 5 | 6 | --- 7 | shell/platform/android/android_context_gl.cc | 4 + 8 | shell/platform/android/android_context_gl.h | 2 + 9 | .../android/android_external_texture_gl.cc | 28 +++- 10 | .../android/android_external_texture_gl.h | 3 + 11 | shell/platform/android/android_surface.h | 2 + 12 | shell/platform/android/android_surface_gl.cc | 4 + 13 | shell/platform/android/android_surface_gl.h | 2 + 14 | .../android/android_surface_software.cc | 4 + 15 | .../android/android_surface_software.h | 2 + 16 | .../android/io/flutter/view/FlutterView.java | 129 +++++++++++++++++- 17 | .../io/flutter/view/TextureRegistry.java | 50 +++++++ 18 | .../platform/android/platform_view_android.cc | 10 ++ 19 | .../platform/android/platform_view_android.h | 4 + 20 | .../android/platform_view_android_jni.cc | 40 ++++++ 21 | .../ios/framework/Headers/FlutterTexture.h | 3 + 22 | .../ios/framework/Source/FlutterEngine.mm | 3 + 23 | .../framework/Source/FlutterViewController.mm | 5 + 24 | .../darwin/ios/ios_external_texture_gl.mm | 67 +++++---- 25 | shell/platform/darwin/ios/ios_gl_context.h | 2 + 26 | shell/platform/darwin/ios/ios_gl_context.mm | 9 +- 27 | shell/platform/darwin/ios/ios_surface.h | 2 + 28 | shell/platform/darwin/ios/ios_surface_gl.h | 2 + 29 | shell/platform/darwin/ios/ios_surface_gl.mm | 4 + 30 | .../darwin/ios/ios_surface_software.h | 2 + 31 | .../darwin/ios/ios_surface_software.mm | 4 + 32 | shell/platform/darwin/ios/platform_view_ios.h | 2 + 33 | .../platform/darwin/ios/platform_view_ios.mm | 6 + 34 | 27 files changed, 359 insertions(+), 36 deletions(-) 35 | 36 | diff --git a/shell/platform/android/android_context_gl.cc b/shell/platform/android/android_context_gl.cc 37 | index 8ac43b403..bb4e7b653 100644 38 | --- a/shell/platform/android/android_context_gl.cc 39 | +++ b/shell/platform/android/android_context_gl.cc 40 | @@ -143,6 +143,10 @@ bool AndroidContextGL::CreatePBufferSurface() { 41 | return surface_ != EGL_NO_SURFACE; 42 | } 43 | 44 | +void* AndroidContextGL::GetContext() { 45 | + return context_; 46 | +} 47 | + 48 | AndroidContextGL::AndroidContextGL(fml::RefPtr env, 49 | const AndroidContextGL* share_context) 50 | : environment_(env), 51 | diff --git a/shell/platform/android/android_context_gl.h b/shell/platform/android/android_context_gl.h 52 | index e29dc7ac4..9a0be6d42 100644 53 | --- a/shell/platform/android/android_context_gl.h 54 | +++ b/shell/platform/android/android_context_gl.h 55 | @@ -35,6 +35,8 @@ class AndroidContextGL : public fml::RefCountedThreadSafe { 56 | 57 | bool Resize(const SkISize& size); 58 | 59 | + void* GetContext(); 60 | + 61 | private: 62 | fml::RefPtr environment_; 63 | fml::RefPtr window_; 64 | diff --git a/shell/platform/android/android_external_texture_gl.cc b/shell/platform/android/android_external_texture_gl.cc 65 | index c587becd6..f8580fdbe 100644 66 | --- a/shell/platform/android/android_external_texture_gl.cc 67 | +++ b/shell/platform/android/android_external_texture_gl.cc 68 | @@ -16,7 +16,18 @@ AndroidExternalTextureGL::AndroidExternalTextureGL( 69 | const fml::jni::JavaObjectWeakGlobalRef& surfaceTexture) 70 | : Texture(id), surface_texture_(surfaceTexture), transform(SkMatrix::I()) {} 71 | 72 | -AndroidExternalTextureGL::~AndroidExternalTextureGL() = default; 73 | +AndroidExternalTextureGL::AndroidExternalTextureGL(int64_t id, 74 | + int64_t texture_id) 75 | + : Texture(id), texture_name_(texture_id) { 76 | + use_out_texture_ = true; 77 | +} 78 | + 79 | +AndroidExternalTextureGL::~AndroidExternalTextureGL() { 80 | + if (texture_name_ != 0 && !use_out_texture_) { 81 | + glDeleteTextures(1, &texture_name_); 82 | + texture_name_ = 0; 83 | + } 84 | +}; 85 | 86 | void AndroidExternalTextureGL::OnGrContextCreated() { 87 | state_ = AttachmentState::uninitialized; 88 | @@ -33,16 +44,25 @@ void AndroidExternalTextureGL::Paint(SkCanvas& canvas, 89 | return; 90 | } 91 | if (state_ == AttachmentState::uninitialized) { 92 | - glGenTextures(1, &texture_name_); 93 | - Attach(static_cast(texture_name_)); 94 | + if (!use_out_texture_) { 95 | + glGenTextures(1, &texture_name_); 96 | + Attach(static_cast(texture_name_)); 97 | + } 98 | state_ = AttachmentState::attached; 99 | } 100 | if (!freeze && new_frame_ready_) { 101 | - Update(); 102 | + if (!use_out_texture_) { 103 | + Update(); 104 | + } 105 | new_frame_ready_ = false; 106 | } 107 | GrGLTextureInfo textureInfo = {GL_TEXTURE_EXTERNAL_OES, texture_name_, 108 | GL_RGBA8_OES}; 109 | + if (use_out_texture_) { 110 | + textureInfo.fTarget = GL_TEXTURE_2D; 111 | + transform.setIdentity(); 112 | + } 113 | + 114 | GrBackendTexture backendTexture(1, 1, GrMipMapped::kNo, textureInfo); 115 | sk_sp image = SkImage::MakeFromTexture( 116 | canvas.getGrContext(), backendTexture, kTopLeft_GrSurfaceOrigin, 117 | diff --git a/shell/platform/android/android_external_texture_gl.h b/shell/platform/android/android_external_texture_gl.h 118 | index 09a56766e..936efec81 100644 119 | --- a/shell/platform/android/android_external_texture_gl.h 120 | +++ b/shell/platform/android/android_external_texture_gl.h 121 | @@ -16,6 +16,7 @@ class AndroidExternalTextureGL : public flow::Texture { 122 | AndroidExternalTextureGL( 123 | int64_t id, 124 | const fml::jni::JavaObjectWeakGlobalRef& surfaceTexture); 125 | + AndroidExternalTextureGL(int64_t id, int64_t texture_id); 126 | 127 | ~AndroidExternalTextureGL() override; 128 | 129 | @@ -44,6 +45,8 @@ class AndroidExternalTextureGL : public flow::Texture { 130 | 131 | bool new_frame_ready_ = false; 132 | 133 | + bool use_out_texture_ = false; 134 | + 135 | GLuint texture_name_ = 0; 136 | 137 | SkMatrix transform; 138 | diff --git a/shell/platform/android/android_surface.h b/shell/platform/android/android_surface.h 139 | index 0ecc9ffc7..0c2557698 100644 140 | --- a/shell/platform/android/android_surface.h 141 | +++ b/shell/platform/android/android_surface.h 142 | @@ -36,6 +36,8 @@ class AndroidSurface { 143 | virtual bool ResourceContextClearCurrent() = 0; 144 | 145 | virtual bool SetNativeWindow(fml::RefPtr window) = 0; 146 | + 147 | + virtual void* GetContext() = 0; 148 | }; 149 | 150 | } // namespace shell 151 | diff --git a/shell/platform/android/android_surface_gl.cc b/shell/platform/android/android_surface_gl.cc 152 | index 4e1ff9f41..a4d6fecc2 100644 153 | --- a/shell/platform/android/android_surface_gl.cc 154 | +++ b/shell/platform/android/android_surface_gl.cc 155 | @@ -87,6 +87,10 @@ bool AndroidSurfaceGL::ResourceContextClearCurrent() { 156 | return offscreen_context_->ClearCurrent(); 157 | } 158 | 159 | +void* AndroidSurfaceGL::GetContext() { 160 | + return offscreen_context_->GetContext(); 161 | +} 162 | + 163 | bool AndroidSurfaceGL::SetNativeWindow( 164 | fml::RefPtr window) { 165 | // In any case, we want to get rid of our current onscreen context. 166 | diff --git a/shell/platform/android/android_surface_gl.h b/shell/platform/android/android_surface_gl.h 167 | index 11badede1..638a81b0c 100644 168 | --- a/shell/platform/android/android_surface_gl.h 169 | +++ b/shell/platform/android/android_surface_gl.h 170 | @@ -58,6 +58,8 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate, 171 | // |shell::GPUSurfaceGLDelegate| 172 | intptr_t GLContextFBO() const override; 173 | 174 | + void* GetContext() override; 175 | + 176 | private: 177 | fml::RefPtr onscreen_context_; 178 | fml::RefPtr offscreen_context_; 179 | diff --git a/shell/platform/android/android_surface_software.cc b/shell/platform/android/android_surface_software.cc 180 | index 475c1de26..c492caf78 100644 181 | --- a/shell/platform/android/android_surface_software.cc 182 | +++ b/shell/platform/android/android_surface_software.cc 183 | @@ -139,6 +139,10 @@ bool AndroidSurfaceSoftware::OnScreenSurfaceResize(const SkISize& size) const { 184 | return true; 185 | } 186 | 187 | +void* AndroidSurfaceSoftware::GetContext() { 188 | + return 0; 189 | +} 190 | + 191 | bool AndroidSurfaceSoftware::SetNativeWindow( 192 | fml::RefPtr window) { 193 | native_window_ = std::move(window); 194 | diff --git a/shell/platform/android/android_surface_software.h b/shell/platform/android/android_surface_software.h 195 | index c7410642c..110e2db7c 100644 196 | --- a/shell/platform/android/android_surface_software.h 197 | +++ b/shell/platform/android/android_surface_software.h 198 | @@ -47,6 +47,8 @@ class AndroidSurfaceSoftware final : public AndroidSurface, 199 | // |shell::GPUSurfaceSoftwareDelegate| 200 | bool PresentBackingStore(sk_sp backing_store) override; 201 | 202 | + void* GetContext() override; 203 | + 204 | private: 205 | sk_sp sk_surface_; 206 | fml::RefPtr native_window_; 207 | diff --git a/shell/platform/android/io/flutter/view/FlutterView.java b/shell/platform/android/io/flutter/view/FlutterView.java 208 | index 759b2744c..a85670700 100644 209 | --- a/shell/platform/android/io/flutter/view/FlutterView.java 210 | +++ b/shell/platform/android/io/flutter/view/FlutterView.java 211 | @@ -25,6 +25,8 @@ import android.view.accessibility.AccessibilityNodeProvider; 212 | import android.view.inputmethod.EditorInfo; 213 | import android.view.inputmethod.InputConnection; 214 | import android.view.inputmethod.InputMethodManager; 215 | +import android.opengl.EGLContext; 216 | +import io.flutter.app.FlutterActivity; 217 | import io.flutter.app.FlutterPluginRegistry; 218 | import io.flutter.plugin.common.*; 219 | import io.flutter.plugin.editing.TextInputPlugin; 220 | @@ -790,10 +792,15 @@ public class FlutterView extends SurfaceView 221 | 222 | private static native void nativeRegisterTexture(long nativePlatformViewAndroid, long textureId, 223 | SurfaceTexture surfaceTexture); 224 | + 225 | + private static native void nativeGLRegisterTexture(long nativePlatformViewAndroid, long textureIndex, long textureId); 226 | 227 | private static native void nativeMarkTextureFrameAvailable(long nativePlatformViewAndroid, long textureId); 228 | + 229 | 230 | private static native void nativeUnregisterTexture(long nativePlatformViewAndroid, long textureId); 231 | + 232 | + private static native EGLContext nativeGetContext(long nativePlatformViewAndroid); 233 | 234 | private void updateViewportMetrics() { 235 | if (!isAttached()) 236 | @@ -1076,11 +1083,85 @@ public class FlutterView extends SurfaceView 237 | nativeRegisterTexture(mNativeView.get(), entry.id(), surfaceTexture); 238 | return entry; 239 | } 240 | + 241 | + @Override 242 | + public void onGLFrameAvaliable(int textureIndex) { 243 | + nativeMarkTextureFrameAvailable(mNativeView.get(), textureIndex); 244 | + } 245 | + 246 | + @Override 247 | + public long registerGLTexture(long textureID) { 248 | + long texIndex = nextTextureId.getAndIncrement(); 249 | + nativeGLRegisterTexture(mNativeView.get(), texIndex, textureID); 250 | + return texIndex; 251 | + } 252 | + 253 | + @Override 254 | + public TextureRegistry.GLTextureEntry createGLTexture(long textureID) { 255 | + long texIndex = nextTextureId.getAndIncrement(); 256 | + final GLTextureRegistryEntry entry = new GLTextureRegistryEntry(texIndex,textureID); 257 | + nativeGLRegisterTexture(mNativeView.get(), texIndex, textureID); 258 | + return entry; 259 | + } 260 | 261 | + @Override 262 | + public EGLContext getGLContext() { 263 | + return nativeGetContext(mNativeView.get()); 264 | + } 265 | + 266 | + final class GLTextureRegistryEntry implements TextureRegistry.GLTextureEntry { 267 | + private final long id; 268 | + private final long textureID; 269 | + private boolean released; 270 | + private boolean suspended; 271 | + GLTextureRegistryEntry(long id, long textureID) { 272 | + this.id = id; 273 | + this.textureID = textureID; 274 | + } 275 | + 276 | + @Override 277 | + public long id() { 278 | + return id; 279 | + } 280 | + 281 | + @Override 282 | + public void release() { 283 | + if (released) { 284 | + return; 285 | + } 286 | + if (suspended) { 287 | + return; 288 | + } 289 | + released = true; 290 | + nativeGLRegisterTexture(mNativeView.get(), id, textureID); 291 | + } 292 | + 293 | + @Override 294 | + public void suspend() { 295 | + if (released) { 296 | + return; 297 | + } 298 | + if (suspended) { 299 | + return; 300 | + } 301 | + suspended = true; 302 | + nativeUnregisterTexture(mNativeView.get(), id); 303 | + } 304 | + 305 | + @Override 306 | + public void resume(long textureID) { 307 | + if(released) return; 308 | + if(!suspended) return; 309 | + suspended = false; 310 | + nativeGLRegisterTexture(mNativeView.get(), id, textureID); 311 | + } 312 | + } 313 | + 314 | final class SurfaceTextureRegistryEntry implements TextureRegistry.SurfaceTextureEntry { 315 | private final long id; 316 | - private final SurfaceTexture surfaceTexture; 317 | + private SurfaceTexture surfaceTexture; 318 | private boolean released; 319 | + private boolean suspended; 320 | 321 | SurfaceTextureRegistryEntry(long id, SurfaceTexture surfaceTexture) { 322 | this.id = id; 323 | @@ -1127,12 +1208,58 @@ public class FlutterView extends SurfaceView 324 | if (released) { 325 | return; 326 | } 327 | + if (suspended) { 328 | + return; 329 | + } 330 | released = true; 331 | nativeUnregisterTexture(mNativeView.get(), id); 332 | // Otherwise onFrameAvailableListener might be called after mNativeView==null 333 | // (https://github.com/flutter/flutter/issues/20951). See also the check in onFrameAvailable. 334 | surfaceTexture.setOnFrameAvailableListener(null); 335 | surfaceTexture.release(); 336 | + surfaceTexture = null; 337 | + } 338 | + 339 | + @Override 340 | + public void suspend() { 341 | + if (released) { 342 | + return; 343 | + } 344 | + if (suspended) { 345 | + return; 346 | + } 347 | + 348 | + suspended = true; 349 | + nativeUnregisterTexture(mNativeView.get(), id); 350 | + // Otherwise onFrameAvailableListener might be called after mNativeView==null 351 | + // (https://github.com/flutter/flutter/issues/20951). See also the check in 352 | + // onFrameAvailable. 353 | + surfaceTexture.setOnFrameAvailableListener(null); 354 | + surfaceTexture.release(); 355 | + surfaceTexture = null; 356 | + } 357 | + 358 | + @Override 359 | + public void resume() { 360 | + if(released) return; 361 | + if(!suspended) return; 362 | + suspended = false; 363 | + if(surfaceTexture == null){ 364 | + surfaceTexture = new SurfaceTexture(0); 365 | + surfaceTexture.detachFromGLContext(); 366 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 367 | + // The callback relies on being executed on the UI thread (unsynchronised read of mNativeView 368 | + // and also the engine code check for platform thread in Shell::OnPlatformViewMarkTextureFrameAvailable), 369 | + // so we explicitly pass a Handler for the current thread. 370 | + surfaceTexture.setOnFrameAvailableListener(onFrameListener, new Handler()); 371 | + } else { 372 | + // Android documentation states that the listener can be called on an arbitrary thread. 373 | + // But in practice, versions of Android that predate the newer API will call the listener 374 | + // on the thread where the SurfaceTexture was constructed. 375 | + surfaceTexture.setOnFrameAvailableListener(onFrameListener); 376 | + } 377 | + } 378 | + nativeRegisterTexture(mNativeView.get(), id, surfaceTexture); 379 | } 380 | } 381 | } 382 | diff --git a/shell/platform/android/io/flutter/view/TextureRegistry.java b/shell/platform/android/io/flutter/view/TextureRegistry.java 383 | index ed3134bb0..1b1045f01 100644 384 | --- a/shell/platform/android/io/flutter/view/TextureRegistry.java 385 | +++ b/shell/platform/android/io/flutter/view/TextureRegistry.java 386 | @@ -5,6 +5,7 @@ 387 | package io.flutter.view; 388 | 389 | import android.graphics.SurfaceTexture; 390 | +import android.opengl.EGLContext; 391 | 392 | /** 393 | * Registry of backend textures used with a single {@link FlutterView} instance. 394 | @@ -19,6 +20,42 @@ public interface TextureRegistry { 395 | * @return A SurfaceTextureEntry. 396 | */ 397 | SurfaceTextureEntry createSurfaceTexture(); 398 | + 399 | + void onGLFrameAvaliable(int index); 400 | + 401 | + long registerGLTexture(long textureID); 402 | + 403 | + EGLContext getGLContext(); 404 | + 405 | + GLTextureEntry createGLTexture(long textureID); 406 | + 407 | + /** 408 | + * A registry entry for a managed SurfaceTexture. 409 | + */ 410 | + interface GLTextureEntry { 411 | + 412 | + /** 413 | + * @return The identity of this SurfaceTexture. 414 | + */ 415 | + long id(); 416 | + 417 | + /** 418 | + * Deregisters and releases this SurfaceTexture. 419 | + */ 420 | + void release(); 421 | + 422 | + /** 423 | + * suspend the SurfaceTexture 424 | + * this will unregister the texture and release the existed surfaceeTexture,but 425 | + * the id will be reserved 426 | + */ 427 | + void suspend(); 428 | + 429 | + /** 430 | + * this will create a new SurfaceTexture, and register texture 431 | + */ 432 | + void resume(long textureID); 433 | + } 434 | 435 | /** 436 | * A registry entry for a managed SurfaceTexture. 437 | @@ -38,5 +75,18 @@ public interface TextureRegistry { 438 | * Deregisters and releases this SurfaceTexture. 439 | */ 440 | void release(); 441 | + 442 | + /** 443 | + * suspend the SurfaceTexture 444 | + * this will unregister the texture and release the existed surfaceeTexture,but 445 | + * the id will be reserved 446 | + */ 447 | + void suspend(); 448 | + 449 | + /** 450 | + * this will create a new SurfaceTexture, and register texture 451 | + */ 452 | + void resume(); 453 | + 454 | } 455 | } 456 | diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc 457 | index 034c05969..d70cd5be3 100644 458 | --- a/shell/platform/android/platform_view_android.cc 459 | +++ b/shell/platform/android/platform_view_android.cc 460 | @@ -355,6 +355,16 @@ void PlatformViewAndroid::RegisterExternalTexture( 461 | std::make_shared(texture_id, surface_texture)); 462 | } 463 | 464 | +void PlatformViewAndroid::RegisterGLExternalTexture(int64_t texture_index, 465 | + int64_t texture_id) { 466 | + RegisterTexture( 467 | + std::make_shared(texture_index, texture_id)); 468 | +} 469 | + 470 | +void* PlatformViewAndroid::GetContext() { 471 | + return android_surface_->GetContext(); 472 | +} 473 | + 474 | // |shell::PlatformView| 475 | std::unique_ptr PlatformViewAndroid::CreateVSyncWaiter() { 476 | return std::make_unique(task_runners_); 477 | diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h 478 | index c162ac5a2..b325d166f 100644 479 | --- a/shell/platform/android/platform_view_android.h 480 | +++ b/shell/platform/android/platform_view_android.h 481 | @@ -73,6 +73,10 @@ class PlatformViewAndroid final : public PlatformView { 482 | int64_t texture_id, 483 | const fml::jni::JavaObjectWeakGlobalRef& surface_texture); 484 | 485 | + void RegisterGLExternalTexture(int64_t texture_index, int64_t texture_id); 486 | + 487 | + void* GetContext(); 488 | + 489 | private: 490 | const fml::jni::JavaObjectWeakGlobalRef java_object_; 491 | const std::unique_ptr android_surface_; 492 | diff --git a/shell/platform/android/platform_view_android_jni.cc b/shell/platform/android/platform_view_android_jni.cc 493 | index be42414b6..50d93f1b1 100644 494 | --- a/shell/platform/android/platform_view_android_jni.cc 495 | +++ b/shell/platform/android/platform_view_android_jni.cc 496 | @@ -24,6 +24,9 @@ 497 | #include "flutter/shell/platform/android/apk_asset_provider.h" 498 | #include "flutter/shell/platform/android/flutter_main.h" 499 | 500 | +#include 501 | +#include 502 | + 503 | #define ANDROID_SHELL_HOLDER \ 504 | (reinterpret_cast(shell_holder)) 505 | 506 | @@ -502,6 +505,31 @@ static void RegisterTexture(JNIEnv* env, 507 | ); 508 | } 509 | 510 | +static void RegisterGLTexture(JNIEnv* env, 511 | + jobject jcaller, 512 | + jlong shell_holder, 513 | + jlong texture_index, 514 | + jlong texture_id) { 515 | + ANDROID_SHELL_HOLDER->GetPlatformView()->RegisterGLExternalTexture( 516 | + static_cast(texture_index), static_cast(texture_id)); 517 | +} 518 | + 519 | +static jobject GetContext(JNIEnv* env, jobject jcaller, jlong shell_holder) { 520 | + jclass eglcontextClassLocal = env->FindClass("android/opengl/EGLContext"); 521 | + jmethodID eglcontextConstructor = 522 | + env->GetMethodID(eglcontextClassLocal, "", "(J)V"); 523 | + 524 | + void* cxt = ANDROID_SHELL_HOLDER->GetPlatformView()->GetContext(); 525 | + 526 | + if ((EGLContext)cxt == EGL_NO_CONTEXT) { 527 | + return env->NewObject(eglcontextClassLocal, eglcontextConstructor, 528 | + reinterpret_cast(EGL_NO_CONTEXT)); 529 | + } 530 | + 531 | + return env->NewObject(eglcontextClassLocal, eglcontextConstructor, 532 | + reinterpret_cast(cxt)); 533 | +} 534 | + 535 | static void MarkTextureFrameAvailable(JNIEnv* env, 536 | jobject jcaller, 537 | jlong shell_holder, 538 | @@ -688,6 +716,12 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { 539 | .signature = "(JJLandroid/graphics/SurfaceTexture;)V", 540 | .fnPtr = reinterpret_cast(&shell::RegisterTexture), 541 | }, 542 | + { 543 | + .name = "nativeGLRegisterTexture", 544 | + .signature = "(JJJ)V", 545 | + .fnPtr = reinterpret_cast(&shell::RegisterGLTexture), 546 | + }, 547 | + 548 | { 549 | .name = "nativeMarkTextureFrameAvailable", 550 | .signature = "(JJ)V", 551 | @@ -698,6 +732,12 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { 552 | .signature = "(JJ)V", 553 | .fnPtr = reinterpret_cast(&shell::UnregisterTexture), 554 | }, 555 | + { 556 | + .name = "nativeGetContext", 557 | + .signature = "(J)Landroid/opengl/EGLContext;", 558 | + .fnPtr = reinterpret_cast(&shell::GetContext), 559 | + }, 560 | + 561 | }; 562 | 563 | static const JNINativeMethod callback_info_methods[] = { 564 | diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h b/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h 565 | index e7cd01337..4abccee96 100644 566 | --- a/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h 567 | +++ b/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h 568 | @@ -7,6 +7,7 @@ 569 | 570 | #import 571 | #import 572 | +#import 573 | 574 | #include "FlutterMacros.h" 575 | 576 | @@ -15,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN 577 | FLUTTER_EXPORT 578 | @protocol FlutterTexture 579 | - (CVPixelBufferRef _Nullable)copyPixelBuffer; 580 | +- (GLuint)copyTextureID; 581 | @end 582 | 583 | FLUTTER_EXPORT 584 | @@ -22,6 +24,7 @@ FLUTTER_EXPORT 585 | - (int64_t)registerTexture:(NSObject*)texture; 586 | - (void)textureFrameAvailable:(int64_t)textureId; 587 | - (void)unregisterTexture:(int64_t)textureId; 588 | +- (EAGLSharegroup*)glShareGroup; 589 | @end 590 | 591 | NS_ASSUME_NONNULL_END 592 | diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm 593 | index c5f3b8d9a..c6c4f1af6 100644 594 | --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm 595 | +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm 596 | @@ -459,6 +459,9 @@ - (void)setMessageHandlerOnChannel:(NSString*)channel 597 | } 598 | 599 | #pragma mark - FlutterTextureRegistry 600 | +- (EAGLSharegroup*)glShareGroup { 601 | + return (EAGLSharegroup*)(self.iosPlatformView -> GetGLShareGroup()); 602 | +} 603 | 604 | - (int64_t)registerTexture:(NSObject*)texture { 605 | int64_t textureId = _nextTextureId++; 606 | diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 607 | index 5a367bdea..9f01c4002 100644 608 | --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 609 | +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 610 | @@ -953,6 +953,11 @@ - (void)setMessageHandlerOnChannel:(NSString*)channel 611 | } 612 | 613 | #pragma mark - FlutterTextureRegistry 614 | +- (EAGLSharegroup*)glShareGroup { 615 | + shell::PlatformViewIOS* platformViewIOS = 616 | + static_cast([_engine.get() platformView].get()); 617 | + return (EAGLSharegroup*)(platformViewIOS->GetGLShareGroup()); 618 | +} 619 | 620 | - (int64_t)registerTexture:(NSObject*)texture { 621 | return [_engine.get() registerTexture:texture]; 622 | diff --git a/shell/platform/darwin/ios/ios_external_texture_gl.mm b/shell/platform/darwin/ios/ios_external_texture_gl.mm 623 | index e77970697..b1480efae 100644 624 | --- a/shell/platform/darwin/ios/ios_external_texture_gl.mm 625 | +++ b/shell/platform/darwin/ios/ios_external_texture_gl.mm 626 | @@ -25,39 +25,48 @@ 627 | IOSExternalTextureGL::~IOSExternalTextureGL() = default; 628 | 629 | void IOSExternalTextureGL::Paint(SkCanvas& canvas, const SkRect& bounds, bool freeze) { 630 | - if (!cache_ref_) { 631 | - CVOpenGLESTextureCacheRef cache; 632 | - CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, 633 | - [EAGLContext currentContext], NULL, &cache); 634 | - if (err == noErr) { 635 | - cache_ref_.Reset(cache); 636 | - } else { 637 | - FML_LOG(WARNING) << "Failed to create GLES texture cache: " << err; 638 | - return; 639 | - } 640 | - } 641 | - fml::CFRef bufferRef; 642 | - if (!freeze) { 643 | - bufferRef.Reset([external_texture_ copyPixelBuffer]); 644 | - if (bufferRef != nullptr) { 645 | - CVOpenGLESTextureRef texture; 646 | - CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage( 647 | - kCFAllocatorDefault, cache_ref_, bufferRef, nullptr, GL_TEXTURE_2D, GL_RGBA, 648 | - static_cast(CVPixelBufferGetWidth(bufferRef)), 649 | - static_cast(CVPixelBufferGetHeight(bufferRef)), GL_BGRA, GL_UNSIGNED_BYTE, 0, 650 | - &texture); 651 | - texture_ref_.Reset(texture); 652 | - if (err != noErr) { 653 | - FML_LOG(WARNING) << "Could not create texture from pixel buffer: " << err; 654 | + GrGLTextureInfo textureInfo; 655 | + if ([external_texture_ respondsToSelector:@selector(copyTextureID)]) { 656 | + textureInfo.fFormat = GL_RGBA8_OES; 657 | + textureInfo.fID = [external_texture_ copyTextureID]; 658 | + textureInfo.fTarget = GL_TEXTURE_2D; 659 | + } else { 660 | + if (!cache_ref_) { 661 | + CVOpenGLESTextureCacheRef cache; 662 | + CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, 663 | + [EAGLContext currentContext], NULL, &cache); 664 | + if (err == noErr) { 665 | + cache_ref_.Reset(cache); 666 | + } else { 667 | + FML_LOG(WARNING) << "Failed to create GLES texture cache: " << err; 668 | return; 669 | } 670 | } 671 | + if (!freeze) { 672 | + fml::CFRef bufferRef; 673 | + bufferRef.Reset([external_texture_ copyPixelBuffer]); 674 | + if (bufferRef != nullptr) { 675 | + CVOpenGLESTextureRef texture; 676 | + CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage( 677 | + kCFAllocatorDefault, cache_ref_, bufferRef, nullptr, GL_TEXTURE_2D, GL_RGBA, 678 | + static_cast(CVPixelBufferGetWidth(bufferRef)), 679 | + static_cast(CVPixelBufferGetHeight(bufferRef)), GL_BGRA, GL_UNSIGNED_BYTE, 0, 680 | + &texture); 681 | + texture_ref_.Reset(texture); 682 | + if (err != noErr) { 683 | + FML_LOG(WARNING) << "Could not create texture from pixel buffer: " << err; 684 | + return; 685 | + } 686 | + } 687 | + } 688 | + 689 | + if (!texture_ref_) { 690 | + return; 691 | + } 692 | + textureInfo.fFormat = GL_RGBA8_OES; 693 | + textureInfo.fID = CVOpenGLESTextureGetName(texture_ref_); 694 | + textureInfo.fTarget = CVOpenGLESTextureGetTarget(texture_ref_); 695 | } 696 | - if (!texture_ref_) { 697 | - return; 698 | - } 699 | - GrGLTextureInfo textureInfo = {CVOpenGLESTextureGetTarget(texture_ref_), 700 | - CVOpenGLESTextureGetName(texture_ref_), GL_RGBA8_OES}; 701 | GrBackendTexture backendTexture(bounds.width(), bounds.height(), GrMipMapped::kNo, textureInfo); 702 | sk_sp image = 703 | SkImage::MakeFromTexture(canvas.getGrContext(), backendTexture, kTopLeft_GrSurfaceOrigin, 704 | diff --git a/shell/platform/darwin/ios/ios_gl_context.h b/shell/platform/darwin/ios/ios_gl_context.h 705 | index 08778d213..6758c93cd 100644 706 | --- a/shell/platform/darwin/ios/ios_gl_context.h 707 | +++ b/shell/platform/darwin/ios/ios_gl_context.h 708 | @@ -30,6 +30,8 @@ class IOSGLContext { 709 | 710 | bool ResourceMakeCurrent(); 711 | 712 | + void* GetGLShareGroup(); 713 | + 714 | sk_sp ColorSpace() const { return color_space_; } 715 | 716 | private: 717 | diff --git a/shell/platform/darwin/ios/ios_gl_context.mm b/shell/platform/darwin/ios/ios_gl_context.mm 718 | index c8819a78b..276d330f9 100644 719 | --- a/shell/platform/darwin/ios/ios_gl_context.mm 720 | +++ b/shell/platform/darwin/ios/ios_gl_context.mm 721 | @@ -13,9 +13,9 @@ 722 | namespace shell { 723 | 724 | IOSGLContext::IOSGLContext() { 725 | - context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]); 726 | + context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]); 727 | if (context_ != nullptr) { 728 | - resource_context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3 729 | + resource_context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 730 | sharegroup:context_.get().sharegroup]); 731 | } else { 732 | context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]); 733 | @@ -61,4 +61,9 @@ 734 | return [EAGLContext setCurrentContext:resource_context_.get()]; 735 | } 736 | 737 | +void* IOSGLContext::GetGLShareGroup() { 738 | + EAGLSharegroup* shareGroup = context_.get().sharegroup; 739 | + return (void*)shareGroup; 740 | +} 741 | + 742 | } // namespace shell 743 | diff --git a/shell/platform/darwin/ios/ios_surface.h b/shell/platform/darwin/ios/ios_surface.h 744 | index 1fc6a4218..e8bb37c84 100644 745 | --- a/shell/platform/darwin/ios/ios_surface.h 746 | +++ b/shell/platform/darwin/ios/ios_surface.h 747 | @@ -33,6 +33,8 @@ class IOSSurface { 748 | 749 | virtual std::unique_ptr CreateGPUSurface() = 0; 750 | 751 | + virtual void* GetGLShareGroup() = 0; 752 | + 753 | protected: 754 | FlutterPlatformViewsController* GetPlatformViewsController(); 755 | 756 | diff --git a/shell/platform/darwin/ios/ios_surface_gl.h b/shell/platform/darwin/ios/ios_surface_gl.h 757 | index 93fcc0f51..8d6515db5 100644 758 | --- a/shell/platform/darwin/ios/ios_surface_gl.h 759 | +++ b/shell/platform/darwin/ios/ios_surface_gl.h 760 | @@ -39,6 +39,8 @@ class IOSSurfaceGL : public IOSSurface, 761 | 762 | bool GLContextMakeCurrent() override; 763 | 764 | + void* GetGLShareGroup() override; 765 | + 766 | bool GLContextClearCurrent() override; 767 | 768 | bool GLContextPresent() override; 769 | diff --git a/shell/platform/darwin/ios/ios_surface_gl.mm b/shell/platform/darwin/ios/ios_surface_gl.mm 770 | index cd0bb093d..914bf2a33 100644 771 | --- a/shell/platform/darwin/ios/ios_surface_gl.mm 772 | +++ b/shell/platform/darwin/ios/ios_surface_gl.mm 773 | @@ -50,6 +50,10 @@ 774 | return IsValid() ? render_target_->framebuffer() : GL_NONE; 775 | } 776 | 777 | +void* IOSSurfaceGL::GetGLShareGroup() { 778 | + return context_.get()->GetGLShareGroup(); 779 | +} 780 | + 781 | bool IOSSurfaceGL::UseOffscreenSurface() const { 782 | // The onscreen surface wraps a GL renderbuffer, which is extremely slow to read. 783 | // Certain filter effects require making a copy of the current destination, so we 784 | diff --git a/shell/platform/darwin/ios/ios_surface_software.h b/shell/platform/darwin/ios/ios_surface_software.h 785 | index 79695b3a2..ecc640dbb 100644 786 | --- a/shell/platform/darwin/ios/ios_surface_software.h 787 | +++ b/shell/platform/darwin/ios/ios_surface_software.h 788 | @@ -36,6 +36,8 @@ class IOSSurfaceSoftware final : public IOSSurface, 789 | // |shell::IOSSurface| 790 | std::unique_ptr CreateGPUSurface() override; 791 | 792 | + void* GetGLShareGroup() override; 793 | + 794 | // |shell::GPUSurfaceSoftwareDelegate| 795 | sk_sp AcquireBackingStore(const SkISize& size) override; 796 | 797 | diff --git a/shell/platform/darwin/ios/ios_surface_software.mm b/shell/platform/darwin/ios/ios_surface_software.mm 798 | index 5d120ef47..0c467853b 100644 799 | --- a/shell/platform/darwin/ios/ios_surface_software.mm 800 | +++ b/shell/platform/darwin/ios/ios_surface_software.mm 801 | @@ -52,6 +52,10 @@ 802 | return surface; 803 | } 804 | 805 | +void* IOSSurfaceSoftware::GetGLShareGroup() { 806 | + return nullptr; 807 | +} 808 | + 809 | sk_sp IOSSurfaceSoftware::AcquireBackingStore(const SkISize& size) { 810 | TRACE_EVENT0("flutter", "IOSSurfaceSoftware::AcquireBackingStore"); 811 | if (!IsValid()) { 812 | diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h 813 | index a0d85a7ff..294885c15 100644 814 | --- a/shell/platform/darwin/ios/platform_view_ios.h 815 | +++ b/shell/platform/darwin/ios/platform_view_ios.h 816 | @@ -36,6 +36,8 @@ class PlatformViewIOS final : public PlatformView { 817 | 818 | void RegisterExternalTexture(int64_t id, NSObject* texture); 819 | 820 | + void* GetGLShareGroup(); 821 | + 822 | fml::scoped_nsprotocol GetTextInputPlugin() const; 823 | 824 | void SetTextInputPlugin(fml::scoped_nsprotocol plugin); 825 | diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm 826 | index f3371a983..3231c1736 100644 827 | --- a/shell/platform/darwin/ios/platform_view_ios.mm 828 | +++ b/shell/platform/darwin/ios/platform_view_ios.mm 829 | @@ -63,6 +63,12 @@ 830 | RegisterTexture(std::make_shared(texture_id, texture)); 831 | } 832 | 833 | +void* PlatformViewIOS::GetGLShareGroup() { 834 | + if (ios_surface_.get() == NULL) 835 | + return NULL; 836 | + return ios_surface_->GetGLShareGroup(); 837 | +} 838 | + 839 | // |shell::PlatformView| 840 | std::unique_ptr PlatformViewIOS::CreateRenderingSurface() { 841 | if (!ios_surface_) { 842 | -- 843 | 2.20.1 (Apple Git-117) 844 | 845 | -------------------------------------------------------------------------------- /patches/stable_v1.0/engine#src#flutter/0002-Fix-a-tap-failure-problem-when-double-click.patch: -------------------------------------------------------------------------------- 1 | From 58992412b0afc66c777583f7925a908f31f11b35 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sat, 22 Dec 2018 23:35:01 +0800 4 | Subject: [PATCH] alfpatch:Fix a tap failure problem when double click on 5 | FlutterViewController 6 | 7 | --- 8 | .../framework/Source/FlutterViewController.mm | 74 ++++++++++++++++--- 9 | 1 file changed, 65 insertions(+), 9 deletions(-) 10 | 11 | diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 12 | index 9f01c4002..ea8beaaa0 100644 13 | --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 14 | +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 15 | @@ -22,6 +22,8 @@ 16 | #include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" 17 | #include "flutter/shell/platform/darwin/ios/platform_view_ios.h" 18 | 19 | +static double kTouchTrackerCheckInterval = 1.f; 20 | + 21 | @implementation FlutterViewController { 22 | std::unique_ptr> _weakFactory; 23 | fml::scoped_nsobject _engine; 24 | @@ -37,6 +39,8 @@ @implementation FlutterViewController { 25 | BOOL _initialized; 26 | BOOL _viewOpaque; 27 | BOOL _engineNeedsLaunch; 28 | + NSMutableSet* _touchTrackerSet; 29 | + NSMutableDictionary* _touchTrackerDict; 30 | } 31 | 32 | #pragma mark - Manage and override all designated initializers 33 | @@ -113,6 +117,8 @@ - (void)performCommonViewControllerInitialization { 34 | _orientationPreferences = UIInterfaceOrientationMaskAll; 35 | _statusBarStyle = UIStatusBarStyleDefault; 36 | 37 | + _touchTrackerSet = [[NSMutableSet set] retain]; 38 | + _touchTrackerDict = [[NSMutableDictionary dictionary] retain]; 39 | [self setupNotificationCenterObservers]; 40 | } 41 | 42 | @@ -429,6 +435,8 @@ - (void)viewDidDisappear:(BOOL)animated { 43 | 44 | - (void)dealloc { 45 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 46 | + [_touchTrackerSet release]; 47 | + [_touchTrackerDict release]; 48 | [super dealloc]; 49 | } 50 | 51 | @@ -498,18 +506,40 @@ - (void)applicationWillEnterForeground:(NSNotification*)notification { 52 | // in the status bar area are available to framework code. The change type (optional) of the faked 53 | // touch is specified in the second argument. 54 | - (void)dispatchTouches:(NSSet*)touches 55 | - pointerDataChangeOverride:(blink::PointerData::Change*)overridden_change { 56 | + pointerDataChangeOverride:(blink::PointerData::Change*)overridden_change 57 | + trackTouches:(BOOL)bTrack { 58 | const CGFloat scale = [UIScreen mainScreen].scale; 59 | auto packet = std::make_unique(touches.count); 60 | - 61 | + NSTimeInterval tsNow = [[NSDate date] timeIntervalSinceReferenceDate]; 62 | size_t pointer_index = 0; 63 | 64 | for (UITouch* touch in touches) { 65 | CGPoint windowCoordinates = [touch locationInView:self.view]; 66 | - 67 | + UITouchPhase phase = touch.phase; 68 | + NSValue* key = [NSValue valueWithPointer:(void*)touch]; 69 | blink::PointerData pointer_data; 70 | pointer_data.Clear(); 71 | 72 | + switch (phase) { 73 | + case UITouchPhaseBegan: 74 | + case UITouchPhaseMoved: 75 | + case UITouchPhaseStationary: 76 | + if (bTrack) { 77 | + [_touchTrackerSet addObject:touch]; 78 | + _touchTrackerDict[key] = @(tsNow + kTouchTrackerCheckInterval); 79 | + } 80 | + break; 81 | + case UITouchPhaseEnded: 82 | + case UITouchPhaseCancelled: 83 | + if (bTrack) { 84 | + [_touchTrackerDict removeObjectForKey:key]; 85 | + [_touchTrackerSet removeObject:touch]; 86 | + } 87 | + break; 88 | + default: 89 | + break; 90 | + } 91 | + 92 | constexpr int kMicrosecondsPerSecond = 1000 * 1000; 93 | pointer_data.time_stamp = touch.timestamp * kMicrosecondsPerSecond; 94 | 95 | @@ -584,19 +614,45 @@ - (void)dispatchTouches:(NSSet*)touches 96 | } 97 | 98 | - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { 99 | - [self dispatchTouches:touches pointerDataChangeOverride:nullptr]; 100 | + [self dispatchTouches:touches pointerDataChangeOverride:nullptr trackTouches:TRUE]; 101 | + [self checkIfCompleteTouches]; 102 | } 103 | 104 | - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { 105 | - [self dispatchTouches:touches pointerDataChangeOverride:nullptr]; 106 | + [self dispatchTouches:touches pointerDataChangeOverride:nullptr trackTouches:TRUE]; 107 | } 108 | 109 | - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { 110 | - [self dispatchTouches:touches pointerDataChangeOverride:nullptr]; 111 | + [self dispatchTouches:touches pointerDataChangeOverride:nullptr trackTouches:TRUE]; 112 | } 113 | 114 | - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { 115 | - [self dispatchTouches:touches pointerDataChangeOverride:nullptr]; 116 | + [self dispatchTouches:touches pointerDataChangeOverride:nullptr trackTouches:TRUE]; 117 | +} 118 | + 119 | +- (BOOL)checkIfCompleteTouches { 120 | + NSInteger cnt = _touchTrackerSet.count; 121 | + if (cnt <= 0) 122 | + return FALSE; 123 | + NSTimeInterval tsNow = [[NSDate date] timeIntervalSinceReferenceDate]; 124 | + NSSet* tmpTrackingTouches = [_touchTrackerSet copy]; 125 | + NSMutableSet* set = [NSMutableSet set]; 126 | + for (UITouch* touch in tmpTrackingTouches) { 127 | + NSValue* key = [NSValue valueWithPointer:(void*)touch]; 128 | + NSNumber* expiredTime = [_touchTrackerDict objectForKey:key]; 129 | + if (expiredTime.doubleValue <= tsNow) { 130 | + [touch setValue:@(UITouchPhaseEnded) forKey:@"phase"]; 131 | + [set addObject:touch]; 132 | + [_touchTrackerDict removeObjectForKey:key]; 133 | + [_touchTrackerSet removeObject:touch]; 134 | + } 135 | + } 136 | + if (set.count > 0) { 137 | + [self dispatchTouches:set pointerDataChangeOverride:nullptr trackTouches:FALSE]; 138 | + [self dispatchTouches:set pointerDataChangeOverride:nullptr trackTouches:FALSE]; 139 | + return TRUE; 140 | + } 141 | + return FALSE; 142 | } 143 | 144 | #pragma mark - Handle view resizing 145 | @@ -892,9 +948,9 @@ - (void)handleStatusBarTouches:(UIEvent*)event { 146 | NSSet* statusbarTouches = [NSSet setWithObject:touch]; 147 | 148 | blink::PointerData::Change change = blink::PointerData::Change::kDown; 149 | - [self dispatchTouches:statusbarTouches pointerDataChangeOverride:&change]; 150 | + [self dispatchTouches:statusbarTouches pointerDataChangeOverride:&change trackTouches:TRUE]; 151 | change = blink::PointerData::Change::kUp; 152 | - [self dispatchTouches:statusbarTouches pointerDataChangeOverride:&change]; 153 | + [self dispatchTouches:statusbarTouches pointerDataChangeOverride:&change trackTouches:TRUE]; 154 | return; 155 | } 156 | } 157 | -- 158 | 2.20.1 (Apple Git-117) 159 | 160 | -------------------------------------------------------------------------------- /patches/stable_v1.0/engine#src#flutter/0003-A-workaround-for-libgpu-related-crash-in-ba.patch: -------------------------------------------------------------------------------- 1 | From 1745f690fde42116aea38c48bec415ebceda09fc Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sun, 23 Dec 2018 00:04:44 +0800 4 | Subject: [PATCH] alfpatch:A workaround for libgpu related crash in background 5 | 6 | --- 7 | fml/message_loop_impl.cc | 26 ++++++-- 8 | fml/message_loop_impl.h | 17 ++++- 9 | fml/task_runner.cc | 8 +++ 10 | fml/task_runner.h | 2 + 11 | shell/common/shell.cc | 8 +++ 12 | .../framework/Source/FlutterViewController.mm | 62 +++++++++++++++++++ 13 | 6 files changed, 116 insertions(+), 7 deletions(-) 14 | 15 | diff --git a/fml/message_loop_impl.cc b/fml/message_loop_impl.cc 16 | index 4d2c5bf4f..dd2b05cd1 100644 17 | --- a/fml/message_loop_impl.cc 18 | +++ b/fml/message_loop_impl.cc 19 | @@ -39,7 +39,8 @@ fml::RefPtr MessageLoopImpl::Create() { 20 | #endif 21 | } 22 | 23 | -MessageLoopImpl::MessageLoopImpl() : order_(0), terminated_(false) {} 24 | +MessageLoopImpl::MessageLoopImpl() 25 | + : order_(0), terminated_(false), task_limit_per_looprun_(10000) {} 26 | 27 | MessageLoopImpl::~MessageLoopImpl() = default; 28 | 29 | @@ -116,25 +117,34 @@ void MessageLoopImpl::RunExpiredTasks() { 30 | TRACE_EVENT0("fml", "MessageLoop::RunExpiredTasks"); 31 | std::vector invocations; 32 | 33 | + int i_tasks_cnt = 0; 34 | + bool need_call_run_again = false; 35 | + auto now = fml::TimePoint::Now(); 36 | + 37 | { 38 | std::lock_guard lock(delayed_tasks_mutex_); 39 | 40 | - if (delayed_tasks_.empty()) { 41 | + if (delayed_tasks_.empty() || !IsMessageLoopEnabled()) { 42 | return; 43 | } 44 | 45 | - auto now = fml::TimePoint::Now(); 46 | - while (!delayed_tasks_.empty()) { 47 | + is_runninging_expired_tasks_ = true; 48 | + while (!delayed_tasks_.empty() && i_tasks_cnt < task_limit_per_looprun_) { 49 | const auto& top = delayed_tasks_.top(); 50 | if (top.target_time > now) { 51 | break; 52 | } 53 | invocations.emplace_back(std::move(top.task)); 54 | delayed_tasks_.pop(); 55 | + i_tasks_cnt++; 56 | } 57 | 58 | - WakeUp(delayed_tasks_.empty() ? fml::TimePoint::Max() 59 | - : delayed_tasks_.top().target_time); 60 | + if (i_tasks_cnt >= task_limit_per_looprun_ && !delayed_tasks_.empty()) { 61 | + need_call_run_again = true; 62 | + } else { 63 | + WakeUp(delayed_tasks_.empty() ? fml::TimePoint::Max() 64 | + : delayed_tasks_.top().target_time); 65 | + } 66 | } 67 | 68 | for (const auto& invocation : invocations) { 69 | @@ -143,6 +153,10 @@ void MessageLoopImpl::RunExpiredTasks() { 70 | observer.second(); 71 | } 72 | } 73 | + is_runninging_expired_tasks_ = false; 74 | + if (need_call_run_again) { 75 | + RunExpiredTasks(); 76 | + } 77 | } 78 | 79 | MessageLoopImpl::DelayedTask::DelayedTask(size_t p_order, 80 | diff --git a/fml/message_loop_impl.h b/fml/message_loop_impl.h 81 | index 9dab218d0..0a89161cb 100644 82 | --- a/fml/message_loop_impl.h 83 | +++ b/fml/message_loop_impl.h 84 | @@ -42,6 +42,18 @@ class MessageLoopImpl : public fml::RefCountedThreadSafe { 85 | 86 | void DoTerminate(); 87 | 88 | + void EnableMessageLoop(bool isEnable) { is_loop_enabled_ = isEnable; } 89 | + 90 | + void SetTaskLimitPerLoopRun(int task_limit_per_looprun) { 91 | + task_limit_per_looprun_ = task_limit_per_looprun; 92 | + } 93 | + 94 | + inline bool IsMessageLoopEnabled() { return is_loop_enabled_; } 95 | + 96 | + inline bool IsRunningingExpiredTasks() { 97 | + return is_runninging_expired_tasks_; 98 | + } 99 | + 100 | // Exposed for the embedder shell which allows clients to poll for events 101 | // instead of dedicating a thread to the message loop. 102 | void RunExpiredTasksNow(); 103 | @@ -73,13 +85,16 @@ class MessageLoopImpl : public fml::RefCountedThreadSafe { 104 | 105 | using DelayedTaskQueue = std:: 106 | priority_queue, DelayedTaskCompare>; 107 | - 108 | + bool is_loop_enabled_ = true; 109 | std::map task_observers_; 110 | std::mutex delayed_tasks_mutex_; 111 | DelayedTaskQueue delayed_tasks_; 112 | size_t order_; 113 | std::atomic_bool terminated_; 114 | 115 | + bool is_runninging_expired_tasks_; 116 | + int task_limit_per_looprun_; 117 | + 118 | void RegisterTask(fml::closure task, fml::TimePoint target_time); 119 | 120 | void RunExpiredTasks(); 121 | diff --git a/fml/task_runner.cc b/fml/task_runner.cc 122 | index 2c4cfe4b6..58b1bad46 100644 123 | --- a/fml/task_runner.cc 124 | +++ b/fml/task_runner.cc 125 | @@ -39,6 +39,14 @@ bool TaskRunner::RunsTasksOnCurrentThread() { 126 | return MessageLoop::GetCurrent().GetLoopImpl() == loop_; 127 | } 128 | 129 | +void TaskRunner::EnableMessageLoop(bool isEnable) { 130 | + loop_->EnableMessageLoop(isEnable); 131 | +} 132 | + 133 | +MessageLoopImpl* TaskRunner::getMessageLoop() { 134 | + return loop_.get(); 135 | +} 136 | + 137 | void TaskRunner::RunNowOrPostTask(fml::RefPtr runner, 138 | fml::closure task) { 139 | FML_DCHECK(runner); 140 | diff --git a/fml/task_runner.h b/fml/task_runner.h 141 | index 04696752c..60a23c1ea 100644 142 | --- a/fml/task_runner.h 143 | +++ b/fml/task_runner.h 144 | @@ -24,6 +24,8 @@ class TaskRunner : public fml::RefCountedThreadSafe { 145 | virtual void PostDelayedTask(fml::closure task, fml::TimeDelta delay); 146 | 147 | virtual bool RunsTasksOnCurrentThread(); 148 | + void EnableMessageLoop(bool isEnable); 149 | + MessageLoopImpl* getMessageLoop(); 150 | 151 | virtual ~TaskRunner(); 152 | 153 | diff --git a/shell/common/shell.cc b/shell/common/shell.cc 154 | index 4adf55a3f..4503059be 100644 155 | --- a/shell/common/shell.cc 156 | +++ b/shell/common/shell.cc 157 | @@ -981,6 +981,14 @@ Rasterizer::Screenshot Shell::Screenshot( 158 | Rasterizer::ScreenshotType screenshot_type, 159 | bool base64_encode) { 160 | TRACE_EVENT0("flutter", "Shell::Screenshot"); 161 | + fml::TaskRunner* taskRunner = 162 | + (fml::TaskRunner*)this->GetTaskRunners().GetUITaskRunner().get(); 163 | + taskRunner->EnableMessageLoop(true); 164 | + 165 | + taskRunner = 166 | + (fml::TaskRunner*)this->GetTaskRunners().GetGPUTaskRunner().get(); 167 | + taskRunner->EnableMessageLoop(true); 168 | + 169 | fml::AutoResetWaitableEvent latch; 170 | Rasterizer::Screenshot screenshot; 171 | fml::TaskRunner::RunNowOrPostTask( 172 | diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 173 | index ea8beaaa0..43f74c8ee 100644 174 | --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 175 | +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 176 | @@ -9,8 +9,10 @@ 177 | 178 | #include 179 | 180 | +#include "flutter/common/task_runners.h" 181 | #include "flutter/fml/memory/weak_ptr.h" 182 | #include "flutter/fml/message_loop.h" 183 | +#include "flutter/fml/message_loop_impl.h" 184 | #include "flutter/fml/platform/darwin/platform_version.h" 185 | #include "flutter/fml/platform/darwin/scoped_nsobject.h" 186 | #include "flutter/shell/common/thread_host.h" 187 | @@ -119,6 +121,14 @@ - (void)performCommonViewControllerInitialization { 188 | 189 | _touchTrackerSet = [[NSMutableSet set] retain]; 190 | _touchTrackerDict = [[NSMutableDictionary dictionary] retain]; 191 | + 192 | + fml::MessageLoopImpl* gpuLoop = 193 | + ((fml::TaskRunner*)[self getTaskRunners].GetGPUTaskRunner().get())->getMessageLoop(); 194 | + gpuLoop->SetTaskLimitPerLoopRun(10); 195 | + fml::MessageLoopImpl* ioLoop = 196 | + ((fml::TaskRunner*)[self getTaskRunners].GetIOTaskRunner().get())->getMessageLoop(); 197 | + ioLoop->SetTaskLimitPerLoopRun(10); 198 | + 199 | [self setupNotificationCenterObservers]; 200 | } 201 | 202 | @@ -378,6 +388,7 @@ - (void)setFlutterViewDidRenderCallback:(void (^)(void))callback { 203 | 204 | - (void)surfaceUpdated:(BOOL)appeared { 205 | // NotifyCreated/NotifyDestroyed are synchronous and require hops between the UI and GPU thread. 206 | + [self setEnableForRunnersBatch:YES]; 207 | if (appeared) { 208 | [self installSplashScreenViewCallback]; 209 | [_engine.get() platformViewsController] -> SetFlutterView(_flutterView.get()); 210 | @@ -385,6 +396,7 @@ - (void)surfaceUpdated:(BOOL)appeared { 211 | } else { 212 | [_engine.get() platformView] -> NotifyDestroyed(); 213 | [_engine.get() platformViewsController] -> SetFlutterView(nullptr); 214 | + [self disableGPUOperation]; 215 | } 216 | } 217 | 218 | @@ -465,6 +477,56 @@ - (void)applicationWillEnterForeground:(NSNotification*)notification { 219 | [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.inactive"]; 220 | } 221 | 222 | +- (blink::TaskRunners)getTaskRunners { 223 | + return ([_engine.get() shell].GetTaskRunners()); 224 | +} 225 | + 226 | +- (void)disableGPUOperation { 227 | + [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.paused"]; 228 | + //暂时通过延时来等待GL操作结束(否则进入后台后的GL操作会闪退) 229 | + NSDate* date = [NSDate date]; 230 | + double delayMax = 8; //最多等8S 231 | + fml::MessageLoopImpl* gpuLoop = 232 | + ((fml::TaskRunner*)[self getTaskRunners].GetGPUTaskRunner().get())->getMessageLoop(); 233 | + fml::MessageLoopImpl* ioLoop = 234 | + ((fml::TaskRunner*)[self getTaskRunners].GetIOTaskRunner().get())->getMessageLoop(); 235 | + while (true) { 236 | + //两个TaskRunner没内容了,好,可以退出 237 | + if (!gpuLoop->IsRunningingExpiredTasks() && !ioLoop->IsRunningingExpiredTasks()) 238 | + break; 239 | + //超时退出 240 | + if ([[NSDate date] timeIntervalSinceDate:date] > delayMax) 241 | + break; 242 | + [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]]; 243 | + } 244 | + [self setEnableForRunnersBatch:FALSE]; 245 | +} 246 | + 247 | +- (void)enableMessageLoop:(bool)isEnable forTaskRunner:(NSString*)aTaskRunnerId { 248 | + if ([@"io.flutter.io" caseInsensitiveCompare:aTaskRunnerId] == NSOrderedSame) { 249 | + fml::TaskRunner* taskRunner = (fml::TaskRunner*)[self getTaskRunners].GetIOTaskRunner().get(); 250 | + taskRunner->EnableMessageLoop(isEnable); 251 | + } 252 | + if ([@"io.flutter.ui" caseInsensitiveCompare:aTaskRunnerId] == NSOrderedSame) { 253 | + fml::TaskRunner* taskRunner = (fml::TaskRunner*)[self getTaskRunners].GetUITaskRunner().get(); 254 | + taskRunner->EnableMessageLoop(isEnable); 255 | + } 256 | + if ([@"io.flutter.gpu" caseInsensitiveCompare:aTaskRunnerId] == NSOrderedSame) { 257 | + fml::TaskRunner* taskRunner = (fml::TaskRunner*)[self getTaskRunners].GetGPUTaskRunner().get(); 258 | + taskRunner->EnableMessageLoop(isEnable); 259 | + } 260 | + if ([@"io.flutter.platform" caseInsensitiveCompare:aTaskRunnerId] == NSOrderedSame) { 261 | + fml::TaskRunner* taskRunner = 262 | + (fml::TaskRunner*)[self getTaskRunners].GetPlatformTaskRunner().get(); 263 | + taskRunner->EnableMessageLoop(isEnable); 264 | + } 265 | +} 266 | + 267 | +- (void)setEnableForRunnersBatch:(BOOL)enable { 268 | + [self enableMessageLoop:enable forTaskRunner:@"io.flutter.gpu"]; 269 | + [self enableMessageLoop:enable forTaskRunner:@"io.flutter.io"]; 270 | +} 271 | + 272 | #pragma mark - Touch event handling 273 | 274 | static blink::PointerData::Change PointerDataChangeFromUITouchPhase(UITouchPhase phase) { 275 | -- 276 | 2.20.1 (Apple Git-117) 277 | 278 | -------------------------------------------------------------------------------- /patches/stable_v1.0/engine#src#flutter/0004-Add-notify-idle-api-for-engine-by-Fuju.patch: -------------------------------------------------------------------------------- 1 | From 0cef1bdee641788903d12db8081a5c228c456a19 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sun, 23 Dec 2018 00:04:44 +0800 4 | Subject: [PATCH] alfpatch:Add notify idle api for engine by Fuju 5 | 6 | --- 7 | .../framework/Headers/FlutterViewController.h | 10 ++++++++++ 8 | .../framework/Source/FlutterViewController.mm | 19 +++++++++++++++++++ 9 | 2 files changed, 29 insertions(+) 10 | 11 | diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h 12 | index 53f3adc85..b74efe0ff 100644 13 | --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h 14 | +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h 15 | @@ -151,6 +151,16 @@ FLUTTER_EXPORT 16 | */ 17 | @property(nonatomic, getter=isViewOpaque) BOOL viewOpaque; 18 | 19 | +typedef void (^DartApiCompletion)(NSError*, void*); 20 | +/* 21 | + * Trigger memory warning for dart. 22 | + * */ 23 | +- (void)notifyMemoryWarning:(DartApiCompletion)completion; 24 | + 25 | +/* 26 | + * Trigger idle*/ 27 | +- (void)notifyIdle:(DartApiCompletion)completion; 28 | + 29 | @end 30 | 31 | #endif // FLUTTER_FLUTTERVIEWCONTROLLER_H_ 32 | diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 33 | index 43f74c8ee..fb669f567 100644 34 | --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 35 | +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm 36 | @@ -23,6 +23,7 @@ 37 | #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h" 38 | #include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" 39 | #include "flutter/shell/platform/darwin/ios/platform_view_ios.h" 40 | +#include "third_party/dart/runtime/include/dart_tools_api.h" 41 | 42 | static double kTouchTrackerCheckInterval = 1.f; 43 | 44 | @@ -1115,4 +1116,22 @@ - (NSObject*)valuePublishedByPlugin:(NSString*)pluginKey { 45 | return [_engine.get() valuePublishedByPlugin:pluginKey]; 46 | } 47 | 48 | +#pragma mark - Garbage Collection Trigger 49 | + 50 | +#define FLAG_idle_duration_micros 500 51 | +- (void)notifyIdle:(DartApiCompletion)completion { 52 | + [self getTaskRunners].GetUITaskRunner()->PostTask( 53 | + fml::MakeCopyable([engine = [_engine.get() shell].GetEngine()] { 54 | + if (engine) { 55 | + const int64_t now = Dart_TimelineGetMicros(); 56 | + const int64_t deadline = now + FLAG_idle_duration_micros; 57 | + engine->NotifyIdle(deadline); 58 | + } 59 | + })); 60 | +} 61 | + 62 | +- (void)notifyMemoryWarning:(DartApiCompletion)completion { 63 | + // Do nothing right now. 64 | +} 65 | + 66 | @end 67 | -- 68 | 2.20.1 (Apple Git-117) 69 | 70 | -------------------------------------------------------------------------------- /patches/stable_v1.0/engine#src#flutter/0005-Workaround-for-android-eglCreateContext-fai.patch: -------------------------------------------------------------------------------- 1 | From 995991a014972021fb96383f199bf16566cdc920 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sun, 23 Dec 2018 16:54:39 +0800 4 | Subject: [PATCH] alfpatch:Workaround for android eglCreateContext fail 5 | 6 | --- 7 | shell/platform/android/android_context_gl.cc | 6 ++++++ 8 | 1 file changed, 6 insertions(+) 9 | 10 | diff --git a/shell/platform/android/android_context_gl.cc b/shell/platform/android/android_context_gl.cc 11 | index bb4e7b653..2878d1087 100644 12 | --- a/shell/platform/android/android_context_gl.cc 13 | +++ b/shell/platform/android/android_context_gl.cc 14 | @@ -65,6 +65,12 @@ static EGLResult CreateContext(EGLDisplay display, 15 | EGLint attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; 16 | 17 | EGLContext context = eglCreateContext(display, config, share, attributes); 18 | + if (context == EGL_NO_CONTEXT) { 19 | + EGLint last_error = eglGetError(); 20 | + if (last_error == EGL_BAD_MATCH && share != EGL_NO_CONTEXT) { 21 | + context = eglCreateContext(display, config, EGL_NO_CONTEXT, attributes); 22 | + } 23 | + } 24 | 25 | return {context != EGL_NO_CONTEXT, context}; 26 | } 27 | -- 28 | 2.20.1 (Apple Git-117) 29 | 30 | -------------------------------------------------------------------------------- /patches/stable_v1.0/engine#src#flutter/0006-Fix-accessibility-dealloc-resulted-crash.patch: -------------------------------------------------------------------------------- 1 | From 8c5a14d3ac667d26398d7dca8a6827e4e85a057f Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Wed, 24 Apr 2019 16:57:09 +0800 4 | Subject: [PATCH] top1 crash 5 | 6 | --- 7 | .../darwin/ios/framework/Source/accessibility_bridge.mm | 5 +++-- 8 | 1 file changed, 3 insertions(+), 2 deletions(-) 9 | 10 | diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm 11 | index d744e5fc0..e7ed90efd 100644 12 | --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm 13 | +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm 14 | @@ -110,7 +110,7 @@ - (instancetype)initWithBridge:(fml::WeakPtr)bridge 15 | if (self) { 16 | _bridge = bridge; 17 | _uid = uid; 18 | - self.children = [[[NSMutableArray alloc] init] autorelease]; 19 | + _children = [[NSMutableArray alloc] init]; 20 | } 21 | 22 | return self; 23 | @@ -121,7 +121,8 @@ - (void)dealloc { 24 | child.parent = nil; 25 | } 26 | [_children removeAllObjects]; 27 | - [_children dealloc]; 28 | + [_children release]; 29 | + _children = nil; 30 | _parent = nil; 31 | [_container release]; 32 | _container = nil; 33 | -- 34 | 2.20.1 (Apple Git-117) 35 | 36 | -------------------------------------------------------------------------------- /patches/stable_v1.0/engine#src#third_party#boringssl#src/0001-Add-intel-emulation-layer-logic-for-arm.patch: -------------------------------------------------------------------------------- 1 | From 8c8bc7b2f96b2db415bfba08764b8007b46ee119 Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sun, 23 Dec 2018 16:35:57 +0800 4 | Subject: [PATCH] alfpatch:Add intel emulation layer logic for arm 5 | 6 | --- 7 | crypto/cpu-arm-linux.c | 16 ++++++++++++++++ 8 | 1 file changed, 16 insertions(+) 9 | 10 | diff --git a/crypto/cpu-arm-linux.c b/crypto/cpu-arm-linux.c 11 | index 839b632b0..18a1d747d 100644 12 | --- a/crypto/cpu-arm-linux.c 13 | +++ b/crypto/cpu-arm-linux.c 14 | @@ -276,6 +276,12 @@ static unsigned long get_hwcap2_cpuinfo(const STRING_PIECE *cpuinfo) { 15 | return ret; 16 | } 17 | 18 | +// is_intel returns true if /proc/cpuinfo reports that it is for an intel CPU. 19 | +static int is_intel(const STRING_PIECE *cpuinfo) { 20 | + return cpuinfo_field_equals(cpuinfo, "Hardware", "placeholder"); 21 | +} 22 | + 23 | + 24 | // has_broken_neon returns one if |in| matches a CPU known to have a broken 25 | // NEON unit. See https://crbug.com/341598. 26 | static int has_broken_neon(const STRING_PIECE *cpuinfo) { 27 | @@ -300,6 +306,16 @@ void OPENSSL_cpuid_setup(void) { 28 | cpuinfo.data = cpuinfo_data; 29 | cpuinfo.len = cpuinfo_len; 30 | 31 | + // If we are in a broken emulation environment, and the CPU reports that it is 32 | + // not an ARM CPU, then we should not trust the values reported by 33 | + // getauxval(), etc., and so bail out here. 34 | + if (is_intel(&cpuinfo)) { 35 | + g_has_broken_neon = 1; 36 | + OPENSSL_free(cpuinfo_data); 37 | + return; 38 | + } 39 | + 40 | + 41 | // |getauxval| is not available on Android until API level 20. If it is 42 | // unavailable, read from /proc/self/auxv as a fallback. This is unreadable 43 | // on some versions of Android, so further fall back to /proc/cpuinfo. 44 | -- 45 | 2.20.1 (Apple Git-117) 46 | 47 | -------------------------------------------------------------------------------- /patches/stable_v1.0/engine#src#third_party#skia/0001-Workaround-for-Flutter-related-black-screen.patch: -------------------------------------------------------------------------------- 1 | From 52759e65691a585e32f62f4e4f624a5d224fcdad Mon Sep 17 00:00:00 2001 2 | From: KyleWong 3 | Date: Sun, 23 Dec 2018 16:35:56 +0800 4 | Subject: [PATCH] alfpatch:Workaround for Flutter related black screen in some 5 | 6 | --- 7 | src/gpu/gl/GrGLInterface.cpp | 4 ++-- 8 | 1 file changed, 2 insertions(+), 2 deletions(-) 9 | 10 | diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp 11 | index f63f483d40..d1643e5b77 100644 12 | --- a/src/gpu/gl/GrGLInterface.cpp 13 | +++ b/src/gpu/gl/GrGLInterface.cpp 14 | @@ -370,7 +370,7 @@ bool GrGLInterface::validate() const { 15 | fExtensions.has("GL_EXT_texture_buffer")) { 16 | if (!fFunctions.fTexBuffer || 17 | !fFunctions.fTexBufferRange) { 18 | - RETURN_FALSE_INTERFACE; 19 | +// RETURN_FALSE_INTERFACE; 20 | } 21 | } 22 | } 23 | @@ -397,7 +397,7 @@ bool GrGLInterface::validate() const { 24 | if (!fFunctions.fInsertEventMarker || 25 | !fFunctions.fPushGroupMarker || 26 | !fFunctions.fPopGroupMarker) { 27 | - RETURN_FALSE_INTERFACE 28 | +// RETURN_FALSE_INTERFACE 29 | } 30 | } 31 | 32 | -- 33 | 2.20.1 (Apple Git-117) 34 | 35 | -------------------------------------------------------------------------------- /script/android_engine_symbolicate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #-*-coding:utf-8-*- 3 | import argparse,os,sys,errno,json,time,tempfile,shutil 4 | 5 | # Colors for print 6 | CEND = '\33[0m' 7 | CRED = '\33[31m' 8 | CREDBG = '\33[41m' 9 | CWHITE = '\33[37m' 10 | CGREEN = '\33[32m' 11 | CBOLD = '\33[1m' 12 | 13 | def check_command_output(command): 14 | import subprocess 15 | p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 16 | (result, err) = p.communicate() 17 | # Wait for date to terminate. Get return returncode 18 | p_status = p.wait() 19 | return result,err,p.returncode 20 | 21 | def exit_on_msg(msg): 22 | print(CBOLD+CRED+"Error occurs with message:\n"+msg.rstrip()+"\n"+CEND) 23 | sys.exit(errno.EACCES) 24 | 25 | def symbolicate_address_with_entry(addr2line_path,sopath,entry_point_address,symbol_address): 26 | entry_point_address_dec=int(entry_point_address,16) 27 | symbol_address_dec=int(symbol_address,16) 28 | real_address_dec=entry_point_address_dec+symbol_address_dec 29 | result,err,returncode=check_command_output(addr2line_path+" -e "+sopath+" "+hex(real_address_dec)) 30 | if returncode != 0: 31 | exit_on_msg("Invalid libflutter.so "+sopath) 32 | return result 33 | 34 | def read_entry_address(readelf_path,sopath): 35 | result,err,returncode=check_command_output(readelf_path+" -h "+sopath) 36 | if returncode != 0: 37 | exit_on_msg("Invalid libflutter.so "+sopath) 38 | expected_prefix="Entry point address:" 39 | for line in result.split("\n"): 40 | line=line.strip() 41 | if line.startswith(expected_prefix): 42 | return line[len(expected_prefix):].strip() 43 | exit_on_msg(expected_prefix+" not found.") 44 | 45 | def main(): 46 | parser = argparse.ArgumentParser(add_help=False) 47 | file_name=os.path.basename(__file__) 48 | parser.add_argument('-h','--help',action='help',default=argparse.SUPPRESS,help=file_name+' -c crashreport-file-path -a addr2line-command-full-path -s libflutter.so-with-symbols-full-path') 49 | parser.add_argument("-c", "--crash", help="crashreport file") 50 | parser.add_argument("-a","--addr2line", help="addr2line command full-path") 51 | parser.add_argument("-s","--so_with_symbols_path", help="libflutter.so with symbols full path") 52 | parser.add_argument("-v", "--verbose", help="print verbose logging",dest='verbose') 53 | parser.set_defaults(verbose=False) 54 | args = parser.parse_args() 55 | crash_path = args.crash 56 | addr2line_path=args.addr2line 57 | symbols_so_path=args.so_with_symbols_path 58 | prior_cwd=os.getcwd() 59 | 60 | script_dir=os.path.dirname(os.path.abspath(__file__)) 61 | 62 | if crash_path is None or os.path.exists(crash_path) is False or addr2line_path is None or os.path.exists(addr2line_path) is False or symbols_so_path is None or os.path.exists(symbols_so_path) is False : 63 | exit_on_msg("Use -h to see how to use this script") 64 | 65 | if os.path.basename(os.path.normpath(addr2line_path)).endswith("addr2line") is False or os.path.basename(os.path.normpath(symbols_so_path))=="libflutter.so" is False : 66 | exit_on_msg("Use -h to see how to use this script") 67 | 68 | addr2line_folder=os.path.dirname(addr2line_path) 69 | addr2line_basename=os.path.basename(os.path.normpath(addr2line_path)) 70 | readelf_command_fullpath=os.path.join(addr2line_folder,addr2line_basename.replace("-addr2line","-readelf")) 71 | 72 | if os.path.exists(readelf_command_fullpath) is False: 73 | exit_on_msg(readelf_command_fullpath+" not exists.") 74 | 75 | entry_point_address=read_entry_address(readelf_command_fullpath,symbols_so_path) 76 | 77 | with open(crash_path, 'r') as crashfile: 78 | lines=crashfile.read().split("\n") 79 | for line in lines: 80 | compos=line.strip().split(" ") 81 | if len(compos)!=4 or compos[3]!="libflutter.so": 82 | continue 83 | symbolicated_info=symbolicate_address_with_entry(addr2line_path,symbols_so_path,entry_point_address,compos[2]) 84 | print(line.strip()+"--->"+symbolicated_info.strip()) 85 | 86 | os.chdir(prior_cwd) 87 | 88 | if __name__ == '__main__': 89 | main() 90 | 91 | -------------------------------------------------------------------------------- /script/get_dartsdk_for_flutter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #-*-coding:utf-8-*- 3 | import argparse,os,sys,errno,json,time,tempfile,shutil 4 | 5 | # Colors for print 6 | CEND = '\33[0m' 7 | CRED = '\33[31m' 8 | CREDBG = '\33[41m' 9 | CWHITE = '\33[37m' 10 | CGREEN = '\33[32m' 11 | CBOLD = '\33[1m' 12 | 13 | #base64 encoding for "This is the dart environment." 14 | unique_folder_name="VGhpcyBpcyB0aGUgZGFydCBlbnZpcm9ubWVudC4=" 15 | 16 | def check_command_output(command): 17 | import subprocess 18 | print("Command:"+command) 19 | p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 20 | (result, err) = p.communicate() 21 | # Wait for date to terminate. Get return returncode 22 | p_status = p.wait() 23 | print("Result:"+result.strip()+";error:"+err.strip()+";returnCode:"+str(p.returncode)) 24 | return result,err,p.returncode 25 | 26 | def read_dart_gitsha(depth_file): 27 | import re 28 | with open(depth_file, 'r') as myfile: 29 | deps_content=myfile.read().replace('\n', '') 30 | m = re.search('\'dart_revision\': \'[0-9a-z]+\'',deps_content) 31 | gitsha=(m.group(0).split(':')[1]).strip() 32 | return gitsha[1:len(gitsha)-2] 33 | 34 | def exit_on_msg(msg): 35 | print(CBOLD+CRED+"Error occurs with message:\n"+msg.rstrip()+"\n"+CEND) 36 | sys.exit(errno.EACCES) 37 | 38 | def sparse_checkout_engine_deps(engine_version): 39 | cwd=os.getcwd() 40 | result,err,returncode = check_command_output("which gclient") 41 | if returncode != 0: 42 | exit_on_msg("Please make sure that gclient is installed and configured in your PATH environment.") 43 | if os.path.exists("engine") is False: 44 | check_command_output("mkdir engine && cd engine && git init && git remote add origin -f git@github.com:flutter/engine.git && git config core.sparsecheckout true && echo \"DEPS\" >> .git/info/sparse-checkout && git pull --depth=1 origin master && git reset --hard "+engine_version) 45 | os.chdir(cwd) 46 | return read_dart_gitsha(os.path.join(cwd,"engine","DEPS")) 47 | 48 | def checkout_dartsdk_with_sha(dart_gitsha): 49 | cwd=os.getcwd() 50 | if os.path.exists(".gclient") is False: 51 | check_command_output("gclient config --name=sdk https://dart.googlesource.com/sdk.git@"+dart_gitsha) 52 | check_command_output("gclient sync") 53 | os.chdir(cwd) 54 | return os.path.join(cwd,"sdk") 55 | 56 | def generate_dart_snapshot(dart_bin_dir,sdk_path,package_root_rel_path,entry_dart_file,snapshot_name,training_flags): 57 | cwd=os.getcwd() 58 | snapshot_to_save=os.path.join(os.getcwd(),snapshot_name) 59 | os.chdir(os.path.join(sdk_path,package_root_rel_path)) 60 | dart_binary_path=os.path.join(dart_bin_dir,"dart") 61 | if os.path.exists(snapshot_to_save): 62 | os.remove(snapshot_to_save) 63 | if training_flags is None: 64 | training_flags=""; 65 | check_command_output(dart_binary_path+" --snapshot="+snapshot_to_save+" --snapshot-kind=app-jit --packages="+os.path.join(sdk_path,".packages")+" "+entry_dart_file+" "+training_flags) 66 | os.chdir(cwd) 67 | 68 | def generate_snapshots(dart_sdk_path, flutter_path): 69 | cwd=os.getcwd() 70 | flutter_dart_bin_path=os.path.join(flutter_path,"bin","cache","dart-sdk","bin") 71 | training_flags=" --sdk="+os.path.join(cwd,"sdk","sdk")+" --train-using="+os.path.join(cwd,"sdk","pkg","analyzer_cli") 72 | generate_dart_snapshot(flutter_dart_bin_path,dart_sdk_path,os.path.join("pkg","analysis_server"),os.path.join("bin","server.dart"),"analysis_server.dart.snapshot",training_flags) 73 | training_flags=" --dart-sdk="+os.path.join(cwd,"sdk","sdk")+" "+os.path.join(cwd,"sdk","tests","language_2","first_test.dart") 74 | generate_dart_snapshot(flutter_dart_bin_path,dart_sdk_path,os.path.join("pkg","analyzer_cli"),os.path.join("bin","analyzer.dart"),"dartanalyzer.dart.snapshot",training_flags) 75 | training_flags=" --help" 76 | generate_dart_snapshot(flutter_dart_bin_path,dart_sdk_path,os.path.join("third_party","pkg","dartdoc"),os.path.join("bin","dartdoc.dart"),"dartdoc.dart.snapshot",training_flags) 77 | training_flags=os.path.join(dart_sdk_path,"third_party","pkg_tested","dart_style") 78 | generate_dart_snapshot(flutter_dart_bin_path,dart_sdk_path,os.path.join("third_party","pkg_tested","dart_style"),os.path.join("bin","format.dart"),"dartfmt.dart.snapshot",training_flags) 79 | #Ignore this as not modified generally. 80 | #generate_dart_snapshot(flutter_dart_bin_path,dart_sdk_path,os.path.join("third_party","pkg","pub"),os.path.join("bin","pub.dart"),"kernel-service.dart.snapshot",training_flags) 81 | training_flags="" 82 | generate_dart_snapshot(flutter_dart_bin_path,dart_sdk_path,os.path.join("third_party","pkg","pub"),os.path.join("bin","pub.dart"),"pub.dart.snapshot",training_flags) 83 | 84 | def main(): 85 | parser = argparse.ArgumentParser(add_help=False) 86 | file_name=os.path.basename(__file__) 87 | parser.add_argument('-h','--help',action='help',default=argparse.SUPPRESS,help=file_name+' -fp flutter-root-path') 88 | parser.add_argument("-fp", "--flutter_path", help="flutter root path") 89 | parser.add_argument("-v", "--verbose", help="print verbose logging",dest='verbose') 90 | parser.set_defaults(verbose=False) 91 | args = parser.parse_args() 92 | flutter_path = args.flutter_path 93 | prior_cwd=os.getcwd() 94 | script_dir=os.path.dirname(os.path.abspath(__file__)) 95 | engine_version_rel_path = os.path.join("bin","internal","engine.version") 96 | 97 | if flutter_path is None or os.path.exists(flutter_path) is False or os.path.exists(os.path.join(flutter_path,engine_version_rel_path)) is False: 98 | exit_on_msg("Use -h to see how to use this script") 99 | with open(os.path.join(flutter_path,engine_version_rel_path), 'r') as myfile: 100 | engine_version=myfile.read().replace('\n', '') 101 | 102 | if os.path.exists(os.path.join(prior_cwd,unique_folder_name)) is False: 103 | os.mkdir(unique_folder_name) 104 | os.chdir(unique_folder_name) 105 | 106 | dart_sha=sparse_checkout_engine_deps(engine_version) 107 | dart_sdk_path = checkout_dartsdk_with_sha(dart_sha) 108 | generate_snapshots(dart_sdk_path, flutter_path) 109 | os.chdir(prior_cwd) 110 | 111 | if __name__ == '__main__': 112 | main() --------------------------------------------------------------------------------