1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/resources/texture_uploader.h"
7 #include "cc/base/util.h"
8 #include "cc/resources/prioritized_resource.h"
9 #include "gpu/command_buffer/client/gles2_interface_stub.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/khronos/GLES2/gl2.h"
13 #include "third_party/khronos/GLES2/gl2ext.h"
18 class TextureUploadTestContext : public gpu::gles2::GLES2InterfaceStub {
20 TextureUploadTestContext() : result_available_(0), unpack_alignment_(4) {}
22 void PixelStorei(GLenum pname, GLint param) override {
24 case GL_UNPACK_ALIGNMENT:
25 // Param should be a power of two <= 8.
26 EXPECT_EQ(0, param & (param - 1));
33 unpack_alignment_ = param;
44 void GetQueryObjectuivEXT(GLuint, GLenum type, GLuint* value) override {
46 case GL_QUERY_RESULT_AVAILABLE_EXT:
47 *value = result_available_;
55 void TexSubImage2D(GLenum target,
63 const void* pixels) override {
64 EXPECT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
68 EXPECT_LE(0, xoffset);
69 EXPECT_LE(0, yoffset);
73 // Check for allowed format/type combination.
74 unsigned int bytes_per_pixel = 0;
77 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
81 EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_4_4_4_4), type);
82 EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_5_5_1), type);
84 case GL_UNSIGNED_BYTE:
87 case GL_UNSIGNED_SHORT_5_6_5:
93 EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_6_5), type);
95 case GL_UNSIGNED_BYTE:
98 case GL_UNSIGNED_SHORT_4_4_4_4:
101 case GL_UNSIGNED_SHORT_5_5_5_1:
107 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
110 case GL_LUMINANCE_ALPHA:
111 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
116 // If NULL, we aren't checking texture contents.
120 const uint8* bytes = static_cast<const uint8*>(pixels);
121 // We'll expect the first byte of every row to be 0x1, and the last byte to
123 const unsigned int stride =
124 RoundUp(bytes_per_pixel * width, unpack_alignment_);
125 for (GLsizei row = 0; row < height; ++row) {
126 const uint8* row_bytes =
127 bytes + (xoffset * bytes_per_pixel + (yoffset + row) * stride);
128 EXPECT_EQ(0x1, row_bytes[0]);
129 EXPECT_EQ(0x2, row_bytes[width * bytes_per_pixel - 1]);
133 void SetResultAvailable(unsigned result_available) {
134 result_available_ = result_available;
138 unsigned result_available_;
139 unsigned unpack_alignment_;
141 DISALLOW_COPY_AND_ASSIGN(TextureUploadTestContext);
144 void UploadTexture(TextureUploader* uploader,
145 ResourceFormat format,
146 const gfx::Size& size,
149 data, gfx::Rect(size), gfx::Rect(size), gfx::Vector2d(), format, size);
152 TEST(TextureUploaderTest, NumBlockingUploads) {
153 TextureUploadTestContext context;
154 scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
156 context.SetResultAvailable(0);
157 EXPECT_EQ(0u, uploader->NumBlockingUploads());
158 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
159 EXPECT_EQ(1u, uploader->NumBlockingUploads());
160 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
161 EXPECT_EQ(2u, uploader->NumBlockingUploads());
163 context.SetResultAvailable(1);
164 EXPECT_EQ(0u, uploader->NumBlockingUploads());
165 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
166 EXPECT_EQ(0u, uploader->NumBlockingUploads());
167 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
168 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
169 EXPECT_EQ(0u, uploader->NumBlockingUploads());
172 TEST(TextureUploaderTest, MarkPendingUploadsAsNonBlocking) {
173 TextureUploadTestContext context;
174 scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
176 context.SetResultAvailable(0);
177 EXPECT_EQ(0u, uploader->NumBlockingUploads());
178 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
179 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
180 EXPECT_EQ(2u, uploader->NumBlockingUploads());
182 uploader->MarkPendingUploadsAsNonBlocking();
183 EXPECT_EQ(0u, uploader->NumBlockingUploads());
184 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
185 EXPECT_EQ(1u, uploader->NumBlockingUploads());
187 context.SetResultAvailable(1);
188 EXPECT_EQ(0u, uploader->NumBlockingUploads());
189 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
190 uploader->MarkPendingUploadsAsNonBlocking();
191 EXPECT_EQ(0u, uploader->NumBlockingUploads());
194 TEST(TextureUploaderTest, UploadContentsTest) {
195 TextureUploadTestContext context;
196 scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
198 uint8 buffer[256 * 256 * 4];
200 // Upload a tightly packed 256x256 RGBA texture.
201 memset(buffer, 0, sizeof(buffer));
202 for (int i = 0; i < 256; ++i) {
203 // Mark the beginning and end of each row, for the test.
204 buffer[i * 4 * 256] = 0x1;
205 buffer[(i + 1) * 4 * 256 - 1] = 0x2;
207 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(256, 256), buffer);
209 // Upload a tightly packed 41x43 RGBA texture.
210 memset(buffer, 0, sizeof(buffer));
211 for (int i = 0; i < 43; ++i) {
212 // Mark the beginning and end of each row, for the test.
213 buffer[i * 4 * 41] = 0x1;
214 buffer[(i + 1) * 4 * 41 - 1] = 0x2;
216 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(41, 43), buffer);
218 // Upload a tightly packed 41x86 ALPHA texture.
219 memset(buffer, 0, sizeof(buffer));
220 for (int i = 0; i < 86; ++i) {
221 // Mark the beginning and end of each row, for the test.
222 buffer[i * 1 * 41] = 0x1;
223 buffer[(i + 1) * 41 - 1] = 0x2;
225 UploadTexture(uploader.get(), ALPHA_8, gfx::Size(41, 86), buffer);
227 // Upload a tightly packed 82x86 LUMINANCE texture.
228 memset(buffer, 0, sizeof(buffer));
229 for (int i = 0; i < 86; ++i) {
230 // Mark the beginning and end of each row, for the test.
231 buffer[i * 1 * 82] = 0x1;
232 buffer[(i + 1) * 82 - 1] = 0x2;
234 UploadTexture(uploader.get(), LUMINANCE_8, gfx::Size(82, 86), buffer);