// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/flow/layers/layer_state_stack.h"

#include "flutter/display_list/display_list_matrix_clip_tracker.h"
#include "flutter/flow/layers/layer.h"
#include "flutter/flow/paint_utils.h"
#include "flutter/flow/raster_cache_util.h"

namespace flutter {

// ==============================================================
// Delegate subclasses
// ==============================================================

// The DummyDelegate class implements most Delegate methods as NOP
// but throws errors if the caller starts executing query methods
// that require an active delegate to be tracking. It is specifically
// designed to be immutable, lightweight, and a singleton so that it
// can be substituted into the delegate slot in a LayerStateStack
// quickly and cheaply when no externally supplied delegates are present.
class DummyDelegate : public LayerStateStack::Delegate {
 public:
  static const std::shared_ptr<DummyDelegate> kInstance;

  void decommission() override {}

  SkRect local_cull_rect() const override {
    error();
    return {};
  }
  SkRect device_cull_rect() const override {
    error();
    return {};
  }
  SkM44 matrix_4x4() const override {
    error();
    return {};
  }
  SkMatrix matrix_3x3() const override {
    error();
    return {};
  }
  bool content_culled(const SkRect& content_bounds) const override {
    error();
    return true;
  }

  void save() override {}
  void saveLayer(const SkRect& bounds,
                 LayerStateStack::RenderingAttributes& attributes,
                 DlBlendMode blend,
                 const DlImageFilter* backdrop) override {}
  void restore() override {}

  void translate(SkScalar tx, SkScalar ty) override {}
  void transform(const SkM44& m44) override {}
  void transform(const SkMatrix& matrix) override {}
  void integralTransform() override {}

  void clipRect(const SkRect& rect, ClipOp op, bool is_aa) override {}
  void clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) override {}
  void clipPath(const SkPath& path, ClipOp op, bool is_aa) override {}

 private:
  static void error() {
    FML_DCHECK(false) << "LayerStateStack state queried without a delegate";
  }
};
const std::shared_ptr<DummyDelegate> DummyDelegate::kInstance =
    std::make_shared<DummyDelegate>();

class DlCanvasDelegate : public LayerStateStack::Delegate {
 public:
  explicit DlCanvasDelegate(DlCanvas* canvas)
      : canvas_(canvas), initial_save_level_(canvas->GetSaveCount()) {}

  void decommission() override { canvas_->RestoreToCount(initial_save_level_); }

  DlCanvas* canvas() const override { return canvas_; }

  SkRect local_cull_rect() const override {
    return canvas_->GetLocalClipBounds();
  }
  SkRect device_cull_rect() const override {
    return canvas_->GetDestinationClipBounds();
  }
  SkM44 matrix_4x4() const override {
    return canvas_->GetTransformFullPerspective();
  }
  SkMatrix matrix_3x3() const override { return canvas_->GetTransform(); }
  bool content_culled(const SkRect& content_bounds) const override {
    return canvas_->QuickReject(content_bounds);
  }

  void save() override { canvas_->Save(); }
  void saveLayer(const SkRect& bounds,
                 LayerStateStack::RenderingAttributes& attributes,
                 DlBlendMode blend_mode,
                 const DlImageFilter* backdrop) override {
    TRACE_EVENT0("flutter", "Canvas::saveLayer");
    DlPaint paint;
    canvas_->SaveLayer(&bounds, attributes.fill(paint, blend_mode), backdrop);
  }
  void restore() override { canvas_->Restore(); }

  void translate(SkScalar tx, SkScalar ty) override {
    canvas_->Translate(tx, ty);
  }
  void transform(const SkM44& m44) override { canvas_->Transform(m44); }
  void transform(const SkMatrix& matrix) override {
    canvas_->Transform(matrix);
  }
  void integralTransform() override {
    SkM44 matrix = RasterCacheUtil::GetIntegralTransCTM(matrix_4x4());
    canvas_->SetTransform(matrix);
  }

