| Index: cc/resources/texture_uploader_unittest.cc
|
| diff --git a/cc/resources/texture_uploader_unittest.cc b/cc/resources/texture_uploader_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b1689627d1f32bbd0a7aed726e935bedf2cb9c74
|
| --- /dev/null
|
| +++ b/cc/resources/texture_uploader_unittest.cc
|
| @@ -0,0 +1,255 @@
|
| +// 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;
|
| + case GL_RED_EXT:
|
| + EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
|
| + bytes_per_pixel = 1;
|
| + break;
|
| + case GL_RG_EXT:
|
| + 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);
|
| +
|
| + // Upload a tightly packed 82x86 RED 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(), RED_8, gfx::Size(82, 86), buffer);
|
| +}
|
| +
|
| +} // namespace
|
| +} // namespace cc
|
|
|