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 |