// Copyright 2014 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 "cc/resources/texture_uploader.h"

#include "cc/base/util.h"
#include "cc/resources/prioritized_resource.h"
#include "gpu/command_buffer/client/gles2_interface_stub.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"

namespace cc {
namespace {

class TextureUploadTestContext : public gpu::gles2::GLES2InterfaceStub {
 public:
  TextureUploadTestContext() : result_available_(0), unpack_alignment_(4) {}

  void PixelStorei(GLenum pname, GLint param) override {
    switch (pname) {
      case GL_UNPACK_ALIGNMENT:
        // Param should be a power of two <= 8.
        EXPECT_EQ(0, param & (param - 1));
        EXPECT_GE(8, param);
        switch (param) {
          case 1:
          case 2:
          case 4:
          case 8:
            unpack_alignment_ = param;
            break;
          default:
            break;
        }
        break;
      default:
        break;
    }
  }

  void GetQueryObjectuivEXT(GLuint, GLenum type, GLuint* value) override {
    switch (type) {
      case GL_QUERY_RESULT_AVAILABLE_EXT:
        *value = result_available_;
        break;
      default:
        *value = 0;
        break;
    }
  }

  void TexSubImage2D(GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLsizei width,
                     GLsizei height,
                     GLenum format,
                     GLenum type,
                     const void* pixels) override {
    EXPECT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
    EXPECT_EQ(0, level);
    EXPECT_LE(0, width);
    EXPECT_LE(0, height);
    EXPECT_LE(0, xoffset);
    EXPECT_LE(0, yoffset);
    EXPECT_LE(0, width);
    EXPECT_LE(0, height);

    // Check for allowed format/type combination.
    unsigned int bytes_per_pixel = 0;
    switch (format) {
      case GL_ALPHA:
        EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
        bytes_per_pixel = 1;
        break;
      case GL_RGB:
        EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_4_4_4_4), type);
        EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_5_5_1), type);
        switch (type) {
          case GL_UNSIGNED_BYTE:
            bytes_per_pixel = 3;
            break;
          case GL_UNSIGNED_SHORT_5_6_5:
            bytes_per_pixel = 2;
            break;
        }
        break;
      case GL_RGBA:
        EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_6_5), type);
        switch (type) {
          case GL_UNSIGNED_BYTE:
            bytes_per_pixel = 4;
            break;
          case GL_UNSIGNED_SHORT_4_4_4_4:
            bytes_per_pixel = 2;
            break;
          case GL_UNSIGNED_SHORT_5_5_5_1:
            bytes_per_pixel = 2;
            break;
        }
        break;
      case GL_LUMINANCE:
        EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
        bytes_per_pixel = 1;
        break;
      case GL_LUMINANCE_ALPHA:
        EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
        bytes_per_pixel = 2;
        break;
    }

    // If NULL, we aren't checking texture contents.
    if (pixels == NULL)
      return;

    const uint8* bytes = static_cast<const uint8*>(pixels);
    // We'll expect the first byte of every row to be 0x1, and the last byte to
    // be 0x2.
    const unsigned int stride =
        RoundUp(bytes_per_pixel * width, unpack_alignment_);
    for (GLsizei row = 0; row < height; ++row) {
      const uint8* row_bytes =
          bytes + (xoffset * bytes_per_pixel + (yoffset + row) * stride);
      EXPECT_EQ(0x1, row_bytes[0]);
      EXPECT_EQ(0x2, row_bytes[width * bytes_per_pixel - 1]);
    }
  }

  void SetResultAvailable(unsigned result_available) {
    result_available_ = result_available;
  }

 private:
  unsigned result_available_;
  unsigned unpack_alignment_;

  DISALLOW_COPY_AND_ASSIGN(TextureUploadTestContext);
};

void UploadTexture(TextureUploader* uploader,
                   ResourceFormat format,
                   const gfx::Size& size,
                   const uint8* data) {
  uploader->Upload(
      data, gfx::Rect(size), gfx::Rect(size), gfx::Vector2d(), format, size);
}

TEST(TextureUploaderTest, NumBlockingUploads) {
  TextureUploadTestContext context;
  scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);

  context.SetResultAvailable(0);
  EXPECT_EQ(0u, uploader->NumBlockingUploads());
  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
  EXPECT_EQ(1u, uploader->NumBlockingUploads());
  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
  EXPECT_EQ(2u, uploader->NumBlockingUploads());

  context.SetResultAvailable(1);
  EXPECT_EQ(0u, uploader->NumBlockingUploads());
  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
  EXPECT_EQ(0u, uploader->NumBlockingUploads());
  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
  EXPECT_EQ(0u, uploader->NumBlockingUploads());
}

TEST(TextureUploaderTest, MarkPendingUploadsAsNonBlocking) {
  TextureUploadTestContext context;
  scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);

  context.SetResultAvailable(0);
  EXPECT_EQ(0u, uploader->NumBlockingUploads());
  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
  EXPECT_EQ(2u, uploader->NumBlockingUploads());

  uploader->MarkPendingUploadsAsNonBlocking();
  EXPECT_EQ(0u, uploader->NumBlockingUploads());
  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
  EXPECT_EQ(1u, uploader->NumBlockingUploads());

  context.SetResultAvailable(1);
  EXPECT_EQ(0u, uploader->NumBlockingUploads());
  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
  uploader->MarkPendingUploadsAsNonBlocking();
  EXPECT_EQ(0u, uploader->NumBlockingUploads());
}

TEST(TextureUploaderTest, UploadContentsTest) {
  TextureUploadTestContext context;
  scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);

  uint8 buffer[256 * 256 * 4];

  // Upload a tightly packed 256x256 RGBA texture.
  memset(buffer, 0, sizeof(buffer));
  for (int i = 0; i < 256; ++i) {
    // Mark the beginning and end of each row, for the test.
    buffer[i * 4 * 256] = 0x1;
    buffer[(i + 1) * 4 * 256 - 1] = 0x2;
  }
  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(256, 256), buffer);

  // Upload a tightly packed 41x43 RGBA texture.
  memset(buffer, 0, sizeof(buffer));
  for (int i = 0; i < 43; ++i) {
    // Mark the beginning and end of each row, for the test.
    buffer[i * 4 * 41] = 0x1;
    buffer[(i + 1) * 4 * 41 - 1] = 0x2;
  }
  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(41, 43), buffer);

  // Upload a tightly packed 41x86 ALPHA texture.
  memset(buffer, 0, sizeof(buffer));
  for (int i = 0; i < 86; ++i) {
    // Mark the beginning and end of each row, for the test.
    buffer[i * 1 * 41] = 0x1;
    buffer[(i + 1) * 41 - 1] = 0x2;
  }
  UploadTexture(uploader.get(), ALPHA_8, gfx::Size(41, 86), buffer);

  // Upload a tightly packed 82x86 LUMINANCE texture.
  memset(buffer, 0, sizeof(buffer));
  for (int i = 0; i < 86; ++i) {
    // Mark the beginning and end of each row, for the test.
    buffer[i * 1 * 82] = 0x1;
    buffer[(i + 1) * 82 - 1] = 0x2;
  }
  UploadTexture(uploader.get(), LUMINANCE_8, gfx::Size(82, 86), buffer);
}

}  // namespace
}  // namespace cc
