当前位置: 首页 > news >正文

赣州建设局 网站今天进京最新通知

赣州建设局 网站,今天进京最新通知,北京模板网站建设全包,网站建设的流程分析跨平台开发里的 PlatformView 实现一直是一个经久不衰的话题,在之前的 《深入 Flutter 和 Compose 的 PlatformView 实现对比》 我们就详细聊过 Flutter 和 Compose 在 PlatformView 实现上的异同之处,也聊到了 Compose 为什么在相同实现上对比 Flutter …

跨平台开发里的 PlatformView 实现一直是一个经久不衰的话题,在之前的 《深入 Flutter 和 Compose 的 PlatformView 实现对比》 我们就详细聊过 Flutter 和 Compose 在 PlatformView 实现上的异同之处,也聊到了 Compose 为什么在相同实现上对比 Flutter 会更有优势的原因。

那么随着 3.29 的发布,恰好关注到其实 Flutter 在 Android 的 PlatformView 上其实正在落地另外一种实现,而这种实现目前看来可以做到在 HC 的基础上得到更好的性能,所以也被暂时称为 HCPP。

在聊 HCPP 之前我们再简单回顾下 Flutter 在 Android 上的 PlatformView 实现模式:

  • VD:最老的实现模式,利用副屏 VirtualDisplay 的相关支持在内存实现原生控件的模拟绘制和纹理提取
  • HC:通过直接将原生控件 add 到 FlutterView 上,然后通过新的 FlutterImageView 提供新的 Surface 来实现控件 UI 堆叠合成
  • TLHC:还是直接将原生控件 add 到 FlutterView 上,但是中间利用通过 parent 替代掉 child 的 canvas,让原生控件绘制的对应的 surface.lockHardwareCanvas

有点抽象?,没关系,后面有简单的直观例子。

在这个过程中几种模式各有优劣,比如:

  • TLHC 模式不支持 SurfaceView 等控件,因为 SurfaceView 有自己独立的 Surface 和 Canva ,它的 Surface 直接来自 SurfaceFlinger ,也就是当前 Window 下
  • TLHC 模式与异步更新 View 一起使用时(如 TextureView 或基于 GL 的渲染器),需要在更新内容时在对应 PlatformView 显式调用 invalidate 才能保证正确渲染,例如 textureViewonSurfaceTextureUpdated 调用 mapView.invalidate
  • HC 模式因为不同 API 版本和线程问题,会有同步和额外的性能开销
  • ····

所以目前这三种模式是协同工作,例如:

  • initAndroidView : 默认会使用最新的模式,目前就是 TLHC,如果遇到不支持的就降级到 VD

  • initSurfaceAndroidView: 默认会使用最新的模,目前就是 TLHC,如果遇到不支持的就降级到 HC

  • initExpensiveAndroidView:直接强制使用 HC 模式

那么,回到本次的主题 ,针对全新的 HCPP 实现,Flutter 提供了全新的 API initHybridAndroidView ,可以看到,它需要 Vulkan 和 API 34 的环境才支持使用,如果从这点看,它的通用性又相对较低

那为什么它需要 API 34 呢?这和它直接使用 SurfaceControl 的 API 逻辑有很大关系,另外,从 Engine 的判断逻辑上可以看到,目前除了判断 Vulkan 和 API 之后,还需要配置对应的 EnableSurfaceControl 才可以测试 HCPP,也就是在 AndroidManifest 增加:

<meta-dataandroid:name="io.flutter.embedding.android.EnableSurfaceControl"android:value="true" />

接着就让我们来看看 HCPP 和其他几种模式有什么区别,其实主要就是和 HC 和 TLHC 进行比较,这里首先做一个容器 Demo ,主要是通过混合 Flutter 和原生控件的效果来区分它们的实现,让 platformView 渲染在两个 Flutter Widget 之间:

