// 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.

#ifndef FLUTTER_DISPLAY_LIST_DISPLAY_LIST_COLOR_SOURCE_H_
#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_COLOR_SOURCE_H_

#include <memory>
#include <utility>
#include <vector>

#include "flutter/display_list/display_list.h"
#include "flutter/display_list/display_list_attributes.h"
#include "flutter/display_list/display_list_color.h"
#include "flutter/display_list/display_list_image.h"
#include "flutter/display_list/display_list_runtime_effect.h"
#include "flutter/display_list/display_list_sampling_options.h"
#include "flutter/display_list/display_list_tile_mode.h"
#include "flutter/display_list/types.h"
#include "flutter/fml/logging.h"
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "third_party/skia/include/effects/SkRuntimeEffect.h"

#ifdef IMPELLER_ENABLE_3D
#include "impeller/geometry/matrix.h"  // nogncheck
#include "impeller/scene/node.h"       // nogncheck
namespace flutter {
class DlSceneColorSource;
}
#endif  // IMPELLER_ENABLE_3D

namespace flutter {

class DlColorColorSource;
class DlImageColorSource;
class DlLinearGradientColorSource;
class DlRadialGradientColorSource;
class DlConicalGradientColorSource;
class DlSweepGradientColorSource;
class DlRuntimeEffectColorSource;

// The DisplayList ColorSource class. This class implements all of the
// facilities and adheres to the design goals of the |DlAttribute| base
// class.
//
// The role of the DlColorSource is to provide color information for
// the pixels of a rendering operation. The object is essentially the
// origin of all color being rendered, though its output may be
// modified or transformed by geometric coverage data, the filter
// attributes, and the final blend with the pixels in the destination.

enum class DlColorSourceType {
  kColor,
  kImage,
  kLinearGradient,
  kRadialGradient,
  kConicalGradient,
  kSweepGradient,
  kRuntimeEffect,
#ifdef IMPELLER_ENABLE_3D
  kScene,
#endif  // IMPELLER_ENABLE_3D
};

class DlColorSource
    : public DlAttribute<DlColorSource, SkShader, DlColorSourceType> {
 public:
  static std::shared_ptr<DlColorSource> MakeLinear(
      const SkPoint start_point,
      const SkPoint end_point,
      uint32_t stop_count,
      const DlColor* colors,
      const float* stops,
      DlTileMode tile_mode,
      const SkMatrix* matrix = nullptr);

  static std::shared_ptr<DlColorSource> MakeRadial(
      SkPoint center,
      SkScalar radius,
      uint32_t stop_count,
      const DlColor* colors,
      const float* stops,
      DlTileMode tile_mode,
      const SkMatrix* matrix = nullptr);

  static std::shared_ptr<DlColorSource> MakeConical(
      SkPoint start_center,
      SkScalar start_radius,
      SkPoint end_center,
      SkScalar end_radius,
      uint32_t stop_count,
      const DlColor* colors,
      const float* stops,
      DlTileMode tile_mode,
      const SkMatrix* matrix = nullptr);

  static std::shared_ptr<DlColorSource> MakeSweep(
      SkPoint center,
      SkScalar start,
      SkScalar end,
      uint32_t stop_count,
      const DlColor* colors,
      const float* stops,
      DlTileMode tile_mode,
      const SkMatrix* matrix = nullptr);

  static std::shared_ptr<DlRuntimeEffectColorSource> MakeRuntimeEffect(
      sk_sp<DlRuntimeEffect> runtime_effect,
      std::vector<std::shared_ptr<DlColorSource>> samplers,
      std::shared_ptr<std::vector<uint8_t>> uniform_data);

  virtual bool is_opaque() const = 0;

  virtual std::shared_ptr<DlColorSource> with_sampling(
      DlImageSampling options) const {
    return shared();
  }

  // Return a DlColorColorSource pointer to this object iff it is an Color
  // type of ColorSource, otherwise return nullptr.
  virtual const DlColorColorSource* asColor() const { return nullptr; }

  // Return a DlImageColorSource pointer to this object iff it is an Image
  // type of ColorSource, otherwise return nullptr.
  virtual const DlImageColorSource* asImage() const { return nullptr; }

  // Return a DlLinearGradientColorSource pointer to this object iff it is a
  // Linear Gradient type of ColorSource, otherwise return nullptr.
  virtual const DlLinearGradientColorSource* asLinearGradient() const {
    return nullptr;
  }

  // Return a DlRadialGradientColorSource pointer to this object iff it is a
  // Radial Gradient type of ColorSource, otherwise return nullptr.
  virtual const DlRadialGradientColorSource* asRadialGradient() const {
    return nullptr;
  }

  // Return a DlConicalGradientColorSource pointer to this object iff it is a
  // Conical Gradient type of ColorSource, otherwise return nullptr.
  virtual const DlConicalGradientColorSource* asConicalGradient() const {
    return nullptr;
  }

  // Return a DlSweepGradientColorSource pointer to this object iff it is a
  // Sweep Gradient type of ColorSource, otherwise return nullptr.
  virtual const DlSweepGradientColorSource* asSweepGradient() const {
    return nullptr;
  }

  virtual const DlRuntimeEffectColorSource* asRuntimeEffect() const {
    return nullptr;
  }

#ifdef IMPELLER_ENABLE_3D
  virtual const DlSceneColorSource* asScene() const { return nullptr; }
#endif  // IMPELLER_ENABLE_3D

  // If this filter contains images, specifies the owning context for those
  // images.
  // Images with a DlImage::OwningContext::kRaster must only call skia_object
  // on the raster task runner.
  // A nullopt return means there is no image.
  virtual std::optional<DlImage::OwningContext> owning_context() const {
    return std::nullopt;
  }

 protected:
  DlColorSource() = default;

 private:
  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlColorSource);
};

