// Copyright 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 <stdint.h>

#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"

namespace gpu {
namespace gles2 {

using namespace cmds;

TEST_F(GLES3DecoderPassthroughTest, ReadPixelsBufferBound) {
  const GLsizei kWidth = 5;
  const GLsizei kHeight = 3;
  const GLint kBytesPerPixel = 4;
  GLint size = kWidth * kHeight * kBytesPerPixel;
  typedef ReadPixels::Result Result;
  Result* result = GetSharedMemoryAs<Result*>();
  uint32_t result_shm_id = shared_memory_id_;
  uint32_t result_shm_offset = kSharedMemoryOffset;
  uint32_t pixels_shm_id = shared_memory_id_;
  uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);

  DoBindBuffer(GL_PIXEL_PACK_BUFFER, kClientBufferId);
  DoBufferData(GL_PIXEL_PACK_BUFFER, size, nullptr, GL_STATIC_DRAW);

  ReadPixels cmd;
  cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels_shm_id,
           pixels_shm_offset, result_shm_id, result_shm_offset, false);
  result->success = 0;
  EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_F(GLES3DecoderPassthroughTest, ReadPixels2PixelPackBufferNoBufferBound) {
  const GLsizei kWidth = 5;
  const GLsizei kHeight = 3;

  ReadPixels cmd;
  cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0, 0, 0, false);
  EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_F(GLES3DecoderPassthroughTest, ReadPixels2PixelPackBuffer) {
  const GLsizei kWidth = 5;
  const GLsizei kHeight = 3;
  const GLint kBytesPerPixel = 4;
  GLint size = kWidth * kHeight * kBytesPerPixel;

  DoBindBuffer(GL_PIXEL_PACK_BUFFER, kClientBufferId);
  DoBufferData(GL_PIXEL_PACK_BUFFER, size, nullptr, GL_STATIC_DRAW);

  ReadPixels cmd;
  cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0, 0, 0, false);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_F(GLES2DecoderPassthroughTest, DiscardFramebufferEXTUnsupported) {
  const GLenum target = GL_FRAMEBUFFER;
  const GLsizei count = 1;
  const GLenum attachments[] = {GL_COLOR_EXT};
  DiscardFramebufferEXTImmediate& cmd =
      *GetImmediateAs<DiscardFramebufferEXTImmediate>();
  cmd.Init(target, count, attachments);
  EXPECT_EQ(error::kUnknownCommand,
            ExecuteImmediateCmd(cmd, sizeof(attachments)));
}

TEST_F(GLES2DecoderPassthroughTest, ReadPixelsOutOfRange) {
  const GLint kWidth = 5;
  const GLint kHeight = 3;
  const GLenum kFormat = GL_RGBA;

  // Set up GL objects for the read pixels with a known framebuffer size
  DoBindTexture(GL_TEXTURE_2D, kClientTextureId);
  DoTexImage2D(GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0, kFormat,
               GL_UNSIGNED_BYTE, 0, 0);
  DoBindFramebuffer(GL_FRAMEBUFFER, kClientFramebufferId);
  DoFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                         kClientTextureId, 0);