  void clipRect(const SkRect& rect, ClipOp op, bool is_aa) override {
    canvas_->ClipRect(rect, op, is_aa);
  }
  void clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) override {
    canvas_->ClipRRect(rrect, op, is_aa);
  }
  void clipPath(const SkPath& path, ClipOp op, bool is_aa) override {
    canvas_->ClipPath(path, op, is_aa);
  }

 private:
  DlCanvas* canvas_;
  const int initial_save_level_;
};

class PrerollDelegate : public LayerStateStack::Delegate {
 public:
  PrerollDelegate(const SkRect& cull_rect, const SkMatrix& matrix)
      : tracker_(cull_rect, matrix) {}

  void decommission() override {}

  SkM44 matrix_4x4() const override { return tracker_.matrix_4x4(); }
  SkMatrix matrix_3x3() const override { return tracker_.matrix_3x3(); }
  SkRect local_cull_rect() const override { return tracker_.local_cull_rect(); }
  SkRect device_cull_rect() const override {
    return tracker_.device_cull_rect();
  }
  bool content_culled(const SkRect& content_bounds) const override {
    return tracker_.content_culled(content_bounds);
  }

  void save() override { tracker_.save(); }
  void saveLayer(const SkRect& bounds,
                 LayerStateStack::RenderingAttributes& attributes,
                 DlBlendMode blend,
                 const DlImageFilter* backdrop) override {
    tracker_.save();
  }
  void restore() override { tracker_.restore(); }

  void translate(SkScalar tx, SkScalar ty) override {
    tracker_.translate(tx, ty);
  }
  void transform(const SkM44& m44) override { tracker_.transform(m44); }
  void transform(const SkMatrix& matrix) override {
    tracker_.transform(matrix);
  }
  void integralTransform() override {
    if (tracker_.using_4x4_matrix()) {
      tracker_.setTransform(
          RasterCacheUtil::GetIntegralTransCTM(tracker_.matrix_4x4()));
    } else {
      tracker_.setTransform(
          RasterCacheUtil::GetIntegralTransCTM(tracker_.matrix_3x3()));
    }
  }

  void clipRect(const SkRect& rect, ClipOp op, bool is_aa) override {
    tracker_.clipRect(rect, op, is_aa);
  }
  void clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) override {
    tracker_.clipRRect(rrect, op, is_aa);
  }
  void clipPath(const SkPath& path, ClipOp op, bool is_aa) override {
    tracker_.clipPath(path, op, is_aa);
  }

 private:
  DisplayListMatrixClipTracker tracker_;
};

// ==============================================================
// StateEntry subclasses
// ==============================================================

class SaveEntry : public LayerStateStack::StateEntry {
 public:
  SaveEntry() = default;

  void apply(LayerStateStack* stack) const override {
    stack->delegate_->save();
  }
  void restore(LayerStateStack* stack) const override {
    stack->delegate_->restore();
  }

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(SaveEntry);
};

class SaveLayerEntry : public LayerStateStack::StateEntry {
 public:
  SaveLayerEntry(const SkRect& bounds,
                 DlBlendMode blend_mode,
                 const LayerStateStack::RenderingAttributes& prev)
      : bounds_(bounds), blend_mode_(blend_mode), old_attributes_(prev) {}

  void apply(LayerStateStack* stack) const override {
    stack->delegate_->saveLayer(bounds_, stack->outstanding_, blend_mode_,
                                nullptr);
    stack->outstanding_ = {};
  }
  void restore(LayerStateStack* stack) const override {
    if (stack->checkerboard_func_) {
      DlCanvas* canvas = stack->canvas_delegate();
      if (canvas != nullptr) {
        (*stack->checkerboard_func_)(canvas, bounds_);
      }
    }
    stack->delegate_->restore();
    stack->outstanding_ = old_attributes_;
  }

 protected:
  const SkRect bounds_;
  const DlBlendMode blend_mode_;
  const LayerStateStack::RenderingAttributes old_attributes_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(SaveLayerEntry);
};

