// Copyright 2018 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/service/raster_decoder_unittest_base.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/common/raster_cmd_format.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/copy_texture_chromium_mock.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/logger.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/program_manager.h"
#include "gpu/command_buffer/service/raster_decoder_context_state.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/command_buffer/service/test_helper.h"
#include "gpu/command_buffer/service/vertex_attrib_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_mock.h"
#include "ui/gl/init/gl_factory.h"
#include "ui/gl/test/gl_surface_test_support.h"

using ::gl::MockGLInterface;
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::AtMost;
using ::testing::Between;
using ::testing::InSequence;
using ::testing::Ne;
using ::testing::Pointee;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::StrictMock;

namespace gpu {
namespace raster {

RasterDecoderTestBase::InitState::InitState() = default;
RasterDecoderTestBase::InitState::~InitState() = default;

RasterDecoderTestBase::RasterDecoderTestBase()
    : surface_(nullptr),
      context_(nullptr),
      client_texture_id_(106),
      shared_memory_id_(0),
      shared_memory_offset_(0),
      shared_memory_address_(nullptr),
      shared_memory_base_(nullptr),
      ignore_cached_state_for_test_(GetParam()),
      shader_translator_cache_(gpu_preferences_),
      copy_texture_manager_(nullptr) {
  memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_));
}

RasterDecoderTestBase::~RasterDecoderTestBase() = default;

void RasterDecoderTestBase::OnConsoleMessage(int32_t id,
                                             const std::string& message) {}
void RasterDecoderTestBase::CacheShader(const std::string& key,
                                        const std::string& shader) {}
void RasterDecoderTestBase::OnFenceSyncRelease(uint64_t release) {}
void RasterDecoderTestBase::OnDescheduleUntilFinished() {}
void RasterDecoderTestBase::OnRescheduleAfterFinished() {}
void RasterDecoderTestBase::OnSwapBuffers(uint64_t swap_id, uint32_t flags) {}

void RasterDecoderTestBase::SetUp() {
  InitDecoder(InitState());
}

void RasterDecoderTestBase::AddExpectationsForRestoreAttribState(
    GLuint attrib) {
  EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, _))
      .Times(1)
      .RetiresOnSaturation();

  EXPECT_CALL(*gl_, VertexAttribPointer(attrib, _, _, _, _, _))
      .Times(1)
      .RetiresOnSaturation();

  EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(attrib, _))
      .Times(testing::AtMost(1))
      .RetiresOnSaturation();

  EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, _))
      .Times(1)
      .RetiresOnSaturation();

  if (attrib != 0 || group_->feature_info()->gl_version_info().is_es) {
    // TODO(bajones): Not sure if I can tell which of these will be called
    EXPECT_CALL(*gl_, EnableVertexAttribArray(attrib))
        .Times(testing::AtMost(1))
        .RetiresOnSaturation();

    EXPECT_CALL(*gl_, DisableVertexAttribArray(attrib))
        .Times(testing::AtMost(1))
        .RetiresOnSaturation();
  }
}

void RasterDecoderTestBase::SetupInitStateManualExpectations(bool es3_capable) {
  if (es3_capable) {
    EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ROW_LENGTH, 0))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_ROW_LENGTH, 0))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0))
        .Times(1)
        .RetiresOnSaturation();
    if (group_->feature_info()->feature_flags().ext_window_rectangles) {
      EXPECT_CALL(*gl_, WindowRectanglesEXT(GL_EXCLUSIVE_EXT, 0, nullptr))
          .Times(1)
          .RetiresOnSaturation();
    }
  }
}

void RasterDecoderTestBase::SetupInitStateManualExpectationsForDoLineWidth(
    GLfloat width) {
  EXPECT_CALL(*gl_, LineWidth(width)).Times(1).RetiresOnSaturation();
}

void RasterDecoderTestBase::ExpectEnableDisable(GLenum cap, bool enable) {
  if (enable) {
    EXPECT_CALL(*gl_, Enable(cap)).Times(1).RetiresOnSaturation();
  } else {
    EXPECT_CALL(*gl_, Disable(cap)).Times(1).RetiresOnSaturation();
  }
}

