flutter中的drawFrame

举报
坚果的博客 发表于 2021/08/10 13:48:59 2021/08/10
【摘要】 本文主要介绍RendererBinding.drawFrame() 负责生成帧。这个方法对于理解 Flutter 渲染过程非常重要。简单了解下。RendererBinding.drawFrame() 由 SchedulerBinding.handleDrawFrame() 方法调用,而后者又自动被引擎调用(如果引擎需要布局和绘制一帧的话)。RendererBinding.drawFrame(...

本文主要介绍RendererBinding.drawFrame() 负责生成帧。这个方法对于理解 Flutter 渲染过程非常重要。简单了解下。

RendererBinding.drawFrame()SchedulerBinding.handleDrawFrame() 方法调用,而后者又自动被引擎调用(如果引擎需要布局和绘制一帧的话)。

RendererBinding.drawFrame() 的源码如下:

void drawFrame() {
    assert(renderView != null);
    // 布局
    pipelineOwner.flushLayout();
    // 检查是否需要重绘
    pipelineOwner.flushCompositingBits();
    // 重绘
    pipelineOwner.flushPaint();
    renderView.compositeFrame(); // this sends the bits to the GPU
    pipelineOwner.flushSemantics(); // this also sends the semantics to the OS.
}

flushPaint() 调用 PaintingContext.repaintCompositedChild(node) 方法,后者是真正的绘制逻辑。

每帧由以下几个阶段组成:

  1. 动画阶段 - SchedulerBinding.handleBeginFrame (由 Window.onBeginFrame 注册),按注册顺序调用所有的临时帧回调 (由 scheduleFrameCallback 注册)。这些回调包括所有用于驱动 AnimationController 对象的 Ticker 实例,即该时间点的所有活跃 Animation 对象。

  2. Microtasks - handleBeginFrame 返回后,由临时帧回调注册的方法调度的 microtasks 开始运行。之后,由 Window.onDrawFrame 注册的 handleDrawFrame 回调开始执行,它调用所有的持久帧回调。其中最重要的是 drawFrame 方法,它的处理过程如下

  3. 布局阶段 - 对系统中的所有标记为脏的 RenderObject (如何将对象标脏以便布局,可参考 RenderObject.markNeedsLayout) 进行布局

  4. compositing bits 阶段 - 更新所有标脏 RenderObject 中的 compositing bits。具体参考 RenderObject.markNeedsCompositingBitsUpdate

  5. 绘制阶段 - 系统中的所有标脏 RenderObject 被重绘。这个过程生成 Layer 树。如何将对象标脏以便绘制,可参考 RenderObject.markNeedsPaint

  6. 合成阶段 - 将 layer tree 转换成 Scene 并发送到 GPU

  7. semantics 阶段 - 系统中的所有标脏 RenderObject 的 semantics 被更新。具体见 RenderObject.semanticsAnnotator。这个过程生成 SemanticsNode 树。如何将对象标脏以用于 semantics,可参考 RenderObject.markNeedsSemanticsUpdate

  8. 步骤 3-7 的细节请参考 PipelineOwner

  9. 结束阶段 - drawFrame 返回后,handleDrawFrame 调用 post-frame 回调。(由 addPostFrameCallback 注册)

注意:某些绑定会向上述过程添加额外步骤,比如,WidgetsBinding 会添加 WidgetsBinding.drawFrame

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。