// 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_H_
#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_H_

#include <memory>
#include <optional>

#include "flutter/display_list/dl_sampling_options.h"
#include "flutter/display_list/geometry/dl_rtree.h"
#include "flutter/fml/logging.h"

// The Flutter DisplayList mechanism encapsulates a persistent sequence of
// rendering operations.
//
// This file contains the definitions for:
// DisplayList: the base class that holds the information about the
//              sequence of operations and can dispatch them to a DlOpReceiver
// DlOpReceiver: a pure virtual interface which can be implemented to field
//               the requests for purposes such as sending them to an SkCanvas
//               or detecting various rendering optimization scenarios
// DisplayListBuilder: a class for constructing a DisplayList from DlCanvas
//                     method calls and which can act as a DlOpReceiver as well
//
// Other files include various class definitions for dealing with display
// lists, such as:
// skia/dl_sk_*.h: classes to interact between SkCanvas and DisplayList
//                 (SkCanvas->DisplayList adapter and vice versa)
//
// display_list_utils.h: various utility classes to ease implementing
//                       a DlOpReceiver, including NOP implementations of
//                       the attribute, clip, and transform methods,
//                       classes to track attributes, clips, and transforms
//                       and a class to compute the bounds of a DisplayList
//                       Any class implementing DlOpReceiver can inherit from
//                       these utility classes to simplify its creation
//
// The Flutter DisplayList mechanism is used in a similar manner to the Skia
// SkPicture mechanism.
//
// A DisplayList must be created using a DisplayListBuilder using its stateless
// methods inherited from DlCanvas.
//
// A DisplayList can be read back by implementing the DlOpReceiver virtual
// methods (with help from some of the classes in the utils file) and
// passing an instance to the Dispatch() method, or it can be rendered
// to Skia using a DlSkCanvasDispatcher.
//
// The mechanism is inspired by the SkLiteDL class that is not directly
// supported by Skia, but has been recommended as a basis for custom
// display lists for a number of their customers.

namespace flutter {

#define FOR_EACH_DISPLAY_LIST_OP(V) \
  V(SetAntiAlias)                   \
  V(SetInvertColors)                \
                                    \
  V(SetStrokeCap)                   \
  V(SetStrokeJoin)                  \
                                    \
  V(SetStyle)                       \
  V(SetStrokeWidth)                 \
  V(SetStrokeMiter)                 \
                                    \
  V(SetColor)                       \
  V(SetBlendMode)                   \
                                    \
  V(SetPodPathEffect)               \
  V(ClearPathEffect)                \
                                    \
  V(ClearColorFilter)               \
  V(SetPodColorFilter)              \
                                    \
  V(ClearColorSource)               \
  V(SetPodColorSource)              \
  V(SetImageColorSource)            \
  V(SetRuntimeEffectColorSource)    \
                                    \
  V(ClearImageFilter)               \
  V(SetPodImageFilter)              \
  V(SetSharedImageFilter)           \
                                    \
  V(ClearMaskFilter)                \
  V(SetPodMaskFilter)               \
                                    \
  V(Save)                           \
  V(SaveLayer)                      \
  V(SaveLayerBackdrop)              \
  V(Restore)                        \
                                    \
  V(Translate)                      \
  V(Scale)                          \
  V(Rotate)                         \
  V(Skew)                           \
  V(Transform2DAffine)              \
  V(TransformFullPerspective)       \
  V(TransformReset)                 \
                                    \
  V(ClipIntersectRect)              \
  V(ClipIntersectRRect)             \
  V(ClipIntersectPath)              \
  V(ClipDifferenceRect)             \
  V(ClipDifferenceRRect)            \
  V(ClipDifferencePath)             \
                                    \
  V(DrawPaint)                      \
  V(DrawColor)                      \
                                    \
  V(DrawLine)                       \
  V(DrawRect)                       \
  V(DrawOval)                       \
  V(DrawCircle)                     \
  V(DrawRRect)                      \
  V(DrawDRRect)                     \
  V(DrawArc)                        \
  V(DrawPath)                       \
                                    \
  V(DrawPoints)                     \
  V(DrawLines)                      \
  V(DrawPolygon)                    \
  V(DrawVertices)                   \
                                    \
  V(DrawImage)                      \
  V(DrawImageWithAttr)              \
  V(DrawImageRect)                  \
  V(DrawImageNine)                  \
  V(DrawImageNineWithAttr)          \
  V(DrawAtlas)                      \
  V(DrawAtlasCulled)                \
                                    \
  V(DrawDisplayList)                \
  V(DrawTextBlob)                   \
  V(DrawTextFrame)                  \
                                    \
  V(DrawShadow)                     \
  V(DrawShadowTransparentOccluder)

#define DL_OP_TO_ENUM_VALUE(name) k##name,
enum class DisplayListOpType {
  FOR_EACH_DISPLAY_LIST_OP(DL_OP_TO_ENUM_VALUE)
#ifdef IMPELLER_ENABLE_3D
      DL_OP_TO_ENUM_VALUE(SetSceneColorSource)
#endif  // IMPELLER_ENABLE_3D
};
#undef DL_OP_TO_ENUM_VALUE

class DlOpReceiver;
class DisplayListBuilder;

class SaveLayerOptions {
 public:
  static const SaveLayerOptions kWithAttributes;
  static const SaveLayerOptions kNoAttributes;