return MaterialApp(debugShowCheckedModeBanner: false,home: Stack(alignment: AlignmentDirectional.center,children: <Widget>[///200x200的绿色 Flutter 方块TextButton(key: const ValueKey<String>('AddOverlay'),onPressed: _togglePlatformView,child: const SizedBox(width: 190, height: 190, child: ColoredBox(color: Colors.green)),),///200x200的原生控件,这里用的是一个红色的原生方块if (showPlatformView) ...<Widget>[SizedBox(width: 200, height: 200, child: widget.platformView),///黄色 Flutter 条TextButton(key: const ValueKey<String>('RemoveOverlay'),onPressed: _togglePlatformView,child: const SizedBox(width: 800,height: 25,child: ColoredBox(color: Colors.yellow),),),],],),
);

之后我们可以通过 initExpensiveAndroidView 强制 PlatformView 使用 HC 模式,可以看到,在 HC 模式下出现很多经典的原生层,特别是多了 FlutterImageView 的转换还有它的子类 PlatformOverlayView

我们通过 3D 图可以看到,红色的原生 BoxPlatformView 正常被渲染,然后在其之上的 Flutter 控件(一部分黄色条),是通过 FlutterImageView 的子类 PlatformOverlayView 提供的 Surface 独立渲染:

然后我们再通过 initAndroidView 来使用 TLHC 模式,可以看到此时是通过 PlatformViewWrapper 这个 parent 作为容器来承载,而 PlatformViewWrapper 会替换掉原生 BoxPlatformView 的 Canvas,让原生控件的内容渲染到指定 Surface 上 :

我们通过原生 3D 图可以看到,此时的 BoxPlatformView 其实在原生层并没有绘制任何东西,因为其 Canvas 是被替换到内存的 SurfaceTexture 上:

说到 SurfaceTexture ,这个插个题外话,对于 THLC 和 VD 而言,现在创建纹理时是会根据 Android API 来使用不同实现,其中 SurfaceProducer 比较特殊:

因为在此之前,Android 上的 Flutter 引擎支持两个外部渲染源:SurfaceTexture (OpenGLES 纹理)和 ImageReader(GPU-ready buffer),其中 Image.getHardwareBuffer 需要 API 28 支持。

而为了适配 Impeller 团队提出了 SurfaceProducer 概念,让 Android 在运行时选择“最佳”渲染 Surface,除了 PlatformView 场景,在外界纹理场景也需要适配的情况:

- TextureRegistry.SurfaceTextureEntry entry = textureRegistry.createSurfaceTexture();
+ TextureRegistry.SurfaceProducer producer = textureRegistry.createSurfaceProducer();- Surface surface = new Surface(entry.surfaceTexture());
+ Surface surface = producer.getSurface();

那么我们看 HCPP,通过 initHybridAndroidView 我们启用了 HCPP 模式,可以看到,此时 UI 的层级结构类似 TLHC, 但是 parent 使用的是 HC 模式中的 FlutterMutatorView

然后我们看 3D 效果,原生控件 BoxPlatformView 其实可以被完整被渲染,证明其 Canvas 并没有被替代,那么这里就有一个神奇的问题了:Flutter 的黄色控件,是如何渲染到红色的 BoxPlatformView 之上的

这就不得不提 PlatformViewsController2 ,作为一个 HCPP 的临时对象,它的实现里有一个关键的对象 SurfaceControl ,并且在事务提交时通过 setLayer 设置了 z 轴为 1000

我们可以看提交更改里,基本上全新的 PlatformViewsController2 核心逻辑都在于操作 SurfaceControl

在 Android 里,SurfaceControl 是一种用于管理和操作与显示系统相关的图形资源的类,简单说就是与 Surface 相关的操作,SurfaceControl 可以用于创建和管理 Surface ,它是和SurfaceFlinger 交互的一个主要接口,交互的方式则是通过 Transaction

而在 HCPP 里,我们可以看到,此时的 Surface 正是通过一个全新的 SurfaceControl 创建得到,而这个 SurfaceControlTransaction 来自 FlutterView

也就是,在 HCPP 模式里,Flutter 通过 SurfaceControl.Transaction 构造了一个全新的 Surface 用于 SurfaceFlinger 合成,并且还通过 setLayer 将 Surface 的 z 轴设置到了 1000 ,而这个 1000 就是黄色 Flutter 控件可以渲染到原生红色方块之上的原因

举个例子,我们将 SurfaceControl 这部分代码复制到一个简单的纯原生项目里,并且同样对创建的 Surface 设置 1000 和绘制红色:

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);········// 获取 FrameLayoutFrameLayout rootView = findViewById(R.id.container);rootView.postDelayed(new Runnable() {@Overridepublic void run() {final SurfaceControl.Builder surfaceControlBuilder = new SurfaceControl.Builder();surfaceControlBuilder.setBufferSize(500, 500);surfaceControlBuilder.setFormat(PixelFormat.RGBA_8888);surfaceControlBuilder.setName("Flutter Overlay Surface");surfaceControlBuilder.setOpaque(false);surfaceControlBuilder.setHidden(false);final SurfaceControl surfaceControl = surfaceControlBuilder.build();final SurfaceControl.Transaction tx =binding.container.getRootSurfaceControl().buildReparentTransaction(surfaceControl);tx.setLayer(surfaceControl, 1000);tx.apply();surface1 = new Surface(surfaceControl);surfaceControl1 = surfaceControl;// 在 SurfaceView 上绘制一些内容drawOnSurface(surface1, Color.RED);   }}, 2000);}private void drawOnSurface(Surface surface, int color) {Canvas canvas = surface.lockCanvas(null);if (canvas != null) {canvas.drawColor(color);surface.unlockCanvasAndPost(canvas);}
}