class DlColorColorSource final : public DlColorSource {
 public:
  DlColorColorSource(DlColor color) : color_(color) {}

  std::shared_ptr<DlColorSource> shared() const override {
    return std::make_shared<DlColorColorSource>(color_);
  }

  const DlColorColorSource* asColor() const override { return this; }

  DlColorSourceType type() const override { return DlColorSourceType::kColor; }
  size_t size() const override { return sizeof(*this); }

  bool is_opaque() const override { return (color_ >> 24) == 255; }

  DlColor color() const { return color_; }

  sk_sp<SkShader> skia_object() const override {
    return SkShaders::Color(color_);
  }

 protected:
  bool equals_(DlColorSource const& other) const override {
    FML_DCHECK(other.type() == DlColorSourceType::kColor);
    auto that = static_cast<DlColorColorSource const*>(&other);
    return color_ == that->color_;
  }

 private:
  DlColor color_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlColorColorSource);
};

class DlMatrixColorSourceBase : public DlColorSource {
 public:
  const SkMatrix& matrix() const { return matrix_; }
  const SkMatrix* matrix_ptr() const {
    return matrix_.isIdentity() ? nullptr : &matrix_;
  }

 protected:
  DlMatrixColorSourceBase(const SkMatrix* matrix)
      : matrix_(matrix ? *matrix : SkMatrix::I()) {}

 private:
  const SkMatrix matrix_;
};

class DlImageColorSource final : public SkRefCnt,
                                 public DlMatrixColorSourceBase {
 public:
  DlImageColorSource(sk_sp<const DlImage> image,
                     DlTileMode horizontal_tile_mode,
                     DlTileMode vertical_tile_mode,
                     DlImageSampling sampling = DlImageSampling::kLinear,
                     const SkMatrix* matrix = nullptr)
      : DlMatrixColorSourceBase(matrix),
        image_(image),
        horizontal_tile_mode_(horizontal_tile_mode),
        vertical_tile_mode_(vertical_tile_mode),
        sampling_(sampling) {}

  const DlImageColorSource* asImage() const override { return this; }

  std::shared_ptr<DlColorSource> shared() const override {
    return with_sampling(sampling_);
  }

  std::shared_ptr<DlColorSource> with_sampling(
      DlImageSampling sampling) const override {
    return std::make_shared<DlImageColorSource>(image_, horizontal_tile_mode_,
                                                vertical_tile_mode_, sampling,
                                                matrix_ptr());
  }

  DlColorSourceType type() const override { return DlColorSourceType::kImage; }
  size_t size() const override { return sizeof(*this); }

  bool is_opaque() const override { return image_->isOpaque(); }

  std::optional<DlImage::OwningContext> owning_context() const override {
    return image_->owning_context();
  }

  sk_sp<const DlImage> image() const { return image_; }
  DlTileMode horizontal_tile_mode() const { return horizontal_tile_mode_; }
  DlTileMode vertical_tile_mode() const { return vertical_tile_mode_; }
  DlImageSampling sampling() const { return sampling_; }

  virtual sk_sp<SkShader> skia_object() const override {
    if (!image_->skia_image()) {
      return nullptr;
    }
    return image_->skia_image()->makeShader(ToSk(horizontal_tile_mode_),
                                            ToSk(vertical_tile_mode_),
                                            ToSk(sampling_), matrix_ptr());
  }

 protected:
  bool equals_(DlColorSource const& other) const override {
    FML_DCHECK(other.type() == DlColorSourceType::kImage);
    auto that = static_cast<DlImageColorSource const*>(&other);
    return (image_->Equals(that->image_) && matrix() == that->matrix() &&
            horizontal_tile_mode_ == that->horizontal_tile_mode_ &&
            vertical_tile_mode_ == that->vertical_tile_mode_ &&
            sampling_ == that->sampling_);
  }

 private:
  sk_sp<const DlImage> image_;
  DlTileMode horizontal_tile_mode_;
  DlTileMode vertical_tile_mode_;
  DlImageSampling sampling_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlImageColorSource);
};