  SaveLayerOptions() : flags_(0) {}
  SaveLayerOptions(const SaveLayerOptions& options) : flags_(options.flags_) {}
  explicit SaveLayerOptions(const SaveLayerOptions* options)
      : flags_(options->flags_) {}

  SaveLayerOptions without_optimizations() const {
    SaveLayerOptions options;
    options.fRendersWithAttributes = fRendersWithAttributes;
    options.fBoundsFromCaller = fBoundsFromCaller;
    return options;
  }

  bool renders_with_attributes() const { return fRendersWithAttributes; }
  SaveLayerOptions with_renders_with_attributes() const {
    SaveLayerOptions options(this);
    options.fRendersWithAttributes = true;
    return options;
  }

  bool can_distribute_opacity() const { return fCanDistributeOpacity; }
  SaveLayerOptions with_can_distribute_opacity() const {
    SaveLayerOptions options(this);
    options.fCanDistributeOpacity = true;
    return options;
  }

  // Returns true iff the bounds for the saveLayer operation were provided
  // by the caller, otherwise the bounds will have been computed by the
  // DisplayListBuilder and provided for reference.
  bool bounds_from_caller() const { return fBoundsFromCaller; }
  SaveLayerOptions with_bounds_from_caller() const {
    SaveLayerOptions options(this);
    options.fBoundsFromCaller = true;
    return options;
  }
  SaveLayerOptions without_bounds_from_caller() const {
    SaveLayerOptions options(this);
    options.fBoundsFromCaller = false;
    return options;
  }
  bool bounds_were_calculated() const { return !fBoundsFromCaller; }

  // Returns true iff the bounds for the saveLayer do not fully cover the
  // contained rendering operations. This will only occur if the original
  // caller supplied bounds and those bounds were not a strict superset
  // of the content bounds computed by the DisplayListBuilder.
  bool content_is_clipped() const { return fContentIsClipped; }
  SaveLayerOptions with_content_is_clipped() const {
    SaveLayerOptions options(this);
    options.fContentIsClipped = true;
    return options;
  }

  SaveLayerOptions& operator=(const SaveLayerOptions& other) {
    flags_ = other.flags_;
    return *this;
  }
  bool operator==(const SaveLayerOptions& other) const {
    return flags_ == other.flags_;
  }
  bool operator!=(const SaveLayerOptions& other) const {
    return flags_ != other.flags_;
  }

