// Copyright (c) 2017 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.

#include "gpu/command_buffer/client/raster_implementation_gles.h"

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES2/gl2extchromium.h>
#include <GLES3/gl3.h>
#include <memory>
#include <utility>
#include <vector>

#include "base/containers/flat_map.h"
#include "cc/paint/color_space_transfer_cache_entry.h"
#include "cc/paint/display_item_list.h"
#include "cc/paint/image_provider.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface_stub.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/gpu/GrTypes.h"
#include "ui/gfx/color_space.h"

using testing::_;
using testing::Gt;
using testing::Le;
using testing::Return;
using testing::SetArgPointee;
using testing::StrEq;

namespace gpu {
namespace raster {

class RasterMockGLES2Interface : public gles2::GLES2InterfaceStub {
 public:
  // Command buffer Flush / Finish.
  MOCK_METHOD0(Finish, void());
  MOCK_METHOD0(Flush, void());
  MOCK_METHOD0(ShallowFlushCHROMIUM, void());
  MOCK_METHOD0(OrderingBarrierCHROMIUM, void());

  // SyncTokens.
  MOCK_METHOD1(GenSyncTokenCHROMIUM, void(GLbyte* sync_token));
  MOCK_METHOD1(GenUnverifiedSyncTokenCHROMIUM, void(GLbyte* sync_token));
  MOCK_METHOD2(VerifySyncTokensCHROMIUM,
               void(GLbyte** sync_tokens, GLsizei count));
  MOCK_METHOD1(WaitSyncTokenCHROMIUM, void(const GLbyte* sync_token));

  // Command buffer state.
  MOCK_METHOD0(GetError, GLenum());
  MOCK_METHOD0(GetGraphicsResetStatusKHR, GLenum());
  MOCK_METHOD2(GetIntegerv, void(GLenum pname, GLint* params));
  MOCK_METHOD2(LoseContextCHROMIUM, void(GLenum current, GLenum other));

  // Queries: GL_COMMANDS_ISSUED_CHROMIUM / GL_COMMANDS_COMPLETED_CHROMIUM.
  MOCK_METHOD2(GenQueriesEXT, void(GLsizei n, GLuint* queries));
  MOCK_METHOD2(DeleteQueriesEXT, void(GLsizei n, const GLuint* queries));
  MOCK_METHOD2(BeginQueryEXT, void(GLenum target, GLuint id));
  MOCK_METHOD1(EndQueryEXT, void(GLenum target));
  MOCK_METHOD3(GetQueryObjectuivEXT,
               void(GLuint id, GLenum pname, GLuint* params));

  // Texture objects.
  MOCK_METHOD2(GenTextures, void(GLsizei n, GLuint* textures));
  MOCK_METHOD2(DeleteTextures, void(GLsizei n, const GLuint* textures));
  MOCK_METHOD2(BindTexture, void(GLenum target, GLuint texture));
  MOCK_METHOD1(ActiveTexture, void(GLenum texture));
  MOCK_METHOD1(GenerateMipmap, void(GLenum target));
  MOCK_METHOD2(SetColorSpaceMetadataCHROMIUM,
               void(GLuint texture_id, GLColorSpace color_space));
  MOCK_METHOD3(TexParameteri, void(GLenum target, GLenum pname, GLint param));

  // Mailboxes.
  MOCK_METHOD2(ProduceTextureDirectCHROMIUM,
               void(GLuint texture, GLbyte* mailbox));
  MOCK_METHOD1(CreateAndConsumeTextureCHROMIUM, GLuint(const GLbyte* mailbox));

  // Image objects.
  MOCK_METHOD4(CreateImageCHROMIUM,
               GLuint(ClientBuffer buffer,
                      GLsizei width,
                      GLsizei height,
                      GLenum internalformat));
  MOCK_METHOD2(BindTexImage2DCHROMIUM, void(GLenum target, GLint imageId));
  MOCK_METHOD2(ReleaseTexImage2DCHROMIUM, void(GLenum target, GLint imageId));
  MOCK_METHOD1(DestroyImageCHROMIUM, void(GLuint image_id));

