26 static const std::shared_ptr<DummyDelegate>
kInstance;
49 LayerStateStack::RenderingAttributes& attributes,
52 std::optional<int64_t> backdrop_id)
override {}
63 bool is_aa)
override {}
68 FML_DCHECK(
false) <<
"LayerStateStack state queried without a delegate";
73 std::make_shared<DummyDelegate>();
78 : canvas_(
canvas), initial_save_level_(
canvas->GetSaveCount()) {}
97 LayerStateStack::RenderingAttributes& attributes,
100 std::optional<int64_t> backdrop_id)
override {
103 canvas_->
SaveLayer(bounds, attributes.fill(paint, blend_mode), backdrop,
129 bool is_aa)
override {
138 const int initial_save_level_;
144 save_stack_.emplace_back(cull_rect,
matrix);
160 void save()
override { save_stack_.emplace_back(state()); }
162 LayerStateStack::RenderingAttributes& attributes,
165 std::optional<int64_t> backdrop_id)
override {
166 save_stack_.emplace_back(state());
168 void restore()
override { save_stack_.pop_back(); }
189 bool is_aa)
override {
198 const DisplayListMatrixClipState& state()
const {
return save_stack_.back(); }
200 std::vector<DisplayListMatrixClipState> save_stack_;
212 stack->delegate_->save();
215 stack->delegate_->restore();
225 const LayerStateStack::RenderingAttributes& prev)
231 stack->outstanding_ = {};
234 stack->delegate_->restore();
250 const LayerStateStack::RenderingAttributes& prev)
253 old_opacity_(prev.opacity),
254 old_bounds_(prev.save_layer_bounds) {}
257 stack->outstanding_.save_layer_bounds = bounds_;
258 stack->outstanding_.opacity *= opacity_;
261 stack->outstanding_.save_layer_bounds = old_bounds_;
262 stack->outstanding_.opacity = old_opacity_;
280 const std::shared_ptr<DlImageFilter>& filter,
281 const LayerStateStack::RenderingAttributes& prev)
284 old_filter_(prev.image_filter),
285 old_bounds_(prev.save_layer_bounds) {}
289 stack->outstanding_.save_layer_bounds = bounds_;
290 stack->outstanding_.image_filter = filter_;
293 stack->outstanding_.save_layer_bounds = old_bounds_;
294 stack->outstanding_.image_filter = old_filter_;
302 const std::shared_ptr<DlImageFilter> filter_;
303 const std::shared_ptr<DlImageFilter> old_filter_;
312 const std::shared_ptr<const DlColorFilter>& filter,
313 const LayerStateStack::RenderingAttributes& prev)
316 old_filter_(prev.color_filter),
317 old_bounds_(prev.save_layer_bounds) {}
321 stack->outstanding_.save_layer_bounds = bounds_;
322 stack->outstanding_.color_filter = filter_;
325 stack->outstanding_.save_layer_bounds = old_bounds_;
326 stack->outstanding_.color_filter = old_filter_;
334 const std::shared_ptr<const DlColorFilter> filter_;
335 const std::shared_ptr<const DlColorFilter> old_filter_;
344 const std::shared_ptr<DlImageFilter>& filter,
346 std::optional<int64_t> backdrop_id,
347 const LayerStateStack::RenderingAttributes& prev)
350 backdrop_id_(backdrop_id) {}
355 filter_.get(), backdrop_id_);
356 stack->outstanding_ = {};
371 const std::shared_ptr<DlImageFilter> filter_;
372 std::optional<int64_t> backdrop_id_;
382 stack->delegate_->translate(translation_.
x, translation_.
y);
399 stack->delegate_->transform(matrix_);
416 stack->delegate_->integralTransform();
426 : clip_rect_(clip_rect), is_aa_(is_aa) {}
445 : clip_rrect_(clip_rrect), is_aa_(is_aa) {}
465 : clip_rsuperellipse_(clip_rsuperellipse), is_aa_(is_aa) {}
468 stack->delegate_->clipRSuperellipse(clip_rsuperellipse_,
485 : clip_path_(clip_path), is_aa_(is_aa) {}
506DlPaint* LayerStateStack::RenderingAttributes::fill(DlPaint& paint,
508 DlPaint* ret =
nullptr;
509 if (opacity < SK_Scalar1) {
524 if (mode != DlBlendMode::kSrcOver) {
537 layer_state_stack_->save_layer(bounds);
541 if (opacity < SK_Scalar1) {
542 layer_state_stack_->push_opacity(bounds, opacity);
548 const std::shared_ptr<DlImageFilter>& filter) {
550 layer_state_stack_->push_image_filter(bounds, filter);
556 const std::shared_ptr<const DlColorFilter>& filter) {
558 layer_state_stack_->push_color_filter(bounds, filter);
564 const std::shared_ptr<DlImageFilter>& filter,
566 std::optional<int64_t> backdrop_id) {
567 layer_state_stack_->push_backdrop(bounds, filter, blend_mode, backdrop_id);
571 if (!(tx == 0 && ty == 0)) {
572 layer_state_stack_->maybe_save_layer_for_transform(save_needed_);
573 save_needed_ =
false;
574 layer_state_stack_->push_translate(tx, ty);
582 layer_state_stack_->maybe_save_layer_for_transform(save_needed_);
583 save_needed_ =
false;
584 layer_state_stack_->push_transform(
matrix);
589 layer_state_stack_->maybe_save_layer_for_transform(save_needed_);
590 save_needed_ =
false;
591 layer_state_stack_->push_integral_transform();
595 layer_state_stack_->maybe_save_layer_for_clip(save_needed_);
596 save_needed_ =
false;
597 layer_state_stack_->push_clip_rect(rect, is_aa);
601 layer_state_stack_->maybe_save_layer_for_clip(save_needed_);
602 save_needed_ =
false;
603 layer_state_stack_->push_clip_rrect(rrect, is_aa);
608 layer_state_stack_->maybe_save_layer_for_clip(save_needed_);
609 save_needed_ =
false;
610 layer_state_stack_->push_clip_rsuperellipse(rse, is_aa);
614 layer_state_stack_->maybe_save_layer_for_clip(save_needed_);
615 save_needed_ =
false;
616 layer_state_stack_->push_clip_path(
path, is_aa);
626 delegate_->decommission();
632 if (canvas == delegate_->canvas()) {
638 delegate_ = std::make_shared<DlCanvasDelegate>(canvas);
652 delegate_ = std::make_shared<PrerollDelegate>(cull_rect,
matrix);
656void LayerStateStack::reapply_all() {
662 RenderingAttributes attributes = outstanding_;
664 for (
auto& state : state_stack_) {
665 state->reapply(
this);
671 for (
auto& state : state_stack_) {
672 state->update_mutators(mutators);
676void LayerStateStack::restore_to_count(
size_t restore_count) {
677 while (state_stack_.size() > restore_count) {
678 state_stack_.back()->restore(
this);
679 state_stack_.pop_back();
683void LayerStateStack::push_opacity(
const DlRect& bounds,
DlScalar opacity) {
684 maybe_save_layer(opacity);
685 state_stack_.emplace_back(
686 std::make_unique<OpacityEntry>(bounds, opacity, outstanding_));
690void LayerStateStack::push_color_filter(
692 const std::shared_ptr<const DlColorFilter>& filter) {
693 maybe_save_layer(filter);
694 state_stack_.emplace_back(
695 std::make_unique<ColorFilterEntry>(bounds, filter, outstanding_));
699void LayerStateStack::push_image_filter(
701 const std::shared_ptr<DlImageFilter>& filter) {
702 maybe_save_layer(filter);
703 state_stack_.emplace_back(
704 std::make_unique<ImageFilterEntry>(bounds, filter, outstanding_));
708void LayerStateStack::push_backdrop(
710 const std::shared_ptr<DlImageFilter>& filter,
712 std::optional<int64_t> backdrop_id) {
713 state_stack_.emplace_back(std::make_unique<BackdropFilterEntry>(
714 bounds, filter, blend_mode, backdrop_id, outstanding_));
718void LayerStateStack::push_translate(SkScalar tx, SkScalar ty) {
719 state_stack_.emplace_back(std::make_unique<TranslateEntry>(tx, ty));
723void LayerStateStack::push_transform(
const DlMatrix& matrix) {
724 state_stack_.emplace_back(std::make_unique<TransformMatrixEntry>(
matrix));
728void LayerStateStack::push_integral_transform() {
729 state_stack_.emplace_back(std::make_unique<IntegralTransformEntry>());
733void LayerStateStack::push_clip_rect(
const DlRect& rect,
bool is_aa) {
734 state_stack_.emplace_back(std::make_unique<ClipRectEntry>(rect, is_aa));
738void LayerStateStack::push_clip_rrect(
const DlRoundRect& rrect,
bool is_aa) {
739 state_stack_.emplace_back(std::make_unique<ClipRRectEntry>(rrect, is_aa));
745 state_stack_.emplace_back(
746 std::make_unique<ClipRSuperellipseEntry>(rse, is_aa));
750void LayerStateStack::push_clip_path(
const DlPath&
path,
bool is_aa) {
751 state_stack_.emplace_back(std::make_unique<ClipPathEntry>(
path, is_aa));
755bool LayerStateStack::needs_save_layer(
int flags)
const {
756 if (outstanding_.opacity < SK_Scalar1 &&
760 if (outstanding_.image_filter &&
764 if (outstanding_.color_filter &&
771void LayerStateStack::do_save() {
772 state_stack_.emplace_back(std::make_unique<SaveEntry>());
776void LayerStateStack::save_layer(
const DlRect& bounds) {
777 state_stack_.emplace_back(std::make_unique<SaveLayerEntry>(
778 bounds, DlBlendMode::kSrcOver, outstanding_));
782void LayerStateStack::maybe_save_layer_for_transform(
bool save_needed) {
784 if (outstanding_.image_filter) {
785 save_layer(outstanding_.save_layer_bounds);
786 }
else if (save_needed) {
791void LayerStateStack::maybe_save_layer_for_clip(
bool save_needed) {
795 if (outstanding_.image_filter) {
796 save_layer(outstanding_.save_layer_bounds);
797 }
else if (save_needed) {
802void LayerStateStack::maybe_save_layer(
int apply_flags) {
803 if (needs_save_layer(apply_flags)) {
804 save_layer(outstanding_.save_layer_bounds);
808void LayerStateStack::maybe_save_layer(SkScalar opacity) {
809 if (outstanding_.image_filter) {
810 save_layer(outstanding_.save_layer_bounds);
814void LayerStateStack::maybe_save_layer(
815 const std::shared_ptr<const DlColorFilter>& filter) {
816 if (outstanding_.color_filter || outstanding_.image_filter ||
817 (outstanding_.opacity < SK_Scalar1 &&
818 !filter->can_commute_with_opacity())) {
820 save_layer(outstanding_.save_layer_bounds);
824void LayerStateStack::maybe_save_layer(
825 const std::shared_ptr<DlImageFilter>& filter) {
826 if (outstanding_.image_filter) {
828 save_layer(outstanding_.save_layer_bounds);
BackdropFilterEntry(const DlRect &bounds, const std::shared_ptr< DlImageFilter > &filter, DlBlendMode blend_mode, std::optional< int64_t > backdrop_id, const LayerStateStack::RenderingAttributes &prev)
void apply(LayerStateStack *stack) const override
~BackdropFilterEntry() override=default
void reapply(LayerStateStack *stack) const override
void apply(LayerStateStack *stack) const override
void update_mutators(MutatorsStack *mutators_stack) const override
~ClipPathEntry() override=default
ClipPathEntry(const DlPath &clip_path, bool is_aa)
ClipRRectEntry(const DlRoundRect &clip_rrect, bool is_aa)
void apply(LayerStateStack *stack) const override
void update_mutators(MutatorsStack *mutators_stack) const override
ClipRSuperellipseEntry(const DlRoundSuperellipse &clip_rsuperellipse, bool is_aa)
void apply(LayerStateStack *stack) const override
void update_mutators(MutatorsStack *mutators_stack) const override
ClipRectEntry(const DlRect &clip_rect, bool is_aa)
void update_mutators(MutatorsStack *mutators_stack) const override
void apply(LayerStateStack *stack) const override
ColorFilterEntry(const DlRect &bounds, const std::shared_ptr< const DlColorFilter > &filter, const LayerStateStack::RenderingAttributes &prev)
void restore(LayerStateStack *stack) const override
~ColorFilterEntry() override=default
void apply(LayerStateStack *stack) const override
void translate(DlScalar tx, DlScalar ty)
DlRect GetDeviceCullCoverage() const
void clipRect(const DlRect &rect, DlClipOp op, bool is_aa)
const DlMatrix & matrix() const
void clipRRect(const DlRoundRect &rrect, DlClipOp op, bool is_aa)
void clipRSuperellipse(const DlRoundSuperellipse &rse, DlClipOp op, bool is_aa)
void setTransform(const DlMatrix &matrix)
bool content_culled(const DlRect &content_bounds) const
void transform(const DlMatrix &matrix)
void clipPath(const DlPath &path, DlClipOp op, bool is_aa)
DlRect GetLocalCullCoverage() const
void saveLayer(const DlRect &bounds, LayerStateStack::RenderingAttributes &attributes, DlBlendMode blend_mode, const DlImageFilter *backdrop, std::optional< int64_t > backdrop_id) override
void clipPath(const DlPath &path, DlClipOp op, bool is_aa) override
DlRect device_cull_rect() const override
void integralTransform() override
void clipRRect(const DlRoundRect &rrect, DlClipOp op, bool is_aa) override
bool content_culled(const DlRect &content_bounds) const override
DlCanvasDelegate(DlCanvas *canvas)
void clipRect(const DlRect &rect, DlClipOp op, bool is_aa) override
DlCanvas * canvas() const override
DlMatrix matrix() const override
DlRect local_cull_rect() const override
void decommission() override
void translate(DlScalar tx, DlScalar ty) override
void clipRSuperellipse(const DlRoundSuperellipse &rse, DlClipOp op, bool is_aa) override
void transform(const DlMatrix &matrix) override
Developer-facing API for rendering anything within the engine.
virtual void Transform(const DlMatrix &matrix)=0
virtual void ClipRoundSuperellipse(const DlRoundSuperellipse &rse, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)=0
virtual void ClipRect(const DlRect &rect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)=0
virtual void ClipRoundRect(const DlRoundRect &rrect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)=0
virtual DlRect GetDestinationClipCoverage() const =0
virtual DlRect GetLocalClipCoverage() const =0
virtual bool QuickReject(const DlRect &bounds) const =0
virtual void SaveLayer(const std::optional< DlRect > &bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt)=0
virtual void SetTransform(const DlMatrix &matrix)=0
virtual void Translate(DlScalar tx, DlScalar ty)=0
virtual DlMatrix GetMatrix() const =0
virtual void RestoreToCount(int restore_count)=0
virtual void ClipPath(const DlPath &path, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)=0
DlPaint & setBlendMode(DlBlendMode mode)
DlPaint & setImageFilter(std::nullptr_t filter)
DlPaint & setOpacity(DlScalar opacity)
DlPaint & setColorFilter(std::nullptr_t filter)
static const std::shared_ptr< DummyDelegate > kInstance
void clipRSuperellipse(const DlRoundSuperellipse &rse, DlClipOp op, bool is_aa) override
void saveLayer(const DlRect &bounds, LayerStateStack::RenderingAttributes &attributes, DlBlendMode blend, const DlImageFilter *backdrop, std::optional< int64_t > backdrop_id) override
void integralTransform() override
void decommission() override
void translate(DlScalar tx, DlScalar ty) override
DlRect local_cull_rect() const override
DlMatrix matrix() const override
void transform(const DlMatrix &matrix) override
void clipRRect(const DlRoundRect &rrect, DlClipOp op, bool is_aa) override
void clipPath(const DlPath &path, DlClipOp op, bool is_aa) override
bool content_culled(const DlRect &content_bounds) const override
void clipRect(const DlRect &rect, DlClipOp op, bool is_aa) override
DlRect device_cull_rect() const override
~ImageFilterEntry() override=default
void apply(LayerStateStack *stack) const override
void restore(LayerStateStack *stack) const override
ImageFilterEntry(const DlRect &bounds, const std::shared_ptr< DlImageFilter > &filter, const LayerStateStack::RenderingAttributes &prev)
void apply(LayerStateStack *stack) const override
IntegralTransformEntry()=default
void applyColorFilter(const DlRect &bounds, const std::shared_ptr< const DlColorFilter > &filter)
void clipPath(const DlPath &path, bool is_aa)
void clipRSuperellipse(const DlRoundSuperellipse &rse, bool is_aa)
void saveLayer(const DlRect &bounds)
void translate(DlScalar tx, DlScalar ty)
void clipRRect(const DlRoundRect &rrect, bool is_aa)
void applyOpacity(const DlRect &bounds, DlScalar opacity)
void clipRect(const DlRect &rect, bool is_aa)
void transform(const DlMatrix &matrix)
void applyBackdropFilter(const DlRect &bounds, const std::shared_ptr< DlImageFilter > &filter, DlBlendMode blend_mode, std::optional< int64_t > backdrop_id)
void applyImageFilter(const DlRect &bounds, const std::shared_ptr< DlImageFilter > &filter)
void fill(MutatorsStack *mutators)
static constexpr int kCallerCanApplyColorFilter
void set_delegate(DlCanvas *canvas)
void set_preroll_delegate(const DlRect &cull_rect, const DlMatrix &matrix)
static constexpr int kCallerCanApplyImageFilter
const DlMatrix matrix() const
static constexpr int kCallerCanApplyOpacity
void PushTransform(const DlMatrix &matrix)
void PushClipRect(const DlRect &rect)
void PushClipPath(const DlPath &path)
void PushClipRRect(const DlRoundRect &rrect)
void PushOpacity(const uint8_t &alpha)
void PushClipRSE(const DlRoundSuperellipse &rrect)
void update_mutators(MutatorsStack *mutators_stack) const override
void restore(LayerStateStack *stack) const override
void apply(LayerStateStack *stack) const override
OpacityEntry(const DlRect &bounds, DlScalar opacity, const LayerStateStack::RenderingAttributes &prev)
DlRect device_cull_rect() const override
DlMatrix matrix() const override
void transform(const DlMatrix &matrix) override
PrerollDelegate(const DlRect &cull_rect, const DlMatrix &matrix)
bool content_culled(const DlRect &content_bounds) const override
void translate(DlScalar tx, DlScalar ty) override
void integralTransform() override
DlRect local_cull_rect() const override
void clipRRect(const DlRoundRect &rrect, DlClipOp op, bool is_aa) override
void saveLayer(const DlRect &bounds, LayerStateStack::RenderingAttributes &attributes, DlBlendMode blend, const DlImageFilter *backdrop, std::optional< int64_t > backdrop_id) override
void decommission() override
void clipPath(const DlPath &path, DlClipOp op, bool is_aa) override
void clipRSuperellipse(const DlRoundSuperellipse &rse, DlClipOp op, bool is_aa) override
void clipRect(const DlRect &rect, DlClipOp op, bool is_aa) override
FML_DISALLOW_COPY_ASSIGN_AND_MOVE(SaveEntry)
void apply(LayerStateStack *stack) const override
void restore(LayerStateStack *stack) const override
const LayerStateStack::RenderingAttributes old_attributes_
void apply(LayerStateStack *stack) const override
void restore(LayerStateStack *stack) const override
SaveLayerEntry(const DlRect &bounds, DlBlendMode blend_mode, const LayerStateStack::RenderingAttributes &prev)
FML_DISALLOW_COPY_ASSIGN_AND_MOVE(SaveLayerEntry)
const DlBlendMode blend_mode_
TransformMatrixEntry(const DlMatrix &matrix)
void update_mutators(MutatorsStack *mutators_stack) const override
void apply(LayerStateStack *stack) const override
void apply(LayerStateStack *stack) const override
void update_mutators(MutatorsStack *mutators_stack) const override
TranslateEntry(DlScalar tx, DlScalar ty)
#define FML_DCHECK(condition)
#define FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName)
impeller::Scalar DlScalar
impeller::RoundRect DlRoundRect
impeller::Matrix DlMatrix
impeller::RoundSuperellipse DlRoundSuperellipse
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
static constexpr DlRect kGiantRect
impeller::BlendMode DlBlendMode
static uint8_t toAlpha(DlScalar opacity)
static bool ComputeIntegralTransCTM(const SkMatrix &in, SkMatrix *out)
Snap the translation components of the |in| matrix to integers and store the snapped matrix in |out|.
A 4x4 matrix using column-major storage.
constexpr bool IsTranslationOnly() const
Returns true if the matrix has no entries other than translation components. Note that an identity ma...
static constexpr Matrix MakeTranslation(const Vector3 &t)
constexpr bool IsIdentity() const
#define TRACE_EVENT0(category_group, name)