// 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 <memory>

#include "base/threading/simple_thread.h"

#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "cobalt/render_tree/resource_provider.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();

  // 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<backend::GraphicsSystem> graphics_system_;
  std::unique_ptr<backend::GraphicsContext> graphics_context_;
  std::unique_ptr<rasterizer::Rasterizer> rasterizer_;

  bool run_run_loop_manually_;
};

ResourceProviderTest::ResourceProviderTest()
    : message_loop_(base::MessageLoop::TYPE_DEFAULT),
      run_run_loop_manually_(false) {
  graphics_system_ = backend::CreateDefaultGraphicsSystem();
  graphics_context_ = graphics_system_->CreateGraphicsContext();

  // Create the rasterizer using the platform default RenderModule options.
  RendererModule::Options render_module_options;
  rasterizer_ = render_module_options.create_rasterizer_function.Run(
      graphics_context_.get(), render_module_options);
}

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

// 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