void RasterDecoderTestBase::CreateFakeTexture(
    GLuint client_id,
    GLuint service_id,
    viz::ResourceFormat resource_format,
    GLsizei width,
    GLsizei height,
    bool cleared) {
  // Create texture and temporary ref.
  const GLuint kTempClientId = 271828;
  auto* temp_ref =
      group_->texture_manager()->CreateTexture(kTempClientId, service_id);
  group_->texture_manager()->SetTarget(temp_ref, GL_TEXTURE_2D);
  group_->texture_manager()->SetLevelInfo(
      temp_ref, GL_TEXTURE_2D, 0, viz::GLInternalFormat(resource_format),
      /*width=*/width, /*height=*/height, 1, 0,
      viz::GLDataFormat(resource_format), viz::GLDataType(resource_format),
      cleared ? gfx::Rect(width, height) : gfx::Rect());
  gpu::Mailbox mailbox = gpu::Mailbox::Generate();
  group_->mailbox_manager()->ProduceTexture(mailbox, temp_ref->texture());

  // Consume texture to hold a permanent ref.
  cmds::CreateAndConsumeTextureINTERNALImmediate& cmd =
      *GetImmediateAs<cmds::CreateAndConsumeTextureINTERNALImmediate>();
  cmd.Init(client_id, false /* use_buffer */, gfx::BufferUsage::GPU_READ,
           resource_format, mailbox.name);
  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(mailbox.name)));

  // Check that client_texture_id has appropriate attributes.
  auto* texture_ref = group().texture_manager()->GetTexture(client_id);
  ASSERT_NE(texture_ref, nullptr);
  auto* texture = texture_ref->texture();
  EXPECT_EQ(service_id, texture->service_id());

  // Release temporary ref.
  group_->texture_manager()->RemoveTexture(kTempClientId);
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

void RasterDecoderTestBase::InitDecoder(const InitState& init) {
  std::string all_extensions;
  for (const std::string& extension : init.extensions) {
    all_extensions += extension + " ";
  }
  const bool bind_generates_resource(false);
  const ContextType context_type(CONTEXT_TYPE_OPENGLES2);

  // For easier substring/extension matching
  gl::SetGLGetProcAddressProc(gl::MockGLInterface::GetGLProcAddress);
  gl::GLSurfaceTestSupport::InitializeOneOffWithMockBindings();

  gl_.reset(new StrictMock<MockGLInterface>());
  ::gl::MockGLInterface::SetGLInterface(gl_.get());

  GpuFeatureInfo gpu_feature_info;
  scoped_refptr<gles2::FeatureInfo> feature_info =
      new gles2::FeatureInfo(init.workarounds, gpu_feature_info);

  group_ = scoped_refptr<gles2::ContextGroup>(new gles2::ContextGroup(
      gpu_preferences_, false, &mailbox_manager_, nullptr /* memory_tracker */,
      &shader_translator_cache_, &framebuffer_completeness_cache_, feature_info,
      bind_generates_resource, &image_manager_, nullptr /* image_factory */,
      nullptr /* progress_reporter */, gpu_feature_info, &discardable_manager_,
      nullptr /* passthrough_discardable_manager */, &shared_image_manager_));

  InSequence sequence;

  surface_ = new gl::GLSurfaceStub;

  // Context needs to be created before initializing ContextGroup, which willxo
  // in turn initialize FeatureInfo, which needs a context to determine
  // extension support.
  context_ = new StrictMock<GLContextMock>();
  context_->SetExtensionsString(all_extensions.c_str());
  context_->SetGLVersionString(init.gl_version.c_str());

  context_->GLContextStub::MakeCurrent(surface_.get());

  gles2::TestHelper::SetupContextGroupInitExpectations(
      gl_.get(), gles2::DisallowedFeatures(), all_extensions.c_str(),
      init.gl_version.c_str(), context_type, bind_generates_resource);

  // We initialize the ContextGroup with a MockRasterDecoder so that
  // we can use the ContextGroup to figure out how the real RasterDecoder
  // will initialize itself.
  command_buffer_service_.reset(new FakeCommandBufferServiceBase());
  command_buffer_service_for_mock_decoder_.reset(
      new FakeCommandBufferServiceBase());
  mock_decoder_.reset(
      new MockRasterDecoder(command_buffer_service_for_mock_decoder_.get()));

  EXPECT_EQ(group_->Initialize(mock_decoder_.get(), context_type,
                               gles2::DisallowedFeatures()),
            gpu::ContextResult::kSuccess);

  scoped_refptr<gpu::Buffer> buffer =
      command_buffer_service_->CreateTransferBufferHelper(kSharedBufferSize,
                                                          &shared_memory_id_);
  shared_memory_offset_ = kSharedMemoryOffset;
  shared_memory_address_ =
      static_cast<int8_t*>(buffer->memory()) + shared_memory_offset_;
  shared_memory_base_ = buffer->memory();
  ClearSharedMemory();

  ContextCreationAttribs attribs;
  attribs.lose_context_when_out_of_memory =
      init.lose_context_when_out_of_memory;
  attribs.context_type = context_type;

  // Setup expections for RasterDecoderContextState::InitializeGL()
  // It will initialize a FeatureInfo and
  gles2::TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
      gl_.get(), all_extensions.c_str(), "" /* gl_renderer */,
      init.gl_version.c_str(), CONTEXT_TYPE_OPENGLES2);
  EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _))
      .WillOnce(SetArgPointee<1>(8u))
      .RetiresOnSaturation();
  SetupInitCapabilitiesExpectations(group_->feature_info()->IsES3Capable());
  SetupInitStateExpectations(group_->feature_info()->IsES3Capable());

  raster_decoder_context_state_ = new raster::RasterDecoderContextState(
      new gl::GLShareGroup(), surface_, context_,
      feature_info->workarounds().use_virtualized_gl_contexts,
      base::DoNothing());

  raster_decoder_context_state_->InitializeGL(init.workarounds,
                                              gpu_feature_info);

  decoder_.reset(RasterDecoder::Create(this, command_buffer_service_.get(),
                                       &outputter_, group_.get(),
                                       raster_decoder_context_state_));
  decoder_->SetIgnoreCachedStateForTest(ignore_cached_state_for_test_);
  decoder_->GetLogger()->set_log_synthesized_gl_errors(false);

  copy_texture_manager_ = new gles2::MockCopyTextureResourceManager();
  decoder_->SetCopyTextureResourceManagerForTest(copy_texture_manager_);

  ASSERT_EQ(
      decoder_->Initialize(surface_, raster_decoder_context_state_->context(),
                           true, gles2::DisallowedFeatures(), attribs),
      gpu::ContextResult::kSuccess);

  EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(true));
  if (context_->WasAllocatedUsingRobustnessExtension()) {
    EXPECT_CALL(*gl_, GetGraphicsResetStatusARB())
        .WillOnce(Return(GL_NO_ERROR));
  }
  decoder_->MakeCurrent();
  decoder_->BeginDecoding();

  CreateFakeTexture(client_texture_id_, kServiceTextureId,
                    viz::ResourceFormat::RGBA_8888, /*width=*/2,
                    /*height=*/2, /*cleared=*/false);
}