  // Texture allocation and copying.
  MOCK_METHOD9(TexImage2D,
               void(GLenum target,
                    GLint level,
                    GLint internalformat,
                    GLsizei width,
                    GLsizei height,
                    GLint border,
                    GLenum format,
                    GLenum type,
                    const void* pixels));
  MOCK_METHOD9(TexSubImage2D,
               void(GLenum target,
                    GLint level,
                    GLint xoffset,
                    GLint yoffset,
                    GLsizei width,
                    GLsizei height,
                    GLenum format,
                    GLenum type,
                    const void* pixels));
  MOCK_METHOD8(CompressedTexImage2D,
               void(GLenum target,
                    GLint level,
                    GLenum internalformat,
                    GLsizei width,
                    GLsizei height,
                    GLint border,
                    GLsizei imageSize,
                    const void* data));
  MOCK_METHOD5(TexStorage2DEXT,
               void(GLenum target,
                    GLsizei levels,
                    GLenum internalFormat,
                    GLsizei width,
                    GLsizei height));
  MOCK_METHOD5(TexStorage2DImageCHROMIUM,
               void(GLenum target,
                    GLenum internalFormat,
                    GLenum bufferUsage,
                    GLsizei width,
                    GLsizei height));

  // OOP-Raster
  MOCK_METHOD6(BeginRasterCHROMIUM,
               void(GLuint texture_id,
                    GLuint sk_color,
                    GLuint msaa_sample_count,
                    GLboolean can_use_lcd_text,
                    GLint color_type,
                    GLuint color_space_id));
  MOCK_METHOD2(RasterCHROMIUM, void(GLsizeiptr size, const void* list));
  MOCK_METHOD1(MapRasterCHROMIUM, void*(GLsizeiptr size));
  MOCK_METHOD1(UnmapRasterCHROMIUM, void(GLsizeiptr written));
  MOCK_METHOD0(EndRasterCHROMIUM, void());

  MOCK_METHOD2(PixelStorei, void(GLenum pname, GLint param));
  MOCK_METHOD2(TraceBeginCHROMIUM,
               void(const char* category_name, const char* trace_name));
  MOCK_METHOD0(TraceEndCHROMIUM, void());
};

class ContextSupportStub : public ContextSupport {
 public:
  ~ContextSupportStub() override = default;

  void FlushPendingWork() override {}
  void SignalSyncToken(const SyncToken& sync_token,
                       base::OnceClosure callback) override {}
  bool IsSyncTokenSignaled(const SyncToken& sync_token) override {
    return false;
  }
  void SignalQuery(uint32_t query, base::OnceClosure callback) override {}
  void GetGpuFence(uint32_t gpu_fence_id,
                   base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)>
                       callback) override {}
  void SetAggressivelyFreeResources(bool aggressively_free_resources) override {
  }

  void Swap(uint32_t flags,
            SwapCompletedCallback swap_completed,
            PresentationCallback presentation_callback) override {}
  void SwapWithBounds(const std::vector<gfx::Rect>& rects,
                      uint32_t flags,
                      SwapCompletedCallback swap_completed,
                      PresentationCallback presentation_callback) override {}
  void PartialSwapBuffers(const gfx::Rect& sub_buffer,
                          uint32_t flags,
                          SwapCompletedCallback swap_completed,
                          PresentationCallback presentation_callback) override {
  }
  void CommitOverlayPlanes(
      uint32_t flags,
      SwapCompletedCallback swap_completed,
      PresentationCallback presentation_callback) override {}
  void ScheduleOverlayPlane(int plane_z_order,
                            gfx::OverlayTransform plane_transform,
                            unsigned overlay_texture_id,
                            const gfx::Rect& display_bounds,
                            const gfx::RectF& uv_rect,
                            bool enable_blend,
                            unsigned gpu_fence_id) override {}
  uint64_t ShareGroupTracingGUID() const override { return 0; }
  void SetErrorMessageCallback(
      base::RepeatingCallback<void(const char*, int32_t)> callback) override {}
  bool ThreadSafeShallowLockDiscardableTexture(uint32_t texture_id) override {
    return true;
  }
  void CompleteLockDiscardableTexureOnContextThread(
      uint32_t texture_id) override {}
  bool ThreadsafeDiscardableTextureIsDeletedForTracing(
      uint32_t texture_id) override {
    return false;
  }
  void* MapTransferCacheEntry(uint32_t serialized_size) override {
    mapped_transfer_cache_entry_.reset(new char[serialized_size]);
    return mapped_transfer_cache_entry_.get();
  }
  void UnmapAndCreateTransferCacheEntry(uint32_t type, uint32_t id) override {
    mapped_transfer_cache_entry_.reset();
  }
  bool ThreadsafeLockTransferCacheEntry(uint32_t type, uint32_t id) override {
    return true;
  }
  void UnlockTransferCacheEntries(
      const std::vector<std::pair<uint32_t, uint32_t>>& entries) override {}
  void DeleteTransferCacheEntry(uint32_t type, uint32_t id) override {}
  unsigned int GetTransferBufferFreeSize() const override { return 0; }
  bool HasGrContextSupport() const override { return false; }
  void SetGrContext(GrContext* gr) override {}
  void WillCallGLFromSkia() override {}
  void DidCallGLFromSkia() override {}

