// Copyright 2016 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.

#ifndef DrawingBufferTestHelpers_h
#define DrawingBufferTestHelpers_h

#include "build/build_config.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/graphics/CanvasColorParams.h"
#include "platform/graphics/gpu/DrawingBuffer.h"
#include "platform/graphics/gpu/Extensions3DUtil.h"
#include "public/platform/WebGraphicsContext3DProvider.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace blink {

enum {
  kInitialWidth = 100,
  kInitialHeight = 100,
  kAlternateHeight = 50,
};

enum UseMultisampling {
  kDisableMultisampling,
  kEnableMultisampling,
};

class WebGraphicsContext3DProviderForTests
    : public WebGraphicsContext3DProvider {
 public:
  WebGraphicsContext3DProviderForTests(
      std::unique_ptr<gpu::gles2::GLES2Interface> gl)
      : gl_(std::move(gl)) {}

  gpu::gles2::GLES2Interface* ContextGL() override { return gl_.get(); }
  bool IsSoftwareRendering() const override { return false; }

  // Not used by WebGL code.
  GrContext* GetGrContext() override { return nullptr; }
  bool BindToCurrentThread() override { return false; }
  gpu::Capabilities GetCapabilities() override { return gpu::Capabilities(); }
  void SetLostContextCallback(const base::Closure&) {}
  void SetErrorMessageCallback(
      const base::Callback<void(const char*, int32_t id)>&) {}
  void SignalQuery(uint32_t, const base::Closure&) override {}

 private:
  std::unique_ptr<gpu::gles2::GLES2Interface> gl_;
};

// The target to use when binding a texture to a Chromium image.
GLenum ImageCHROMIUMTextureTarget() {
#if defined(OS_MACOSX)
  return GC3D_TEXTURE_RECTANGLE_ARB;
#else
  return GL_TEXTURE_2D;
#endif
}

// The target to use when preparing a mailbox texture.
GLenum DrawingBufferTextureTarget() {
  if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled())
    return ImageCHROMIUMTextureTarget();
  return GL_TEXTURE_2D;
}

