美文网首页
2023-03-22 flutter widget更新3

2023-03-22 flutter widget更新3

作者: 我是小胡胡123 | 来源:发表于2023-03-22 10:35 被阅读0次

1、flutter 渲染机制

通过自己之前的短点调试 setState的代码执行过程 。结合别人的文章:

原来我一直在错误的使用 setState()?

image.png

开始FrameWork层会通知Engine表示自己可以进行渲染了,在下一个Vsync信号到来之时,Engine层会通过Windows.onDrawFrame回调Framework进行整个页面的构建与绘制。(这里我想为什么要先由Framework发起通知,而不是直接由Vsync驱动。如果一个页面非常卡顿,恰好每一帧绘制的时间大于一个Vsync周期,这样每帧都不能在一个Vsync的时间段内完成绘制。而先由framework保证上完成构建与绘制后,发起通知在下一个Vsync信号再绘制则可以避免这样的情况)。每次收到渲染页面的通知后,Engine调用Windows.onDrawFrame最终交给_handleDrawFrame()方法进行处理。

《Flutter实战·第二版》14.3.2 渲染管线

Flutter中 的 frame 概念并不等同于屏幕刷新帧(frame),因为Flutter UI 框架的 frame 并不是每次屏幕刷新都会触发,这是因为,如果 UI 在一段时间不变,那么每次屏幕刷新都重新走一遍渲染流程是不必要的,因此,Flutter 在第一帧渲染结束后会采取一种主动请求 frame 的方式来实现只有当UI可能会改变时才会重新走渲染流程。

  • Flutter 在 window 上注册一个 onBeginFrame和一个 onDrawFrame 回调,在onDrawFrame 回调中最终会调用 drawFrame。
  • 当我们调用 window.scheduleFrame() 方法之后,Flutter引擎会在合适的时机(可以认为是在屏幕下一次刷新之前,具体取决于Flutter引擎的实现)来调用onBeginFrame和onDrawFrame。

可以看见,只有主动调用scheduleFrame(),才会执行 drawFrame。所以,我们在Flutter 中的提到 frame 时,如无特别说明,则是和 drawFrame() 的调用对应,而不是和屏幕的刷新频率对应。

2、iOS native渲染机制

转1 -屏幕图像显示原理

image.png

首先从过去的 CRT 显示器原理说起。CRT 的电子枪按照上面方式,从上到下一行行扫描,扫描完成后显示器就呈现一帧画面,随后电子枪回到初始位置继续下一次扫描。为了把显示器的显示过程和系统的视频控制器进行同步,显示器(或者其他硬件)会用硬件时钟产生一系列的定时信号。当电子枪换到新的一行,准备进行扫描时,显示器会发出一个水平同步信号(horizonal synchronization),简称 HSync;而当一帧画面绘制完成后,电子枪回复到原位,准备画下一帧前,显示器会发出一个垂直同步信号(vertical synchronization),简称 VSync。显示器通常以固定频率进行刷新,这个刷新率就是 VSync 信号产生的频率。尽管现在的设备大都是液晶显示屏了,但原理仍然没有变。

image.png

通常来说,计算机系统中 CPU、GPU、显示器是以上面这种方式协同工作的。CPU 计算好显示内容提交到 GPU,GPU 渲染完成后将渲染结果放入帧缓冲区,随后视频控制器会按照 VSync 信号逐行读取帧缓冲区的数据,经过可能的数模转换传递给显示器显示。

在最简单的情况下,帧缓冲区只有一个,这时帧缓冲区的读取和刷新都都会有比较大的效率问题。为了解决效率问题,显示系统通常会引入两个缓冲区,即双缓冲机制。在这种情况下,GPU 会预先渲染好一帧放入一个缓冲区内,让视频控制器读取,当下一帧渲染好后,GPU 会直接把视频控制器的指针指向第二个缓冲器。如此一来效率会有很大的提升。

