// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/trace_event/benchmark.h"

#include <memory>

#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/math/size.h"
#include "cobalt/renderer/backend/default_graphics_system.h"
#include "cobalt/renderer/backend/graphics_context.h"
#include "cobalt/renderer/backend/graphics_system.h"
#include "cobalt/renderer/backend/render_target.h"
#include "cobalt/renderer/rasterizer/rasterizer.h"
#include "cobalt/renderer/renderer_module.h"
#include "cobalt/renderer/test/scenes/all_scenes_combined_scene.h"
#include "cobalt/system_window/system_window.h"

using cobalt::math::Size;
using cobalt::math::SizeF;
using cobalt::render_tree::AlphaFormat;
using cobalt::render_tree::ImageData;
using cobalt::render_tree::Node;
using cobalt::render_tree::PixelFormat;
using cobalt::render_tree::ResourceProvider;
using cobalt::render_tree::animations::AnimateNode;
using cobalt::renderer::RendererModule;
using cobalt::renderer::backend::Display;
using cobalt::renderer::backend::GraphicsContext;
using cobalt::renderer::backend::GraphicsSystem;
using cobalt::renderer::backend::RenderTarget;
using cobalt::renderer::backend::SurfaceInfo;
using cobalt::renderer::rasterizer::Rasterizer;
using cobalt::renderer::test::scenes::AddBlankBackgroundToScene;
using cobalt::renderer::test::scenes::CreateAllScenesCombinedScene;
using cobalt::system_window::SystemWindow;

namespace {
const int kViewportWidth = 1920;
const int kViewportHeight = 1080;

std::unique_ptr<Rasterizer> CreateDefaultRasterizer(
    GraphicsContext* graphics_context) {
  RendererModule::Options render_module_options;
  return render_module_options.create_rasterizer_function.Run(
      graphics_context, render_module_options);
}

// Allow test writers to choose whether the rasterizer results should be drawn
// on-screen or off-screen.  The major difference between the two is that when
// drawing to a display, we must wait for v-sync, and thus the framerate will
// be capped at 60fps.
enum OutputSurfaceType {
  kOutputSurfaceTypeDisplay,
  kOutputSurfaceTypeOffscreen,
};

typedef base::Callback<scoped_refptr<Node>(ResourceProvider*, const SizeF&,
                                           base::TimeDelta)>
    SceneCreateFunction;

// RunRenderTreeSceneBenchmark serves as a framework for render tree scene
// based benchmarks.  In other words, it makes it easy to test performance
// metrics given different render tree scenes.
void RunRenderTreeSceneBenchmark(SceneCreateFunction scene_create_function,
                                 OutputSurfaceType output_surface_type) {
  // Disable tracing so that we can iterate one round without recording
  // results.  This is to trigger any lazy initialization that may need to
  // be done.
  base::trace_event::TraceLog::GetInstance()->SetDisabled(
      base::trace_event::TraceLog::RECORDING_MODE);

  base::EventDispatcher event_dispatcher;
  std::unique_ptr<SystemWindow> test_system_window;
  if (output_surface_type == kOutputSurfaceTypeDisplay) {
    Size view_size(kViewportWidth, kViewportHeight);
    test_system_window.reset(
        new cobalt::system_window::SystemWindow(&event_dispatcher, view_size));
  }

  // Setup our graphics system.
  std::unique_ptr<GraphicsSystem> graphics_system =
      cobalt::renderer::backend::CreateDefaultGraphicsSystem(
          test_system_window.get());
  std::unique_ptr<GraphicsContext> graphics_context =
      graphics_system->CreateGraphicsContext();

  // Create the rasterizer using the platform default RenderModule options.
  std::unique_ptr<Rasterizer> rasterizer =
      CreateDefaultRasterizer(graphics_context.get());

  std::unique_ptr<Display> test_display;
  scoped_refptr<RenderTarget> test_surface;
  if (output_surface_type == kOutputSurfaceTypeDisplay) {
    test_display = graphics_system->CreateDisplay(test_system_window.get());
    test_surface = test_display->GetRenderTarget();
  } else if (output_surface_type == kOutputSurfaceTypeOffscreen) {
    // Create our offscreen surface that will be the target of our test
    // rasterizations.
    const Size kTestOffscreenDimensions(1920, 1080);
    test_surface = graphics_context->CreateDownloadableOffscreenRenderTarget(
        kTestOffscreenDimensions);
  } else {
    DLOG(FATAL) << "Unknown output surface type.";
  }

  scoped_refptr<Node> scene =
      scene_create_function.Run(rasterizer->GetResourceProvider(),
                                test_surface->GetSize(), base::TimeDelta());

  const int kRenderIterationCount = 100;
  const float kFixedTimeStepInSecondsPerFrame = 0.016f;
  for (int i = 0; i < kRenderIterationCount; ++i) {
    AnimateNode* animate_node =
        base::polymorphic_downcast<AnimateNode*>(scene.get());
    scoped_refptr<Node> animated = animate_node
                                       ->Apply(base::TimeDelta::FromSecondsD(
                                           i * kFixedTimeStepInSecondsPerFrame))
                                       .animated->source();

    // Submit the render tree to be rendered.
    rasterizer->Submit(animated, test_surface);
    graphics_context->Finish();

    if (i == 0) {
      // Enable tracing again after one iteration has passed and any lazy
      // initializations are out of the way.
      base::trace_event::TraceLog::GetInstance()->SetEnabled(
          base::trace_event::TraceConfig(),
          base::trace_event::TraceLog::RECORDING_MODE);
    }
  }
}
}  // namespace