  // Put the resulting pixels and the result in shared memory
  typedef ReadPixels::Result Result;
  Result* result = GetSharedMemoryAs<Result*>();
  uint32_t result_shm_id = shared_memory_id_;
  uint32_t result_shm_offset = kSharedMemoryOffset;
  uint32_t pixels_shm_id = shared_memory_id_;
  uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);

  uint8_t* dest = reinterpret_cast<uint8_t*>(&result[1]);

  // The test cases
  static struct {
    GLint x, y, w, h;
  } tests[] = {
      {
          -2, -1, 9, 5,
      },  // out of range on all sides
      {
          2, 1, 9, 5,
      },  // out of range on right, bottom
      {
          -7, -4, 9, 5,
      },  // out of range on left, top
      {
          0, -5, 9, 5,
      },  // completely off top
      {
          0, 3, 9, 5,
      },  // completely off bottom
      {
          -9, 0, 9, 5,
      },  // completely off left
      {
          5, 0, 9, 5,
      },  // completely off right
  };

  for (auto test : tests) {
    // Clear the readpixels buffer so that we can see which pixels have been
    // written
    memset(dest, 0, 4 * test.w * test.h);

    ReadPixels cmd;
    cmd.Init(test.x, test.y, test.w, test.h, kFormat, GL_UNSIGNED_BYTE,
             pixels_shm_id, pixels_shm_offset, result_shm_id, result_shm_offset,
             false);
    result->success = 0;
    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));

    EXPECT_TRUE(result->success);

    // Check the Result has the correct metadata for what was read.
    GLint startx = std::max(test.x, 0);
    GLint endx = std::min(test.x + test.w, kWidth);
    EXPECT_EQ(result->row_length, endx - startx);

    GLint starty = std::max(test.y, 0);
    GLint endy = std::min(test.y + test.h, kHeight);
    EXPECT_EQ(result->num_rows, endy - starty);

    // Check each pixel and expect them to be non-zero if they were written. The
    // non-zero values are written by ANGLE's NULL backend to simulate the
    // memory that would be modified by the call.
    for (GLint dx = 0; dx < test.w; ++dx) {
      GLint x = test.x + dx;
      for (GLint dy = 0; dy < test.h; ++dy) {
        GLint y = test.y + dy;

        bool expect_written = 0 <= x && x < kWidth && 0 <= y && y < kHeight;
        for (GLint component = 0; component < 4; ++component) {
          uint8_t value = dest[4 * (dy * test.w + dx) + component];
          EXPECT_EQ(expect_written, value != 0)
              << x << " " << y << " " << value;
        }
      }
    }
  }
}

