// 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_DISPLAY_LIST_COMPLEXITY_METAL_H_
#define FLUTTER_FLOW_DISPLAY_LIST_COMPLEXITY_METAL_H_

#include "flutter/display_list/display_list_complexity_helper.h"

namespace flutter {

class DisplayListMetalComplexityCalculator
    : public DisplayListComplexityCalculator {
 public:
  static DisplayListMetalComplexityCalculator* GetInstance();

  unsigned int Compute(DisplayList* display_list) override {
    MetalHelper helper(ceiling_);
    display_list->Dispatch(helper);
    return helper.ComplexityScore();
  }

  bool ShouldBeCached(unsigned int complexity_score) override {
    // Set cache threshold at 1ms
    return complexity_score > 200000u;
  }

  void SetComplexityCeiling(unsigned int ceiling) override {
    ceiling_ = ceiling;
  }

 private:
  class MetalHelper : public ComplexityCalculatorHelper {
   public:
    MetalHelper(unsigned int ceiling)
        : ComplexityCalculatorHelper(ceiling),
          save_layer_count_(0),
          draw_text_blob_count_(0) {}

    void saveLayer(const SkRect* bounds,
                   const SaveLayerOptions options) override;

    void drawLine(const SkPoint& p0, const SkPoint& p1) override;
    void drawRect(const SkRect& rect) override;
    void drawOval(const SkRect& bounds) override;
    void drawCircle(const SkPoint& center, SkScalar radius) override;
    void drawRRect(const SkRRect& rrect) override;
    void drawDRRect(const SkRRect& outer, const SkRRect& inner) override;
    void drawPath(const SkPath& path) override;
    void drawArc(const SkRect& oval_bounds,
                 SkScalar start_degrees,
                 SkScalar sweep_degrees,
                 bool use_center) override;
    void drawPoints(SkCanvas::PointMode mode,
                    uint32_t count,
                    const SkPoint points[]) override;
    void drawSkVertices(const sk_sp<SkVertices> vertices,
                        SkBlendMode mode) override;
    void drawVertices(const DlVertices* vertices, DlBlendMode mode) override;
    void drawImage(const sk_sp<DlImage> image,
                   const SkPoint point,
                   const SkSamplingOptions& sampling,
                   bool render_with_attributes) override;
    void drawImageNine(const sk_sp<DlImage> image,
                       const SkIRect& center,
                       const SkRect& dst,
                       SkFilterMode filter,
                       bool render_with_attributes) override;
    void drawDisplayList(const sk_sp<DisplayList> display_list) override;
    void drawTextBlob(const sk_sp<SkTextBlob> blob,
                      SkScalar x,
                      SkScalar y) override;
    void drawShadow(const SkPath& path,
                    const DlColor color,
                    const SkScalar elevation,
                    bool transparent_occluder,
                    SkScalar dpr) override;

   protected:
    void ImageRect(const SkISize& size,
                   bool texture_backed,
                   bool render_with_attributes,
                   SkCanvas::SrcRectConstraint constraint) override;

    unsigned int BatchedComplexity() override;

   private:
    unsigned int save_layer_count_;
    unsigned int draw_text_blob_count_;
  };

  DisplayListMetalComplexityCalculator()
      : ceiling_(std::numeric_limits<unsigned int>::max()) {}
  static DisplayListMetalComplexityCalculator* instance_;

  unsigned int ceiling_;
};

}  // namespace flutter

#endif  // FLUTTER_FLOW_DISPLAY_LIST_COMPLEXITY_METAL_H_
