由上文我们知道由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.dart
flushCompositingBits
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.dart
flushPaint
:绘制所有的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.dart
render
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.cc
Shell::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。
网友评论