1 // Copyright 2012 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/scheduler/texture_uploader.h"
7 #include "cc/base/util.h"
8 #include "cc/debug/test_web_graphics_context_3d.h"
9 #include "cc/resources/prioritized_resource.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"
15 using WebKit::WGC3Denum
;
16 using WebKit::WGC3Dint
;
17 using WebKit::WGC3Dsizei
;
18 using WebKit::WebGLId
;
19 using WebKit::WGC3Duint
;
24 class TestWebGraphicsContext3DTextureUpload
: public TestWebGraphicsContext3D
{
26 TestWebGraphicsContext3DTextureUpload()
27 : result_available_(0),
28 unpack_alignment_(4) {}
30 virtual void pixelStorei(WGC3Denum pname
, WGC3Dint param
) OVERRIDE
{
32 case GL_UNPACK_ALIGNMENT
:
33 // Param should be a power of two <= 8.
34 EXPECT_EQ(0, param
& (param
- 1));
41 unpack_alignment_
= param
;
52 virtual void getQueryObjectuivEXT(WebGLId
, WGC3Denum type
, WGC3Duint
* value
)
55 case GL_QUERY_RESULT_AVAILABLE_EXT
:
56 *value
= result_available_
;
64 virtual void texSubImage2D(WGC3Denum target
,
72 const void* pixels
) OVERRIDE
{
73 EXPECT_EQ(static_cast<unsigned>(GL_TEXTURE_2D
), target
);
77 EXPECT_LE(0, xoffset
);
78 EXPECT_LE(0, yoffset
);
82 // Check for allowed format/type combination.
83 unsigned int bytes_per_pixel
= 0;
86 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE
), type
);
90 EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_4_4_4_4
), type
);
91 EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_5_5_1
), type
);
93 case GL_UNSIGNED_BYTE
:
96 case GL_UNSIGNED_SHORT_5_6_5
:
102 EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_6_5
), type
);
104 case GL_UNSIGNED_BYTE
:
107 case GL_UNSIGNED_SHORT_4_4_4_4
:
110 case GL_UNSIGNED_SHORT_5_5_5_1
:
116 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE
), type
);
119 case GL_LUMINANCE_ALPHA
:
120 EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE
), type
);
125 // If NULL, we aren't checking texture contents.
129 const uint8
* bytes
= static_cast<const uint8
*>(pixels
);
130 // We'll expect the first byte of every row to be 0x1, and the last byte to
132 const unsigned int stride
=
133 RoundUp(bytes_per_pixel
* width
, unpack_alignment_
);
134 for (WGC3Dsizei row
= 0; row
< height
; ++row
) {
135 const uint8
* row_bytes
=
136 bytes
+ (xoffset
* bytes_per_pixel
+ (yoffset
+ row
) * stride
);
137 EXPECT_EQ(0x1, row_bytes
[0]);
138 EXPECT_EQ(0x2, row_bytes
[width
* bytes_per_pixel
- 1]);
142 void SetResultAvailable(unsigned result_available
) {
143 result_available_
= result_available
;
147 unsigned result_available_
;
148 unsigned unpack_alignment_
;
150 DISALLOW_COPY_AND_ASSIGN(TestWebGraphicsContext3DTextureUpload
);
153 void UploadTexture(TextureUploader
* uploader
,
154 ResourceFormat format
,
157 uploader
->Upload(data
,
165 TEST(TextureUploaderTest
, NumBlockingUploads
) {
166 scoped_ptr
<TestWebGraphicsContext3DTextureUpload
> fake_context(
167 new TestWebGraphicsContext3DTextureUpload
);
168 scoped_ptr
<TextureUploader
> uploader
=
169 TextureUploader::Create(fake_context
.get(), false, false);
171 fake_context
->SetResultAvailable(0);
172 EXPECT_EQ(0u, uploader
->NumBlockingUploads());
173 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(), NULL
);
174 EXPECT_EQ(1u, uploader
->NumBlockingUploads());
175 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(), NULL
);
176 EXPECT_EQ(2u, uploader
->NumBlockingUploads());
178 fake_context
->SetResultAvailable(1);
179 EXPECT_EQ(0u, uploader
->NumBlockingUploads());
180 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(), NULL
);
181 EXPECT_EQ(0u, uploader
->NumBlockingUploads());
182 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(), NULL
);
183 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(), NULL
);
184 EXPECT_EQ(0u, uploader
->NumBlockingUploads());
187 TEST(TextureUploaderTest
, MarkPendingUploadsAsNonBlocking
) {
188 scoped_ptr
<TestWebGraphicsContext3DTextureUpload
> fake_context(
189 new TestWebGraphicsContext3DTextureUpload
);
190 scoped_ptr
<TextureUploader
> uploader
=
191 TextureUploader::Create(fake_context
.get(), false, false);
193 fake_context
->SetResultAvailable(0);
194 EXPECT_EQ(0u, uploader
->NumBlockingUploads());
195 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(), NULL
);
196 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(), NULL
);
197 EXPECT_EQ(2u, uploader
->NumBlockingUploads());
199 uploader
->MarkPendingUploadsAsNonBlocking();
200 EXPECT_EQ(0u, uploader
->NumBlockingUploads());
201 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(), NULL
);
202 EXPECT_EQ(1u, uploader
->NumBlockingUploads());
204 fake_context
->SetResultAvailable(1);
205 EXPECT_EQ(0u, uploader
->NumBlockingUploads());
206 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(), NULL
);
207 uploader
->MarkPendingUploadsAsNonBlocking();
208 EXPECT_EQ(0u, uploader
->NumBlockingUploads());
211 TEST(TextureUploaderTest
, UploadContentsTest
) {
212 scoped_ptr
<TestWebGraphicsContext3DTextureUpload
> fake_context(
213 new TestWebGraphicsContext3DTextureUpload
);
214 scoped_ptr
<TextureUploader
> uploader
=
215 TextureUploader::Create(fake_context
.get(), false, false);
216 uint8 buffer
[256 * 256 * 4];
218 // Upload a tightly packed 256x256 RGBA texture.
219 memset(buffer
, 0, sizeof(buffer
));
220 for (int i
= 0; i
< 256; ++i
) {
221 // Mark the beginning and end of each row, for the test.
222 buffer
[i
* 4 * 256] = 0x1;
223 buffer
[(i
+ 1) * 4 * 256 - 1] = 0x2;
225 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(256, 256), buffer
);
227 // Upload a tightly packed 41x43 RGBA texture.
228 memset(buffer
, 0, sizeof(buffer
));
229 for (int i
= 0; i
< 43; ++i
) {
230 // Mark the beginning and end of each row, for the test.
231 buffer
[i
* 4 * 41] = 0x1;
232 buffer
[(i
+ 1) * 4 * 41 - 1] = 0x2;
234 UploadTexture(uploader
.get(), RGBA_8888
, gfx::Size(41, 43), buffer
);
236 // Upload a tightly packed 82x86 LUMINANCE texture.
237 memset(buffer
, 0, sizeof(buffer
));
238 for (int i
= 0; i
< 86; ++i
) {
239 // Mark the beginning and end of each row, for the test.
240 buffer
[i
* 1 * 82] = 0x1;
241 buffer
[(i
+ 1) * 82 - 1] = 0x2;
243 UploadTexture(uploader
.get(), LUMINANCE_8
, gfx::Size(82, 86), buffer
);