class OpacityEntry : public LayerStateStack::StateEntry {
 public:
  OpacityEntry(const SkRect& bounds,
               SkScalar opacity,
               const LayerStateStack::RenderingAttributes& prev)
      : bounds_(bounds),
        opacity_(opacity),
        old_opacity_(prev.opacity),
        old_bounds_(prev.save_layer_bounds) {}

  void apply(LayerStateStack* stack) const override {
    stack->outstanding_.save_layer_bounds = bounds_;
    stack->outstanding_.opacity *= opacity_;
  }
  void restore(LayerStateStack* stack) const override {
    stack->outstanding_.save_layer_bounds = old_bounds_;
    stack->outstanding_.opacity = old_opacity_;
  }
  void update_mutators(MutatorsStack* mutators_stack) const override {
    mutators_stack->PushOpacity(DlColor::toAlpha(opacity_));
  }

 private:
  const SkRect bounds_;
  const SkScalar opacity_;
  const SkScalar old_opacity_;
  const SkRect old_bounds_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(OpacityEntry);
};

class ImageFilterEntry : public LayerStateStack::StateEntry {
 public:
  ImageFilterEntry(const SkRect& bounds,
                   const std::shared_ptr<const DlImageFilter>& filter,
                   const LayerStateStack::RenderingAttributes& prev)
      : bounds_(bounds),
        filter_(filter),
        old_filter_(prev.image_filter),
        old_bounds_(prev.save_layer_bounds) {}
  ~ImageFilterEntry() override = default;

  void apply(LayerStateStack* stack) const override {
    stack->outstanding_.save_layer_bounds = bounds_;
    stack->outstanding_.image_filter = filter_;
  }
  void restore(LayerStateStack* stack) const override {
    stack->outstanding_.save_layer_bounds = old_bounds_;
    stack->outstanding_.image_filter = old_filter_;
  }

  // There is no ImageFilter mutator currently
  // void update_mutators(MutatorsStack* mutators_stack) const override;

 private:
  const SkRect bounds_;
  const std::shared_ptr<const DlImageFilter> filter_;
  const std::shared_ptr<const DlImageFilter> old_filter_;
  const SkRect old_bounds_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(ImageFilterEntry);
};

class ColorFilterEntry : public LayerStateStack::StateEntry {
 public:
  ColorFilterEntry(const SkRect& bounds,
                   const std::shared_ptr<const DlColorFilter>& filter,
                   const LayerStateStack::RenderingAttributes& prev)
      : bounds_(bounds),
        filter_(filter),
        old_filter_(prev.color_filter),
        old_bounds_(prev.save_layer_bounds) {}
  ~ColorFilterEntry() override = default;

  void apply(LayerStateStack* stack) const override {
    stack->outstanding_.save_layer_bounds = bounds_;
    stack->outstanding_.color_filter = filter_;
  }
  void restore(LayerStateStack* stack) const override {
    stack->outstanding_.save_layer_bounds = old_bounds_;
    stack->outstanding_.color_filter = old_filter_;
  }

  // There is no ColorFilter mutator currently
  // void update_mutators(MutatorsStack* mutators_stack) const override;

 private:
  const SkRect bounds_;
  const std::shared_ptr<const DlColorFilter> filter_;
  const std::shared_ptr<const DlColorFilter> old_filter_;
  const SkRect old_bounds_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(ColorFilterEntry);
};

class BackdropFilterEntry : public SaveLayerEntry {
 public:
  BackdropFilterEntry(const SkRect& bounds,
                      const std::shared_ptr<const DlImageFilter>& filter,
                      DlBlendMode blend_mode,
                      const LayerStateStack::RenderingAttributes& prev)
      : SaveLayerEntry(bounds, blend_mode, prev), filter_(filter) {}
  ~BackdropFilterEntry() override = default;

