// 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/render_tree/resource_provider.h"

#include <memory>

#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/simple_thread.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 "testing/gtest/include/gtest/gtest.h"

using cobalt::render_tree::ResourceProvider;

namespace cobalt {
namespace renderer {

namespace {
render_tree::PixelFormat ChoosePixelFormat(
    ResourceProvider* resource_provider) {
  if (resource_provider->PixelFormatSupported(render_tree::kPixelFormatRGBA8)) {
    return render_tree::kPixelFormatRGBA8;
  } else if (resource_provider->PixelFormatSupported(
                 render_tree::kPixelFormatBGRA8)) {
    return render_tree::kPixelFormatBGRA8;
  } else {
    return render_tree::kPixelFormatInvalid;
  }
}

// This functor/thread is designed to simply allocate many textures as quickly
// in a row as possible.  Many threads should be capable of doing this
// simultaneously.
class CreateImagesThread : public base::SimpleThread {
 public:
  CreateImagesThread(ResourceProvider* resource_provider,
                     int num_images_to_create, const math::Size& image_size)
      : base::SimpleThread("CreateImages"),
        resource_provider_(resource_provider),
        num_images_to_create_(num_images_to_create),
        image_size_(image_size) {}

  void Run() override {
    for (int i = 0; i < num_images_to_create_; ++i) {
      std::unique_ptr<render_tree::ImageData> image_data =
          resource_provider_->AllocateImageData(
              image_size_, ChoosePixelFormat(resource_provider_),
              render_tree::kAlphaFormatPremultiplied);
      int num_bytes = image_data->GetDescriptor().pitch_in_bytes *
                      image_data->GetDescriptor().size.height();
      uint8* image_memory = image_data->GetMemory();
      for (int i = 0; i < num_bytes; ++i) {
        image_memory[i] = 0;
      }
      resource_provider_->CreateImage(std::move(image_data));
    }
  }

 private:
  ResourceProvider* resource_provider_;
  int num_images_to_create_;
  const math::Size image_size_;
};

// This functor/thread will spawn the given number of CreateImagesThreads,
// execute them, and then wait for them to complete.  Upon completion, it will
// call the provided callback function.
class CreateImagesSpawnerThread : public base::SimpleThread {
 public:
  CreateImagesSpawnerThread(ResourceProvider* resource_provider,
                            int threads_to_create,
                            int images_to_create_per_thread,
                            const math::Size& image_size,
                            base::Closure finished_callback)
      : base::SimpleThread("CreateImagesSpawner"),
        resource_provider_(resource_provider),
        threads_to_create_(threads_to_create),
        images_to_create_per_thread_(images_to_create_per_thread),
        image_size_(image_size),
        finished_callback_(finished_callback) {}

  void Run() override {
    // First, create our threads.
    typedef std::vector<CreateImagesThread*> ThreadVector;
    ThreadVector image_creating_threads;
    for (int i = 0; i < threads_to_create_; ++i) {
      image_creating_threads.push_back(new CreateImagesThread(
          resource_provider_, images_to_create_per_thread_, image_size_));
    }

    // Second, tell them all to begin executing at the same time.
    for (ThreadVector::iterator iter = image_creating_threads.begin();
         iter != image_creating_threads.end(); ++iter) {
      (*iter)->Start();
    }

    // Thirdly, wait for them to all finish executing and then destroy them.
    for (ThreadVector::iterator iter = image_creating_threads.begin();
         iter != image_creating_threads.end(); ++iter) {
      (*iter)->Join();
      delete *iter;
    }

    finished_callback_.Run();
  }

 private:
  ResourceProvider* resource_provider_;
  int threads_to_create_;
  int images_to_create_per_thread_;
  const math::Size image_size_;
  base::Closure finished_callback_;
};
}  // namespace

class ResourceProviderTest : public testing::Test {
 public:
  ResourceProviderTest();
  ~ResourceProviderTest();

