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