class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub,
                               public DrawingBuffer::Client {
 public:
  // GLES2InterfaceStub implementation:
  void BindTexture(GLenum target, GLuint texture) override {
    if (target == GL_TEXTURE_2D)
      state_.active_texture2d_binding = texture;
    bound_textures_[target] = texture;
  }

  void BindFramebuffer(GLenum target, GLuint framebuffer) override {
    switch (target) {
      case GL_FRAMEBUFFER:
        state_.draw_framebuffer_binding = framebuffer;
        state_.read_framebuffer_binding = framebuffer;
        break;
      case GL_DRAW_FRAMEBUFFER:
        state_.draw_framebuffer_binding = framebuffer;
        break;
      case GL_READ_FRAMEBUFFER:
        state_.read_framebuffer_binding = framebuffer;
        break;
      default:
        break;
    }
  }

  void BindRenderbuffer(GLenum target, GLuint renderbuffer) override {
    state_.renderbuffer_binding = renderbuffer;
  }

  void Enable(GLenum cap) {
    if (cap == GL_SCISSOR_TEST)
      state_.scissor_enabled = true;
  }

  void Disable(GLenum cap) {
    if (cap == GL_SCISSOR_TEST)
      state_.scissor_enabled = false;
  }

  void ClearColor(GLfloat red,
                  GLfloat green,
                  GLfloat blue,
                  GLfloat alpha) override {
    state_.clear_color[0] = red;
    state_.clear_color[1] = green;
    state_.clear_color[2] = blue;
    state_.clear_color[3] = alpha;
  }

  void ClearDepthf(GLfloat depth) override { state_.clear_depth = depth; }

  void ClearStencil(GLint s) override { state_.clear_stencil = s; }

  void ColorMask(GLboolean red,
                 GLboolean green,
                 GLboolean blue,
                 GLboolean alpha) override {
    state_.color_mask[0] = red;
    state_.color_mask[1] = green;
    state_.color_mask[2] = blue;
    state_.color_mask[3] = alpha;
  }

  void DepthMask(GLboolean flag) override { state_.depth_mask = flag; }

  void StencilMask(GLuint mask) override { state_.stencil_mask = mask; }

  void StencilMaskSeparate(GLenum face, GLuint mask) override {
    if (face == GL_FRONT)
      state_.stencil_mask = mask;
  }

  void PixelStorei(GLenum pname, GLint param) override {
    if (pname == GL_PACK_ALIGNMENT)
      state_.pack_alignment = param;
  }

  void BindBuffer(GLenum target, GLuint buffer) override {
    switch (target) {
      case GL_PIXEL_UNPACK_BUFFER:
        state_.pixel_unpack_buffer_binding = buffer;
        break;
      case GL_PIXEL_PACK_BUFFER:
        state_.pixel_pack_buffer_binding = buffer;
        break;
      default:
        break;
    }
  }

  GLuint64 InsertFenceSyncCHROMIUM() override {
    static GLuint64 sync_point_generator = 0;
    return ++sync_point_generator;
  }

  void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override {
    memcpy(&most_recently_waited_sync_token_, sync_token,
           sizeof(most_recently_waited_sync_token_));
  }

  GLenum CheckFramebufferStatus(GLenum target) override {
    return GL_FRAMEBUFFER_COMPLETE;
  }

  void GetIntegerv(GLenum pname, GLint* value) override {
    switch (pname) {
      case GL_DRAW_FRAMEBUFFER_BINDING:
        *value = state_.draw_framebuffer_binding;
        break;
      case GL_READ_FRAMEBUFFER_BINDING:
        *value = state_.read_framebuffer_binding;
        break;
      case GL_MAX_TEXTURE_SIZE:
        *value = 1024;
      default:
        break;
    }
  }

  void GenMailboxCHROMIUM(GLbyte* mailbox) override {
    ++current_mailbox_byte_;
    memset(mailbox, current_mailbox_byte_, GL_MAILBOX_SIZE_CHROMIUM);
  }

  void ProduceTextureDirectCHROMIUM(GLuint texture,
                                    GLenum target,
                                    const GLbyte* mailbox) override {
    ASSERT_EQ(target, DrawingBufferTextureTarget());

    if (!create_image_chromium_fail_) {
      ASSERT_TRUE(texture_sizes_.Contains(texture));
      most_recently_produced_size_ = texture_sizes_.at(texture);
    }
  }

  void TexImage2D(GLenum target,
                  GLint level,
                  GLint internalformat,
                  GLsizei width,
                  GLsizei height,
                  GLint border,
                  GLenum format,
                  GLenum type,
                  const void* pixels) override {
    if (target == GL_TEXTURE_2D && !level) {
      texture_sizes_.Set(bound_textures_[target], IntSize(width, height));
    }
  }

  GLuint CreateImageCHROMIUM(ClientBuffer buffer,
                             GLsizei width,
                             GLsizei height,
                             GLenum internalformat) override {
    if (create_image_chromium_fail_)
      return 0;
    image_sizes_.Set(current_image_id_, IntSize(width, height));
    return current_image_id_++;
  }

  MOCK_METHOD1(DestroyImageMock, void(GLuint imageId));
  void DestroyImageCHROMIUM(GLuint image_id) {
    image_sizes_.erase(image_id);
    // No textures should be bound to this.
    CHECK(image_to_texture_map_.find(image_id) == image_to_texture_map_.end());
    image_sizes_.erase(image_id);
    DestroyImageMock(image_id);
  }

  MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId));
  void BindTexImage2DCHROMIUM(GLenum target, GLint image_id) {
    if (target == ImageCHROMIUMTextureTarget()) {
      texture_sizes_.Set(bound_textures_[target],
                         image_sizes_.find(image_id)->value);
      image_to_texture_map_.Set(image_id, bound_textures_[target]);
      BindTexImage2DMock(image_id);
    }
  }

  MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId));
  void ReleaseTexImage2DCHROMIUM(GLenum target, GLint image_id) {
    if (target == ImageCHROMIUMTextureTarget()) {
      image_sizes_.Set(current_image_id_, IntSize());
      image_to_texture_map_.erase(image_id);
      ReleaseTexImage2DMock(image_id);
    }
  }

  void GenSyncTokenCHROMIUM(GLuint64 fence_sync, GLbyte* sync_token) override {
    static uint64_t unique_id = 1;
    gpu::SyncToken source(
        gpu::GPU_IO, 1, gpu::CommandBufferId::FromUnsafeValue(unique_id++), 2);
    memcpy(sync_token, &source, sizeof(source));
  }

  void GenTextures(GLsizei n, GLuint* textures) override {
    static GLuint id = 1;
    for (GLsizei i = 0; i < n; ++i)
      textures[i] = id++;
  }

  // DrawingBuffer::Client implementation.
  bool DrawingBufferClientIsBoundForDraw() override {
    return !state_.draw_framebuffer_binding;
  }
  void DrawingBufferClientRestoreScissorTest() override {
    state_.scissor_enabled = saved_state_.scissor_enabled;
  }
  void DrawingBufferClientRestoreMaskAndClearValues() override {
    memcpy(state_.color_mask, saved_state_.color_mask,
           sizeof(state_.color_mask));
    state_.clear_depth = saved_state_.clear_depth;
    state_.clear_stencil = saved_state_.clear_stencil;

    memcpy(state_.clear_color, saved_state_.clear_color,
           sizeof(state_.clear_color));
    state_.depth_mask = saved_state_.depth_mask;
    state_.stencil_mask = saved_state_.stencil_mask;
  }
  void DrawingBufferClientRestorePixelPackParameters() override {
    // TODO(zmo): restore ES3 pack parameters?
    state_.pack_alignment = saved_state_.pack_alignment;
  }
  void DrawingBufferClientRestoreTexture2DBinding() override {
    state_.active_texture2d_binding = saved_state_.active_texture2d_binding;
  }
  void DrawingBufferClientRestoreRenderbufferBinding() override {
    state_.renderbuffer_binding = saved_state_.renderbuffer_binding;
  }
  void DrawingBufferClientRestoreFramebufferBinding() override {
    state_.draw_framebuffer_binding = saved_state_.draw_framebuffer_binding;
    state_.read_framebuffer_binding = saved_state_.read_framebuffer_binding;
  }
  void DrawingBufferClientRestorePixelUnpackBufferBinding() override {
    state_.pixel_unpack_buffer_binding =
        saved_state_.pixel_unpack_buffer_binding;
  }
  void DrawingBufferClientRestorePixelPackBufferBinding() override {
    state_.pixel_pack_buffer_binding = saved_state_.pixel_pack_buffer_binding;
  }

  // Testing methods.
  gpu::SyncToken MostRecentlyWaitedSyncToken() const {
    return most_recently_waited_sync_token_;
  }
  GLuint NextImageIdToBeCreated() const { return current_image_id_; }
  IntSize MostRecentlyProducedSize() const {
    return most_recently_produced_size_;
  }

  void SetCreateImageChromiumFail(bool fail) {
    create_image_chromium_fail_ = fail;
  }

  // Saves current GL state for later verification.
  void SaveState() { saved_state_ = state_; }
  void VerifyStateHasNotChangedSinceSave() const {
    for (size_t i = 0; i < 4; ++i) {
      EXPECT_EQ(state_.clear_color[0], saved_state_.clear_color[0]);
      EXPECT_EQ(state_.color_mask[0], saved_state_.color_mask[0]);
    }
    EXPECT_EQ(state_.clear_depth, saved_state_.clear_depth);
    EXPECT_EQ(state_.clear_stencil, saved_state_.clear_stencil);
    EXPECT_EQ(state_.depth_mask, saved_state_.depth_mask);
    EXPECT_EQ(state_.stencil_mask, saved_state_.stencil_mask);
    EXPECT_EQ(state_.pack_alignment, saved_state_.pack_alignment);
    EXPECT_EQ(state_.active_texture2d_binding,
              saved_state_.active_texture2d_binding);
    EXPECT_EQ(state_.renderbuffer_binding, saved_state_.renderbuffer_binding);
    EXPECT_EQ(state_.draw_framebuffer_binding,
              saved_state_.draw_framebuffer_binding);
    EXPECT_EQ(state_.read_framebuffer_binding,
              saved_state_.read_framebuffer_binding);
    EXPECT_EQ(state_.pixel_unpack_buffer_binding,
              saved_state_.pixel_unpack_buffer_binding);
    EXPECT_EQ(state_.pixel_pack_buffer_binding,
              saved_state_.pixel_pack_buffer_binding);
  }

 private:
  std::map<GLenum, GLuint> bound_textures_;

  // State tracked to verify that it is restored correctly.
  struct State {
    bool scissor_enabled = false;

    GLfloat clear_color[4] = {0, 0, 0, 0};
    GLfloat clear_depth = 0;
    GLint clear_stencil = 0;

    GLboolean color_mask[4] = {0, 0, 0, 0};
    GLboolean depth_mask = 0;
    GLuint stencil_mask = 0;

    GLint pack_alignment = 4;

    // The bound 2D texture for the active texture unit.
    GLuint active_texture2d_binding = 0;
    GLuint renderbuffer_binding = 0;
    GLuint draw_framebuffer_binding = 0;
    GLuint read_framebuffer_binding = 0;
    GLuint pixel_unpack_buffer_binding = 0;
    GLuint pixel_pack_buffer_binding = 0;
  };
  State state_;
  State saved_state_;

  gpu::SyncToken most_recently_waited_sync_token_;
  GLbyte current_mailbox_byte_ = 0;
  IntSize most_recently_produced_size_;
  bool create_image_chromium_fail_ = false;
  GLuint current_image_id_ = 1;
  HashMap<GLuint, IntSize> texture_sizes_;
  HashMap<GLuint, IntSize> image_sizes_;
  HashMap<GLuint, GLuint> image_to_texture_map_;
};

