// 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_FLOW_RASTER_CACHE_ITEM_H_
#define FLUTTER_FLOW_RASTER_CACHE_ITEM_H_

#include <memory>
#include <optional>

#include "flutter/display_list/dl_canvas.h"
#include "flutter/flow/raster_cache_key.h"

namespace flutter {

struct PrerollContext;
struct PaintContext;
class DisplayList;
class RasterCache;
class LayerRasterCacheItem;
class DisplayListRasterCacheItem;

class RasterCacheItem {
 public:
  enum CacheState {
    kNone = 0,
    kCurrent,
    kChildren,
  };

  explicit RasterCacheItem(RasterCacheKeyID key_id,
                           CacheState cache_state = CacheState::kNone,
                           unsigned child_entries = 0)
      : key_id_(key_id),
        cache_state_(cache_state),
        child_items_(child_entries) {}

  virtual void PrerollSetup(PrerollContext* context,
                            const SkMatrix& matrix) = 0;

  virtual void PrerollFinalize(PrerollContext* context,
                               const SkMatrix& matrix) = 0;

  virtual bool Draw(const PaintContext& context,
                    const DlPaint* paint) const = 0;

  virtual bool Draw(const PaintContext& context,
                    DlCanvas* canvas,
                    const DlPaint* paint) const = 0;

  virtual std::optional<RasterCacheKeyID> GetId() const { return key_id_; }

  virtual bool TryToPrepareRasterCache(const PaintContext& context,
                                       bool parent_cached = false) const = 0;

  unsigned child_items() const { return child_items_; }

  void set_matrix(const SkMatrix& matrix) { matrix_ = matrix; }

  CacheState cache_state() const { return cache_state_; }

  bool need_caching() const { return cache_state_ != CacheState::kNone; }

  virtual ~RasterCacheItem() = default;

 protected:
  // The id for cache the layer self.
  RasterCacheKeyID key_id_;
  CacheState cache_state_ = CacheState::kNone;
  mutable SkMatrix matrix_;
  unsigned child_items_;
};

}  // namespace flutter

#endif  // FLUTTER_FLOW_RASTER_CACHE_ITEM_H_