然后我们看最终绘制的效果,可以看到绿色背景的 FrameLayout 是在 WebView 下方的,但是通过 container.getRootSurfaceControl() 创建的 Surface 因为 z 轴为 1000 的原因,最终红色方块会绘制到 WebView 之上:

另外,在目前逻辑中,Engine 如果判断当前帧如果不存在 PlatformView ,并且上一帧存在 PlatformView,那么就会调用 hideOverlaySurface2 从而直接触发 Java 层面的 platformViewsController2.hideOverlaySurface() ,进而隐藏不需要的 Layer :

  if (!FrameHasPlatformLayers()) {frame->Submit();// If the previous frame had platform views, hide the overlay surface.if (previous_frame_view_count_ > 0) {jni_facade_->hideOverlaySurface2();}jni_facade_->applyTransaction();return;}

所以可以看到,HCPP 主要就是通过 SurfaceControl 来构造一个高层级的 Surface 从而实现最终绘制时混合覆盖的问题,这和我们之前聊 《深入 Flutter 和 Compose 的 PlatformView 实现对比》 里 Compose 可以在 PlatformView 里直接使用 SurfaceView 的道理类似,都是 SurfaceFlinger 合成时的层级操作。

至于为什么需要 API 34, 主要也是 SurfaceControl 对应的一些 API 需要的版本都很高,另外我依稀记得, Android 14 在通过 SurfaceControl 实现低延迟绘图时,可以更好支持 Canvas API 通过硬件加速绘制到 HardwareBuffer :

如果对于 Engine 部份逻辑感兴趣的,也可以看 external_view_embedder_2#SubmitFlutterView 这部分逻辑里如何通过 GetLayer 去创建 FlutterOverlaySurface

目前 HCPP 还处于 main 分之的 beta 状态,如果后续正式落地,那对于 Android PlatformView 实现将会是存在 4 种组合模式,相比较 iOS 端多个 CALayer 的合成模式,Android 的 PlatformView 可以说是一路坎坷至今。

最后,你觉得 HCPP 会成为落地为全新的 PlatformView 支持吗?

PS :io.flutter.embedding.android.EnableSurfaceControl 标识还用于控制 Impeller 内部使用 Vulkan swapchain 或者 Android SurfaceControl (AHB swapchain),在 Android SurfaceControl 模式下,Java 端创建的 Transaction 会链接到 AHB swapchain。

当然, AHBSwapchainVK 交换链实现并非在所有 Android 版本上都可用,一般不支持的话,会回退到 KHR swapchain。

参考链接

  • https://github.com/flutter/flutter/issues/163073

  • https://github.com/flutter/flutter/pull/161829

  • https://github.com/flutter/flutter/issues/144184

http://www.dtcms.com/a/441401.html

相关文章:

  • 国外网站流量查询北京市住房和城乡建设网官网
  • 外贸网站产品分析wordpress域名变更
  • 切图做网站如何做怎样注册电商平台成为卖家
  • 大学生html网页设计作业江苏网站优化建站
  • 商业网站建设咨询女人脱内衣裤给男人做网站
  • 网站开发项目启动成本WordPress微信如何赚钱
  • 二级域名网站怎么建设如何网站建设
  • 手机测评做视频网站淘宝客网站建设
  • 做电脑网站用什么软件好用专业的建设网站
  • 建站公司 phpwind中文域名网站建设
  • 注册了域名怎样做网站有啥好玩的网页游戏
  • 廊坊网站建设系统个人做网站郊游的英
  • 吉林大学建设工程学院网站如何在网站上做标注
  • 做网站的项目实施方案广州网站建设系统
  • 网站手机版绑定域名制作自助网站
  • 免费开发个人网站建设系统网站全名
  • 陕西 网站备案网站新闻不收录
  • 公司建设网站怎么作账美观网站建设哪家好
  • 汕头网站制作方法长沙设计网站多少钱
  • 做游戏必备的几个网站性价比高柳州网站建设
  • 企业做网站有什么作用什么类型网站
  • 怎么样制作网站网站开发的主要技术难点和重点
  • 建立了公司门户网站如何编写网站后台程序
  • 芜湖网站建设怎么做wordpress 博客实例
  • 网站建设基本流程图片抚州seo
  • 网站备案查询不了邵阳市 网站建设
  • dw 做网站模板建设银行住房公积网站
  • 网站如何做快捷支付接口搜房网房天下官网
  • 网站集群建设解决方案自己做的网站如何调入dede
  • 推荐成都网站建设服装网站建设费用预算