class DrawingBufferForTests : public DrawingBuffer {
 public:
  static PassRefPtr<DrawingBufferForTests> Create(
      std::unique_ptr<WebGraphicsContext3DProvider> context_provider,
      DrawingBuffer::Client* client,
      const IntSize& size,
      PreserveDrawingBuffer preserve,
      UseMultisampling use_multisampling) {
    std::unique_ptr<Extensions3DUtil> extensions_util =
        Extensions3DUtil::Create(context_provider->ContextGL());
    RefPtr<DrawingBufferForTests> drawing_buffer =
        AdoptRef(new DrawingBufferForTests(std::move(context_provider),
                                           std::move(extensions_util), client,
                                           preserve));
    if (!drawing_buffer->Initialize(
            size, use_multisampling != kDisableMultisampling)) {
      drawing_buffer->BeginDestruction();
      return nullptr;
    }
    return drawing_buffer;
  }

  DrawingBufferForTests(
      std::unique_ptr<WebGraphicsContext3DProvider> context_provider,
      std::unique_ptr<Extensions3DUtil> extensions_util,
      DrawingBuffer::Client* client,
      PreserveDrawingBuffer preserve)
      : DrawingBuffer(
            std::move(context_provider),
            std::move(extensions_util),
            client,
            false /* discardFramebufferSupported */,
            true /* wantAlphaChannel */,
            false /* premultipliedAlpha */,
            preserve,
            kWebGL1,
            false /* wantDepth */,
            false /* wantStencil */,
            DrawingBuffer::kAllowChromiumImage /* ChromiumImageUsage */,
            CanvasColorParams()),
        live_(0) {}

  ~DrawingBufferForTests() override {
    if (live_)
      *live_ = false;
  }

  GLES2InterfaceForTests* ContextGLForTests() {
    return static_cast<GLES2InterfaceForTests*>(ContextGL());
  }

  bool* live_;

  int RecycledBitmapCount() { return recycled_bitmaps_.size(); }
};

}  // blink

#endif  // DrawingBufferTestHelpers_h
