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/texture_uploader.h"
7 #include "cc/prioritized_resource.h"
8 #include "cc/test/test_web_graphics_context_3d.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/khronos/GLES2/gl2.h"
12 #include "third_party/khronos/GLES2/gl2ext.h"
14 using namespace WebKit
;
19 unsigned int RoundUp(unsigned int n
, unsigned int mul
)
21 return (((n
- 1) / mul
) * mul
) + mul
;
24 class TestWebGraphicsContext3DTextureUpload
: public TestWebGraphicsContext3D
{
26 TestWebGraphicsContext3DTextureUpload()
27 : m_resultAvailable(0)
28 , m_unpackAlignment(4)
32 virtual void pixelStorei(WGC3Denum pname
, WGC3Dint param
)
35 case GL_UNPACK_ALIGNMENT
:
36 // param should be a power of two <= 8
37 EXPECT_EQ(0, param
& (param
- 1));
44 m_unpackAlignment
= param
;
55 virtual void getQueryObjectuivEXT(WebGLId
, WGC3Denum type
, WGC3Duint
* value
)
58 case GL_QUERY_RESULT_AVAILABLE_EXT
:
59 *value
= m_resultAvailable
;
67 virtual void texSubImage2D(WGC3Denum target
, WGC3Dint level
, WGC3Dint xoffset
, WGC3Dint yoffset
, WGC3Dsizei width
, WGC3Dsizei height
, WGC3Denum format
, WGC3Denum type
, const void* pixels
)
69 EXPECT_EQ(GL_TEXTURE_2D
, target
);
73 EXPECT_LE(0, xoffset
);
74 EXPECT_LE(0, yoffset
);
78 // Check for allowed format/type combination.
79 unsigned int bytesPerPixel
= 0;
82 EXPECT_EQ(GL_UNSIGNED_BYTE
, type
);
86 EXPECT_NE(GL_UNSIGNED_SHORT_4_4_4_4
, type
);
87 EXPECT_NE(GL_UNSIGNED_SHORT_5_5_5_1
, type
);
89 case GL_UNSIGNED_BYTE
:
92 case GL_UNSIGNED_SHORT_5_6_5
:
98 EXPECT_NE(GL_UNSIGNED_SHORT_5_6_5
, type
);
100 case GL_UNSIGNED_BYTE
:
103 case GL_UNSIGNED_SHORT_4_4_4_4
:
106 case GL_UNSIGNED_SHORT_5_5_5_1
:
112 EXPECT_EQ(GL_UNSIGNED_BYTE
, type
);
115 case GL_LUMINANCE_ALPHA
:
116 EXPECT_EQ(GL_UNSIGNED_BYTE
, type
);
121 // If NULL, we aren't checking texture contents.
125 const uint8
* bytes
= static_cast<const uint8
*>(pixels
);
126 // We'll expect the first byte of every row to be 0x1, and the last byte to be 0x2
127 const unsigned int stride
= RoundUp(bytesPerPixel
* width
, m_unpackAlignment
);
128 for (WGC3Dsizei row
= 0; row
< height
; ++row
) {
129 const uint8
* rowBytes
= bytes
+ (xoffset
* bytesPerPixel
+ (yoffset
+ row
) * stride
);
130 EXPECT_EQ(0x1, rowBytes
[0]);
131 EXPECT_EQ(0x2, rowBytes
[width
* bytesPerPixel
- 1]);
135 void setResultAvailable(unsigned resultAvailable
) { m_resultAvailable
= resultAvailable
; }
138 unsigned m_unpackAlignment
;
139 unsigned m_resultAvailable
;
142 void uploadTexture(TextureUploader
* uploader
, WGC3Denum format
, const gfx::Size
& size
, const uint8
* data
)
144 uploader
->upload(data
,
145 gfx::Rect(gfx::Point(0, 0), size
),
146 gfx::Rect(gfx::Point(0, 0), size
),
152 TEST(TextureUploaderTest
, NumBlockingUploads
)
154 scoped_ptr
<TestWebGraphicsContext3DTextureUpload
> fakeContext(new TestWebGraphicsContext3DTextureUpload
);
155 scoped_ptr
<TextureUploader
> uploader
= TextureUploader::create(fakeContext
.get(), false, false);
157 fakeContext
->setResultAvailable(0);
158 EXPECT_EQ(0, uploader
->numBlockingUploads());
159 uploadTexture(uploader
.get(), GL_RGBA
, gfx::Size(0, 0), NULL
);
160 EXPECT_EQ(1, uploader
->numBlockingUploads());
161 uploadTexture(uploader
.get(), GL_RGBA
, gfx::Size(0, 0), NULL
);
162 EXPECT_EQ(2, uploader
->numBlockingUploads());
164 fakeContext
->setResultAvailable(1);
165 EXPECT_EQ(0, uploader
->numBlockingUploads());
166 uploadTexture(uploader
.get(), GL_RGBA
, gfx::Size(0, 0), NULL
);
167 EXPECT_EQ(0, uploader
->numBlockingUploads());
168 uploadTexture(uploader
.get(), GL_RGBA
, gfx::Size(0, 0), NULL
);
169 uploadTexture(uploader
.get(), GL_RGBA
, gfx::Size(0, 0), NULL
);
170 EXPECT_EQ(0, uploader
->numBlockingUploads());
173 TEST(TextureUploaderTest
, MarkPendingUploadsAsNonBlocking
)
175 scoped_ptr
<TestWebGraphicsContext3DTextureUpload
> fakeContext(new TestWebGraphicsContext3DTextureUpload
);
176 scoped_ptr
<TextureUploader
> uploader
= TextureUploader::create(fakeContext
.get(), false, false);
178 fakeContext
->setResultAvailable(0);
179 EXPECT_EQ(0, uploader
->numBlockingUploads());
180 uploadTexture(uploader
.get(), GL_RGBA
, gfx::Size(0, 0), NULL
);
181 uploadTexture(uploader
.get(), GL_RGBA
, gfx::Size(0, 0), NULL
);
182 EXPECT_EQ(2, uploader
->numBlockingUploads());
184 uploader
->markPendingUploadsAsNonBlocking();
185 EXPECT_EQ(0, uploader
->numBlockingUploads());
186 uploadTexture(uploader
.get(), GL_RGBA
, gfx::Size(0, 0), NULL
);
187 EXPECT_EQ(1, uploader
->numBlockingUploads());
189 fakeContext
->setResultAvailable(1);
190 EXPECT_EQ(0, uploader
->numBlockingUploads());
191 uploadTexture(uploader
.get(), GL_RGBA
, gfx::Size(0, 0), NULL
);
192 uploader
->markPendingUploadsAsNonBlocking();
193 EXPECT_EQ(0, uploader
->numBlockingUploads());
196 TEST(TextureUploaderTest
, UploadContentsTest
)
198 scoped_ptr
<TestWebGraphicsContext3DTextureUpload
> fakeContext(new TestWebGraphicsContext3DTextureUpload
);
199 scoped_ptr
<TextureUploader
> uploader
= TextureUploader::create(fakeContext
.get(), false, false);
200 uint8 buffer
[256 * 256 * 4];
202 // Upload a tightly packed 256x256 RGBA texture.
203 memset(buffer
, 0, sizeof(buffer
));
204 for (int i
= 0; i
< 256; ++i
) {
205 // Mark the beginning and end of each row, for the test.
206 buffer
[i
* 4 * 256] = 0x1;
207 buffer
[(i
+ 1) * 4 * 256 - 1] = 0x2;
209 uploadTexture(uploader
.get(), GL_RGBA
, gfx::Size(256, 256), buffer
);
211 // Upload a tightly packed 41x43 RGBA texture.
212 memset(buffer
, 0, sizeof(buffer
));
213 for (int i
= 0; i
< 43; ++i
) {
214 // Mark the beginning and end of each row, for the test.
215 buffer
[i
* 4 * 41] = 0x1;
216 buffer
[(i
+ 1) * 4 * 41 - 1] = 0x2;
218 uploadTexture(uploader
.get(), GL_RGBA
, gfx::Size(41, 43), buffer
);
220 // Upload a tightly packed 82x86 LUMINANCE texture.
221 memset(buffer
, 0, sizeof(buffer
));
222 for (int i
= 0; i
< 86; ++i
) {
223 // Mark the beginning and end of each row, for the test.
224 buffer
[i
* 1 * 82] = 0x1;
225 buffer
[(i
+ 1) * 82 - 1] = 0x2;
227 uploadTexture(uploader
.get(), GL_LUMINANCE
, gfx::Size(82, 86), buffer
);