美文网首页Android基础知识
从systrace看app冷启动过程(二)-首帧的绘制与渲染

从systrace看app冷启动过程(二)-首帧的绘制与渲染

作者: Stan_Z | 来源:发表于2019-04-15 22:50 被阅读258次

原创文章,转载注明出处,多谢合作。

上篇我们分析完了App的启动部分,这篇我们来看看第二个Vsync信号响应阶段:首帧的绘制与渲染

接上篇的systrace图继续往后分析:

frameworks/base/core/java/android/view/Choreographer.java

   void doFrame(long frameTimeNanos, int frame) {
               ...
        try {
            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#doFrame");
            AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);
            mFrameInfo.markInputHandlingStart();
            doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
            mFrameInfo.markAnimationsStart();
            doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
            mFrameInfo.markPerformTraversalsStart();
            doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
            doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
        } finally {
            AnimationUtils.unlockAnimationClock();
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
        }
                ...
}

Choreographers作为用户层监听Vsync信号的处理者,它统一动画、输入和绘制的处理时机。主要针对3种类型事件:输入、绘制、动画。它主要干两件事情:通过postCallback请求vsync信号收到vsync信号并回调

一旦接收到回调信号,则通过doFrame统一对以上几种事件进行回调。

把图拉大之后能看到doFrame主要处理了Input 、animation和traversal。

这里我们主要来看看traversal阶段,它是执行视图绘制流程。这里视图绘制流程又分软件绘制与硬件加速,4.0之后默认走硬件加速,所以这里跟的是硬件加速流程。

ViewRootImpl.java中按从上往下的调用流程:

setView
|
requestLayout
|
scheduleTraversals
|
mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);//这里响应vsync回调
|
TraversalRunnable中执行doTraversal
|
performTraversals

而performTraversals主要就是执行performMeasure、performLayout、performDraw, 其中measure和layout在当前vsync信号内完成,draw在下一个vsync信号内完成。

private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
    if (mView == null) {
        return;
   }
    Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
   try {
        mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
   } finally {
        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
   }
}

private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
       int desiredWindowHeight) {
    ...
    Trace.traceBegin(Trace.TRACE_TAG_VIEW, "layout");
   try {
        host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
      ...
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
   }
 ...
}

private void performDraw() {
  ...
   Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
   try {
        draw(fullRedrawNeeded);
   } finally {
        mIsDrawing = false;
       Trace.traceEnd(Trace.TRACE_TAG_VIEW);
   }
  ...
}

不管是硬件加速还是软件绘制,draw的过程都是在应用层构建DisplayList的数据封装,其中View tree中每个View对应一个RenderNode节点,通过绘制引擎把视图View转化成绘制操作Op,并保存在对应的View的DisplayList中,而子View又会作为一个Op保存到父容器视图的DisplayList中。

详细绘制过程请参考之前的文章:Android9.0 硬件加速(四)-UI Thread绘制过程

与此同时,除了UI Thread外,还有个RenderThread被初始化,开始了setSurface的工作。

RenderThread初始化流程参考文章:Android9.0 硬件加速(二)-RenderThread线程的启动

流程如下图所示:

而setSurface部分:参考之前文章:Android9.0 硬件加速(三)-绑定Surface到RenderThread

流程如下图所示:

这个过程做了一系列初始化,最终创建并设置EGLSurface, 其中EGLSurface最主要任务就是dequeueBuffer/queueBuffer操作.

接下来再看看核心部分:DrawFrame过程。

硬件加速把视图的渲染工作转到了一个新的线程RenderThread中来处理。trace不好展开,这里拆分简单介绍下:

syncFrameState/prepareThree: 将UI thread的DisplayList同步到RenderThread来, 这个同步过程是阻塞UI线程的,可以看到此时UI线程是sleep状态:

dequeueBuffer:通过Surface申请存放绘制数据的buffer。

flash commands : DisplayList按层重新组织数据:LayerBuilder ,并转为OpenGL命令,并缓存在本地的GL命令缓冲区中。

swapbuffers:通过Surface queueBuffer将绘制好的数据放入之前申请好的buffer中,并通知SurfaceFlinger去合成。

详细渲染过程请参考之前的文章:Android9.0 硬件加速(五) -RenderThread渲染过程

RenderThread setSurface 同步数据以及渲染操作在硬件加速篇都列出了具体标签出处及其流程,可以跟着看一下,这里就不重复贴了。

至此,首帧绘制与渲染过程完成,下一篇分析SurfaceFlinger合成过程。

相关文章

  • 从systrace看app冷启动过程(二)-首帧的绘制与渲染

    原创文章,转载注明出处,多谢合作。 上篇我们分析完了App的启动部分,这篇我们来看看第二个Vsync信号响应阶段:...

  • 从systrace看app冷启动过程(一)-首帧绘制前的准备

    原创文章,转载注明出处,多谢合作。 本文从systrace的角度通过关键标签,来简单看下app冷启动牵扯到的图形渲...

  • framemonitor原理分析

    最近写了一个开源项目叫framemonitor, 相当于SDK版的Systrace,可以监控App的帧绘制时间,接...

  • 对App的冷启动的总结

    app的冷启动:即app从来没有打开,从点击app到看到首屏为止的这个过程,叫做app的冷启动。 应用程序的入口为...

  • iOS 离屏渲染

    1.离屏渲染的概念 普通app在加载过程中,CPU跟GPU合作不断地将要渲染的内容存储在帧缓存区,屏幕也不断地从帧...

  • 浏览器渲染帧

    浏览器的绘制渲染过程可以总结为 一帧数据的渲染注意:浏览器并不是因为页面的重绘和回流才会进行数据帧的渲染,一般情况...

  • App冷启动优化

    冷启动定义 冷启动定义: 从用户点击App到首屏展示为止。 T1:main()函数之前,即操作系统加载App可执行...

  • iOS性能优化 — 五、App启动优化

    冷启动定义 1、我们把用户点击App图标(App处于杀死状态)到首页渲染完这段时间定义为冷启动。其中点击App图标...

  • iOS 冷启动

    iOS 冷启动分为几个阶段,每个阶段的的过程是什么 冷启动的过程定义为:从用户点击 App 图标开始到 appDe...

  • 跨线程通信-Handler

    从通信机制角度看应用启动过程 首先,让我们结合通信机制,来看看通过Launcher启动App的过程(假设为冷启动)...

网友评论

    本文标题:从systrace看app冷启动过程(二)-首帧的绘制与渲染

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