 private:
  std::unique_ptr<char[]> mapped_transfer_cache_entry_;
};

class ImageProviderStub : public cc::ImageProvider {
 public:
  ~ImageProviderStub() override {}
  ScopedResult GetRasterContent(const cc::DrawImage& draw_image) override {
    return ScopedResult();
  }
};

class RasterImplementationGLESTest : public testing::Test {
 protected:
  RasterImplementationGLESTest() {}

  void SetUp() override {
    gl_ = std::make_unique<RasterMockGLES2Interface>();
    ri_ = std::make_unique<RasterImplementationGLES>(gl_.get());
  }

  void TearDown() override {}

  void ExpectBindTexture(GLenum target, GLuint texture_id) {
    if (bound_texture_ != texture_id) {
      bound_texture_ = texture_id;
      EXPECT_CALL(*gl_, BindTexture(target, texture_id)).Times(1);
    }
  }

  ContextSupportStub support_;
  std::unique_ptr<RasterMockGLES2Interface> gl_;
  std::unique_ptr<RasterImplementationGLES> ri_;

  GLuint bound_texture_ = 0;
};

TEST_F(RasterImplementationGLESTest, Finish) {
  EXPECT_CALL(*gl_, Finish()).Times(1);
  ri_->Finish();
}

TEST_F(RasterImplementationGLESTest, Flush) {
  EXPECT_CALL(*gl_, Flush()).Times(1);
  ri_->Flush();
}

TEST_F(RasterImplementationGLESTest, ShallowFlushCHROMIUM) {
  EXPECT_CALL(*gl_, ShallowFlushCHROMIUM()).Times(1);
  ri_->ShallowFlushCHROMIUM();
}

TEST_F(RasterImplementationGLESTest, OrderingBarrierCHROMIUM) {
  EXPECT_CALL(*gl_, OrderingBarrierCHROMIUM()).Times(1);
  ri_->OrderingBarrierCHROMIUM();
}

TEST_F(RasterImplementationGLESTest, GenUnverifiedSyncTokenCHROMIUM) {
  GLbyte sync_token_data[GL_SYNC_TOKEN_SIZE_CHROMIUM] = {};

  EXPECT_CALL(*gl_, GenUnverifiedSyncTokenCHROMIUM(sync_token_data)).Times(1);
  ri_->GenUnverifiedSyncTokenCHROMIUM(sync_token_data);
}

TEST_F(RasterImplementationGLESTest, VerifySyncTokensCHROMIUM) {
  const GLsizei kNumSyncTokens = 2;
  GLbyte sync_token_data[GL_SYNC_TOKEN_SIZE_CHROMIUM][kNumSyncTokens] = {};
  GLbyte* sync_tokens[2] = {sync_token_data[0], sync_token_data[1]};

  EXPECT_CALL(*gl_, VerifySyncTokensCHROMIUM(sync_tokens, kNumSyncTokens))
      .Times(1);
  ri_->VerifySyncTokensCHROMIUM(sync_tokens, kNumSyncTokens);
}

TEST_F(RasterImplementationGLESTest, WaitSyncTokenCHROMIUM) {
  GLbyte sync_token_data[GL_SYNC_TOKEN_SIZE_CHROMIUM] = {};

  EXPECT_CALL(*gl_, WaitSyncTokenCHROMIUM(sync_token_data)).Times(1);
  ri_->WaitSyncTokenCHROMIUM(sync_token_data);
}

TEST_F(RasterImplementationGLESTest, GetError) {
  const GLuint kGLInvalidOperation = GL_INVALID_OPERATION;

  EXPECT_CALL(*gl_, GetError()).WillOnce(Return(kGLInvalidOperation));
  GLenum error = ri_->GetError();
  EXPECT_EQ(kGLInvalidOperation, error);
}

TEST_F(RasterImplementationGLESTest, GetGraphicsResetStatusKHR) {
  const GLuint kGraphicsResetStatus = GL_UNKNOWN_CONTEXT_RESET_KHR;

  EXPECT_CALL(*gl_, GetGraphicsResetStatusKHR())
      .WillOnce(Return(kGraphicsResetStatus));
  GLenum status = ri_->GetGraphicsResetStatusKHR();
  EXPECT_EQ(kGraphicsResetStatus, status);
}

TEST_F(RasterImplementationGLESTest, LoseContextCHROMIUM) {
  const GLenum kCurrent = GL_GUILTY_CONTEXT_RESET_ARB;
  const GLenum kOther = GL_INNOCENT_CONTEXT_RESET_ARB;

  EXPECT_CALL(*gl_, LoseContextCHROMIUM(kCurrent, kOther)).Times(1);
  ri_->LoseContextCHROMIUM(kCurrent, kOther);
}

TEST_F(RasterImplementationGLESTest, GenQueriesEXT) {
  const GLsizei kNumQueries = 2;
  GLuint queries[kNumQueries] = {};

  EXPECT_CALL(*gl_, GenQueriesEXT(kNumQueries, queries)).Times(1);
  ri_->GenQueriesEXT(kNumQueries, queries);
}

TEST_F(RasterImplementationGLESTest, DeleteQueriesEXT) {
  const GLsizei kNumQueries = 2;
  GLuint queries[kNumQueries] = {2, 3};

  EXPECT_CALL(*gl_, DeleteQueriesEXT(kNumQueries, queries)).Times(1);
  ri_->DeleteQueriesEXT(kNumQueries, queries);
}

TEST_F(RasterImplementationGLESTest, BeginQueryEXT) {
  const GLsizei kQueryTarget = GL_COMMANDS_ISSUED_CHROMIUM;
  const GLuint kQueryId = 23;

  EXPECT_CALL(*gl_, BeginQueryEXT(kQueryTarget, kQueryId)).Times(1);
  ri_->BeginQueryEXT(kQueryTarget, kQueryId);
}

TEST_F(RasterImplementationGLESTest, EndQueryEXT) {
  const GLsizei kQueryTarget = GL_COMMANDS_ISSUED_CHROMIUM;

  EXPECT_CALL(*gl_, EndQueryEXT(kQueryTarget)).Times(1);
  ri_->EndQueryEXT(kQueryTarget);
}

TEST_F(RasterImplementationGLESTest, GetQueryObjectuivEXT) {
  const GLuint kQueryId = 23;
  const GLsizei kQueryParam = GL_QUERY_RESULT_AVAILABLE_EXT;
  GLuint result = 0;

  EXPECT_CALL(*gl_, GetQueryObjectuivEXT(kQueryId, kQueryParam, &result))
      .Times(1);
  ri_->GetQueryObjectuivEXT(kQueryId, kQueryParam, &result);
}

TEST_F(RasterImplementationGLESTest, DeleteGpuRasterTexture) {
  GLuint texture_id = 3;
  gpu::Mailbox mailbox;

  EXPECT_CALL(*gl_, CreateAndConsumeTextureCHROMIUM(mailbox.name))
      .WillOnce(Return(texture_id))
      .RetiresOnSaturation();

  EXPECT_EQ(texture_id, ri_->CreateAndConsumeForGpuRaster(mailbox.name));

  EXPECT_CALL(*gl_, DeleteTextures(1, _)).Times(1);
  ri_->DeleteGpuRasterTexture(texture_id);
}

TEST_F(RasterImplementationGLESTest, CreateAndConsumeForGpuRaster) {
  const GLuint kTextureId = 23;
  GLuint texture_id = 0;
  gpu::Mailbox mailbox;

  EXPECT_CALL(*gl_, CreateAndConsumeTextureCHROMIUM(mailbox.name))
      .WillOnce(Return(kTextureId));
  texture_id = ri_->CreateAndConsumeForGpuRaster(mailbox.name);
  EXPECT_EQ(kTextureId, texture_id);
}

TEST_F(RasterImplementationGLESTest, BeginGpuRaster) {
  EXPECT_CALL(*gl_, TraceBeginCHROMIUM(StrEq("BeginGpuRaster"),
                                       StrEq("GpuRasterization")))
      .Times(1);
  ri_->BeginGpuRaster();
}

TEST_F(RasterImplementationGLESTest, EndGpuRaster) {
  EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_ALIGNMENT, 4)).Times(1);
  EXPECT_CALL(*gl_, TraceEndCHROMIUM()).Times(1);
  ri_->EndGpuRaster();
}

}  // namespace raster
}  // namespace gpu
