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/math_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
);
115 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE
), type
);
119 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE
), type
);
124 // If NULL, we aren't checking texture contents.
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
131 const unsigned int stride
=
132 MathUtil::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]);
141 void SetResultAvailable(unsigned result_available
) {
142 result_available_
= result_available
;
146 unsigned result_available_
;
147 unsigned unpack_alignment_
;
149 DISALLOW_COPY_AND_ASSIGN(TextureUploadTestContext
);
152 void UploadTexture(TextureUploader
* uploader
,
153 ResourceFormat format
,
154 const gfx::Size
& size
,
157 data
, gfx::Rect(size
), gfx::Rect(size
), gfx::Vector2d(), format
, size
);
160 TEST(TextureUploaderTest
, NumBlockingUploads
) {
161 TextureUploadTestContext context
;
162 scoped_ptr
<TextureUploader
> uploader
= TextureUploader::Create(&context
);
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());
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());
180 TEST(TextureUploaderTest
, MarkPendingUploadsAsNonBlocking
) {
181 TextureUploadTestContext context
;
182 scoped_ptr
<TextureUploader
> uploader
= TextureUploader::Create(&context
);
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());
190 uploader
->MarkPendingUploadsAsNonBlocking();
191 EXPECT_EQ(0u, uploader
->NumBlockingUploads());
192 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(), NULL
);
193 EXPECT_EQ(1u, uploader
->NumBlockingUploads());
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());
202 TEST(TextureUploaderTest
, UploadContentsTest
) {
203 TextureUploadTestContext context
;
204 scoped_ptr
<TextureUploader
> uploader
= TextureUploader::Create(&context
);
206 uint8 buffer
[256 * 256 * 4];
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;
215 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(256, 256), buffer
);
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;
224 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(41, 43), buffer
);
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;
233 UploadTexture(uploader
.get(), ALPHA_8
, gfx::Size(41, 86), buffer
);
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;
242 UploadTexture(uploader
.get(), LUMINANCE_8
, gfx::Size(82, 86), buffer
);
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;
251 UploadTexture(uploader
.get(), RED_8
, gfx::Size(82, 86), buffer
);