class DlGradientColorSourceBase : public DlMatrixColorSourceBase {
 public:
  bool is_opaque() const override {
    if (mode_ == DlTileMode::kDecal) {
      return false;
    }
    const DlColor* my_colors = colors();
    for (uint32_t i = 0; i < stop_count_; i++) {
      if ((my_colors[i] >> 24) < 255) {
        return false;
      }
    }
    return true;
  }

  DlTileMode tile_mode() const { return mode_; }
  int stop_count() const { return stop_count_; }
  const DlColor* colors() const {
    return reinterpret_cast<const DlColor*>(pod());
  }
  const float* stops() const {
    return reinterpret_cast<const float*>(colors() + stop_count());
  }

 protected:
  DlGradientColorSourceBase(uint32_t stop_count,
                            DlTileMode tile_mode,
                            const SkMatrix* matrix = nullptr)
      : DlMatrixColorSourceBase(matrix),
        mode_(tile_mode),
        stop_count_(stop_count) {}

  size_t vector_sizes() const {
    return stop_count_ * (sizeof(DlColor) + sizeof(float));
  }

  virtual const void* pod() const = 0;

  bool base_equals_(DlGradientColorSourceBase const* other_base) const {
    if (mode_ != other_base->mode_ || matrix() != other_base->matrix() ||
        stop_count_ != other_base->stop_count_) {
      return false;
    }
    static_assert(sizeof(colors()[0]) == 4);
    static_assert(sizeof(stops()[0]) == 4);
    int num_bytes = stop_count_ * 4;
    return (memcmp(colors(), other_base->colors(), num_bytes) == 0 &&
            memcmp(stops(), other_base->stops(), num_bytes) == 0);
  }

  void store_color_stops(void* pod,
                         const DlColor* color_data,
                         const float* stop_data) {
    DlColor* color_storage = reinterpret_cast<DlColor*>(pod);
    memcpy(color_storage, color_data, stop_count_ * sizeof(*color_data));
    float* stop_storage = reinterpret_cast<float*>(color_storage + stop_count_);
    if (stop_data) {
      memcpy(stop_storage, stop_data, stop_count_ * sizeof(*stop_data));
    } else {
      float div = stop_count_ - 1;
      if (div <= 0) {
        div = 1;
      }
      for (uint32_t i = 0; i < stop_count_; i++) {
        stop_storage[i] = i / div;
      }
    }
  }

 private:
  DlTileMode mode_;
  uint32_t stop_count_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlGradientColorSourceBase);
};

class DlLinearGradientColorSource final : public DlGradientColorSourceBase {
 public:
  const DlLinearGradientColorSource* asLinearGradient() const override {
    return this;
  }

  DlColorSourceType type() const override {
    return DlColorSourceType::kLinearGradient;
  }
  size_t size() const override { return sizeof(*this) + vector_sizes(); }

  std::shared_ptr<DlColorSource> shared() const override {
    return MakeLinear(start_point_, end_point_, stop_count(), colors(), stops(),
                      tile_mode(), matrix_ptr());
  }

  const SkPoint& start_point() const { return start_point_; }
  const SkPoint& end_point() const { return end_point_; }