TEST_F(GLES2DecoderPassthroughTest, ReadPixelsAsync) {
  typedef ReadPixels::Result Result;
  Result* result = GetSharedMemoryAs<Result*>();
  const GLsizei kWidth = 4;
  const GLsizei kHeight = 4;
  uint32_t result_shm_id = shared_memory_id_;
  uint32_t result_shm_offset = kSharedMemoryOffset;
  uint32_t pixels_shm_id = shared_memory_id_;
  uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);

  ReadPixels read_pixels_cmd;
  read_pixels_cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
                       pixels_shm_id, pixels_shm_offset, result_shm_id,
                       result_shm_offset, true);
  result->success = 0;

  EXPECT_EQ(error::kNoError, ExecuteCmd(read_pixels_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_TRUE(GetDecoder()->HasMoreIdleWork());

  {
    // Verify internals of pending read pixels
    const auto& all_pending_read_pixels = GetPendingReadPixels();
    EXPECT_EQ(1u, all_pending_read_pixels.size());

    const auto& pending_read_pixels = all_pending_read_pixels.front();
    EXPECT_NE(nullptr, pending_read_pixels.fence);
    EXPECT_EQ(pixels_shm_id, pending_read_pixels.pixels_shm_id);
    EXPECT_EQ(pixels_shm_offset, pending_read_pixels.pixels_shm_offset);
    EXPECT_EQ(result_shm_offset, pending_read_pixels.result_shm_offset);
    EXPECT_EQ(result_shm_id, pending_read_pixels.result_shm_id);
    EXPECT_NE(0u, pending_read_pixels.buffer_service_id);
    EXPECT_TRUE(pending_read_pixels.waiting_async_pack_queries.empty());
  }

  Finish finish_cmd;
  finish_cmd.Init();
  EXPECT_EQ(error::kNoError, ExecuteCmd(finish_cmd));
  EXPECT_FALSE(GetDecoder()->HasMoreIdleWork());
  EXPECT_TRUE(GetPendingReadPixels().empty());
}

TEST_F(GLES3DecoderPassthroughTest, ReadPixelsAsyncSkippedIfPBOBound) {
  typedef ReadPixels::Result Result;
  Result* result = GetSharedMemoryAs<Result*>();
  const GLsizei kWidth = 4;
  const GLsizei kHeight = 4;
  uint32_t result_shm_id = shared_memory_id_;
  uint32_t result_shm_offset = kSharedMemoryOffset;

  cmds::BindBuffer bind_cmd;
  bind_cmd.Init(GL_PIXEL_PACK_BUFFER, kClientBufferId);
  EXPECT_EQ(error::kNoError, ExecuteCmd(bind_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  cmds::BufferData buffer_data_cmd;
  size_t read_pixels_result_size = kWidth * kHeight * 4;
  buffer_data_cmd.Init(GL_PIXEL_PACK_BUFFER, read_pixels_result_size, 0, 0,
                       GL_STREAM_DRAW);
  EXPECT_EQ(error::kNoError, ExecuteCmd(buffer_data_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  // Check that there is no idle work to do when a PBO is already bound and that
  // the ReadPixel succeeded
  ReadPixels read_pixels_cmd;
  read_pixels_cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0,
                       result_shm_id, result_shm_offset, true);
  result->success = 0;
  EXPECT_EQ(error::kNoError, ExecuteCmd(read_pixels_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_FALSE(GetDecoder()->HasMoreIdleWork());
}

TEST_F(GLES2DecoderPassthroughTest, ReadPixelsAsyncModifyCommand) {
  typedef ReadPixels::Result Result;
  size_t shm_size = 0;
  Result* result = GetSharedMemoryAsWithSize<Result*>(&shm_size);
  const GLsizei kWidth = 4;
  const GLsizei kHeight = 4;
  uint32_t result_shm_id = shared_memory_id_;
  uint32_t result_shm_offset = kSharedMemoryOffset;
  uint32_t pixels_shm_id = shared_memory_id_;
  uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);

  size_t pixels_memory_size = shm_size - 1;
  char* pixels = reinterpret_cast<char*>(result + 1);

  constexpr char kDummyValue = 11;
  size_t read_pixels_result_size = kWidth * kHeight * 4;
  EXPECT_GT(pixels_memory_size, read_pixels_result_size);
  memset(pixels, kDummyValue, pixels_memory_size);

  ReadPixels read_pixels_cmd;
  read_pixels_cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
                       pixels_shm_id, pixels_shm_offset, result_shm_id,
                       result_shm_offset, true);
  result->success = 0;

  EXPECT_EQ(error::kNoError, ExecuteCmd(read_pixels_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_TRUE(GetDecoder()->HasMoreIdleWork());

  // Change command after ReadPixels issued, but before we finish the read,
  // should have no impact.
  read_pixels_cmd.Init(1, 2, 6, 7, GL_RGB, GL_UNSIGNED_SHORT, pixels_shm_id,
                       pixels_shm_offset, result_shm_id, result_shm_offset,
                       false);

  Finish finish_cmd;
  finish_cmd.Init();
  EXPECT_EQ(error::kNoError, ExecuteCmd(finish_cmd));
  EXPECT_FALSE(GetDecoder()->HasMoreIdleWork());
  EXPECT_TRUE(GetPendingReadPixels().empty());

  // Validate that only the correct bytes of pixels have been written to.
  for (size_t i = 0; i < pixels_memory_size; i++) {
    // ANGLE's null context always returns 42 for all pixel bytes for ReadPixels
    // calls.
    constexpr char kReadPixelsValue = 42;
    char expected_value =
        i < read_pixels_result_size ? kReadPixelsValue : kDummyValue;
    EXPECT_EQ(expected_value, pixels[i]);
  }
}

TEST_F(GLES2DecoderPassthroughTest, ReadPixelsAsyncChangePackAlignment) {
  typedef ReadPixels::Result Result;
  size_t shm_size = 0;
  Result* result = GetSharedMemoryAsWithSize<Result*>(&shm_size);
  const GLsizei kWidth = 4;
  const GLsizei kHeight = 4;
  uint32_t result_shm_id = shared_memory_id_;
  uint32_t result_shm_offset = kSharedMemoryOffset;
  uint32_t pixels_shm_id = shared_memory_id_;
  uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);

  size_t pixels_memory_size = shm_size - 1;
  char* pixels = reinterpret_cast<char*>(result + 1);

  constexpr char kDummyValue = 11;
  size_t read_pixels_result_size = kWidth * kHeight * 4;
  EXPECT_GT(pixels_memory_size, read_pixels_result_size);
  memset(pixels, kDummyValue, pixels_memory_size);

  ReadPixels read_pixels_cmd;
  read_pixels_cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
                       pixels_shm_id, pixels_shm_offset, result_shm_id,
                       result_shm_offset, true);
  result->success = 0;

  EXPECT_EQ(error::kNoError, ExecuteCmd(read_pixels_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_TRUE(GetDecoder()->HasMoreIdleWork());

  PixelStorei pixel_store_i_cmd;
  pixel_store_i_cmd.Init(GL_PACK_ALIGNMENT, 8);
  EXPECT_EQ(error::kNoError, ExecuteCmd(pixel_store_i_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  Finish finish_cmd;
  finish_cmd.Init();
  EXPECT_EQ(error::kNoError, ExecuteCmd(finish_cmd));
  EXPECT_FALSE(GetDecoder()->HasMoreIdleWork());
  EXPECT_TRUE(GetPendingReadPixels().empty());

  // Validate that only the correct bytes of pixels have been written to.
  for (size_t i = 0; i < pixels_memory_size; i++) {
    // ANGLE's null context always returns 42 for all pixel bytes for ReadPixels
    // calls.
    constexpr char kReadPixelsValue = 42;
    char expected_value =
        i < read_pixels_result_size ? kReadPixelsValue : kDummyValue;
    EXPECT_EQ(expected_value, pixels[i]);
  }
}

TEST_F(GLES2DecoderPassthroughTest, ReadPixelsAsyncError) {
  typedef ReadPixels::Result Result;
  Result* result = GetSharedMemoryAs<Result*>();
  const GLsizei kWidth = 4;
  const GLsizei kHeight = 4;
  uint32_t result_shm_id = shared_memory_id_;
  uint32_t result_shm_offset = kSharedMemoryOffset;
  uint32_t pixels_shm_id = shared_memory_id_;
  uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);

  // Provide parameters that will cause glReadPixels to fail with
  // GL_INVALID_OPERATION
  ReadPixels cmd;
  cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_SHORT, pixels_shm_id,
           pixels_shm_offset, result_shm_id, result_shm_offset, true);
  result->success = 0;
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
  EXPECT_FALSE(GetDecoder()->HasMoreIdleWork());
  EXPECT_TRUE(GetPendingReadPixels().empty());
}

TEST_F(GLES2DecoderPassthroughTest,
       RenderbufferStorageMultisampleEXTNotSupported) {
  DoBindRenderbuffer(GL_RENDERBUFFER, kClientRenderbufferId);
  // GL_EXT_framebuffer_multisample uses RenderbufferStorageMultisampleCHROMIUM.
  RenderbufferStorageMultisampleEXT cmd;
  cmd.Init(GL_RENDERBUFFER, 1, GL_RGBA4, 1, 1);
  EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
}

TEST_F(GLES2DecoderPassthroughTest,
       GetFramebufferAttachmentParameterivWithRenderbuffer) {
  DoBindFramebuffer(GL_FRAMEBUFFER, kClientFramebufferId);
  DoBindRenderbuffer(GL_RENDERBUFFER, kClientRenderbufferId);
  DoFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                            GL_RENDERBUFFER, kClientRenderbufferId);

  GetFramebufferAttachmentParameteriv::Result* result =
      static_cast<GetFramebufferAttachmentParameteriv::Result*>(
          shared_memory_address_);
  result->size = 0;
  const GLint* result_value = result->GetData();

  GetFramebufferAttachmentParameteriv cmd;
  cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
           GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, shared_memory_id_,
           shared_memory_offset_);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_EQ(kClientRenderbufferId, static_cast<GLuint>(*result_value));
}

TEST_F(GLES2DecoderPassthroughTest,
       GetFramebufferAttachmentParameterivWithTexture) {
  DoBindFramebuffer(GL_FRAMEBUFFER, kClientFramebufferId);
  DoBindTexture(GL_TEXTURE_2D, kClientTextureId);
  DoFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                         kClientTextureId, 0);

  GetFramebufferAttachmentParameteriv::Result* result =
      static_cast<GetFramebufferAttachmentParameteriv::Result*>(
          shared_memory_address_);
  result->size = 0;
  const GLint* result_value = result->GetData();

  GetFramebufferAttachmentParameteriv cmd;
  cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
           GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, shared_memory_id_,
           shared_memory_offset_);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_EQ(kClientTextureId, static_cast<GLuint>(*result_value));
}

}  // namespace gles2
}  // namespace gpu