void RasterDecoderTestBase::ResetDecoder() {
  if (!decoder_.get())
    return;
  // All Tests should have read all their GLErrors before getting here.
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  decoder_->EndDecoding();

  if (!decoder_->WasContextLost()) {
    EXPECT_CALL(*copy_texture_manager_, Destroy())
        .Times(1)
        .RetiresOnSaturation();
    copy_texture_manager_ = nullptr;
  }

  decoder_->Destroy(!decoder_->WasContextLost());
  decoder_.reset();
  group_->Destroy(mock_decoder_.get(), false);
  command_buffer_service_.reset();
  command_buffer_service_for_mock_decoder_.reset();
  ::gl::MockGLInterface::SetGLInterface(nullptr);
  gl_.reset();
  gl::init::ShutdownGL(false);
}

void RasterDecoderTestBase::TearDown() {
  ResetDecoder();
}

GLint RasterDecoderTestBase::GetGLError() {
  EXPECT_CALL(*gl_, GetError())
      .WillOnce(Return(GL_NO_ERROR))
      .RetiresOnSaturation();
  cmds::GetError cmd;
  cmd.Init(shared_memory_id_, shared_memory_offset_);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  return static_cast<GLint>(*GetSharedMemoryAs<GLenum*>());
}

void RasterDecoderTestBase::SetBucketData(uint32_t bucket_id,
                                          const void* data,
                                          uint32_t data_size) {
  DCHECK(data || data_size == 0);
  cmd::SetBucketSize cmd1;
  cmd1.Init(bucket_id, data_size);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
  if (data) {
    memcpy(shared_memory_address_, data, data_size);
    cmd::SetBucketData cmd2;
    cmd2.Init(bucket_id, 0, data_size, shared_memory_id_, kSharedMemoryOffset);
    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
    ClearSharedMemory();
  }
}

void RasterDecoderTestBase::SetBucketAsCString(uint32_t bucket_id,
                                               const char* str) {
  SetBucketData(bucket_id, str, str ? (strlen(str) + 1) : 0);
}

