OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 | |
danakj
2012/11/20 20:43:39
remove this extra newline
| |
2 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 4 // found in the LICENSE file. |
4 | 5 |
5 #include "cc/texture_uploader.h" | 6 #include "cc/texture_uploader.h" |
6 | 7 |
8 #include "base/bits.h" | |
7 #include "cc/prioritized_resource.h" | 9 #include "cc/prioritized_resource.h" |
10 #include "cc/resource.h" | |
8 #include "cc/test/fake_web_graphics_context_3d.h" | 11 #include "cc/test/fake_web_graphics_context_3d.h" |
9 #include "testing/gmock/include/gmock/gmock.h" | 12 #include "testing/gmock/include/gmock/gmock.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
11 #include "third_party/khronos/GLES2/gl2.h" | 14 #include "third_party/khronos/GLES2/gl2.h" |
12 #include "third_party/khronos/GLES2/gl2ext.h" | 15 #include "third_party/khronos/GLES2/gl2ext.h" |
13 | 16 |
14 using namespace WebKit; | 17 using namespace WebKit; |
15 | 18 |
16 namespace cc { | 19 namespace cc { |
17 namespace { | 20 namespace { |
18 | 21 |
19 class FakeWebGraphicsContext3DWithQueryTesting : public FakeWebGraphicsContext3D { | 22 class FakeWebGraphicsContext3DTextureUpload : public FakeWebGraphicsContext3D { |
20 public: | 23 public: |
21 FakeWebGraphicsContext3DWithQueryTesting() : m_resultAvailable(0) | 24 FakeWebGraphicsContext3DTextureUpload() |
25 : m_resultAvailable(0), | |
26 m_unpackAlignment(4) | |
22 { | 27 { |
23 } | 28 } |
24 | 29 |
30 virtual void pixelStorei(WGC3Denum pname, WGC3Dint param) | |
31 { | |
32 switch (pname) { | |
33 case GL_UNPACK_ALIGNMENT: | |
34 // param should be a power of two <= 8 | |
35 EXPECT_EQ(0, param & (param - 1)); | |
36 EXPECT_GE(8, param); | |
37 switch (param) { | |
38 case 1: | |
39 case 2: | |
40 case 4: | |
41 case 8: | |
42 m_unpackAlignment = param; | |
43 break; | |
44 default: | |
45 break; | |
46 } | |
47 break; | |
48 default: | |
49 break; | |
50 } | |
51 } | |
52 | |
25 virtual void getQueryObjectuivEXT(WebGLId, WGC3Denum type, WGC3Duint* value) | 53 virtual void getQueryObjectuivEXT(WebGLId, WGC3Denum type, WGC3Duint* value) |
26 { | 54 { |
27 switch (type) { | 55 switch (type) { |
28 case GL_QUERY_RESULT_AVAILABLE_EXT: | 56 case GL_QUERY_RESULT_AVAILABLE_EXT: |
29 *value = m_resultAvailable; | 57 *value = m_resultAvailable; |
30 break; | 58 break; |
31 default: | 59 default: |
32 *value = 0; | 60 *value = 0; |
33 break; | 61 break; |
34 } | 62 } |
35 } | 63 } |
36 | 64 |
65 virtual void texSubImage2D(WGC3Denum target, WGC3Dint level, WGC3Dint xoffse t, WGC3Dint yoffset, WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3 Denum type, const void* pixels) | |
66 { | |
67 EXPECT_EQ(GL_TEXTURE_2D, target); | |
68 EXPECT_EQ(0, level); | |
69 EXPECT_LE(0, width); | |
70 EXPECT_LE(0, height); | |
71 EXPECT_LE(0, xoffset); | |
72 EXPECT_LE(0, yoffset); | |
73 EXPECT_LE(0, width); | |
74 EXPECT_LE(0, height); | |
75 | |
76 // Check for allowed format/type combination. | |
77 unsigned int bytesPerPixel = 0; | |
78 switch (format) | |
79 { | |
danakj
2012/11/20 20:43:39
{ onto the previous line.
| |
80 case GL_ALPHA: | |
danakj
2012/11/20 20:43:39
line up the cases with the swich
| |
81 EXPECT_EQ(GL_UNSIGNED_BYTE, type); | |
82 bytesPerPixel = 1; | |
83 break; | |
84 case GL_RGB: | |
85 EXPECT_NE(GL_UNSIGNED_SHORT_4_4_4_4, type); | |
86 EXPECT_NE(GL_UNSIGNED_SHORT_5_5_5_1, type); | |
87 switch (type) | |
88 { | |
danakj
2012/11/20 20:43:39
{ onto the previous line
| |
89 case GL_UNSIGNED_BYTE: | |
90 bytesPerPixel = 3; | |
91 break; | |
92 case GL_UNSIGNED_SHORT_5_6_5: | |
93 bytesPerPixel = 2; | |
94 break; | |
95 } | |
96 break; | |
97 case GL_RGBA: | |
98 EXPECT_NE(GL_UNSIGNED_SHORT_5_6_5, type); | |
99 switch (type) | |
100 { | |
danakj
2012/11/20 20:43:39
{ up
| |
101 case GL_UNSIGNED_BYTE: | |
danakj
2012/11/20 20:43:39
line up case with switch
| |
102 bytesPerPixel = 4; | |
103 break; | |
104 case GL_UNSIGNED_SHORT_4_4_4_4: | |
105 bytesPerPixel = 2; | |
106 break; | |
107 case GL_UNSIGNED_SHORT_5_5_5_1: | |
108 bytesPerPixel = 2; | |
109 break; | |
110 } | |
111 break; | |
112 case GL_LUMINANCE: | |
113 EXPECT_EQ(GL_UNSIGNED_BYTE, type); | |
114 bytesPerPixel = 1; | |
115 break; | |
116 case GL_LUMINANCE_ALPHA: | |
117 EXPECT_EQ(GL_UNSIGNED_BYTE, type); | |
118 bytesPerPixel = 2; | |
119 break; | |
120 } | |
121 | |
122 // If NULL, we aren't checking texture contents. | |
123 if (pixels == NULL) | |
124 return; | |
125 | |
126 const uint8 *bytes = static_cast<const uint8*>(pixels); | |
danakj
2012/11/20 20:43:39
uint8* bytes
| |
127 // We'll expect the first byte of every row to be 0x1, and the last byte to be 0x2 | |
128 const unsigned int stride = base::bits::RoundUp(bytesPerPixel * width, m_unpackAlignment); | |
129 for (WGC3Dsizei row = 0; row < height; row += 1) | |
danakj
2012/11/20 20:43:39
++row
| |
130 { | |
danakj
2012/11/20 20:43:39
{ on previous line
| |
131 const uint8 *rowBytes = bytes + (xoffset * bytesPerPixel + (yoffset + row) * stride); | |
danakj
2012/11/20 20:43:39
uint8* rowBytes
| |
132 EXPECT_EQ(0x1, rowBytes[0]); | |
133 EXPECT_EQ(0x2, rowBytes[width * bytesPerPixel - 1]); | |
134 } | |
135 } | |
136 | |
37 void setResultAvailable(unsigned resultAvailable) { m_resultAvailable = resu ltAvailable; } | 137 void setResultAvailable(unsigned resultAvailable) { m_resultAvailable = resu ltAvailable; } |
38 | 138 |
39 private: | 139 private: |
140 unsigned m_unpackAlignment; | |
40 unsigned m_resultAvailable; | 141 unsigned m_resultAvailable; |
41 }; | 142 }; |
42 | 143 |
43 void uploadTexture(TextureUploader* uploader) | 144 void uploadTexture(TextureUploader* uploader, WGC3Denum format, const gfx::Size& size, const uint8* data) |
44 { | 145 { |
45 gfx::Size size(256, 256); | 146 uploader->upload(data, |
46 uploader->upload(NULL, | |
47 gfx::Rect(gfx::Point(0, 0), size), | 147 gfx::Rect(gfx::Point(0, 0), size), |
48 gfx::Rect(gfx::Point(0, 0), size), | 148 gfx::Rect(gfx::Point(0, 0), size), |
49 gfx::Vector2d(), | 149 gfx::Vector2d(), |
50 GL_RGBA, | 150 format, |
51 size); | 151 size); |
52 } | 152 } |
53 | 153 |
54 TEST(TextureUploaderTest, NumBlockingUploads) | 154 TEST(TextureUploaderTest, NumBlockingUploads) |
55 { | 155 { |
56 scoped_ptr<FakeWebGraphicsContext3DWithQueryTesting> fakeContext(new FakeWeb GraphicsContext3DWithQueryTesting); | 156 scoped_ptr<FakeWebGraphicsContext3DTextureUpload> fakeContext(new FakeWebGra phicsContext3DTextureUpload); |
57 scoped_ptr<TextureUploader> uploader = TextureUploader::create(fakeContext.g et(), false, false); | 157 scoped_ptr<TextureUploader> uploader = TextureUploader::create(fakeContext.g et(), false, false); |
58 | 158 |
59 fakeContext->setResultAvailable(0); | 159 fakeContext->setResultAvailable(0); |
60 EXPECT_EQ(0, uploader->numBlockingUploads()); | 160 EXPECT_EQ(0, uploader->numBlockingUploads()); |
61 uploadTexture(uploader.get()); | 161 uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); |
62 EXPECT_EQ(1, uploader->numBlockingUploads()); | 162 EXPECT_EQ(1, uploader->numBlockingUploads()); |
63 uploadTexture(uploader.get()); | 163 uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); |
64 EXPECT_EQ(2, uploader->numBlockingUploads()); | 164 EXPECT_EQ(2, uploader->numBlockingUploads()); |
65 | 165 |
66 fakeContext->setResultAvailable(1); | 166 fakeContext->setResultAvailable(1); |
67 EXPECT_EQ(0, uploader->numBlockingUploads()); | 167 EXPECT_EQ(0, uploader->numBlockingUploads()); |
68 uploadTexture(uploader.get()); | 168 uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); |
69 EXPECT_EQ(0, uploader->numBlockingUploads()); | 169 EXPECT_EQ(0, uploader->numBlockingUploads()); |
70 uploadTexture(uploader.get()); | 170 uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); |
71 uploadTexture(uploader.get()); | 171 uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); |
72 EXPECT_EQ(0, uploader->numBlockingUploads()); | 172 EXPECT_EQ(0, uploader->numBlockingUploads()); |
73 } | 173 } |
74 | 174 |
75 TEST(TextureUploaderTest, MarkPendingUploadsAsNonBlocking) | 175 TEST(TextureUploaderTest, MarkPendingUploadsAsNonBlocking) |
76 { | 176 { |
77 scoped_ptr<FakeWebGraphicsContext3DWithQueryTesting> fakeContext(new FakeWeb GraphicsContext3DWithQueryTesting); | 177 scoped_ptr<FakeWebGraphicsContext3DTextureUpload> fakeContext(new FakeWebGra phicsContext3DTextureUpload); |
78 scoped_ptr<TextureUploader> uploader = TextureUploader::create(fakeContext.g et(), false, false); | 178 scoped_ptr<TextureUploader> uploader = TextureUploader::create(fakeContext.g et(), false, false); |
79 | 179 |
80 fakeContext->setResultAvailable(0); | 180 fakeContext->setResultAvailable(0); |
81 EXPECT_EQ(0, uploader->numBlockingUploads()); | 181 EXPECT_EQ(0, uploader->numBlockingUploads()); |
82 uploadTexture(uploader.get()); | 182 uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); |
83 uploadTexture(uploader.get()); | 183 uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); |
84 EXPECT_EQ(2, uploader->numBlockingUploads()); | 184 EXPECT_EQ(2, uploader->numBlockingUploads()); |
85 | 185 |
86 uploader->markPendingUploadsAsNonBlocking(); | 186 uploader->markPendingUploadsAsNonBlocking(); |
87 EXPECT_EQ(0, uploader->numBlockingUploads()); | 187 EXPECT_EQ(0, uploader->numBlockingUploads()); |
88 uploadTexture(uploader.get()); | 188 uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); |
89 EXPECT_EQ(1, uploader->numBlockingUploads()); | 189 EXPECT_EQ(1, uploader->numBlockingUploads()); |
90 | 190 |
91 fakeContext->setResultAvailable(1); | 191 fakeContext->setResultAvailable(1); |
92 EXPECT_EQ(0, uploader->numBlockingUploads()); | 192 EXPECT_EQ(0, uploader->numBlockingUploads()); |
93 uploadTexture(uploader.get()); | 193 uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); |
94 uploader->markPendingUploadsAsNonBlocking(); | 194 uploader->markPendingUploadsAsNonBlocking(); |
95 EXPECT_EQ(0, uploader->numBlockingUploads()); | 195 EXPECT_EQ(0, uploader->numBlockingUploads()); |
96 } | 196 } |
97 | 197 |
198 TEST(TextureUploaderTest, UploadContentsTest) | |
199 { | |
200 scoped_ptr<FakeWebGraphicsContext3DTextureUpload> fakeContext(new FakeWebGra phicsContext3DTextureUpload); | |
201 scoped_ptr<TextureUploader> uploader = TextureUploader::create(fakeContext.g et(), false, false); | |
202 uint8 buffer[256 * 256 * 4]; | |
203 | |
204 // Upload a tightly packed 256x256 RGBA texture. | |
danakj
2012/11/20 20:43:39
How about a test with a non-multiple-of-bytes-per-
| |
205 memset(buffer, 0, sizeof(buffer)); | |
206 for (int i = 0; i < 256; i += 1) | |
danakj
2012/11/20 20:43:39
++i
| |
207 { | |
danakj
2012/11/20 20:43:39
{ up
| |
208 // Mark the beginning and end of each row, for the test. | |
209 buffer[i * 4 * 256] = 0x1; | |
210 buffer[(i + 1) * 4 * 256 - 1] = 0x2; | |
211 } | |
212 uploadTexture(uploader.get(), GL_RGBA, gfx::Size(256, 256), buffer); | |
213 | |
214 // Upload a tightly packed 82x86 LUMINANCE texture. | |
215 memset(buffer, 0, sizeof(buffer)); | |
216 for (int i = 0; i < 86; i += 1) | |
danakj
2012/11/20 20:43:39
++i
| |
217 { | |
danakj
2012/11/20 20:43:39
{ up
| |
218 // Mark the beginning and end of each row, for the test. | |
219 buffer[i * 1 * 82] = 0x1; | |
220 buffer[(i + 1) * 82 - 1] = 0x2; | |
221 } | |
222 uploadTexture(uploader.get(), GL_LUMINANCE, gfx::Size(82, 86), buffer); | |
223 } | |
224 | |
98 } // namespace | 225 } // namespace |
99 } // namespace cc | 226 } // namespace cc |
OLD | NEW |