  void apply(LayerStateStack* stack) const override {
    stack->delegate_->saveLayer(bounds_, stack->outstanding_, blend_mode_,
                                filter_.get());
    stack->outstanding_ = {};
  }

  void reapply(LayerStateStack* stack) const override {
    // On the reapply for subsequent overlay layers, we do not
    // want to reapply the backdrop filter, but we do need to
    // do a saveLayer to encapsulate the contents and match the
    // restore that will be forthcoming. Note that this is not
    // perfect if the BlendMode is not associative as we will be
    // compositing multiple parts of the content in batches.
    // Luckily the most common SrcOver is associative.
    SaveLayerEntry::apply(stack);
  }

 private:
  const std::shared_ptr<const DlImageFilter> filter_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(BackdropFilterEntry);
};

class TranslateEntry : public LayerStateStack::StateEntry {
 public:
  TranslateEntry(SkScalar tx, SkScalar ty) : tx_(tx), ty_(ty) {}

  void apply(LayerStateStack* stack) const override {
    stack->delegate_->translate(tx_, ty_);
  }
  void update_mutators(MutatorsStack* mutators_stack) const override {
    mutators_stack->PushTransform(SkMatrix::Translate(tx_, ty_));
  }

 private:
  const SkScalar tx_;
  const SkScalar ty_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TranslateEntry);
};

class TransformMatrixEntry : public LayerStateStack::StateEntry {
 public:
  explicit TransformMatrixEntry(const SkMatrix& matrix) : matrix_(matrix) {}

  void apply(LayerStateStack* stack) const override {
    stack->delegate_->transform(matrix_);
  }
  void update_mutators(MutatorsStack* mutators_stack) const override {
    mutators_stack->PushTransform(matrix_);
  }

 private:
  const SkMatrix matrix_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TransformMatrixEntry);
};

class TransformM44Entry : public LayerStateStack::StateEntry {
 public:
  explicit TransformM44Entry(const SkM44& m44) : m44_(m44) {}

  void apply(LayerStateStack* stack) const override {
    stack->delegate_->transform(m44_);
  }
  void update_mutators(MutatorsStack* mutators_stack) const override {
    mutators_stack->PushTransform(m44_.asM33());
  }

 private:
  const SkM44 m44_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TransformM44Entry);
};

class IntegralTransformEntry : public LayerStateStack::StateEntry {
 public:
  IntegralTransformEntry() = default;

  void apply(LayerStateStack* stack) const override {
    stack->delegate_->integralTransform();
  }

 private:
  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(IntegralTransformEntry);
};

class ClipRectEntry : public LayerStateStack::StateEntry {
 public:
  ClipRectEntry(const SkRect& clip_rect, bool is_aa)
      : clip_rect_(clip_rect), is_aa_(is_aa) {}

  void apply(LayerStateStack* stack) const override {
    stack->delegate_->clipRect(clip_rect_, DlCanvas::ClipOp::kIntersect,
                               is_aa_);
  }
  void update_mutators(MutatorsStack* mutators_stack) const override {
    mutators_stack->PushClipRect(clip_rect_);
  }

 private:
  const SkRect clip_rect_;
  const bool is_aa_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(ClipRectEntry);
};

class ClipRRectEntry : public LayerStateStack::StateEntry {
 public:
  ClipRRectEntry(const SkRRect& clip_rrect, bool is_aa)
      : clip_rrect_(clip_rrect), is_aa_(is_aa) {}

  void apply(LayerStateStack* stack) const override {
    stack->delegate_->clipRRect(clip_rrect_, DlCanvas::ClipOp::kIntersect,
                                is_aa_);
  }
  void update_mutators(MutatorsStack* mutators_stack) const override {
    mutators_stack->PushClipRRect(clip_rrect_);
  }

 private:
  const SkRRect clip_rrect_;
  const bool is_aa_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(ClipRRectEntry);
};