  sk_sp<SkShader> skia_object() const override {
    SkPoint pts[] = {start_point_, end_point_};
    const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors());
    return SkGradientShader::MakeLinear(pts, sk_colors, stops(), stop_count(),
                                        ToSk(tile_mode()), 0, matrix_ptr());
  }

 protected:
  virtual const void* pod() const override { return this + 1; }

  bool equals_(DlColorSource const& other) const override {
    FML_DCHECK(other.type() == DlColorSourceType::kLinearGradient);
    auto that = static_cast<DlLinearGradientColorSource const*>(&other);
    return (start_point_ == that->start_point_ &&
            end_point_ == that->end_point_ && base_equals_(that));
  }

 private:
  DlLinearGradientColorSource(const SkPoint start_point,
                              const SkPoint end_point,
                              uint32_t stop_count,
                              const DlColor* colors,
                              const float* stops,
                              DlTileMode tile_mode,
                              const SkMatrix* matrix = nullptr)
      : DlGradientColorSourceBase(stop_count, tile_mode, matrix),
        start_point_(start_point),
        end_point_(end_point) {
    store_color_stops(this + 1, colors, stops);
  }

  DlLinearGradientColorSource(const DlLinearGradientColorSource* source)
      : DlGradientColorSourceBase(source->stop_count(),
                                  source->tile_mode(),
                                  source->matrix_ptr()),
        start_point_(source->start_point()),
        end_point_(source->end_point()) {
    store_color_stops(this + 1, source->colors(), source->stops());
  }

  SkPoint start_point_;
  SkPoint end_point_;

  friend class DlColorSource;
  friend class DisplayListBuilder;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlLinearGradientColorSource);
};

class DlRadialGradientColorSource final : public DlGradientColorSourceBase {
 public:
  const DlRadialGradientColorSource* asRadialGradient() const override {
    return this;
  }

  std::shared_ptr<DlColorSource> shared() const override {
    return MakeRadial(center_, radius_, stop_count(), colors(), stops(),
                      tile_mode(), matrix_ptr());
  }

  DlColorSourceType type() const override {
    return DlColorSourceType::kRadialGradient;
  }
  size_t size() const override { return sizeof(*this) + vector_sizes(); }

  SkPoint center() const { return center_; }
  SkScalar radius() const { return radius_; }

  sk_sp<SkShader> skia_object() const override {
    const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors());
    return SkGradientShader::MakeRadial(center_, radius_, sk_colors, stops(),
                                        stop_count(), ToSk(tile_mode()), 0,
                                        matrix_ptr());
  }

 protected:
  virtual const void* pod() const override { return this + 1; }

  bool equals_(DlColorSource const& other) const override {
    FML_DCHECK(other.type() == DlColorSourceType::kRadialGradient);
    auto that = static_cast<DlRadialGradientColorSource const*>(&other);
    return (center_ == that->center_ && radius_ == that->radius_ &&
            base_equals_(that));
  }

 private:
  DlRadialGradientColorSource(SkPoint center,
                              SkScalar radius,
                              uint32_t stop_count,
                              const DlColor* colors,
                              const float* stops,
                              DlTileMode tile_mode,
                              const SkMatrix* matrix = nullptr)
      : DlGradientColorSourceBase(stop_count, tile_mode, matrix),
        center_(center),
        radius_(radius) {
    store_color_stops(this + 1, colors, stops);
  }

  DlRadialGradientColorSource(const DlRadialGradientColorSource* source)
      : DlGradientColorSourceBase(source->stop_count(),
                                  source->tile_mode(),
                                  source->matrix_ptr()),
        center_(source->center()),
        radius_(source->radius()) {
    store_color_stops(this + 1, source->colors(), source->stops());
  }

  SkPoint center_;
  SkScalar radius_;

  friend class DlColorSource;
  friend class DisplayListBuilder;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlRadialGradientColorSource);
};

class DlConicalGradientColorSource final : public DlGradientColorSourceBase {
 public:
  const DlConicalGradientColorSource* asConicalGradient() const override {
    return this;
  }

  std::shared_ptr<DlColorSource> shared() const override {
    return MakeConical(start_center_, start_radius_, end_center_, end_radius_,
                       stop_count(), colors(), stops(), tile_mode(),
                       matrix_ptr());
  }

  DlColorSourceType type() const override {
    return DlColorSourceType::kConicalGradient;
  }
  size_t size() const override { return sizeof(*this) + vector_sizes(); }

  SkPoint start_center() const { return start_center_; }
  SkScalar start_radius() const { return start_radius_; }
  SkPoint end_center() const { return end_center_; }
  SkScalar end_radius() const { return end_radius_; }