  static void SetUpTestCase();
  static void TearDownTestCase();

  // Lets the fixture know that it will run the run loop manually, and the
  // ResourceProviderTest destructor does not need to run it.
  void SetWillRunRunLoopManually() { run_run_loop_manually_ = true; }

  void Quit() {
    message_loop_.task_runner()->PostTask(FROM_HERE, run_loop_.QuitClosure());
  }

 protected:
  base::MessageLoop message_loop_;
  base::RunLoop run_loop_;
  std::unique_ptr<rasterizer::Rasterizer> rasterizer_;

  bool run_run_loop_manually_;

  static backend::GraphicsSystem* graphics_system_;
  static backend::GraphicsContext* graphics_context_;
};

ResourceProviderTest::ResourceProviderTest()
    : message_loop_(base::MessageLoop::TYPE_DEFAULT),
      run_run_loop_manually_(false) {
  // Create the rasterizer using the platform default RenderModule options.
  RendererModule::Options render_module_options;
  rasterizer_ = render_module_options.create_rasterizer_function.Run(
      graphics_context_, render_module_options);
}

ResourceProviderTest::~ResourceProviderTest() {
  if (!run_run_loop_manually_) {
    message_loop_.task_runner()->PostTask(FROM_HERE, run_loop_.QuitClosure());
    run_loop_.Run();
  }
}

// static
backend::GraphicsSystem* ResourceProviderTest::graphics_system_ = nullptr;
// static
backend::GraphicsContext* ResourceProviderTest::graphics_context_ = nullptr;

// static
void ResourceProviderTest::SetUpTestCase() {
  graphics_system_ = backend::CreateDefaultGraphicsSystem().release();
  graphics_context_ = graphics_system_->CreateGraphicsContext().release();
}

// static
void ResourceProviderTest::TearDownTestCase() {
  delete graphics_context_;
  graphics_context_ = nullptr;
  delete graphics_system_;
  graphics_system_ = nullptr;
}

// The following test ensures that any thread can successfully create render
// tree images both at the same time and also while a graphics frame is started.
// This might be a problem in an OpenGL implementation for instance if we
// are naively setting ourselves as the current OpenGL context in order to
// create a texture, in which case another thread holding the context would
// be upset that it was taken away.  This test is essentially attempting to
// cause a crash or DCHECK() to be hit, if the test executes without crashing,
// everything is okay.
TEST_F(ResourceProviderTest, TexturesCanBeCreatedFromSecondaryThread) {
  SetWillRunRunLoopManually();

  // Create a dummy offscreen surface so that we can have a target when we start
  // a frame with the graphics context.
  const math::Size kDummySurfaceDimensions(1, 1);
  scoped_refptr<backend::RenderTarget> dummy_output_surface =
      graphics_context_->CreateOffscreenRenderTarget(kDummySurfaceDimensions);

  // Now that we're inside of a new frame, create images from a separate
  // thread.  This should be perfectly legal and cause no problems.
  const int kNumThreads = 20;
  const int kNumImagesCreatedPerThread = 300;

  // Create a thread to create other threads that will create images.
  CreateImagesSpawnerThread spawner_thread(
      rasterizer_->GetResourceProvider(), kNumThreads,
      kNumImagesCreatedPerThread, math::Size(1, 1),
      base::Bind(&ResourceProviderTest::Quit, base::Unretained(this)));
  spawner_thread.Start();

  // Run our message loop to process backend image creation/destruction
  // requests.
  run_loop_.Run();

  spawner_thread.Join();
}

// If textures never get passed to the renderer, then both allocating and
// releasing them should happen instantly.  In other words, this test ensures
// that we don't have a problem where texture allocations are instantaneous
// but texture deallocations are delayed.  This might be a problem if the
// video decoder is tracking its video frame texture memory usage to maintain
// up to N textures in memory at a time.  If it skips some frames, it might
// release them and then expect that it can allocate N more, but if those
// released frames have a delay on their release, we may have many more than
// N textures allocated at a time.
TEST_F(ResourceProviderTest, ManyTexturesCanBeCreatedAndDestroyedQuickly) {
  SetWillRunRunLoopManually();

  // Create a dummy offscreen surface so that we can have a target when we start
  // a frame with the graphics context.
  const math::Size kDummySurfaceDimensions(1, 1);
  scoped_refptr<backend::RenderTarget> dummy_output_surface =
      graphics_context_->CreateOffscreenRenderTarget(kDummySurfaceDimensions);

  // Now that we're inside of a new frame, create images from a separate
  // thread.  This should be perfectly legal and cause no problems.
  const int kNumThreads = 2;
  const int kNumImagesCreatedPerThread = 500;

  // Create a thread to create other threads that will create images.
  CreateImagesSpawnerThread spawner_thread(
      rasterizer_->GetResourceProvider(), kNumThreads,
      kNumImagesCreatedPerThread, math::Size(256, 256),
      base::Bind(&ResourceProviderTest::Quit, base::Unretained(this)));
  spawner_thread.Start();

  // Run our message loop to process backend image creation/destruction
  // requests.
  run_loop_.Run();

  spawner_thread.Join();
}

// Test that we won't crash even if we attempt to create a very large number
// of textures.
TEST_F(ResourceProviderTest, NoCrashWhenManyTexturesAreAllocated) {
  render_tree::ResourceProvider* resource_provider =
      rasterizer_->GetResourceProvider();

  const int kNumImages = 5000;
  const math::Size kImageSize = math::Size(32, 32);

  std::unique_ptr<render_tree::ImageData> image_datas[kNumImages];
  scoped_refptr<render_tree::Image> images[kNumImages];

  for (int i = 0; i < kNumImages; ++i) {
    image_datas[i] = resource_provider->AllocateImageData(
        kImageSize, ChoosePixelFormat(resource_provider),
        render_tree::kAlphaFormatOpaque);
  }

  for (int i = 0; i < kNumImages; ++i) {
    if (image_datas[i]) {
      images[i] = resource_provider->CreateImage(std::move(image_datas[i]));
    }
  }

  for (int i = 0; i < kNumImages; ++i) {
    images[i] = NULL;
  }
}

// Test that we can attempt to allocate one massive image without crashing.
// There will likely be an out-of-memory issue when attempting to create the
// image.
TEST_F(ResourceProviderTest, NoCrashWhenMassiveTextureIsAllocated) {
  render_tree::ResourceProvider* resource_provider =
      rasterizer_->GetResourceProvider();

  const math::Size kImageSize = math::Size(16384, 16384);

  std::unique_ptr<render_tree::ImageData> image_data =
      resource_provider->AllocateImageData(kImageSize,
                                           ChoosePixelFormat(resource_provider),
                                           render_tree::kAlphaFormatOpaque);
  if (image_data) {
    scoped_refptr<render_tree::Image> image =
        resource_provider->CreateImage(std::move(image_data));
  }
}

// This test is likely not to fail for any out-of-memory reasons, but rather
// maximum texture size reasons.
TEST_F(ResourceProviderTest,
       NoCrashWhenTextureWithOneLargeDimensionIsAllocated) {
  render_tree::ResourceProvider* resource_provider =
      rasterizer_->GetResourceProvider();

  const math::Size kImageSize = math::Size(1024 * 1024, 32);

  std::unique_ptr<render_tree::ImageData> image_data =
      resource_provider->AllocateImageData(kImageSize,
                                           ChoosePixelFormat(resource_provider),
                                           render_tree::kAlphaFormatOpaque);
  if (image_data) {
    scoped_refptr<render_tree::Image> image =
        resource_provider->CreateImage(std::move(image_data));
  }
}

}  // namespace renderer
}  // namespace cobalt