 private:
  union {
    struct {
      unsigned fRendersWithAttributes : 1;
      unsigned fCanDistributeOpacity : 1;
      unsigned fBoundsFromCaller : 1;
      unsigned fContentIsClipped : 1;
    };
    uint32_t flags_;
  };
};

// Manages a buffer allocated with malloc.
class DisplayListStorage {
 public:
  DisplayListStorage() = default;
  DisplayListStorage(DisplayListStorage&&) = default;

  uint8_t* get() const { return ptr_.get(); }

  void realloc(size_t count) {
    ptr_.reset(static_cast<uint8_t*>(std::realloc(ptr_.release(), count)));
    FML_CHECK(ptr_);
  }

 private:
  struct FreeDeleter {
    void operator()(uint8_t* p) { std::free(p); }
  };
  std::unique_ptr<uint8_t, FreeDeleter> ptr_;
};

class Culler;

// The base class that contains a sequence of rendering operations
// for dispatch to a DlOpReceiver. These objects must be instantiated
// through an instance of DisplayListBuilder::build().
class DisplayList : public SkRefCnt {
 public:
  DisplayList();

  ~DisplayList();

  void Dispatch(DlOpReceiver& ctx) const;
  void Dispatch(DlOpReceiver& ctx, const SkRect& cull_rect) const;
  void Dispatch(DlOpReceiver& ctx, const SkIRect& cull_rect) const;

  // From historical behavior, SkPicture always included nested bytes,
  // but nested ops are only included if requested. The defaults used
  // here for these accessors follow that pattern.
  size_t bytes(bool nested = true) const {
    return sizeof(DisplayList) + byte_count_ +
           (nested ? nested_byte_count_ : 0);
  }

  unsigned int op_count(bool nested = false) const {
    return op_count_ + (nested ? nested_op_count_ : 0);
  }

  uint32_t unique_id() const { return unique_id_; }

  const SkRect& bounds() const { return bounds_; }

  bool has_rtree() const { return rtree_ != nullptr; }
  sk_sp<const DlRTree> rtree() const { return rtree_; }

  bool Equals(const DisplayList* other) const;
  bool Equals(const DisplayList& other) const { return Equals(&other); }
  bool Equals(const sk_sp<const DisplayList>& other) const {
    return Equals(other.get());
  }

  bool can_apply_group_opacity() const { return can_apply_group_opacity_; }
  bool isUIThreadSafe() const { return is_ui_thread_safe_; }

  /// @brief     Indicates if there are any rendering operations in this
  ///            DisplayList that will modify a surface of transparent black
  ///            pixels.
  ///
  /// This condition can be used to determine whether to create a cleared
  /// surface, render a DisplayList into it, and then composite the
  /// result into a scene. It is not uncommon for code in the engine to
  /// come across such degenerate DisplayList objects when slicing up a
  /// frame between platform views.
  bool modifies_transparent_black() const {
    return modifies_transparent_black_;
  }

 private:
  DisplayList(DisplayListStorage&& ptr,
              size_t byte_count,
              unsigned int op_count,
              size_t nested_byte_count,
              unsigned int nested_op_count,
              const SkRect& bounds,
              bool can_apply_group_opacity,
              bool is_ui_thread_safe,
              bool modifies_transparent_black,
              sk_sp<const DlRTree> rtree);

  static uint32_t next_unique_id();

  static void DisposeOps(uint8_t* ptr, uint8_t* end);

  const DisplayListStorage storage_;
  const size_t byte_count_;
  const unsigned int op_count_;

  const size_t nested_byte_count_;
  const unsigned int nested_op_count_;

  const uint32_t unique_id_;
  const SkRect bounds_;

  const bool can_apply_group_opacity_;
  const bool is_ui_thread_safe_;
  const bool modifies_transparent_black_;

  const sk_sp<const DlRTree> rtree_;

  void Dispatch(DlOpReceiver& ctx,
                uint8_t* ptr,
                uint8_t* end,
                Culler& culler) const;

  friend class DisplayListBuilder;
};

}  // namespace flutter

#endif  // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_H_