class ClipPathEntry : public LayerStateStack::StateEntry {
 public:
  ClipPathEntry(const SkPath& clip_path, bool is_aa)
      : clip_path_(clip_path), is_aa_(is_aa) {}
  ~ClipPathEntry() override = default;

  void apply(LayerStateStack* stack) const override {
    stack->delegate_->clipPath(clip_path_, DlCanvas::ClipOp::kIntersect,
                               is_aa_);
  }
  void update_mutators(MutatorsStack* mutators_stack) const override {
    mutators_stack->PushClipPath(clip_path_);
  }

 private:
  const SkPath clip_path_;
  const bool is_aa_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(ClipPathEntry);
};

// ==============================================================
// RenderingAttributes methods
// ==============================================================

DlPaint* LayerStateStack::RenderingAttributes::fill(DlPaint& paint,
                                                    DlBlendMode mode) const {
  DlPaint* ret = nullptr;
  if (opacity < SK_Scalar1) {
    paint.setOpacity(std::max(opacity, 0.0f));
    ret = &paint;
  } else {
    paint.setOpacity(SK_Scalar1);
  }
  paint.setColorFilter(color_filter);
  if (color_filter) {
    ret = &paint;
  }
  paint.setImageFilter(image_filter);
  if (image_filter) {
    ret = &paint;
  }
  paint.setBlendMode(mode);
  if (mode != DlBlendMode::kSrcOver) {
    ret = &paint;
  }
  return ret;
}

// ==============================================================
// MutatorContext methods
// ==============================================================

using MutatorContext = LayerStateStack::MutatorContext;

void MutatorContext::saveLayer(const SkRect& bounds) {
  layer_state_stack_->save_layer(bounds);
}

void MutatorContext::applyOpacity(const SkRect& bounds, SkScalar opacity) {
  if (opacity < SK_Scalar1) {
    layer_state_stack_->push_opacity(bounds, opacity);
  }
}

void MutatorContext::applyImageFilter(
    const SkRect& bounds,
    const std::shared_ptr<const DlImageFilter>& filter) {
  if (filter) {
    layer_state_stack_->push_image_filter(bounds, filter);
  }
}

void MutatorContext::applyColorFilter(
    const SkRect& bounds,
    const std::shared_ptr<const DlColorFilter>& filter) {
  if (filter) {
    layer_state_stack_->push_color_filter(bounds, filter);
  }
}

void MutatorContext::applyBackdropFilter(
    const SkRect& bounds,
    const std::shared_ptr<const DlImageFilter>& filter,
    DlBlendMode blend_mode) {
  layer_state_stack_->push_backdrop(bounds, filter, blend_mode);
}

void MutatorContext::translate(SkScalar tx, SkScalar ty) {
  if (!(tx == 0 && ty == 0)) {
    layer_state_stack_->maybe_save_layer_for_transform(save_needed_);
    save_needed_ = false;
    layer_state_stack_->push_translate(tx, ty);
  }
}

void MutatorContext::transform(const SkMatrix& matrix) {
  if (matrix.isTranslate()) {
    translate(matrix.getTranslateX(), matrix.getTranslateY());
  } else if (!matrix.isIdentity()) {
    layer_state_stack_->maybe_save_layer_for_transform(save_needed_);
    save_needed_ = false;
    layer_state_stack_->push_transform(matrix);
  }
}

void MutatorContext::transform(const SkM44& m44) {
  layer_state_stack_->maybe_save_layer_for_transform(save_needed_);
  save_needed_ = false;
  layer_state_stack_->push_transform(m44);
}

void MutatorContext::integralTransform() {
  layer_state_stack_->maybe_save_layer_for_transform(save_needed_);
  save_needed_ = false;
  layer_state_stack_->push_integral_transform();
}

void MutatorContext::clipRect(const SkRect& rect, bool is_aa) {
  layer_state_stack_->maybe_save_layer_for_clip(save_needed_);
  save_needed_ = false;
  layer_state_stack_->push_clip_rect(rect, is_aa);
}

