OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "cc/resources/texture_uploader.h" | |
6 | |
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" | |
14 | |
15 namespace cc { | |
16 namespace { | |
17 | |
18 class TextureUploadTestContext : public gpu::gles2::GLES2InterfaceStub { | |
19 public: | |
20 TextureUploadTestContext() : result_available_(0), unpack_alignment_(4) {} | |
21 | |
22 void PixelStorei(GLenum pname, GLint param) override { | |
23 switch (pname) { | |
24 case GL_UNPACK_ALIGNMENT: | |
25 // Param should be a power of two <= 8. | |
26 EXPECT_EQ(0, param & (param - 1)); | |
27 EXPECT_GE(8, param); | |
28 switch (param) { | |
29 case 1: | |
30 case 2: | |
31 case 4: | |
32 case 8: | |
33 unpack_alignment_ = param; | |
34 break; | |
35 default: | |
36 break; | |
37 } | |
38 break; | |
39 default: | |
40 break; | |
41 } | |
42 } | |
43 | |
44 void GetQueryObjectuivEXT(GLuint, GLenum type, GLuint* value) override { | |
45 switch (type) { | |
46 case GL_QUERY_RESULT_AVAILABLE_EXT: | |
47 *value = result_available_; | |
48 break; | |
49 default: | |
50 *value = 0; | |
51 break; | |
52 } | |
53 } | |
54 | |
55 void TexSubImage2D(GLenum target, | |
56 GLint level, | |
57 GLint xoffset, | |
58 GLint yoffset, | |
59 GLsizei width, | |
60 GLsizei height, | |
61 GLenum format, | |
62 GLenum type, | |
63 const void* pixels) override { | |
64 EXPECT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target); | |
65 EXPECT_EQ(0, level); | |
66 EXPECT_LE(0, width); | |
67 EXPECT_LE(0, height); | |
68 EXPECT_LE(0, xoffset); | |
69 EXPECT_LE(0, yoffset); | |
70 EXPECT_LE(0, width); | |
71 EXPECT_LE(0, height); | |
72 | |
73 // Check for allowed format/type combination. | |
74 unsigned int bytes_per_pixel = 0; | |
75 switch (format) { | |
76 case GL_ALPHA: | |
77 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type); | |
78 bytes_per_pixel = 1; | |
79 break; | |
80 case GL_RGB: | |
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); | |
83 switch (type) { | |
84 case GL_UNSIGNED_BYTE: | |
85 bytes_per_pixel = 3; | |
86 break; | |
87 case GL_UNSIGNED_SHORT_5_6_5: | |
88 bytes_per_pixel = 2; | |
89 break; | |
90 } | |
91 break; | |
92 case GL_RGBA: | |
93 EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_6_5), type); | |
94 switch (type) { | |
95 case GL_UNSIGNED_BYTE: | |
96 bytes_per_pixel = 4; | |
97 break; | |
98 case GL_UNSIGNED_SHORT_4_4_4_4: | |
99 bytes_per_pixel = 2; | |
100 break; | |
101 case GL_UNSIGNED_SHORT_5_5_5_1: | |
102 bytes_per_pixel = 2; | |
103 break; | |
104 } | |
105 break; | |
106 case GL_LUMINANCE: | |
107 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type); | |
108 bytes_per_pixel = 1; | |
109 break; | |
110 case GL_LUMINANCE_ALPHA: | |
111 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type); | |
112 bytes_per_pixel = 2; | |
113 break; | |
114 case GL_RED_EXT: | |
115 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type); | |
116 bytes_per_pixel = 1; | |
117 break; | |
118 case GL_RG_EXT: | |
119 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type); | |
120 bytes_per_pixel = 2; | |
121 break; | |
122 } | |
123 | |
124 // If NULL, we aren't checking texture contents. | |
125 if (pixels == NULL) | |
126 return; | |
127 | |
128 const uint8* bytes = static_cast<const uint8*>(pixels); | |
129 // We'll expect the first byte of every row to be 0x1, and the last byte to | |
130 // be 0x2. | |
131 const unsigned int stride = | |
132 RoundUp(bytes_per_pixel * width, unpack_alignment_); | |
133 for (GLsizei row = 0; row < height; ++row) { | |
134 const uint8* row_bytes = | |
135 bytes + (xoffset * bytes_per_pixel + (yoffset + row) * stride); | |
136 EXPECT_EQ(0x1, row_bytes[0]); | |
137 EXPECT_EQ(0x2, row_bytes[width * bytes_per_pixel - 1]); | |
138 } | |
139 } | |
140 | |
141 void SetResultAvailable(unsigned result_available) { | |
142 result_available_ = result_available; | |
143 } | |
144 | |
145 private: | |
146 unsigned result_available_; | |
147 unsigned unpack_alignment_; | |
148 | |
149 DISALLOW_COPY_AND_ASSIGN(TextureUploadTestContext); | |
150 }; | |
151 | |
152 void UploadTexture(TextureUploader* uploader, | |
153 ResourceFormat format, | |
154 const gfx::Size& size, | |
155 const uint8* data) { | |
156 uploader->Upload( | |
157 data, gfx::Rect(size), gfx::Rect(size), gfx::Vector2d(), format, size); | |
158 } | |
159 | |
160 TEST(TextureUploaderTest, NumBlockingUploads) { | |
161 TextureUploadTestContext context; | |
162 scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context); | |
163 | |
164 context.SetResultAvailable(0); | |
165 EXPECT_EQ(0u, uploader->NumBlockingUploads()); | |
166 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL); | |
167 EXPECT_EQ(1u, uploader->NumBlockingUploads()); | |
168 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL); | |
169 EXPECT_EQ(2u, uploader->NumBlockingUploads()); | |
170 | |
171 context.SetResultAvailable(1); | |
172 EXPECT_EQ(0u, uploader->NumBlockingUploads()); | |
173 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL); | |
174 EXPECT_EQ(0u, uploader->NumBlockingUploads()); | |
175 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL); | |
176 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL); | |
177 EXPECT_EQ(0u, uploader->NumBlockingUploads()); | |
178 } | |
179 | |
180 TEST(TextureUploaderTest, MarkPendingUploadsAsNonBlocking) { | |
181 TextureUploadTestContext context; | |
182 scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context); | |
183 | |
184 context.SetResultAvailable(0); | |
185 EXPECT_EQ(0u, uploader->NumBlockingUploads()); | |
186 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL); | |
187 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL); | |
188 EXPECT_EQ(2u, uploader->NumBlockingUploads()); | |
189 | |
190 uploader->MarkPendingUploadsAsNonBlocking(); | |
191 EXPECT_EQ(0u, uploader->NumBlockingUploads()); | |
192 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL); | |
193 EXPECT_EQ(1u, uploader->NumBlockingUploads()); | |
194 | |
195 context.SetResultAvailable(1); | |
196 EXPECT_EQ(0u, uploader->NumBlockingUploads()); | |
197 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL); | |
198 uploader->MarkPendingUploadsAsNonBlocking(); | |
199 EXPECT_EQ(0u, uploader->NumBlockingUploads()); | |
200 } | |
201 | |
202 TEST(TextureUploaderTest, UploadContentsTest) { | |
203 TextureUploadTestContext context; | |
204 scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context); | |
205 | |
206 uint8 buffer[256 * 256 * 4]; | |
207 | |
208 // Upload a tightly packed 256x256 RGBA texture. | |
209 memset(buffer, 0, sizeof(buffer)); | |
210 for (int i = 0; i < 256; ++i) { | |
211 // Mark the beginning and end of each row, for the test. | |
212 buffer[i * 4 * 256] = 0x1; | |
213 buffer[(i + 1) * 4 * 256 - 1] = 0x2; | |
214 } | |
215 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(256, 256), buffer); | |
216 | |
217 // Upload a tightly packed 41x43 RGBA texture. | |
218 memset(buffer, 0, sizeof(buffer)); | |
219 for (int i = 0; i < 43; ++i) { | |
220 // Mark the beginning and end of each row, for the test. | |
221 buffer[i * 4 * 41] = 0x1; | |
222 buffer[(i + 1) * 4 * 41 - 1] = 0x2; | |
223 } | |
224 UploadTexture(uploader.get(), RGBA_8888, gfx::Size(41, 43), buffer); | |
225 | |
226 // Upload a tightly packed 41x86 ALPHA texture. | |
227 memset(buffer, 0, sizeof(buffer)); | |
228 for (int i = 0; i < 86; ++i) { | |
229 // Mark the beginning and end of each row, for the test. | |
230 buffer[i * 1 * 41] = 0x1; | |
231 buffer[(i + 1) * 41 - 1] = 0x2; | |
232 } | |
233 UploadTexture(uploader.get(), ALPHA_8, gfx::Size(41, 86), buffer); | |
234 | |
235 // Upload a tightly packed 82x86 LUMINANCE texture. | |
236 memset(buffer, 0, sizeof(buffer)); | |
237 for (int i = 0; i < 86; ++i) { | |
238 // Mark the beginning and end of each row, for the test. | |
239 buffer[i * 1 * 82] = 0x1; | |
240 buffer[(i + 1) * 82 - 1] = 0x2; | |
241 } | |
242 UploadTexture(uploader.get(), LUMINANCE_8, gfx::Size(82, 86), buffer); | |
243 | |
244 // Upload a tightly packed 82x86 RED texture. | |
245 memset(buffer, 0, sizeof(buffer)); | |
246 for (int i = 0; i < 86; ++i) { | |
247 // Mark the beginning and end of each row, for the test. | |
248 buffer[i * 1 * 82] = 0x1; | |
249 buffer[(i + 1) * 82 - 1] = 0x2; | |
250 } | |
251 UploadTexture(uploader.get(), RED_8, gfx::Size(82, 86), buffer); | |
252 } | |
253 | |
254 } // namespace | |
255 } // namespace cc | |
OLD | NEW |