美文网首页
flutter UI渲染源码解析之UI Framework绘制(

flutter UI渲染源码解析之UI Framework绘制(

作者: heiheiwanne | 来源:发表于2020-09-17 17:33 被阅读0次
    UI Framework绘制

    由上文我们知道由window.cc中Window::BeginFrame调用到了framework层onBeginFrame跟onDrawFrame
    1.window.dart

      FrameCallback? get onBeginFrame => _onBeginFrame;
      FrameCallback? _onBeginFrame;
      Zone _onBeginFrameZone = Zone.root;
      set onBeginFrame(FrameCallback? callback) {
        _onBeginFrame = callback;
        _onBeginFrameZone = Zone.current;
      }
    

    2.onBeginFrame赋值:binding.dart ensureFrameCallbacksRegistered

    @protected
      void ensureFrameCallbacksRegistered() {
        window.onBeginFrame ??= _handleBeginFrame;
        window.onDrawFrame ??= _handleDrawFrame;
      }
    

    3.binding.dart _handleBeginFrame

     void _handleBeginFrame(Duration rawTimeStamp) {
        if (_warmUpFrame) {
          assert(!_ignoreNextEngineDrawFrame);
          _ignoreNextEngineDrawFrame = true;
          return;
        }
        handleBeginFrame(rawTimeStamp);
      }
    

    4.binding.dart handleBeginFrame

    void handleBeginFrame(Duration? rawTimeStamp) {
        Timeline.startSync('Frame', arguments: timelineArgumentsIndicatingLandmarkEvent);
        _firstRawTimeStampInEpoch ??= rawTimeStamp;
        _currentFrameTimeStamp = _adjustForEpoch(rawTimeStamp ?? _lastRawTimeStamp);
        if (rawTimeStamp != null)
          _lastRawTimeStamp = rawTimeStamp;
    
        assert(() {
          _debugFrameNumber += 1;
    
          if (debugPrintBeginFrameBanner || debugPrintEndFrameBanner) {
            final StringBuffer frameTimeStampDescription = StringBuffer();
            if (rawTimeStamp != null) {
              _debugDescribeTimeStamp(_currentFrameTimeStamp!, frameTimeStampDescription);
            } else {
              frameTimeStampDescription.write('(warm-up frame)');
            }
            _debugBanner = '▄▄▄▄▄▄▄▄ Frame ${_debugFrameNumber.toString().padRight(7)}   ${frameTimeStampDescription.toString().padLeft(18)} ▄▄▄▄▄▄▄▄';
            if (debugPrintBeginFrameBanner)
              debugPrint(_debugBanner);
          }
          return true;
        }());
    
        assert(schedulerPhase == SchedulerPhase.idle);
        _hasScheduledFrame = false;
        try {
          // TRANSIENT FRAME CALLBACKS
          Timeline.startSync('Animate', arguments: timelineArgumentsIndicatingLandmarkEvent);
          _schedulerPhase = SchedulerPhase.transientCallbacks;
          //遍历_transientCallbacks
          final Map<int, _FrameCallbackEntry> callbacks = _transientCallbacks;
          _transientCallbacks = <int, _FrameCallbackEntry>{};
          callbacks.forEach((int id, _FrameCallbackEntry callbackEntry) {
            if (!_removedIds.contains(id))
              _invokeFrameCallback(callbackEntry.callback, _currentFrameTimeStamp!, callbackEntry.debugStack);
          });
          _removedIds.clear();
        } finally {
          _schedulerPhase = SchedulerPhase.midFrameMicrotasks;
        }
      }
    

    该方法主要功能是遍历_transientCallbacks,执行相应的Animate操作,可通过scheduleFrameCallback()/cancelFrameCallbackWithId()来完成添加和删除成员,再来简单看看这两个方法。

    int scheduleFrameCallback(FrameCallback callback, { bool rescheduling = false }) {
      //这里触发了scheduleFrame
        scheduleFrame();
        _nextFrameCallbackId += 1;
        _transientCallbacks[_nextFrameCallbackId] = _FrameCallbackEntry(callback, rescheduling: rescheduling);
        return _nextFrameCallbackId;
      }
    
      void cancelFrameCallbackWithId(int id) {
        assert(id > 0);
        _transientCallbacks.remove(id);
        _removedIds.add(id);
      }
    
    
    • 5.binding.dart _handleDrawFrame
      void _handleDrawFrame() {
        if (_ignoreNextEngineDrawFrame) {
          _ignoreNextEngineDrawFrame = false;
          return;
        }
        handleDrawFrame();
      }
    
    • 6.binding.dart handleDrawFrame
    void handleDrawFrame() {
        assert(_schedulerPhase == SchedulerPhase.midFrameMicrotasks);
        Timeline.finishSync(); // end the "Animate" phase
        try {
          // PERSISTENT FRAME CALLBACKS
          _schedulerPhase = SchedulerPhase.persistentCallbacks;
          for (final FrameCallback callback in _persistentCallbacks)
            _invokeFrameCallback(callback, _currentFrameTimeStamp!);
    
          // POST-FRAME CALLBACKS
          _schedulerPhase = SchedulerPhase.postFrameCallbacks;
          final List<FrameCallback> localPostFrameCallbacks =
              List<FrameCallback>.from(_postFrameCallbacks);
          _postFrameCallbacks.clear();
          for (final FrameCallback callback in localPostFrameCallbacks)
            _invokeFrameCallback(callback, _currentFrameTimeStamp!);
        } finally {
          _schedulerPhase = SchedulerPhase.idle;
          Timeline.finishSync(); // end the Frame
          assert(() {
            if (debugPrintEndFrameBanner)
              debugPrint('▀' * _debugBanner!.length);
            _debugBanner = null;
            return true;
          }());
          _currentFrameTimeStamp = null;
        }
      }
    

    1.遍历_persistentCallbacks,执行相应的回调方法,可通过addPersistentFrameCallback()注册,一旦注册后不可移除,后续每一次frame回调都会执行;
    2.遍历_postFrameCallbacks,执行相应的回调方法,可通过addPostFrameCallback()注册,handleDrawFrame()执行完成后会清空_postFrameCallbacks内容。

    • 7.这里我们主要看一下_persistentCallbacks,在flutter app启动过程,也就是执行runApp过程会有WidgetsFlutterBinding初始化过程,WidgetsBinding的initInstances(),根据mixin的顺序,可知此处的super.initInstances() 便是RendererBinding类。
    mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureBinding, SemanticsBinding, HitTestable {
      @override
      void initInstances() {
        super.initInstances();
        _instance = this;
        _pipelineOwner = PipelineOwner(
          onNeedVisualUpdate: ensureVisualUpdate,
          onSemanticsOwnerCreated: _handleSemanticsOwnerCreated,
          onSemanticsOwnerDisposed: _handleSemanticsOwnerDisposed,
        );
        window
          ..onMetricsChanged = handleMetricsChanged
          ..onTextScaleFactorChanged = handleTextScaleFactorChanged
          ..onPlatformBrightnessChanged = handlePlatformBrightnessChanged
          ..onSemanticsEnabledChanged = _handleSemanticsEnabledChanged
          ..onSemanticsAction = _handleSemanticsAction;
        initRenderView();
        _handleSemanticsEnabledChanged();
        assert(renderView != null);
        //在这里进行的赋值
        addPersistentFrameCallback(_handlePersistentFrameCallback);
        initMouseTracker();
      }
    ...
    }
    
    • 8.render/binding.dart _handlePersistentFrameCallback
    void _handlePersistentFrameCallback(Duration timeStamp) {
        drawFrame();
        _mouseTracker.schedulePostFrameCheck();
      }
    
    • 9.render/binding.dart drawFrame
      @protected
      void drawFrame() {
        assert(renderView != null);
        pipelineOwner.flushLayout();
        pipelineOwner.flushCompositingBits();
        pipelineOwner.flushPaint();
        if (sendFramesToEngine) {
          renderView.compositeFrame(); // this sends the bits to the GPU
          pipelineOwner.flushSemantics(); // this also sends the semantics to the OS.
          _firstFrameSent = true;
        }
      }
    

    该方法由[handleDrawFrame]调用,当需要布置和绘制框架时,引擎会自动调用该方法。
    每个框架都包含以下几个阶段:
    1.动画阶段:在[Window.onBeginFrame]中注册的[handleBeginFrame]方法,以注册顺序调用在[scheduleFrameCallback]中注册的所有瞬态帧回调。这包括所有正在驱动[AnimationController]对象的[Ticker]实例,这意味着所有活动的[Animation]对象都在此刻打勾。
    2.微任务:返回[handleBeginFrame]后,由瞬态帧回调安排的任何微任务都将运行。这通常包括完成此帧的[Ticker]和[AnimationController]的期货回调。
    在[handleBeginFrame]之后,将调用向[Window.onDrawFrame]注册的[handleDrawFrame],该调用将调用所有持久性帧回调,其中最引人注目的是此方法[drawFrame],其过程如下:
    3.布局阶段:对系统中所有脏的[RenderObject]进行布局(请参见[RenderObject.performLayout])。有关将对象标记为布局不干净的更多详细信息,请参见[RenderObject.markNeedsLayout]。
    4.合成位阶段:更新任何脏的[RenderObject]对象上的合成位。请参见[RenderObject.markNeedsCompositingBitsUpdate]。
    5.绘制阶段:重新绘制系统中所有脏的[RenderObject](请参阅[RenderObject.paint])。这将生成[Layer]树。请参阅[RenderObject.markNeedsPaint],以获取更多有关将对象标记为脏画的详细信息。
    6.合成阶段:层树变成[场景]并发送到GPU。
    7.语义阶段:系统中所有脏的[RenderObject]的语义都已更新。这将生成[SemanticsNode]树。有关将对象标记为语义脏的更多详细信息,请参见[RenderObject.markNeedsSemanticsUpdate]。有关步骤3-7的更多详细信息,请参见[PipelineOwner]。
    8.完成阶段:在[drawFrame]返回之后,[handleDrawFrame]调用后框架回调(在[addPostFrameCallback]中注册)。一些绑定(例如[WidgetsBinding])向此列表添加了额外的步骤(例如,请参见[WidgetsBinding.drawFrame])。

    • 10.object.dart flushLayout
    void flushLayout() {
        if (!kReleaseMode) {
          Timeline.startSync('Layout', arguments: timelineArgumentsIndicatingLandmarkEvent);
        }
        assert(() {
          _debugDoingLayout = true;
          return true;
        }());
        try {
        //遍历所有的渲染对象
          while (_nodesNeedingLayout.isNotEmpty) {
            final List<RenderObject> dirtyNodes = _nodesNeedingLayout;
            _nodesNeedingLayout = <RenderObject>[];
    
            for (final RenderObject node in dirtyNodes..sort((RenderObject a, RenderObject b) => a.depth - b.depth)) {
              //如果对象需要layout则重新layout
              if (node._needsLayout && node.owner == this)
                node._layoutWithoutResize();
            }
          }
        } finally {
          assert(() {
            _debugDoingLayout = false;
            return true;
          }());
          if (!kReleaseMode) {
            Timeline.finishSync();
          }
        }
      }
    
    • 11.object.dart_layoutWithoutResize
     void _layoutWithoutResize() {
        assert(_relayoutBoundary == this);
        RenderObject debugPreviousActiveLayout;
        assert(!_debugMutationsLocked);
        assert(!_doingThisLayoutWithCallback);
        assert(_debugCanParentUseSize != null);
        assert(() {
          _debugMutationsLocked = true;
          _debugDoingThisLayout = true;
          debugPreviousActiveLayout = _debugActiveLayout;
          _debugActiveLayout = this;
          if (debugPrintLayouts)
            debugPrint('Laying out (without resize) $this');
          return true;
        }());
        try {
          //执行绘制操作,
          performLayout();
          //标记需要更新的
          markNeedsSemanticsUpdate();
        } catch (e, stack) {
          _debugReportException('performLayout', e, stack);
        }
        assert(() {
          _debugActiveLayout = debugPreviousActiveLayout;
          _debugDoingThisLayout = false;
          _debugMutationsLocked = false;
          return true;
        }());
        _needsLayout = false;
        //标记需要绘制的
        markNeedsPaint();
      }
    
    • 12.object.dart``
    void markNeedsSemanticsUpdate() {
        assert(!attached || !owner._debugDoingSemantics);
        if (!attached || owner._semanticsOwner == null) {
          _cachedSemanticsConfiguration = null;
          return;
        }
    
        // Dirty the semantics tree starting at `this` until we have reached a
        // RenderObject that is a semantics boundary. All semantics past this
        // RenderObject are still up-to date. Therefore, we will later only rebuild
        // the semantics subtree starting at the identified semantics boundary.
    
        final bool wasSemanticsBoundary = _semantics != null && _cachedSemanticsConfiguration?.isSemanticBoundary == true;
        _cachedSemanticsConfiguration = null;
        bool isEffectiveSemanticsBoundary = _semanticsConfiguration.isSemanticBoundary && wasSemanticsBoundary;
        RenderObject node = this;
    
        while (!isEffectiveSemanticsBoundary && node.parent is RenderObject) {
          if (node != this && node._needsSemanticsUpdate)
            break;
          node._needsSemanticsUpdate = true;
    
          node = node.parent as RenderObject;
          isEffectiveSemanticsBoundary = node._semanticsConfiguration.isSemanticBoundary;
          if (isEffectiveSemanticsBoundary && node._semantics == null) {
            return;
          }
        }
        if (node != this && _semantics != null && _needsSemanticsUpdate) {
          owner._nodesNeedingSemantics.remove(this);
        }
        if (!node._needsSemanticsUpdate) {
          node._needsSemanticsUpdate = true;
          if (owner != null) {
            assert(node._semanticsConfiguration.isSemanticBoundary || node.parent is! RenderObject);
            //将需要更新的node记录下来
            owner._nodesNeedingSemantics.add(node);
            owner.requestVisualUpdate();
          }
        }
      }
    
    • 13.object.dart ``
    void markNeedsPaint() {
        assert(owner == null || !owner.debugDoingPaint);
        if (_needsPaint)
          return;
        _needsPaint = true;
        if (isRepaintBoundary) {
          assert(() {
            if (debugPrintMarkNeedsPaintStacks)
              debugPrintStack(label: 'markNeedsPaint() called for $this');
            return true;
          }());
       
          assert(_layer is OffsetLayer);
          if (owner != null) {
            //将需要重绘的node记录下来
            owner._nodesNeedingPaint.add(this);
            owner.requestVisualUpdate();
          }
        } else if (parent is RenderObject) {
          final RenderObject parent = this.parent as RenderObject;
          parent.markNeedsPaint();
          assert(parent == this.parent);
        } else {
          assert(() {
            if (debugPrintMarkNeedsPaintStacks)
              debugPrintStack(label: 'markNeedsPaint() called for $this (root of render tree)');
            return true;
          }());
      
          if (owner != null)
            owner.requestVisualUpdate();
        }
      }
    
    • 14.object.dartflushCompositingBits
     void flushCompositingBits() {
        if (!kReleaseMode) {
          Timeline.startSync('Compositing bits');
        }
        _nodesNeedingCompositingBitsUpdate.sort((RenderObject a, RenderObject b) => a.depth - b.depth);
        for (final RenderObject node in _nodesNeedingCompositingBitsUpdate) {
          //node _needsCompositingBitsUpdate=true时进行合成操作
          if (node._needsCompositingBitsUpdate && node.owner == this)
            node._updateCompositingBits();
        }
        _nodesNeedingCompositingBitsUpdate.clear();
        if (!kReleaseMode) {
          Timeline.finishSync();
        }
      }
    
    • 15.object.dart_updateCompositingBits:更新合成位,根据子view来判断当前的view是否需要标记paint
      void _updateCompositingBits() {
        if (!_needsCompositingBitsUpdate)
          return;
        final bool oldNeedsCompositing = _needsCompositing;
        _needsCompositing = false;
        visitChildren((RenderObject child) {
        //遍历子view若子view中有需要更新的,那么当前的view也需要更新
          child._updateCompositingBits();
          if (child.needsCompositing)
            _needsCompositing = true;
        });
        if (isRepaintBoundary || alwaysNeedsCompositing)
          _needsCompositing = true;
        if (oldNeedsCompositing != _needsCompositing)
        //若子view有更新的标记当前的view需要绘制
          markNeedsPaint();
        _needsCompositingBitsUpdate = false;
      }
    
    • 16.object.dartflushPaint:绘制所有的renderobj
    void flushPaint() {
        if (!kReleaseMode) {
          Timeline.startSync('Paint', arguments: timelineArgumentsIndicatingLandmarkEvent);
        }
        assert(() {
          _debugDoingPaint = true;
          return true;
        }());
        try {
          final List<RenderObject> dirtyNodes = _nodesNeedingPaint;
          _nodesNeedingPaint = <RenderObject>[];
          // 排序脏节点,深度最大的节点排在第一位
          for (final RenderObject node in dirtyNodes..sort((RenderObject a, RenderObject b) => b.depth - a.depth)) {
            assert(node._layer != null);
            if (node._needsPaint && node.owner == this) {
              //判断当前的节点是否在链接树上,在:重绘;不在:跳过
              if (node._layer.attached) {
                PaintingContext.repaintCompositedChild(node);
              } else {
                node._skippedPaintingOnLayer();
              }
            }
          }
          assert(_nodesNeedingPaint.isEmpty);
        } finally {
          assert(() {
            _debugDoingPaint = false;
            return true;
          }());
          if (!kReleaseMode) {
            Timeline.finishSync();
          }
        }
      }
    
    • 17.object.dart repaintCompositedChild
      static void repaintCompositedChild(RenderObject child, { bool debugAlsoPaintedParent = false }) {
        assert(child._needsPaint);
        _repaintCompositedChild(
          child,
          debugAlsoPaintedParent: debugAlsoPaintedParent,
        );
      }
    
     static void _repaintCompositedChild(
        RenderObject child, {
        bool debugAlsoPaintedParent = false,
        PaintingContext childContext,
      }) {
        assert(child.isRepaintBoundary);
        assert(() {
          // register the call for RepaintBoundary metrics
          child.debugRegisterRepaintBoundaryPaint(
            includedParent: debugAlsoPaintedParent,
            includedChild: true,
          );
          return true;
        }());
        OffsetLayer childLayer = child._layer as OffsetLayer;
        if (childLayer == null) {
          assert(debugAlsoPaintedParent);
          child._layer = childLayer = OffsetLayer();
        } else {
          assert(childLayer is OffsetLayer);
          assert(debugAlsoPaintedParent || childLayer.attached);
          childLayer.removeAllChildren();
        }
        assert(identical(childLayer, child._layer));
        assert(child._layer is OffsetLayer);
        assert(() {
          child._layer.debugCreator = child.debugCreator ?? child.runtimeType;
          return true;
        }());
        childContext ??= PaintingContext(child._layer, child.paintBounds);
        //执行绘制操作
        child._paintWithContext(childContext, Offset.zero);
    
        assert(identical(childLayer, child._layer));
        childContext.stopRecordingIfNeeded();
      }
    
    void _paintWithContext(PaintingContext context, Offset offset) {
        assert(() {
          if (_debugDoingThisPaint) {
            throw FlutterError.fromParts(<DiagnosticsNode>[
              ErrorSummary('Tried to paint a RenderObject reentrantly.'),
              describeForError(
                'The following RenderObject was already being painted when it was '
                'painted again'
              ),
              ErrorDescription(
                'Since this typically indicates an infinite recursion, it is '
                'disallowed.'
              ),
            ]);
          }
          return true;
        }());
        if (_needsLayout)
          return;
        assert(() {
          if (_needsCompositingBitsUpdate) {
            if (parent is RenderObject) {
              final RenderObject parent = this.parent as RenderObject;
              bool visitedByParent = false;
              parent.visitChildren((RenderObject child) {
                if (child == this) {
                  visitedByParent = true;
                }
              });
              if (!visitedByParent) {
                throw FlutterError.fromParts(<DiagnosticsNode>[
                  ErrorSummary(
                    "A RenderObject was not visited by the parent's visitChildren "
                    'during paint.',
                  ),
                  parent.describeForError(
                    'The parent was',
                  ),
                  describeForError(
                    'The child that was not visited was'
                  ),
                  ErrorDescription(
                    'A RenderObject with children must implement visitChildren and '
                    'call the visitor exactly once for each child; it also should not '
                    'paint children that were removed with dropChild.'
                  ),
                  ErrorHint(
                    'This usually indicates an error in the Flutter framework itself.'
                  ),
                ]);
              }
            }
            throw FlutterError.fromParts(<DiagnosticsNode>[
              ErrorSummary(
                'Tried to paint a RenderObject before its compositing bits were '
                'updated.'
              ),
              describeForError(
                'The following RenderObject was marked as having dirty compositing '
                'bits at the time that it was painted',
              ),
              ErrorDescription(
                'A RenderObject that still has dirty compositing bits cannot be '
                'painted because this indicates that the tree has not yet been '
                'properly configured for creating the layer tree.'
              ),
              ErrorHint(
                'This usually indicates an error in the Flutter framework itself.'
              ),
            ]);
          }
          return true;
        }());
        RenderObject debugLastActivePaint;
        assert(() {
          _debugDoingThisPaint = true;
          debugLastActivePaint = _debugActivePaint;
          _debugActivePaint = this;
          assert(!isRepaintBoundary || _layer != null);
          return true;
        }());
        _needsPaint = false;
        try {
        //执行paint的操作
          paint(context, offset);
          assert(!_needsLayout); // check that the paint() method didn't mark us dirty again
          assert(!_needsPaint); // check that the paint() method didn't mark us dirty again
        } catch (e, stack) {
          _debugReportException('paint', e, stack);
        }
        assert(() {
          debugPaint(context, offset);
          _debugActivePaint = debugLastActivePaint;
          _debugDoingThisPaint = false;
          return true;
        }());
      }
    

    最终的调用跟layout一样都会执行到obejct的performLayout paint方法中,这些方法都会被子类进行重写,子类实现自己的具体layout以及paint

    • 18.view.dart compositeFrame
    void compositeFrame() {
        Timeline.startSync('Compositing', arguments: timelineArgumentsIndicatingLandmarkEvent);
        try {
          final ui.SceneBuilder builder = ui.SceneBuilder();
          final ui.Scene scene = layer.buildScene(builder);
          if (automaticSystemUiAdjustment)
            _updateSystemChrome();
          _window.render(scene);
          scene.dispose();
          assert(() {
            if (debugRepaintRainbowEnabled || debugRepaintTextRainbowEnabled)
              debugCurrentRepaintColor = debugCurrentRepaintColor.withHue((debugCurrentRepaintColor.hue + 2.0) % 360.0);
            return true;
          }());
        } finally {
          Timeline.finishSync();
        }
      }
    

    分别创建Flutter框架(dart)和引擎层(C++)的两个SceneBuilder;
    分别创建Flutter框架(dart)和引擎层(C++)的两个Scene;
    执行render()将layer树发送给GPU线程;

    • 19.SceneBuilder 的初始化
      @pragma('vm:entry-point')
      SceneBuilder() {
        _constructor();
      }
      void _constructor() native 'SceneBuilder_constructor';
    

    此方法会被调用到C++SceneBuilder中即创建的是一个C++层的对象

    • 20.layer.buildScene:
    ui.Scene buildScene(ui.SceneBuilder builder) {
        List<PictureLayer> temporaryLayers;
        assert(() {
          if (debugCheckElevationsEnabled) {
            temporaryLayers = _debugCheckElevations();
          }
          return true;
        }());
      updateSubtreeNeedsAddToScene();  //遍历layer树,将需要子树加入到scene
      addToScene(builder); //将layer添加到SceneBuilder
        _needsAddToScene = false;
        final ui.Scene scene = builder.build();//调用C++层的build来构建Scene对象。
        assert(() {
          if (temporaryLayers != null) {
            for (final PictureLayer temporaryLayer in temporaryLayers) {
              temporaryLayer.remove();
            }
          }
          return true;
        }());
        return scene;
      }
    
    

    遍历layer树,将需要更新的全部都加入到SceneBuilder。再调用build(),同样也是native方法,执行SceneBuilder::build()来构建Scene对象。

    • 21.window.dartrender
    void render(Scene scene) native 'PlatformConfiguration_render';
    

    window.dart的render会调用到C++层window.cc中

    • 22.window.cc ``
    void Render(Dart_NativeArguments args) {
      UIDartState::ThrowIfUIOperationsProhibited();
      Dart_Handle exception = nullptr;
      //获得之前创建的scene
      Scene* scene =
          tonic::DartConverter<Scene*>::FromArguments(args, 1, exception);
      if (exception) {
        Dart_ThrowException(exception);
        return;
      }
      UIDartState::Current()->window()->client()->Render(scene);
    }
    
    • 23.runtime_controller.cc RuntimeController::Render
    // |WindowClient|
    void RuntimeController::Render(Scene* scene) {
      client_.Render(scene->takeLayerTree());
    }
    
    • 24.engine.cc Engine::Render
    void Engine::Render(std::unique_ptr<flutter::LayerTree> layer_tree) {
      if (!layer_tree)
        return;
    
      // Ensure frame dimensions are sane.
      if (layer_tree->frame_size().isEmpty() ||
          layer_tree->frame_physical_depth() <= 0.0f ||
          layer_tree->frame_device_pixel_ratio() <= 0.0f)
        return;
    
      animator_->Render(std::move(layer_tree));
    }
    
    • 25.animator.cc
    void Animator::Render(std::unique_ptr<flutter::LayerTree> layer_tree) {
      if (dimension_change_pending_ &&
          layer_tree->frame_size() != last_layer_tree_size_) {
        dimension_change_pending_ = false;
      }
      last_layer_tree_size_ = layer_tree->frame_size();
      if (layer_tree) {
        //将本次的绘制时间进行记录
        layer_tree->RecordBuildTime(last_frame_begin_time_,
                                    last_frame_target_time_);
      }
      //提交continuation,此次pipeline produce 完成
      bool result = producer_continuation_.Complete(std::move(layer_tree));
      if (!result) {
        FML_DLOG(INFO) << "No pending continuation to commit";
      }
      delegate_.OnAnimatorDraw(layer_tree_pipeline_, last_frame_target_time_);
    }
    

    UI线程的耗时从doFrame(frameTimeNanos)中的frameTimeNanos为起点,以Animator::Render()方法结束为终点, 并将结果保存到LayerTree的成员变量construction_time_,这便是UI线程的耗时时长。

    • 26.shell.cc Shell::OnAnimatorDraw
    // |Animator::Delegate|
    void Shell::OnAnimatorDraw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline,
                               fml::TimePoint frame_target_time) {
      FML_DCHECK(is_setup_);
    
      // record the target time for use by rasterizer.
      {
        std::scoped_lock time_recorder_lock(time_recorder_mutex_);
        if (!latest_frame_target_time_) {
          latest_frame_target_time_ = frame_target_time;
        } else if (latest_frame_target_time_ < frame_target_time) {
          latest_frame_target_time_ = frame_target_time;
        }
      }
    
      task_runners_.GetRasterTaskRunner()->PostTask(
          [&waiting_for_first_frame = waiting_for_first_frame_,
           &waiting_for_first_frame_condition = waiting_for_first_frame_condition_,
           rasterizer = rasterizer_->GetWeakPtr(),
           pipeline = std::move(pipeline)]() {
            if (rasterizer) {
              rasterizer->Draw(pipeline);
    
              if (waiting_for_first_frame.load()) {
                waiting_for_first_frame.store(false);
                waiting_for_first_frame_condition.notify_all();
              }
            }
          });
    }
    

    此方法主要是将当前的绘制内容交给Raster线程(GPU线程),绘制相关内容

    • 27.object.cc flushSemantics
    void flushSemantics() {
        if (_semanticsOwner == null)
          return;
        if (!kReleaseMode) {
          Timeline.startSync('Semantics');
        }
        assert(_semanticsOwner != null);
        assert(() {
          _debugDoingSemantics = true;
          return true;
        }());
        try {
          final List<RenderObject> nodesToProcess = _nodesNeedingSemantics.toList()
            ..sort((RenderObject a, RenderObject b) => a.depth - b.depth);
          _nodesNeedingSemantics.clear();
          //遍历_nodesNeedingSemantics,更新需要更新node的渲染对象
          for (final RenderObject node in nodesToProcess) {
            if (node._needsSemanticsUpdate && node.owner == this)
              node._updateSemantics();
          }
          _semanticsOwner.sendSemanticsUpdate();
        } finally {
          assert(_nodesNeedingSemantics.isEmpty);
          assert(() {
            _debugDoingSemantics = false;
            return true;
          }());
          if (!kReleaseMode) {
            Timeline.finishSync();
          }
        }
      }
    }
    
    • 28.object.dart _updateSemantics
     void _updateSemantics() {
        assert(_semanticsConfiguration.isSemanticBoundary || parent is! RenderObject);
        if (_needsLayout) {
         //此子树中没有足够的信息来计算语义,子树可能被视图窗口保持活着但没有布局
          return;
        }
        final _SemanticsFragment fragment = _getSemanticsForParent(
          mergeIntoParent: _semantics?.parent?.isPartOfNodeMerging ?? false,
        );
        assert(fragment is _InterestingSemanticsFragment);
        final _InterestingSemanticsFragment interestingFragment = fragment as _InterestingSemanticsFragment;
        final SemanticsNode node = interestingFragment.compileChildren(
          parentSemanticsClipRect: _semantics?.parentSemanticsClipRect,
          parentPaintClipRect: _semantics?.parentPaintClipRect,
          elevationAdjustment: _semantics?.elevationAdjustment ?? 0.0,
        ).single;
        // Fragment only wants to add this node's SemanticsNode to the parent.
        assert(interestingFragment.config == null && node == _semantics);
      }
    
    • 29.semantics.dart sendSemanticsUpdate
    void sendSemanticsUpdate() {
        if (_dirtyNodes.isEmpty)
          return;
        final Set<int> customSemanticsActionIds = <int>{};
        final List<SemanticsNode> visitedNodes = <SemanticsNode>[];
        while (_dirtyNodes.isNotEmpty) {
          final List<SemanticsNode> localDirtyNodes = _dirtyNodes.where((SemanticsNode node) => !_detachedNodes.contains(node)).toList();
          _dirtyNodes.clear();
          _detachedNodes.clear();
          localDirtyNodes.sort((SemanticsNode a, SemanticsNode b) => a.depth - b.depth);
          visitedNodes.addAll(localDirtyNodes);
          for (final SemanticsNode node in localDirtyNodes) {
            assert(node._dirty);
            assert(node.parent == null || !node.parent.isPartOfNodeMerging || node.isMergedIntoParent);
            if (node.isPartOfNodeMerging) {
              assert(node.mergeAllDescendantsIntoThisNode || node.parent != null);
             //如果合并到到父节点,确保父节点已被添加到脏列表
              if (node.parent != null && node.parent.isPartOfNodeMerging) {
                node.parent._markDirty(); // 将节点添加到脏列表
                node._dirty = false; // We don't want to send update for this node.
              }
            }
          }
        }
        visitedNodes.sort((SemanticsNode a, SemanticsNode b) => a.depth - b.depth);
        final ui.SemanticsUpdateBuilder builder = SemanticsBinding.instance.createSemanticsUpdateBuilder();
        for (final SemanticsNode node in visitedNodes) {
          assert(node.parent?._dirty != true); // could be null (no parent) or false (not dirty)
          // The _serialize() method marks the node as not dirty, and
          // recurses through the tree to do a deep serialization of all
          // contiguous dirty nodes. This means that when we return here,
          // it's quite possible that subsequent nodes are no longer
          // dirty. We skip these here.
          // We also skip any nodes that were reset and subsequently
          // dropped entirely (RenderObject.markNeedsSemanticsUpdate()
          // calls reset() on its SemanticsNode if onlyChanges isn't set,
          // which happens e.g. when the node is no longer contributing
          // semantics).
          if (node._dirty && node.attached)
            node._addToUpdate(builder, customSemanticsActionIds);
        }
        _dirtyNodes.clear();
        for (final int actionId in customSemanticsActionIds) {
          final CustomSemanticsAction action = CustomSemanticsAction.getAction(actionId);
          builder.updateCustomAction(id: actionId, label: action.label, hint: action.hint, overrideId: action.action?.index ?? -1);
        }
        SemanticsBinding.instance.window.updateSemantics(builder.build());
        notifyListeners();//通知已注册监听器
      }
    
    • 30.updateSemantics这是window.dart中的一个native方法,调用到如下方法。void updateSemantics(SemanticsUpdate update) native 'PlatformConfiguration_updateSemantics';
    void UpdateSemantics(Dart_NativeArguments args) {
      UIDartState::ThrowIfUIOperationsProhibited();
      Dart_Handle exception = nullptr;
      SemanticsUpdate* update =
          tonic::DartConverter<SemanticsUpdate*>::FromArguments(args, 1, exception);
      if (exception) {
        Dart_ThrowException(exception);
        return;
      }
      UIDartState::Current()->window()->client()->UpdateSemantics(update);
    }
    
    • 31.runtime_contorller.cc RuntimeController::UpdateSemantics
    void RuntimeController::UpdateSemantics(SemanticsUpdate* update) {
      if (window_data_.semantics_enabled) {
        client_.UpdateSemantics(update->takeNodes(), update->takeActions());
      }
    }
    
    • 32.engine.cc Engine::UpdateSemantics
    void Engine::UpdateSemantics(SemanticsNodeUpdates update,
                                 CustomAccessibilityActionUpdates actions) {
      delegate_.OnEngineUpdateSemantics(std::move(update), std::move(actions));
    }
    
    • 32.shell.ccShell::OnEngineHandlePlatformMessage
    void Shell::OnEngineHandlePlatformMessage(
        fml::RefPtr<PlatformMessage> message) {
      FML_DCHECK(is_setup_);
      FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread());
    
      if (message->channel() == kSkiaChannel) {
        HandleEngineSkiaMessage(std::move(message));
        return;
      }
    
      task_runners_.GetPlatformTaskRunner()->PostTask(
          [view = platform_view_->GetWeakPtr(), message = std::move(message)]() {
            if (view) {
              view->HandlePlatformMessage(std::move(message));
            }
          });
    }
    

    该方法主要是向各自的平台线程中提交message。

    相关文章

      网友评论

          本文标题:flutter UI渲染源码解析之UI Framework绘制(

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