Open fzyzcjy opened 2 years ago
Canvas对象中也有名为 ...layer 相关的 API,如 Canvas.saveLayer,它和本节介绍的Layer 含义不同。Canvas对象中的 layer 主要是提供一种在绘制过程中缓存中间绘制结果的手段,为了在绘制复杂对象时方便多个绘制元素之间分离绘制而设计的,更多关于Canvas layer相关API读者可以查阅相关文档,我们可以简单认为不管 Canvas 对创建多少个 layer,这些 layer 都是在同一个 PictureLayer 上(当然具体Canvas API底层实现方式还是 Flutter团队说了算,但作为应用开发者,理解到这里就够了)
谢谢回复。不过还是不太理解本issue提出的问题:我没有找到skia引擎中的Layer。比如dart层面的OffsetLayer、ContainerLayer这些,只有engine层C++ TransformLayer,但似乎skia中没有相关的东西。
Canvas对象中也有名为 ...layer 相关的 API,如 Canvas.saveLayer,它和本节介绍的Layer 含义不同。Canvas对象中的 layer 主要是提供一种在绘制过程中缓存中间绘制结果的手段,为了在绘制复杂对象时方便多个绘制元素之间分离绘制而设计的
感谢。仔细查看发现确实是无关的。
当然具体Canvas API底层实现方式还是 Flutter团队说了算,但作为应用开发者,理解到这里就够了
这两天好奇Flutter底层实现,所以研究到C++层了,遇到这个问题。
进一步地,似乎dart层的OffsetLayer
(即c++ engine层的TransformLayer
),对应的是skia层SkCanvas.save
和SkCanvas.restore
,理由如下。
观察TransformLayer::paint
void TransformLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "TransformLayer::Paint");
FML_DCHECK(needs_painting(context));
SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
context.internal_nodes_canvas->concat(transform_);
PaintChildren(context);
}
可以看到SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
。文档:https://api.skia.org/classSkAutoCanvasRestore.html
doSave call SkCanvas::save() Stack helper class calls SkCanvas::restoreToCount when SkAutoCanvasRestore goes out of scope.
由此可知,(1)该对象构造时,调用了SkCanvas::save
(2)该对象析构时,调用SkCanvas::restoreToCount
(类似restore)。
然后,paint就直接调用PaintChildren(context);
了。
所以,它的核心逻辑可能是:
sk_canvas->save();
PaintChildren();
sk_canvas->restore();
换言之,不存在"skia引擎中的layer",而是直接用skia引擎的save/restore机制实现。
@wendux "希望您在阅读的过程中能积极参与到本书的纠错以及未完成内容的创作上来,也算是有所付出。" (https://book.flutterchina.club/)
我可以写一下这一块内容,提交PR
https://book.flutterchina.club/chapter14/paint.html
以OffsetLayer为例
https://github.com/flutter/engine/blob/2962099077b36704071802ea5595f4a016a1c214/lib/ui/compositing/scene_builder.h#L39 https://github.com/flutter/engine/blob/3f2750c1f8965f8f6378f986237bebf46b06689b/lib/ui/compositing/scene_builder.cc#L97
因此,创建了 TransformLayer。其源码为:https://cs.github.com/flutter/engine/blob/e6233bd30b2cf196a41eced388980991e3fe573b/flow/layers/transform_layer.cc
此处并没有找到"skia引擎中的layer"。
挖掘TransformLayer的父类,ContainerLayer: https://cs.github.com/flutter/engine/blob/e6233bd30b2cf196a41eced388980991e3fe573b/flow/layers/container_layer.cc
直接翻阅源码,似乎没有找到;在该文件源码中搜索"sk"也没有类似"skia引擎中的layer"的东西。
因此,请问一下,"...Layer 会对应一个 Skia 引擎中的 Layer..."中,"skia引擎的layer"指的是?
我猜有可能指的是 https://api.skia.org/classSkCanvas.html#a06bd76ce35082366bb6b8e6dfcb6f435 SkCanvas.saveLayer 之类的layer相关行为。然而,这个saveLayer和Flutter Canvas.saveLayer似乎非常接近。那么,平时CustomPainter调用Canvas.saveLayer时,就创建了一个skia引擎的layer吗?
谢谢