void RasterDecoderTestBase::SetBucketAsCStrings(uint32_t bucket_id,
                                                GLsizei count,
                                                const char** str,
                                                GLsizei count_in_header,
                                                char str_end) {
  uint32_t header_size = sizeof(GLint) * (count + 1);
  uint32_t total_size = header_size;
  std::unique_ptr<GLint[]> header(new GLint[count + 1]);
  header[0] = static_cast<GLint>(count_in_header);
  for (GLsizei ii = 0; ii < count; ++ii) {
    header[ii + 1] = str && str[ii] ? strlen(str[ii]) : 0;
    total_size += header[ii + 1] + 1;
  }
  cmd::SetBucketSize cmd1;
  cmd1.Init(bucket_id, total_size);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
  memcpy(shared_memory_address_, header.get(), header_size);
  uint32_t offset = header_size;
  for (GLsizei ii = 0; ii < count; ++ii) {
    if (str && str[ii]) {
      size_t str_len = strlen(str[ii]);
      memcpy(static_cast<char*>(shared_memory_address_) + offset, str[ii],
             str_len);
      offset += str_len;
    }
    memcpy(static_cast<char*>(shared_memory_address_) + offset, &str_end, 1);
    offset += 1;
  }
  cmd::SetBucketData cmd2;
  cmd2.Init(bucket_id, 0, total_size, shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
  ClearSharedMemory();
}

void RasterDecoderTestBase::DoDeleteTexture(GLuint client_id,
                                            GLuint service_id) {
  {
    InSequence s;

    // Calling DoDeleteTexture will unbind the texture from any texture units
    // it's currently bound to.
    EXPECT_CALL(*gl_, BindTexture(_, 0)).Times(AnyNumber());

    EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(service_id)))
        .Times(1)
        .RetiresOnSaturation();

    GenHelper<cmds::DeleteTexturesImmediate>(client_id);
  }
}

void RasterDecoderTestBase::SetScopedTextureBinderExpectations(GLenum target) {
  // ScopedTextureBinder
  EXPECT_CALL(*gl_, ActiveTexture(_))
      .Times(Between(1, 2))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_, BindTexture(target, Ne(0U))).Times(1).RetiresOnSaturation();
  if (!raster_decoder_context_state_->need_context_state_reset)
    EXPECT_CALL(*gl_, BindTexture(target, 0)).Times(1).RetiresOnSaturation();
}

void RasterDecoderTestBase::SetupClearTextureExpectations(
    GLuint service_id,
    GLuint old_service_id,
    GLenum bind_target,
    GLenum target,
    GLint level,
    GLenum format,
    GLenum type,
    GLint xoffset,
    GLint yoffset,
    GLsizei width,
    GLsizei height,
    GLuint bound_pixel_unpack_buffer) {
  EXPECT_CALL(*gl_, BindTexture(bind_target, service_id))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_ALIGNMENT, _))
      .Times(1)
      .RetiresOnSaturation();
  if (bound_pixel_unpack_buffer) {
    EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_UNPACK_BUFFER, _))
        .Times(2)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_ROW_LENGTH, _))
        .Times(2)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_IMAGE_HEIGHT, _))
        .Times(2)
        .RetiresOnSaturation();
  }
  EXPECT_CALL(*gl_, TexSubImage2D(target, level, xoffset, yoffset, width,
                                  height, format, type, _))
      .Times(1)
      .RetiresOnSaturation();
#if DCHECK_IS_ON()
  EXPECT_CALL(*gl_, GetError())
      .WillOnce(Return(GL_NO_ERROR))
      .RetiresOnSaturation();
#endif
}

// Include the auto-generated part of this file. We split this because it means
// we can easily edit the non-auto generated parts right here in this file
// instead of having to edit some template or the code generator.
#include "gpu/command_buffer/service/raster_decoder_unittest_0_autogen.h"

// GCC requires these declarations, but MSVC requires they not be present
#ifndef COMPILER_MSVC
const GLint RasterDecoderTestBase::kMaxTextureSize;
const GLint RasterDecoderTestBase::kNumTextureUnits;

const GLint RasterDecoderTestBase::kViewportX;
const GLint RasterDecoderTestBase::kViewportY;
const GLint RasterDecoderTestBase::kViewportWidth;
const GLint RasterDecoderTestBase::kViewportHeight;

const GLuint RasterDecoderTestBase::kServiceBufferId;
const GLuint RasterDecoderTestBase::kServiceTextureId;
const GLuint RasterDecoderTestBase::kServiceVertexArrayId;

const size_t RasterDecoderTestBase::kSharedBufferSize;
const uint32_t RasterDecoderTestBase::kSharedMemoryOffset;
const int32_t RasterDecoderTestBase::kInvalidSharedMemoryId;
const uint32_t RasterDecoderTestBase::kInvalidSharedMemoryOffset;
const uint32_t RasterDecoderTestBase::kInitialResult;
const uint8_t RasterDecoderTestBase::kInitialMemoryValue;

const uint32_t RasterDecoderTestBase::kNewClientId;
const uint32_t RasterDecoderTestBase::kNewServiceId;
const uint32_t RasterDecoderTestBase::kInvalidClientId;
#endif

}  // namespace raster
}  // namespace gpu
