5#include "flutter/flow/layers/layer_state_stack.h"
7#include "flutter/display_list/utils/dl_matrix_clip_tracker.h"
8#include "flutter/flow/layers/layer.h"
9#include "flutter/flow/paint_utils.h"
10#include "flutter/flow/raster_cache_util.h"
26 static const std::shared_ptr<DummyDelegate>
kInstance;
53 LayerStateStack::RenderingAttributes& attributes,
69 FML_DCHECK(
false) <<
"LayerStateStack state queried without a delegate";
73 std::make_shared<DummyDelegate>();
78 : canvas_(
canvas), initial_save_level_(
canvas->GetSaveCount()) {}
100 LayerStateStack::RenderingAttributes& attributes,
105 canvas_->
SaveLayer(&bounds, attributes.fill(
paint, blend_mode), backdrop);
135 const int initial_save_level_;
141 : tracker_(cull_rect, matrix) {}
157 LayerStateStack::RenderingAttributes& attributes,
210 stack->delegate_->save();
213 stack->delegate_->restore();
223 const LayerStateStack::RenderingAttributes&
prev)
229 stack->outstanding_ = {};
232 if (stack->checkerboard_func_) {
234 if (canvas !=
nullptr) {
235 (*stack->checkerboard_func_)(canvas,
bounds_);
238 stack->delegate_->restore();
254 const LayerStateStack::RenderingAttributes&
prev)
257 old_opacity_(
prev.opacity),
258 old_bounds_(
prev.save_layer_bounds) {}
261 stack->outstanding_.save_layer_bounds = bounds_;
262 stack->outstanding_.opacity *= opacity_;
265 stack->outstanding_.save_layer_bounds = old_bounds_;
266 stack->outstanding_.opacity = old_opacity_;
284 const std::shared_ptr<const DlImageFilter>& filter,
285 const LayerStateStack::RenderingAttributes&
prev)
288 old_filter_(
prev.image_filter),
289 old_bounds_(
prev.save_layer_bounds) {}
293 stack->outstanding_.save_layer_bounds = bounds_;
294 stack->outstanding_.image_filter = filter_;
297 stack->outstanding_.save_layer_bounds = old_bounds_;
298 stack->outstanding_.image_filter = old_filter_;
306 const std::shared_ptr<const DlImageFilter> filter_;
307 const std::shared_ptr<const DlImageFilter> old_filter_;
316 const std::shared_ptr<const DlColorFilter>& filter,
317 const LayerStateStack::RenderingAttributes&
prev)
321 old_bounds_(
prev.save_layer_bounds) {}
325 stack->outstanding_.save_layer_bounds = bounds_;
326 stack->outstanding_.color_filter = filter_;
329 stack->outstanding_.save_layer_bounds = old_bounds_;
330 stack->outstanding_.color_filter = old_filter_;
338 const std::shared_ptr<const DlColorFilter> filter_;
339 const std::shared_ptr<const DlColorFilter> old_filter_;
348 const std::shared_ptr<const DlImageFilter>& filter,
350 const LayerStateStack::RenderingAttributes&
prev)
357 stack->outstanding_ = {};
372 const std::shared_ptr<const DlImageFilter> filter_;
382 stack->delegate_->translate(tx_, ty_);
400 stack->delegate_->transform(matrix_);
417 stack->delegate_->transform(m44_);
434 stack->delegate_->integralTransform();
444 : clip_rect_(clip_rect), is_aa_(is_aa) {}
464 : clip_rrect_(clip_rrect), is_aa_(is_aa) {}
484 : clip_path_(clip_path), is_aa_(is_aa) {}
506DlPaint* LayerStateStack::RenderingAttributes::fill(DlPaint&
paint,
508 DlPaint* ret =
nullptr;
510 paint.setOpacity(std::max(opacity, 0.0f));
519 paint.setImageFilter(image_filter);
537 layer_state_stack_->save_layer(bounds);
542 layer_state_stack_->push_opacity(bounds, opacity);
548 const std::shared_ptr<const 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<const DlImageFilter>& filter,
566 layer_state_stack_->push_backdrop(bounds, filter, blend_mode);
570 if (!(tx == 0 && ty == 0)) {
571 layer_state_stack_->maybe_save_layer_for_transform(save_needed_);
572 save_needed_ =
false;
573 layer_state_stack_->push_translate(tx, ty);
578 if (matrix.isTranslate()) {
579 translate(matrix.getTranslateX(), matrix.getTranslateY());
580 }
else if (!matrix.isIdentity()) {
581 layer_state_stack_->maybe_save_layer_for_transform(save_needed_);
582 save_needed_ =
false;
583 layer_state_stack_->push_transform(matrix);
591 layer_state_stack_->maybe_save_layer_for_transform(save_needed_);
592 save_needed_ =
false;
593 layer_state_stack_->push_transform(m44);
598 layer_state_stack_->maybe_save_layer_for_transform(save_needed_);
599 save_needed_ =
false;
600 layer_state_stack_->push_integral_transform();
604 layer_state_stack_->maybe_save_layer_for_clip(save_needed_);
605 save_needed_ =
false;
606 layer_state_stack_->push_clip_rect(rect, is_aa);
610 layer_state_stack_->maybe_save_layer_for_clip(save_needed_);
611 save_needed_ =
false;
612 layer_state_stack_->push_clip_rrect(rrect, is_aa);
616 layer_state_stack_->maybe_save_layer_for_clip(save_needed_);
617 save_needed_ =
false;
618 layer_state_stack_->push_clip_path(
path, is_aa);
628 delegate_->decommission();
634 if (canvas == delegate_->canvas()) {
640 delegate_ = std::make_shared<DlCanvasDelegate>(canvas);
654 delegate_ = std::make_shared<PrerollDelegate>(cull_rect, matrix);
658void LayerStateStack::reapply_all() {
664 RenderingAttributes attributes = outstanding_;
666 for (
auto&
state : state_stack_) {
667 state->reapply(
this);
673 for (
auto&
state : state_stack_) {
674 state->update_mutators(mutators);
678void LayerStateStack::restore_to_count(
size_t restore_count) {
679 while (state_stack_.size() > restore_count) {
680 state_stack_.back()->restore(
this);
681 state_stack_.pop_back();
685void LayerStateStack::push_opacity(
const SkRect& bounds,
SkScalar opacity) {
686 maybe_save_layer(opacity);
687 state_stack_.emplace_back(
688 std::make_unique<OpacityEntry>(bounds, opacity, outstanding_));
692void LayerStateStack::push_color_filter(
694 const std::shared_ptr<const DlColorFilter>& filter) {
695 maybe_save_layer(filter);
696 state_stack_.emplace_back(
697 std::make_unique<ColorFilterEntry>(bounds, filter, outstanding_));
701void LayerStateStack::push_image_filter(
703 const std::shared_ptr<const DlImageFilter>& filter) {
704 maybe_save_layer(filter);
705 state_stack_.emplace_back(
706 std::make_unique<ImageFilterEntry>(bounds, filter, outstanding_));
710void LayerStateStack::push_backdrop(
712 const std::shared_ptr<const DlImageFilter>& filter,
714 state_stack_.emplace_back(std::make_unique<BackdropFilterEntry>(
715 bounds, filter, blend_mode, outstanding_));
720 state_stack_.emplace_back(std::make_unique<TranslateEntry>(tx, ty));
724void LayerStateStack::push_transform(
const SkM44& m44) {
725 state_stack_.emplace_back(std::make_unique<TransformM44Entry>(m44));
729void LayerStateStack::push_transform(
const SkMatrix& matrix) {
730 state_stack_.emplace_back(std::make_unique<TransformMatrixEntry>(matrix));
734void LayerStateStack::push_integral_transform() {
735 state_stack_.emplace_back(std::make_unique<IntegralTransformEntry>());
739void LayerStateStack::push_clip_rect(
const SkRect& rect,
bool is_aa) {
740 state_stack_.emplace_back(std::make_unique<ClipRectEntry>(rect, is_aa));
744void LayerStateStack::push_clip_rrect(
const SkRRect& rrect,
bool is_aa) {
745 state_stack_.emplace_back(std::make_unique<ClipRRectEntry>(rrect, is_aa));
749void LayerStateStack::push_clip_path(
const SkPath&
path,
bool is_aa) {
750 state_stack_.emplace_back(std::make_unique<ClipPathEntry>(
path, is_aa));
754bool LayerStateStack::needs_save_layer(
int flags)
const {
759 if (outstanding_.image_filter &&
763 if (outstanding_.color_filter &&
770void LayerStateStack::do_save() {
771 state_stack_.emplace_back(std::make_unique<SaveEntry>());
775void LayerStateStack::save_layer(
const SkRect& bounds) {
776 state_stack_.emplace_back(std::make_unique<SaveLayerEntry>(
781void LayerStateStack::maybe_save_layer_for_transform(
bool save_needed) {
783 if (outstanding_.image_filter) {
784 save_layer(outstanding_.save_layer_bounds);
785 }
else if (save_needed) {
790void LayerStateStack::maybe_save_layer_for_clip(
bool save_needed) {
794 if (outstanding_.image_filter) {
795 save_layer(outstanding_.save_layer_bounds);
796 }
else if (save_needed) {
801void LayerStateStack::maybe_save_layer(
int apply_flags) {
803 save_layer(outstanding_.save_layer_bounds);
807void LayerStateStack::maybe_save_layer(
SkScalar opacity) {
808 if (outstanding_.image_filter) {
809 save_layer(outstanding_.save_layer_bounds);
813void LayerStateStack::maybe_save_layer(
814 const std::shared_ptr<const DlColorFilter>& filter) {
815 if (outstanding_.color_filter || outstanding_.image_filter ||
817 !filter->can_commute_with_opacity())) {
819 save_layer(outstanding_.save_layer_bounds);
823void LayerStateStack::maybe_save_layer(
824 const std::shared_ptr<const DlImageFilter>& filter) {
825 if (outstanding_.image_filter) {
827 save_layer(outstanding_.save_layer_bounds);
static void apply_flags(SkFont *font, unsigned flags)
static float prev(float f)
static sk_sp< SkImage > color_filter(const SkImage *image, SkColorFilter *colorFilter)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
static const SkMatrix & I()
void apply(LayerStateStack *stack) const override
~BackdropFilterEntry() override=default
BackdropFilterEntry(const SkRect &bounds, const std::shared_ptr< const DlImageFilter > &filter, DlBlendMode blend_mode, const LayerStateStack::RenderingAttributes &prev)
void reapply(LayerStateStack *stack) const override
ClipPathEntry(const SkPath &clip_path, bool is_aa)
void apply(LayerStateStack *stack) const override
void update_mutators(MutatorsStack *mutators_stack) const override
~ClipPathEntry() override=default
void apply(LayerStateStack *stack) const override
void update_mutators(MutatorsStack *mutators_stack) const override
ClipRRectEntry(const SkRRect &clip_rrect, bool is_aa)
ClipRectEntry(const SkRect &clip_rect, bool is_aa)
void update_mutators(MutatorsStack *mutators_stack) const override
void apply(LayerStateStack *stack) const override
void restore(LayerStateStack *stack) const override
~ColorFilterEntry() override=default
void apply(LayerStateStack *stack) const override
ColorFilterEntry(const SkRect &bounds, const std::shared_ptr< const DlColorFilter > &filter, const LayerStateStack::RenderingAttributes &prev)
void clipRect(const DlRect &rect, ClipOp op, bool is_aa)
bool using_4x4_matrix() const
SkRect local_cull_rect() const
SkRect device_cull_rect() const
static bool is_3x3(const SkM44 &m44)
void clipPath(const SkPath &path, ClipOp op, bool is_aa)
void transform(const DlMatrix &matrix)
void translate(SkScalar tx, SkScalar ty)
void clipRRect(const SkRRect &rrect, ClipOp op, bool is_aa)
void setTransform(const DlMatrix &matrix)
SkMatrix matrix_3x3() const
bool content_culled(const SkRect &content_bounds) const
void saveLayer(const SkRect &bounds, LayerStateStack::RenderingAttributes &attributes, DlBlendMode blend_mode, const DlImageFilter *backdrop) override
void integralTransform() override
void clipPath(const SkPath &path, ClipOp op, bool is_aa) override
SkRect local_cull_rect() const override
SkM44 matrix_4x4() const override
DlCanvasDelegate(DlCanvas *canvas)
void transform(const SkMatrix &matrix) override
void clipRRect(const SkRRect &rrect, ClipOp op, bool is_aa) override
void transform(const SkM44 &m44) override
bool content_culled(const SkRect &content_bounds) const override
SkMatrix matrix_3x3() const override
DlCanvas * canvas() const override
void translate(SkScalar tx, SkScalar ty) override
void clipRect(const SkRect &rect, ClipOp op, bool is_aa) override
void decommission() override
SkRect device_cull_rect() const override
Developer-facing API for rendering anything within the engine.
virtual void Transform(const SkMatrix *matrix)=0
virtual void ClipRect(const SkRect &rect, ClipOp clip_op=ClipOp::kIntersect, bool is_aa=false)=0
virtual SkM44 GetTransformFullPerspective() const =0
virtual void SetTransform(const SkMatrix *matrix)=0
virtual SkRect GetDestinationClipBounds() const =0
virtual void SaveLayer(const SkRect *bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr)=0
virtual SkRect GetLocalClipBounds() const =0
virtual bool QuickReject(const SkRect &bounds) const =0
virtual void RestoreToCount(int restore_count)=0
virtual void Translate(SkScalar tx, SkScalar ty)=0
virtual SkMatrix GetTransform() const =0
virtual void ClipPath(const SkPath &path, ClipOp clip_op=ClipOp::kIntersect, bool is_aa=false)=0
virtual void ClipRRect(const SkRRect &rrect, ClipOp clip_op=ClipOp::kIntersect, bool is_aa=false)=0
bool content_culled(const SkRect &content_bounds) const override
static const std::shared_ptr< DummyDelegate > kInstance
SkM44 matrix_4x4() const override
void clipRRect(const SkRRect &rrect, ClipOp op, bool is_aa) override
void integralTransform() override
void decommission() override
void saveLayer(const SkRect &bounds, LayerStateStack::RenderingAttributes &attributes, DlBlendMode blend, const DlImageFilter *backdrop) override
SkRect local_cull_rect() const override
void clipPath(const SkPath &path, ClipOp op, bool is_aa) override
void transform(const SkM44 &m44) override
SkRect device_cull_rect() const override
void translate(SkScalar tx, SkScalar ty) override
void clipRect(const SkRect &rect, ClipOp op, bool is_aa) override
SkMatrix matrix_3x3() const override
void transform(const SkMatrix &matrix) override
~ImageFilterEntry() override=default
void apply(LayerStateStack *stack) const override
void restore(LayerStateStack *stack) const override
ImageFilterEntry(const SkRect &bounds, const std::shared_ptr< const DlImageFilter > &filter, const LayerStateStack::RenderingAttributes &prev)
void apply(LayerStateStack *stack) const override
IntegralTransformEntry()=default
void applyColorFilter(const SkRect &bounds, const std::shared_ptr< const DlColorFilter > &filter)
void translate(SkScalar tx, SkScalar ty)
void applyImageFilter(const SkRect &bounds, const std::shared_ptr< const DlImageFilter > &filter)
void clipPath(const SkPath &path, bool is_aa)
void applyBackdropFilter(const SkRect &bounds, const std::shared_ptr< const DlImageFilter > &filter, DlBlendMode blend_mode)
void clipRRect(const SkRRect &rrect, bool is_aa)
void clipRect(const SkRect &rect, bool is_aa)
void applyOpacity(const SkRect &bounds, SkScalar opacity)
void saveLayer(const SkRect &bounds)
void transform(const SkM44 &m44)
void fill(MutatorsStack *mutators)
DlCanvas * canvas_delegate()
void set_preroll_delegate(const SkRect &cull_rect, const SkMatrix &matrix)
static constexpr int kCallerCanApplyColorFilter
void set_delegate(DlCanvas *canvas)
static constexpr int kCallerCanApplyImageFilter
static constexpr int kCallerCanApplyOpacity
void update_mutators(MutatorsStack *mutators_stack) const override
void restore(LayerStateStack *stack) const override
OpacityEntry(const SkRect &bounds, SkScalar opacity, const LayerStateStack::RenderingAttributes &prev)
void apply(LayerStateStack *stack) const override
void clipRect(const SkRect &rect, ClipOp op, bool is_aa) override
SkMatrix matrix_3x3() const override
void clipRRect(const SkRRect &rrect, ClipOp op, bool is_aa) override
bool content_culled(const SkRect &content_bounds) const override
void clipPath(const SkPath &path, ClipOp op, bool is_aa) override
void saveLayer(const SkRect &bounds, LayerStateStack::RenderingAttributes &attributes, DlBlendMode blend, const DlImageFilter *backdrop) override
void integralTransform() override
SkRect device_cull_rect() const override
SkRect local_cull_rect() const override
void transform(const SkMatrix &matrix) override
void transform(const SkM44 &m44) override
void decommission() override
SkM44 matrix_4x4() const override
void translate(SkScalar tx, SkScalar ty) override
PrerollDelegate(const SkRect &cull_rect, const SkMatrix &matrix)
FML_DISALLOW_COPY_ASSIGN_AND_MOVE(SaveEntry)
void apply(LayerStateStack *stack) const override
void restore(LayerStateStack *stack) const override
const LayerStateStack::RenderingAttributes old_attributes_
SaveLayerEntry(const SkRect &bounds, DlBlendMode blend_mode, const LayerStateStack::RenderingAttributes &prev)
void apply(LayerStateStack *stack) const override
void restore(LayerStateStack *stack) const override
FML_DISALLOW_COPY_ASSIGN_AND_MOVE(SaveLayerEntry)
const DlBlendMode blend_mode_
TransformM44Entry(const SkM44 &m44)
void apply(LayerStateStack *stack) const override
void update_mutators(MutatorsStack *mutators_stack) const override
void update_mutators(MutatorsStack *mutators_stack) const override
TransformMatrixEntry(const SkMatrix &matrix)
void apply(LayerStateStack *stack) const override
void apply(LayerStateStack *stack) const override
void update_mutators(MutatorsStack *mutators_stack) const override
TranslateEntry(SkScalar tx, SkScalar ty)
FlutterSemanticsFlag flags
#define FML_DCHECK(condition)
#define FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName)
static SkColor blend(SkColor dst, SkColor src, void(*mode)(float, float, float, float *, float *, float *))
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
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
static constexpr SkRect kGiantRect
@ kSrcOver
r = s + (1-sa)*d
static constexpr uint8_t toAlpha(SkScalar 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|.
#define TRACE_EVENT0(category_group, name)