// Copyright 2015 Google Inc. 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/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"
#include "cobalt/trace_event/benchmark.h"

using cobalt::math::Size;
using cobalt::math::SizeF;
using cobalt::render_tree::AlphaFormat;
using cobalt::render_tree::animations::AnimateNode;
using cobalt::render_tree::ImageData;
using cobalt::render_tree::Node;
using cobalt::render_tree::PixelFormat;
using cobalt::render_tree::ResourceProvider;
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::RendererModule;
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;

scoped_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::debug::TraceLog::GetInstance()->SetEnabled(false);

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

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

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

  scoped_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::debug::TraceLog::GetInstance()->SetEnabled(true);
    }
  }
}
}  // 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 excercises 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) {
  scoped_ptr<GraphicsSystem> graphics_system =
      cobalt::renderer::backend::CreateDefaultGraphicsSystem();
  scoped_ptr<GraphicsContext> graphics_context =
      graphics_system->CreateGraphicsContext();

  // Create the rasterizer using the platform default RenderModule options.
  scoped_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.
    scoped_ptr<ImageData> image_data = resource_provider->AllocateImageData(
        kImageSize, pixel_format, alpha_format);

    SynthesizeImageData(image_data.get());

    resource_provider->CreateImage(image_data.Pass());
  }
}
}  // 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);
}
