// Copyright 2013 The Chromium 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 <utility>

#include "base/test/launcher/unit_test_launcher.h"
#include "base/test/test_suite.h"
#include "cc/base/lap_timer.h"
#include "cc/paint/paint_op_buffer.h"
#include "cc/paint/paint_op_buffer_serializer.h"
#include "cc/test/test_options_provider.h"
#include "testing/perf/perf_test.h"
#include "third_party/skia/include/core/SkMaskFilter.h"
#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
#include "third_party/skia/include/effects/SkDashPathEffect.h"
#include "third_party/skia/include/effects/SkLayerDrawLooper.h"
#include "third_party/skia/include/effects/SkOffsetImageFilter.h"

namespace cc {
namespace {

static const int kTimeLimitMillis = 2000;
static const int kNumWarmupRuns = 20;
static const int kTimeCheckInterval = 1;

static const size_t kMaxSerializedBufferBytes = 100000;

class PaintOpPerfTest : public testing::Test {
 public:
  PaintOpPerfTest()
      : timer_(kNumWarmupRuns,
               base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
               kTimeCheckInterval),
        serialized_data_(static_cast<char*>(
            base::AlignedAlloc(kMaxSerializedBufferBytes,
                               PaintOpBuffer::PaintOpAlign))),
        deserialized_data_(static_cast<char*>(
            base::AlignedAlloc(sizeof(LargestPaintOp),
                               PaintOpBuffer::PaintOpAlign))) {}

  void RunTest(const std::string& name, const PaintOpBuffer& buffer) {
    TestOptionsProvider test_options_provider;

    size_t bytes_written = 0u;
    PaintOpBufferSerializer::Preamble preamble;

    timer_.Reset();
    do {
      SimpleBufferSerializer serializer(
          serialized_data_.get(), kMaxSerializedBufferBytes,
          test_options_provider.image_provider(),
          test_options_provider.transfer_cache_helper(),
          test_options_provider.client_paint_cache(),
          test_options_provider.strike_server(),
          test_options_provider.color_space(),
          test_options_provider.can_use_lcd_text(),
          test_options_provider.context_supports_distance_field_text(),
          test_options_provider.max_texture_size(),
          test_options_provider.max_texture_bytes());
      serializer.Serialize(&buffer, nullptr, preamble);
      bytes_written = serializer.written();

      // Force client paint cache entries to be written every time.
      test_options_provider.client_paint_cache()->PurgeAll();
      timer_.NextLap();
    } while (!timer_.HasTimeLimitExpired());
    CHECK_GT(bytes_written, 0u);

    perf_test::PrintResult(name.c_str(), "", "  serialize",
                           buffer.size() * timer_.LapsPerSecond(), "ops/s",
                           true);

    size_t bytes_read = 0;
    timer_.Reset();
    test_options_provider.PushFonts();

    do {
      size_t remaining_read_bytes = bytes_written;
      char* to_read = serialized_data_.get();

      while (true) {
        PaintOp* deserialized_op = PaintOp::Deserialize(
            to_read, remaining_read_bytes, deserialized_data_.get(),
            sizeof(LargestPaintOp), &bytes_read,
            test_options_provider.deserialize_options());
        CHECK(deserialized_op);
        deserialized_op->DestroyThis();

        DCHECK_GE(remaining_read_bytes, bytes_read);
        if (remaining_read_bytes == bytes_read)
          break;

        remaining_read_bytes -= bytes_read;
        to_read += bytes_read;
      }

      timer_.NextLap();
    } while (!timer_.HasTimeLimitExpired());

    perf_test::PrintResult(name.c_str(), "", "deserialize",
                           buffer.size() * timer_.LapsPerSecond(), "ops/s",
                           true);
  }

 protected:
  LapTimer timer_;
  std::unique_ptr<char, base::AlignedFreeDeleter> serialized_data_;
  std::unique_ptr<char, base::AlignedFreeDeleter> deserialized_data_;
};

// Ops that can be memcopied both when serializing and deserializing.
TEST_F(PaintOpPerfTest, SimpleOps) {
  PaintOpBuffer buffer;
  for (size_t i = 0; i < 100; ++i)
    buffer.push<ConcatOp>(SkMatrix::I());
  RunTest("simple", buffer);
}

// Drawing ops with flags that don't have nested objects.
TEST_F(PaintOpPerfTest, DrawOps) {
  PaintOpBuffer buffer;
  PaintFlags flags;
  for (size_t i = 0; i < 100; ++i)
    buffer.push<DrawRectOp>(SkRect::MakeXYWH(1, 1, 1, 1), flags);
  RunTest("draw", buffer);
}

// Ops with worst case flags.
TEST_F(PaintOpPerfTest, ManyFlagsOps) {
  PaintOpBuffer buffer;

  PaintFlags flags;
  SkScalar intervals[] = {1.f, 1.f};
  flags.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
  flags.setMaskFilter(SkMaskFilter::MakeBlur(
      SkBlurStyle::kOuter_SkBlurStyle, 4.3));
  flags.setColorFilter(
      SkColorMatrixFilter::MakeLightingFilter(SK_ColorYELLOW, SK_ColorGREEN));

  SkLayerDrawLooper::Builder looper_builder;
  looper_builder.addLayer();
  looper_builder.addLayer(2.3f, 4.5f);
  SkLayerDrawLooper::LayerInfo layer_info;
  looper_builder.addLayer(layer_info);
  flags.setLooper(looper_builder.detach());

  sk_sp<PaintShader> shader = PaintShader::MakeColor(SK_ColorTRANSPARENT);
  flags.setShader(std::move(shader));

  SkPath path;
  path.addCircle(2, 2, 5);
  path.addCircle(3, 4, 2);
  path.addArc(SkRect::MakeXYWH(1, 2, 3, 4), 5, 6);

  for (size_t i = 0; i < 100; ++i)
    buffer.push<DrawPathOp>(path, flags);
  RunTest("flags", buffer);
}

// DrawTextBlobOps,
TEST_F(PaintOpPerfTest, TextOps) {
  PaintOpBuffer buffer;

  auto typeface = SkTypeface::MakeDefault();

  SkFont font;
  font.setTypeface(typeface);

  SkTextBlobBuilder builder;
  int glyph_count = 5;
  SkRect rect = SkRect::MakeXYWH(1, 1, 1, 1);
  const auto& run = builder.allocRun(font, glyph_count, 1.2f, 2.3f, &rect);
  std::fill(run.glyphs, run.glyphs + glyph_count, 0);
  auto blob = builder.make();

  PaintFlags flags;
  for (size_t i = 0; i < 100; ++i)
    buffer.push<DrawTextBlobOp>(blob, 0.f, 0.f, flags);

  RunTest("text", buffer);
}

}  // namespace
}  // namespace cc