双缓冲虽然能解决效率问题,但会引入一个新的问题。当视频控制器还未读取完成时,即屏幕内容刚显示一半时,GPU 将新的一帧内容提交到帧缓冲区并把两个缓冲区进行交换后,视频控制器就会把新的一帧数据的下半段显示到屏幕上,造成画面撕裂现象,如下图:


image.png

为了解决这个问题,GPU 通常有一个机制叫做垂直同步(简写也是 V-Sync),当开启垂直同步后,GPU 会等待显示器的 VSync 信号发出后,才进行新的一帧渲染和缓冲区更新。这样能解决画面撕裂现象,也增加了画面流畅度,但需要消费更多的计算资源,也会带来部分延迟。

那么目前主流的移动设备是什么情况呢?从网上查到的资料可以知道,iOS 设备会始终使用双缓存,并开启垂直同步。而安卓设备直到 4.1 版本,Google 才开始引入这种机制,目前安卓系统是三缓存+垂直同步。

转2图像显示原理

image.png

CPU和GPU通过总线连接,CPU中计算出的往往是bitmap位图,通过总线由合适的时机传递给GPU,GPU拿到位图后,渲染到帧缓存区FrameBuffer,然后由视频控制器根据Vsync信号在指定时间之前去帧缓冲区提取内容,显示到屏幕上。

CPU工作内容:

  • layout(UI布局,文本计算)
  • display(绘制 drawRect)
  • prepare(图片解码)
  • commit(提交位图)

GPU工作内容:
顶点着色,图元装配,光栅化,片段着色,片段处理,最后提交帧缓冲区

View绘制渲染机制和Runloop什么关系

当在操作 UI 时,比如改变了Frame 、更新了 UIView/CALayer 的层次时,或者手动调用了 UIView/CALayer 的 setNeedsLayout/setNeedsDisplay 方法后,这个 UIView/CALayer 就被标记为待处理,并被提交到一个全局的容器去。 苹果注册了一个 Observer 监听 BeforeWaiting(即将进入休眠) 和 Exit (即将退出Loop) 事件,回调去执行一个很长的函数。这个函数里会遍历所有待处理的 UIView/CAlayer 以执行实际的绘制和调整,并更新 UI 界面。

2020-03-04-A4.png

相关文章

  • Flutter控件之间联动方式整理

    这里说的Flutter中Widget之间的联动方式是指一个Widget更新后,另一个Widget得到响应并更新,我...

  • flutter学习资源

    一、我的github的flutter中的demo项目,持续更新中。。。 flutter_widget组件生命周期的...

  • Flutter Widget

    Flutter Widget 1、显示小部件2、更新小部件的状态信息3、摆放小部件4、添加、删除小部件5、小部件设...

  • Flutter widget更新原理

    一、背景 我们在写StatefulWidget的时候有时候会遇到数据改变了,也刷新(setState)了,但是数据...

  • Flutter 视图树🌲

    Flutter 视图树包含了 3 种树: Widget:存放渲染内容、视图布局信息,widget 的属性最好都是 ...

  • StatefulWidget 和 StatelessWidget

    如何更新 Widget 在 Android 中可以直接通过 View 来更新它们的状态。但是在 Flutter 中...

  • flutter笔记汇总

    Widget 基础Widget flutter笔记(一)-----官方示例&代码解读 flutter笔记(二)-...

  • Flutter之Widget

    Widget说明 在Flutter中几乎所有的对象都是一个 widget。Flutter 中是通过 Widget ...

  • Flutter生命周期及监听状态

    Flutter Widget生命周期分为3个阶段: 1.创建: 构造方法:Flutter通过StatefulWid...

  • Flutter学习总结之三 Widget详解

    一.Flutter Widget 在 Flutter 中一切的显示都是 Widget ,Widget 是一切的基础...

网友评论

      本文标题:2023-03-22 flutter widget更新3

      本文链接:https://www.haomeiwen.com/subject/raumrdtx.html