void MutatorContext::clipRRect(const SkRRect& rrect, bool is_aa) {
  layer_state_stack_->maybe_save_layer_for_clip(save_needed_);
  save_needed_ = false;
  layer_state_stack_->push_clip_rrect(rrect, is_aa);
}

void MutatorContext::clipPath(const SkPath& path, bool is_aa) {
  layer_state_stack_->maybe_save_layer_for_clip(save_needed_);
  save_needed_ = false;
  layer_state_stack_->push_clip_path(path, is_aa);
}

// ==============================================================
// LayerStateStack methods
// ==============================================================

LayerStateStack::LayerStateStack() : delegate_(DummyDelegate::kInstance) {}

void LayerStateStack::clear_delegate() {
  delegate_->decommission();
  delegate_ = DummyDelegate::kInstance;
}

void LayerStateStack::set_delegate(DlCanvas* canvas) {
  if (delegate_) {
    if (canvas == delegate_->canvas()) {
      return;
    }
    clear_delegate();
  }
  if (canvas) {
    delegate_ = std::make_shared<DlCanvasDelegate>(canvas);
    reapply_all();
  }
}

void LayerStateStack::set_preroll_delegate(const SkRect& cull_rect) {
  set_preroll_delegate(cull_rect, SkMatrix::I());
}
void LayerStateStack::set_preroll_delegate(const SkMatrix& matrix) {
  set_preroll_delegate(kGiantRect, matrix);
}
void LayerStateStack::set_preroll_delegate(const SkRect& cull_rect,
                                           const SkMatrix& matrix) {
  clear_delegate();
  delegate_ = std::make_shared<PrerollDelegate>(cull_rect, matrix);
  reapply_all();
}

void LayerStateStack::reapply_all() {
  // We use a local RenderingAttributes instance so that it can track the
  // necessary state changes independently as they occur in the stack.
  // Reusing |outstanding_| would wreak havoc on the current state of
  // the stack. When we are finished, though, the local attributes
  // contents should match the current outstanding_ values;
  RenderingAttributes attributes = outstanding_;
  outstanding_ = {};
  for (auto& state : state_stack_) {
    state->reapply(this);
  }
  FML_DCHECK(attributes == outstanding_);
}

void LayerStateStack::fill(MutatorsStack* mutators) {
  for (auto& state : state_stack_) {
    state->update_mutators(mutators);
  }
}

void LayerStateStack::restore_to_count(size_t restore_count) {
  while (state_stack_.size() > restore_count) {
    state_stack_.back()->restore(this);
    state_stack_.pop_back();
  }
}

void LayerStateStack::push_opacity(const SkRect& bounds, SkScalar opacity) {
  maybe_save_layer(opacity);
  state_stack_.emplace_back(
      std::make_unique<OpacityEntry>(bounds, opacity, outstanding_));
  apply_last_entry();
}

void LayerStateStack::push_color_filter(
    const SkRect& bounds,
    const std::shared_ptr<const DlColorFilter>& filter) {
  maybe_save_layer(filter);
  state_stack_.emplace_back(
      std::make_unique<ColorFilterEntry>(bounds, filter, outstanding_));
  apply_last_entry();
}

void LayerStateStack::push_image_filter(
    const SkRect& bounds,
    const std::shared_ptr<const DlImageFilter>& filter) {
  maybe_save_layer(filter);
  state_stack_.emplace_back(
      std::make_unique<ImageFilterEntry>(bounds, filter, outstanding_));
  apply_last_entry();
}

void LayerStateStack::push_backdrop(
    const SkRect& bounds,
    const std::shared_ptr<const DlImageFilter>& filter,
    DlBlendMode blend_mode) {
  state_stack_.emplace_back(std::make_unique<BackdropFilterEntry>(
      bounds, filter, blend_mode, outstanding_));
  apply_last_entry();
}

void LayerStateStack::push_translate(SkScalar tx, SkScalar ty) {
  state_stack_.emplace_back(std::make_unique<TranslateEntry>(tx, ty));
  apply_last_entry();
}

