// 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/display_list/benchmarking/dl_complexity_metal.h"

// The numbers and weightings used in this file stem from taking the
// data from the DisplayListBenchmarks suite run on an iPhone 12 and
// applying very rough analysis on them to identify the approximate
// trends.
//
// See the comments in display_list_complexity_helper.h for details on the
// process and rationale behind coming up with these numbers.

namespace flutter {

DisplayListMetalComplexityCalculator*
    DisplayListMetalComplexityCalculator::instance_ = nullptr;

DisplayListMetalComplexityCalculator*
DisplayListMetalComplexityCalculator::GetInstance() {
  if (instance_ == nullptr) {
    instance_ = new DisplayListMetalComplexityCalculator();
  }
  return instance_;
}

unsigned int
DisplayListMetalComplexityCalculator::MetalHelper::BatchedComplexity() {
  // Calculate the impact of saveLayer.
  unsigned int save_layer_complexity;
  if (save_layer_count_ == 0) {
    save_layer_complexity = 0;
  } else {
    // saveLayer seems to have two trends; if the count is < 200,
    // then the individual cost of a saveLayer is higher than if
    // the count is > 200.
    //
    // However, the trend is strange and we should gather more data to
    // get a better idea of how to represent the trend. That being said, it's
    // very unlikely we'll ever hit a DisplayList with 200+ saveLayer calls
    // in it, so we will calculate based on the more reasonably anticipated
    // range of less than 200, with the trend line more weighted towards the
    // lower end of that range (as the data itself doesn't present as a straight
    // line). Further, we will easily hit our cache thresholds with such a
    // large number of saveLayer calls.
    //
    // m = 1/2
    // c = 1
    save_layer_complexity = (save_layer_count_ + 2) * 100000;
  }

  unsigned int draw_text_blob_complexity;
  if (draw_text_blob_count_ == 0) {
    draw_text_blob_complexity = 0;
  } else {
    // m = 1/240
    // c = 0.75
    draw_text_blob_complexity = (draw_text_blob_count_ + 180) * 2500 / 3;
  }

  return save_layer_complexity + draw_text_blob_complexity;
}

void DisplayListMetalComplexityCalculator::MetalHelper::saveLayer(
    const SkRect& bounds,
    const SaveLayerOptions options,
    const DlImageFilter* backdrop) {
  if (IsComplex()) {
    return;
  }
  if (backdrop) {
    // Flutter does not offer this operation so this value can only ever be
    // non-null for a frame-wide builder which is not currently evaluated for
    // complexity.
    AccumulateComplexity(Ceiling());
  }
  save_layer_count_++;
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawLine(
    const SkPoint& p0,
    const SkPoint& p1) {
  if (IsComplex()) {
    return;
  }
  // The curve here may be log-linear, although it doesn't really match up that
  // well. To avoid costly computations, try and do a best fit of the data onto
  // a linear graph as a very rough first order approximation.

  float non_hairline_penalty = 1.0f;
  float aa_penalty = 1.0f;

  if (!IsHairline()) {
    non_hairline_penalty = 1.15f;
  }
  if (IsAntiAliased()) {
    aa_penalty = 1.4f;
  }

  // Use an approximation for the distance to avoid floating point or
  // sqrt() calls.
  SkScalar distance = abs(p0.x() - p1.x()) + abs(p0.y() - p1.y());

  // The baseline complexity is for a hairline stroke with no AA.
  // m = 1/45
  // c = 5
  unsigned int complexity =
      ((distance + 225) * 4 / 9) * non_hairline_penalty * aa_penalty;

  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawDashedLine(
    const DlPoint& p0,
    const DlPoint& p1,
    DlScalar on_length,
    DlScalar off_length) {
  // Dashing is slightly more complex than a regular drawLine, but this
  // op is so rare it is not worth measuring the difference.
  drawLine(ToSkPoint(p0), ToSkPoint(p1));
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawRect(
    const SkRect& rect) {
  if (IsComplex()) {
    return;
  }

  unsigned int complexity;

  // If stroked, cost scales linearly with the rectangle width/height.
  // If filled, it scales with the area.
  //
  // Hairline stroke vs non hairline has no real penalty at smaller lengths,
  // but it increases at larger lengths. There isn't enough data to get a good
  // idea of the penalty at lengths > 1000px.
  //
  // There is also a kStrokeAndFill_Style that Skia exposes, but we do not
  // currently use it anywhere in Flutter.
  if (DrawStyle() == DlDrawStyle::kFill) {
    // No real difference for AA with filled styles.
    unsigned int area = rect.width() * rect.height();

    // m = 1/9000
    // c = 0
    complexity = area / 225;
  } else {
    // Take the average of the width and height.
    unsigned int length = (rect.width() + rect.height()) / 2;

    // There is a penalty for AA being *disabled*.
    if (IsAntiAliased()) {
      // m = 1/65
      // c = 0
      complexity = length * 8 / 13;
    } else {
      // m = 1/35
      // c = 0
      complexity = length * 8 / 7;
    }
  }

  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawOval(
    const SkRect& bounds) {
  if (IsComplex()) {
    return;
  }
  // DrawOval scales very roughly linearly with the bounding box width/height
  // (not area) for stroked styles without AA.
  //
  // Filled styles and stroked styles with AA scale linearly with the bounding
  // box area.
  unsigned int area = bounds.width() * bounds.height();

  unsigned int complexity;

  // There is also a kStrokeAndFill_Style that Skia exposes, but we do not
  // currently use it anywhere in Flutter.
  if (DrawStyle() == DlDrawStyle::kFill) {
    // With filled styles, there is no significant AA penalty.
    // m = 1/16000
    // c = 0
    complexity = area / 80;
  } else {
    if (IsAntiAliased()) {
      // m = 1/7500
      // c = 0
      complexity = area * 2 / 75;
    } else {
      // Take the average of the width and height.
      unsigned int length = (bounds.width() + bounds.height()) / 2;

      // m = 1/80
      // c = 0
      complexity = length * 5 / 2;
    }
  }

  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawCircle(
    const SkPoint& center,
    SkScalar radius) {
  if (IsComplex()) {
    return;
  }

  unsigned int complexity;

  // There is also a kStrokeAndFill_Style that Skia exposes, but we do not
  // currently use it anywhere in Flutter.
  if (DrawStyle() == DlDrawStyle::kFill) {
    // We can ignore pi here.
    unsigned int area = radius * radius;
    // m = 1/1300
    // c = 5
    complexity = (area + 6500) * 2 / 65;

    // Penalty of around 5% when AA is disabled.
    if (!IsAntiAliased()) {
      complexity *= 1.05f;
    }
  } else {
    // Hairline vs non-hairline has no significant performance difference.
    if (IsAntiAliased()) {
      // m = 1/7
      // c = 7
      complexity = (radius + 49) * 40 / 7;
    } else {
      // m = 1/16
      // c = 8
      complexity = (radius + 128) * 5 / 2;
    }
  }

  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawRRect(
    const SkRRect& rrect) {
  if (IsComplex()) {
    return;
  }
  // RRects scale linearly with the area of the bounding rect.
  unsigned int area = rrect.width() * rrect.height();

  // Drawing RRects is split into two performance tiers; an expensive
  // one and a less expensive one. Both scale linearly with area.
  //
  // Expensive: All filled style, symmetric w/AA.
  bool expensive =
      (DrawStyle() == DlDrawStyle::kFill) ||
      ((rrect.getType() == SkRRect::Type::kSimple_Type) && IsAntiAliased());

  unsigned int complexity;

  // These values were worked out by creating a straight line graph (y=mx+c)
  // approximately matching the measured data, normalising the data so that
  // 0.0005ms resulted in a score of 100 then simplifying down the formula.
  if (expensive) {
    // m = 1/25000
    // c = 2
    // An area of 7000px^2 ~= baseline timing of 0.0005ms.
    complexity = (area + 10500) / 175;
  } else {
    // m = 1/7000
    // c = 1.5
    // An area of 16000px^2 ~= baseline timing of 0.0005ms.
    complexity = (area + 50000) / 625;
  }

  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawDRRect(
    const SkRRect& outer,
    const SkRRect& inner) {
  if (IsComplex()) {
    return;
  }
  // There are roughly four classes here:
  // a) Filled style with AA enabled.
  // b) Filled style with AA disabled.
  // c) Complex RRect type with AA enabled and filled style.
  // d) Everything else.
  //
  // a) and c) scale linearly with the area, b) and d) scale linearly with
  // a single dimension (length). In all cases, the dimensions refer to
  // the outer RRect.
  unsigned int length = (outer.width() + outer.height()) / 2;

  unsigned int complexity;

  // These values were worked out by creating a straight line graph (y=mx+c)
  // approximately matching the measured data, normalising the data so that
  // 0.0005ms resulted in a score of 100 then simplifying down the formula.
  //
  // There is also a kStrokeAndFill_Style that Skia exposes, but we do not
  // currently use it anywhere in Flutter.
  if (DrawStyle() == DlDrawStyle::kFill) {
    unsigned int area = outer.width() * outer.height();
    if (outer.getType() == SkRRect::Type::kComplex_Type) {
      // m = 1/1000
      // c = 1
      complexity = (area + 1000) / 10;
    } else {
      if (IsAntiAliased()) {
        // m = 1/3500
        // c = 1.5
        complexity = (area + 5250) / 35;
      } else {
        // m = 1/30
        // c = 1
        complexity = (300 + (10 * length)) / 3;
      }
    }
  } else {
    // m = 1/60
    // c = 1.75
    complexity = ((10 * length) + 1050) / 6;
  }

  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawPath(
    const SkPath& path) {
  if (IsComplex()) {
    return;
  }
  // There is negligible effect on the performance for hairline vs. non-hairline
  // stroke widths.
  //
  // The data for filled styles is currently suspicious, so for now we are going
  // to assign scores based on stroked styles.

  unsigned int line_verb_cost, quad_verb_cost, conic_verb_cost, cubic_verb_cost;

  if (IsAntiAliased()) {
    line_verb_cost = 75;
    quad_verb_cost = 100;
    conic_verb_cost = 160;
    cubic_verb_cost = 210;
  } else {
    line_verb_cost = 67;
    quad_verb_cost = 80;
    conic_verb_cost = 140;
    cubic_verb_cost = 210;
  }

  // There seems to be a fixed cost of around 1ms for calling drawPath.
  unsigned int complexity =
      200000 + CalculatePathComplexity(path, line_verb_cost, quad_verb_cost,
                                       conic_verb_cost, cubic_verb_cost);

  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawArc(
    const SkRect& oval_bounds,
    SkScalar start_degrees,
    SkScalar sweep_degrees,
    bool use_center) {
  if (IsComplex()) {
    return;
  }
  // Hairline vs non-hairline makes no difference to the performance.
  // Stroked styles without AA scale linearly with the diameter.
  // Stroked styles with AA scale linearly with the area except for small
  // values. Filled styles scale linearly with the area.
  unsigned int diameter = (oval_bounds.width() + oval_bounds.height()) / 2;
  unsigned int area = oval_bounds.width() * oval_bounds.height();

  unsigned int complexity;

  // These values were worked out by creating a straight line graph (y=mx+c)
  // approximately matching the measured data, normalising the data so that
  // 0.0005ms resulted in a score of 100 then simplifying down the formula.
  //
  // There is also a kStrokeAndFill_Style that Skia exposes, but we do not
  // currently use it anywhere in Flutter.
  if (DrawStyle() == DlDrawStyle::kStroke) {
    if (IsAntiAliased()) {
      // m = 1/8500
      // c = 16
      complexity = (area + 136000) * 2 / 765;
    } else {
      // m = 1/60
      // c = 3
      complexity = (diameter + 180) * 10 / 27;
    }
  } else {
    if (IsAntiAliased()) {
      // m = 1/20000
      // c = 20
      complexity = (area + 400000) / 900;
    } else {
      // m = 1/2100
      // c = 8
      complexity = (area + 16800) * 2 / 189;
    }
  }

  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawPoints(
    DlCanvas::PointMode mode,
    uint32_t count,
    const SkPoint points[]) {
  if (IsComplex()) {
    return;
  }
  unsigned int complexity;

  // If AA is off then they all behave similarly, and scale
  // linearly with the point count.
  if (!IsAntiAliased()) {
    // m = 1/16000
    // c = 0.75
    complexity = (count + 12000) * 25 / 2;
  } else {
    if (mode == DlCanvas::PointMode::kPolygon) {
      // m = 1/1250
      // c = 1
      complexity = (count + 1250) * 160;
    } else {
      if (IsHairline() && mode == DlCanvas::PointMode::kPoints) {
        // This is a special case, it triggers an extremely fast path.
        // m = 1/14500
        // c = 0
        complexity = count * 400 / 29;
      } else {
        // m = 1/2200
        // c = 0.75
        complexity = (count + 1650) * 1000 / 11;
      }
    }
  }
  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawVertices(
    const std::shared_ptr<DlVertices>& vertices,
    DlBlendMode mode) {
  // There is currently no way for us to get the VertexMode from the SkVertices
  // object, but for future reference:
  //
  // TriangleStrip is roughly 25% more expensive than TriangleFan.
  // TriangleFan is roughly 5% more expensive than Triangles.

  // For the baseline, it's hard to identify the trend. It might be O(n^1/2).
  // For now, treat it as linear as an approximation.
  //
  // m = 1/4000
  // c = 1
  unsigned int complexity = (vertices->vertex_count() + 4000) * 50;

  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawImage(
    const sk_sp<DlImage> image,
    const SkPoint point,
    DlImageSampling sampling,
    bool render_with_attributes) {
  if (IsComplex()) {
    return;
  }
  // AA vs non-AA has a cost but it's dwarfed by the overall cost of the
  // drawImage call.
  //
  // The main difference is if the image is backed by a texture already or not
  // If we don't need to upload, then the cost scales linearly with the
  // area of the image. If it needs uploading, the cost scales linearly
  // with the square of the area (!!!).
  SkISize dimensions = image->dimensions();
  unsigned int area = dimensions.width() * dimensions.height();

  // m = 1/17000
  // c = 3
  unsigned int complexity = (area + 51000) * 4 / 170;

  if (!image->isTextureBacked()) {
    // We can't square the area here as we'll overflow, so let's approximate
    // by taking the calculated complexity score and applying a multiplier to
    // it.
    //
    // (complexity * area / 35000) + 1200 gives a reasonable approximation.
    float multiplier = area / 35000.0f;
    complexity = complexity * multiplier + 1200;
  }

  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::ImageRect(
    const SkISize& size,
    bool texture_backed,
    bool render_with_attributes,
    bool enforce_src_edges) {
  if (IsComplex()) {
    return;
  }
  // Two main groups here - texture-backed and non-texture-backed images.
  //
  // Within each group, they all perform within a few % of each other *except*
  // when we have a strict constraint and anti-aliasing enabled.
  unsigned int area = size.width() * size.height();

  // These values were worked out by creating a straight line graph (y=mx+c)
  // approximately matching the measured data, normalising the data so that
  // 0.0005ms resulted in a score of 100 then simplifying down the formula.
  unsigned int complexity;
  if (texture_backed) {
    // Baseline for texture-backed SkImages.
    // m = 1/23000
    // c = 2.3
    complexity = (area + 52900) * 2 / 115;
    if (render_with_attributes && enforce_src_edges && IsAntiAliased()) {
      // There's about a 30% performance penalty from the baseline.
      complexity *= 1.3f;
    }
  } else {
    if (render_with_attributes && enforce_src_edges && IsAntiAliased()) {
      // m = 1/12200
      // c = 2.75
      complexity = (area + 33550) * 2 / 61;
    } else {
      // m = 1/14500
      // c = 2.5
      complexity = (area + 36250) * 4 / 145;
    }
  }

  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawImageNine(
    const sk_sp<DlImage> image,
    const SkIRect& center,
    const SkRect& dst,
    DlFilterMode filter,
    bool render_with_attributes) {
  if (IsComplex()) {
    return;
  }
  // Whether uploading or not, the performance is comparable across all
  // variations.
  SkISize dimensions = image->dimensions();
  unsigned int area = dimensions.width() * dimensions.height();

  // m = 1/8000
  // c = 3
  unsigned int complexity = (area + 24000) / 20;
  AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawDisplayList(
    const sk_sp<DisplayList> display_list,
    SkScalar opacity) {
  if (IsComplex()) {
    return;
  }
  MetalHelper helper(Ceiling() - CurrentComplexityScore());
  if (opacity < SK_Scalar1 && !display_list->can_apply_group_opacity()) {
    auto bounds = display_list->bounds();
    helper.saveLayer(bounds, SaveLayerOptions::kWithAttributes, nullptr);
  }
  display_list->Dispatch(helper);
  AccumulateComplexity(helper.ComplexityScore());
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawTextBlob(
    const sk_sp<SkTextBlob> blob,
    SkScalar x,
    SkScalar y) {
  if (IsComplex()) {
    return;
  }

  // DrawTextBlob has a high fixed cost, but if we call it multiple times
  // per frame, that fixed cost is greatly reduced per subsequent call. This
  // is likely because there is batching being done in SkCanvas.

  // Increment draw_text_blob_count_ and calculate the cost at the end.
  draw_text_blob_count_++;
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawTextFrame(
    const std::shared_ptr<impeller::TextFrame>& text_frame,
    SkScalar x,
    SkScalar y) {}

void DisplayListMetalComplexityCalculator::MetalHelper::drawShadow(
    const SkPath& path,
    const DlColor color,
    const SkScalar elevation,
    bool transparent_occluder,
    SkScalar dpr) {
  if (IsComplex()) {
    return;
  }

  // Elevation has no significant effect on the timings. Whether the shadow
  // is cast by a transparent occluder or not has a small impact of around 5%.
  //
  // The path verbs do have an effect but only if the verb type is cubic; line,
  // quad and conic all perform similarly.
  float occluder_penalty = 1.0f;
  if (transparent_occluder) {
    occluder_penalty = 1.05f;
  }

  // The benchmark uses a test path of around 10 path elements. This is likely
  // to be similar to what we see in real world usage, but we should benchmark
  // different path lengths to see how much impact there is from varying the
  // path length.
  //
  // For now, we will assume that there is no fixed overhead and that the time
  // spent rendering the shadow for a path is split evenly amongst all the verbs
  // enumerated.
  unsigned int line_verb_cost = 20000;   // 0.1ms
  unsigned int quad_verb_cost = 20000;   // 0.1ms
  unsigned int conic_verb_cost = 20000;  // 0.1ms
  unsigned int cubic_verb_cost = 80000;  // 0.4ms

  unsigned int complexity =
      0 + CalculatePathComplexity(path, line_verb_cost, quad_verb_cost,
                                  conic_verb_cost, cubic_verb_cost);

  AccumulateComplexity(complexity * occluder_penalty);
}

}  // namespace flutter