  sk_sp<SkShader> skia_object() const override {
    const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors());
    return SkGradientShader::MakeTwoPointConical(
        start_center_, start_radius_, end_center_, end_radius_, sk_colors,
        stops(), stop_count(), ToSk(tile_mode()), 0, matrix_ptr());
  }

 protected:
  virtual const void* pod() const override { return this + 1; }

  bool equals_(DlColorSource const& other) const override {
    FML_DCHECK(other.type() == DlColorSourceType::kConicalGradient);
    auto that = static_cast<DlConicalGradientColorSource const*>(&other);
    return (start_center_ == that->start_center_ &&
            start_radius_ == that->start_radius_ &&
            end_center_ == that->end_center_ &&
            end_radius_ == that->end_radius_ && base_equals_(that));
  }

 private:
  DlConicalGradientColorSource(SkPoint start_center,
                               SkScalar start_radius,
                               SkPoint end_center,
                               SkScalar end_radius,
                               uint32_t stop_count,
                               const DlColor* colors,
                               const float* stops,
                               DlTileMode tile_mode,
                               const SkMatrix* matrix = nullptr)
      : DlGradientColorSourceBase(stop_count, tile_mode, matrix),
        start_center_(start_center),
        start_radius_(start_radius),
        end_center_(end_center),
        end_radius_(end_radius) {
    store_color_stops(this + 1, colors, stops);
  }

  DlConicalGradientColorSource(const DlConicalGradientColorSource* source)
      : DlGradientColorSourceBase(source->stop_count(),
                                  source->tile_mode(),
                                  source->matrix_ptr()),
        start_center_(source->start_center()),
        start_radius_(source->start_radius()),
        end_center_(source->end_center()),
        end_radius_(source->end_radius()) {
    store_color_stops(this + 1, source->colors(), source->stops());
  }

  SkPoint start_center_;
  SkScalar start_radius_;
  SkPoint end_center_;
  SkScalar end_radius_;

  friend class DlColorSource;
  friend class DisplayListBuilder;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlConicalGradientColorSource);
};

class DlSweepGradientColorSource final : public DlGradientColorSourceBase {
 public:
  const DlSweepGradientColorSource* asSweepGradient() const override {
    return this;
  }

  std::shared_ptr<DlColorSource> shared() const override {
    return MakeSweep(center_, start_, end_, stop_count(), colors(), stops(),
                     tile_mode(), matrix_ptr());
  }

  DlColorSourceType type() const override {
    return DlColorSourceType::kSweepGradient;
  }
  size_t size() const override { return sizeof(*this) + vector_sizes(); }

  SkPoint center() const { return center_; }
  SkScalar start() const { return start_; }
  SkScalar end() const { return end_; }

  sk_sp<SkShader> skia_object() const override {
    const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors());
    return SkGradientShader::MakeSweep(center_.x(), center_.y(), sk_colors,
                                       stops(), stop_count(), ToSk(tile_mode()),
                                       start_, end_, 0, matrix_ptr());
  }

 protected:
  virtual const void* pod() const override { return this + 1; }

  bool equals_(DlColorSource const& other) const override {
    FML_DCHECK(other.type() == DlColorSourceType::kSweepGradient);
    auto that = static_cast<DlSweepGradientColorSource const*>(&other);
    return (center_ == that->center_ && start_ == that->start_ &&
            end_ == that->end_ && base_equals_(that));
  }

 private:
  DlSweepGradientColorSource(SkPoint center,
                             SkScalar start,
                             SkScalar end,
                             uint32_t stop_count,
                             const DlColor* colors,
                             const float* stops,
                             DlTileMode tile_mode,
                             const SkMatrix* matrix = nullptr)
      : DlGradientColorSourceBase(stop_count, tile_mode, matrix),
        center_(center),
        start_(start),
        end_(end) {
    store_color_stops(this + 1, colors, stops);
  }

  DlSweepGradientColorSource(const DlSweepGradientColorSource* source)
      : DlGradientColorSourceBase(source->stop_count(),
                                  source->tile_mode(),
                                  source->matrix_ptr()),
        center_(source->center()),
        start_(source->start()),
        end_(source->end()) {
    store_color_stops(this + 1, source->colors(), source->stops());
  }

  SkPoint center_;
  SkScalar start_;
  SkScalar end_;

  friend class DlColorSource;
  friend class DisplayListBuilder;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlSweepGradientColorSource);
};

class DlRuntimeEffectColorSource final : public DlColorSource {
 public:
  DlRuntimeEffectColorSource(
      sk_sp<DlRuntimeEffect> runtime_effect,
      std::vector<std::shared_ptr<DlColorSource>> samplers,
      std::shared_ptr<std::vector<uint8_t>> uniform_data)
      : runtime_effect_(std::move(runtime_effect)),
        samplers_(std::move(samplers)),
        uniform_data_(std::move(uniform_data)) {}