// Setup a quick macro so that we can measure the same events for each
// render tree builder benchmark.
#define RENDER_TREE_BUILDER_BENCHMARK(test_name)                              \
  TRACE_EVENT_BENCHMARK5(                                                     \
      test_name, "BuildRenderTree", cobalt::trace_event::IN_SCOPE_DURATION,   \
      "AnimateNode::Apply()", cobalt::trace_event::IN_SCOPE_DURATION,         \
      "Rasterizer::Submit()", cobalt::trace_event::FLOW_DURATION,             \
      "Rasterizer::Submit()", cobalt::trace_event::TIME_BETWEEN_EVENT_STARTS, \
      "VisitRenderTree", cobalt::trace_event::IN_SCOPE_DURATION)

// A catch-all test that exercises every different render tree node at the
// same time.  This is the same render tree builder used by the renderer
// sandbox.
RENDER_TREE_BUILDER_BENCHMARK(AllScenesCombinedOffscreenBenchmark) {
  RunRenderTreeSceneBenchmark(base::Bind(&CreateAllScenesCombinedScene),
                              kOutputSurfaceTypeOffscreen);
}

RENDER_TREE_BUILDER_BENCHMARK(AllScenesCombinedOnscreenBenchmark) {
  RunRenderTreeSceneBenchmark(base::Bind(&CreateAllScenesCombinedScene),
                              kOutputSurfaceTypeDisplay);
}

// This benchmark tracks how long it takes to load image data into a image
// via the render_tree::ResourceProvider interface provided by our default
// rasterizer.
namespace {
void SynthesizeImageData(ImageData* image_data) {
  TRACE_EVENT0("rasterizer_benchmark", "SynthesizeImageData");
  // Simply fill the entire image with a single arbitrarily chosen byte value.
  const uint8_t kFillValue = 127;
  int height = image_data->GetDescriptor().size.height();
  int pitch_in_bytes = image_data->GetDescriptor().pitch_in_bytes;
  for (int row = 0; row < height; ++row) {
    uint8_t* pixel_data = image_data->GetMemory() + row * pitch_in_bytes;
    for (int row_byte = 0; row_byte < pitch_in_bytes; ++row_byte) {
      pixel_data[row_byte] = kFillValue;
    }
  }
}

void RunCreateImageViaResourceProviderBenchmark(AlphaFormat alpha_format) {
  std::unique_ptr<GraphicsSystem> graphics_system =
      cobalt::renderer::backend::CreateDefaultGraphicsSystem();
  std::unique_ptr<GraphicsContext> graphics_context =
      graphics_system->CreateGraphicsContext();

  // Create the rasterizer using the platform default RenderModule options.
  std::unique_ptr<Rasterizer> rasterizer =
      CreateDefaultRasterizer(graphics_context.get());

  ResourceProvider* resource_provider = rasterizer->GetResourceProvider();
  if (!resource_provider->AlphaFormatSupported(alpha_format)) {
    // Only run the test if the alpha format is supported.
    return;
  }

  const int kIterationCount = 20;
  const Size kImageSize(400, 400);
  cobalt::render_tree::PixelFormat pixel_format =
      cobalt::render_tree::kPixelFormatRGBA8;
  if (!resource_provider->PixelFormatSupported(pixel_format)) {
    pixel_format = cobalt::render_tree::kPixelFormatBGRA8;
    if (!resource_provider->PixelFormatSupported(pixel_format)) {
      LOG(ERROR) << "Could not find a supported pixel format on this platform, "
                    "returning early from benchmark.";
      return;
    }
  }

  for (int i = 0; i < kIterationCount; ++i) {
    // Repeatedly allocate memory for an image, write to that memory, and then
    // submit the image data back to the ResourceProvider to have it create
    // an image out of it.
    std::unique_ptr<ImageData> image_data =
        resource_provider->AllocateImageData(kImageSize, pixel_format,
                                             alpha_format);

    SynthesizeImageData(image_data.get());

    resource_provider->CreateImage(std::move(image_data));
  }
}
}  // namespace

TRACE_EVENT_BENCHMARK3(
    CreateUnpremultipliedAlphaImageViaResourceProviderBenchmark,
    "ResourceProvider::AllocateImageData()",
    cobalt::trace_event::IN_SCOPE_DURATION, "ResourceProvider::CreateImage()",
    cobalt::trace_event::IN_SCOPE_DURATION, "SynthesizeImageData",
    cobalt::trace_event::IN_SCOPE_DURATION) {
  RunCreateImageViaResourceProviderBenchmark(
      cobalt::render_tree::kAlphaFormatUnpremultiplied);
}

TRACE_EVENT_BENCHMARK3(
    CreatePremultipliedAlphaImageViaResourceProviderBenchmark,
    "ResourceProvider::AllocateImageData()",
    cobalt::trace_event::IN_SCOPE_DURATION, "ResourceProvider::CreateImage()",
    cobalt::trace_event::IN_SCOPE_DURATION, "SynthesizeImageData",
    cobalt::trace_event::IN_SCOPE_DURATION) {
  RunCreateImageViaResourceProviderBenchmark(
      cobalt::render_tree::kAlphaFormatPremultiplied);
}