void LayerStateStack::push_transform(const SkM44& m44) {
  state_stack_.emplace_back(std::make_unique<TransformM44Entry>(m44));
  apply_last_entry();
}

void LayerStateStack::push_transform(const SkMatrix& matrix) {
  state_stack_.emplace_back(std::make_unique<TransformMatrixEntry>(matrix));
  apply_last_entry();
}

void LayerStateStack::push_integral_transform() {
  state_stack_.emplace_back(std::make_unique<IntegralTransformEntry>());
  apply_last_entry();
}

void LayerStateStack::push_clip_rect(const SkRect& rect, bool is_aa) {
  state_stack_.emplace_back(std::make_unique<ClipRectEntry>(rect, is_aa));
  apply_last_entry();
}

void LayerStateStack::push_clip_rrect(const SkRRect& rrect, bool is_aa) {
  state_stack_.emplace_back(std::make_unique<ClipRRectEntry>(rrect, is_aa));
  apply_last_entry();
}

void LayerStateStack::push_clip_path(const SkPath& path, bool is_aa) {
  state_stack_.emplace_back(std::make_unique<ClipPathEntry>(path, is_aa));
  apply_last_entry();
}

bool LayerStateStack::needs_save_layer(int flags) const {
  if (outstanding_.opacity < SK_Scalar1 &&
      (flags & LayerStateStack::kCallerCanApplyOpacity) == 0) {
    return true;
  }
  if (outstanding_.image_filter &&
      (flags & LayerStateStack::kCallerCanApplyImageFilter) == 0) {
    return true;
  }
  if (outstanding_.color_filter &&
      (flags & LayerStateStack::kCallerCanApplyColorFilter) == 0) {
    return true;
  }
  return false;
}

void LayerStateStack::do_save() {
  state_stack_.emplace_back(std::make_unique<SaveEntry>());
  apply_last_entry();
}

void LayerStateStack::save_layer(const SkRect& bounds) {
  state_stack_.emplace_back(std::make_unique<SaveLayerEntry>(
      bounds, DlBlendMode::kSrcOver, outstanding_));
  apply_last_entry();
}

void LayerStateStack::maybe_save_layer_for_transform(bool save_needed) {
  // Alpha and ColorFilter don't care about transform
  if (outstanding_.image_filter) {
    save_layer(outstanding_.save_layer_bounds);
  } else if (save_needed) {
    do_save();
  }
}

void LayerStateStack::maybe_save_layer_for_clip(bool save_needed) {
  // Alpha and ColorFilter don't care about clipping
  // - Alpha of clipped content == clip of alpha content
  // - Color-filtering of clipped content == clip of color-filtered content
  if (outstanding_.image_filter) {
    save_layer(outstanding_.save_layer_bounds);
  } else if (save_needed) {
    do_save();
  }
}

void LayerStateStack::maybe_save_layer(int apply_flags) {
  if (needs_save_layer(apply_flags)) {
    save_layer(outstanding_.save_layer_bounds);
  }
}

void LayerStateStack::maybe_save_layer(SkScalar opacity) {
  if (outstanding_.image_filter) {
    save_layer(outstanding_.save_layer_bounds);
  }
}

void LayerStateStack::maybe_save_layer(
    const std::shared_ptr<const DlColorFilter>& filter) {
  if (outstanding_.color_filter || outstanding_.image_filter ||
      (outstanding_.opacity < SK_Scalar1 &&
       !filter->can_commute_with_opacity())) {
    // TBD: compose the 2 color filters together.
    save_layer(outstanding_.save_layer_bounds);
  }
}

void LayerStateStack::maybe_save_layer(
    const std::shared_ptr<const DlImageFilter>& filter) {
  if (outstanding_.image_filter) {
    // TBD: compose the 2 image filters together.
    save_layer(outstanding_.save_layer_bounds);
  }
}

}  // namespace flutter