  const DlRuntimeEffectColorSource* asRuntimeEffect() const override {
    return this;
  }

  std::shared_ptr<DlColorSource> shared() const override {
    return std::make_shared<DlRuntimeEffectColorSource>(
        runtime_effect_, samplers_, uniform_data_);
  }

  DlColorSourceType type() const override {
    return DlColorSourceType::kRuntimeEffect;
  }
  size_t size() const override { return sizeof(*this); }

  bool is_opaque() const override { return false; }

  const sk_sp<DlRuntimeEffect> runtime_effect() const {
    return runtime_effect_;
  }
  const std::vector<std::shared_ptr<DlColorSource>> samplers() const {
    return samplers_;
  }
  const std::shared_ptr<std::vector<uint8_t>> uniform_data() const {
    return uniform_data_;
  }

  sk_sp<SkShader> skia_object() const override {
    if (!runtime_effect_) {
      return nullptr;
    }
    if (!runtime_effect_->skia_runtime_effect()) {
      return nullptr;
    }
    std::vector<sk_sp<SkShader>> sk_samplers(samplers_.size());
    for (size_t i = 0; i < samplers_.size(); i++) {
      auto sampler = samplers_[i];
      if (sampler == nullptr) {
        return nullptr;
      }
      sk_samplers[i] = sampler->skia_object();
    }

    auto ref = new std::shared_ptr<std::vector<uint8_t>>(uniform_data_);
    auto uniform_data = SkData::MakeWithProc(
        uniform_data_->data(), uniform_data_->size(),
        [](const void* ptr, void* context) {
          delete reinterpret_cast<std::shared_ptr<std::vector<uint8_t>>*>(
              context);
        },
        ref);

    return runtime_effect_->skia_runtime_effect()->makeShader(
        uniform_data, sk_samplers.data(), sk_samplers.size());
  }

 protected:
  bool equals_(DlColorSource const& other) const override {
    FML_DCHECK(other.type() == DlColorSourceType::kRuntimeEffect);
    auto that = static_cast<DlRuntimeEffectColorSource const*>(&other);
    if (runtime_effect_ != that->runtime_effect_) {
      return false;
    }
    if (uniform_data_ != that->uniform_data_) {
      return false;
    }
    if (samplers_.size() != that->samplers_.size()) {
      return false;
    }
    for (size_t i = 0; i < samplers_.size(); i++) {
      if (samplers_[i] != that->samplers_[i]) {
        return false;
      }
    }
    return true;
  }

 private:
  sk_sp<DlRuntimeEffect> runtime_effect_;
  std::vector<std::shared_ptr<DlColorSource>> samplers_;
  std::shared_ptr<std::vector<uint8_t>> uniform_data_;

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlRuntimeEffectColorSource);
};

#ifdef IMPELLER_ENABLE_3D
class DlSceneColorSource final : public DlColorSource {
 public:
  DlSceneColorSource(std::shared_ptr<impeller::scene::Node> node,
                     impeller::Matrix camera_matrix)
      : node_(std::move(node)), camera_matrix_(camera_matrix) {}

  const DlSceneColorSource* asScene() const override { return this; }

  std::shared_ptr<DlColorSource> shared() const override {
    return std::make_shared<DlSceneColorSource>(node_, camera_matrix_);
  }

  DlColorSourceType type() const override { return DlColorSourceType::kScene; }
  size_t size() const override { return sizeof(*this); }

  bool is_opaque() const override { return false; }

  std::shared_ptr<impeller::scene::Node> scene_node() const { return node_; }

  impeller::Matrix camera_matrix() const { return camera_matrix_; }

  sk_sp<SkShader> skia_object() const override { return nullptr; }

 protected:
  bool equals_(DlColorSource const& other) const override {
    FML_DCHECK(other.type() == DlColorSourceType::kScene);
    auto that = static_cast<DlSceneColorSource const*>(&other);
    if (node_ != that->node_) {
      return false;
    }
    return true;
  }

 private:
  std::shared_ptr<impeller::scene::Node> node_;
  impeller::Matrix camera_matrix_;  // the view-projection matrix of the scene.

  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlSceneColorSource);
};
#endif  // IMPELLER_ENABLE_3D

}  // namespace flutter

#endif  // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_COLOR_SOURCE_H_
