Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / tests / compressed_texture_test.cc
1 // Copyright 2013 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.
4
5 #include <GLES2/gl2.h>
6 #include <GLES2/gl2ext.h>
7 #include <GLES2/gl2extchromium.h>
8
9 #include "base/basictypes.h"
10 #include "gpu/command_buffer/tests/gl_manager.h"
11 #include "gpu/command_buffer/tests/gl_test_utils.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 #define SHADER(src) #src
15
16 namespace gpu {
17
18 static const uint16 kRedMask = 0xF800;
19 static const uint16 kGreenMask = 0x07E0;
20 static const uint16 kBlueMask = 0x001F;
21
22 // Color palette in 565 format.
23 static const uint16 kPalette[] = {
24   kGreenMask | kBlueMask,   // Cyan.
25   kBlueMask  | kRedMask,    // Magenta.
26   kRedMask   | kGreenMask,  // Yellow.
27   0x0000,                   // Black.
28   kRedMask,                 // Red.
29   kGreenMask,               // Green.
30   kBlueMask,                // Blue.
31   0xFFFF,                   // White.
32 };
33 static const unsigned kBlockSize = 4;
34 static const unsigned kPaletteSize = sizeof(kPalette) / sizeof(kPalette[0]);
35 static const unsigned kTextureWidth = kBlockSize * kPaletteSize;
36 static const unsigned kTextureHeight = kBlockSize;
37
38 static const char* extension(GLenum format) {
39   switch(format) {
40     case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
41     case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
42       return "GL_EXT_texture_compression_dxt1";
43     case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
44       return "GL_CHROMIUM_texture_compression_dxt3";
45     case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
46       return "GL_CHROMIUM_texture_compression_dxt5";
47     default:
48       NOTREACHED();
49   }
50   return NULL;
51 }
52
53 // Index that chooses the given colors (color_0 and color_1),
54 // not the interpolated colors (color_2 and color_3).
55 static const uint16 kColor0 = 0x0000;
56 static const uint16 kColor1 = 0x5555;
57
58 static GLuint LoadCompressedTexture(const void* data,
59                                     GLsizeiptr size,
60                                     GLenum format,
61                                     GLsizei width,
62                                     GLsizei height) {
63   GLuint texture;
64   glGenTextures(1, &texture);
65   glBindTexture(GL_TEXTURE_2D, texture);
66   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
67   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
68   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
69   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
70   glCompressedTexImage2D(
71       GL_TEXTURE_2D, 0, format, width, height, 0, size, data);
72   return texture;
73 }
74
75 GLuint LoadTextureDXT1(bool alpha) {
76   const unsigned kStride = 4;
77   uint16 data[kStride * kPaletteSize];
78   for (unsigned i = 0; i < kPaletteSize; ++i) {
79     // Each iteration defines a 4x4 block of texture.
80     unsigned j = kStride * i;
81     data[j++] = kPalette[i];  // color_0.
82     data[j++] = kPalette[i];  // color_1.
83     data[j++] = kColor0;  // color index.
84     data[j++] = kColor1;  // color index.
85   }
86   GLenum format = alpha ?
87       GL_COMPRESSED_RGBA_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
88   return LoadCompressedTexture(
89       data, sizeof(data), format, kTextureWidth, kTextureHeight);
90 }
91
92 GLuint LoadTextureDXT3() {
93   const unsigned kStride = 8;
94   const uint16 kOpaque = 0xFFFF;
95   uint16 data[kStride * kPaletteSize];
96   for (unsigned i = 0; i < kPaletteSize; ++i) {
97     // Each iteration defines a 4x4 block of texture.
98     unsigned j = kStride * i;
99     data[j++] = kOpaque;  // alpha row 0.
100     data[j++] = kOpaque;  // alpha row 1.
101     data[j++] = kOpaque;  // alpha row 2.
102     data[j++] = kOpaque;  // alpha row 3.
103     data[j++] = kPalette[i];  // color_0.
104     data[j++] = kPalette[i];  // color_1.
105     data[j++] = kColor0;  // color index.
106     data[j++] = kColor1;  // color index.
107   }
108   return LoadCompressedTexture(data,
109                                sizeof(data),
110                                GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
111                                kTextureWidth,
112                                kTextureHeight);
113 }
114
115 GLuint LoadTextureDXT5() {
116   const unsigned kStride = 8;
117   const uint16 kClear = 0x0000;
118   const uint16 kAlpha7 = 0xFFFF;  // Opaque alpha index.
119   uint16 data[kStride * kPaletteSize];
120   for (unsigned i = 0; i < kPaletteSize; ++i) {
121     // Each iteration defines a 4x4 block of texture.
122     unsigned j = kStride * i;
123     data[j++] = kClear;  // alpha_0 | alpha_1.
124     data[j++] = kAlpha7;  // alpha index.
125     data[j++] = kAlpha7;  // alpha index.
126     data[j++] = kAlpha7;  // alpha index.
127     data[j++] = kPalette[i];  // color_0.
128     data[j++] = kPalette[i];  // color_1.
129     data[j++] = kColor0;  // color index.
130     data[j++] = kColor1;  // color index.
131   }
132   return LoadCompressedTexture(data,
133                                sizeof(data),
134                                GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
135                                kTextureWidth,
136                                kTextureHeight);
137 }
138
139 static void ToRGB888(uint16 rgb565, uint8 rgb888[]) {
140   uint8 r5 = (rgb565 & kRedMask)   >> 11;
141   uint8 g6 = (rgb565 & kGreenMask) >> 5;
142   uint8 b5 = (rgb565 & kBlueMask);
143   // Replicate upper bits to lower empty bits.
144   rgb888[0] = (r5 << 3) | (r5 >> 2);
145   rgb888[1] = (g6 << 2) | (g6 >> 4);
146   rgb888[2] = (b5 << 3) | (b5 >> 2);
147 }
148
149 class CompressedTextureTest : public ::testing::TestWithParam<GLenum> {
150  protected:
151   void SetUp() override {
152     GLManager::Options options;
153     options.size = gfx::Size(kTextureWidth, kTextureHeight);
154     gl_.Initialize(options);
155   }
156
157   void TearDown() override { gl_.Destroy(); }
158
159   GLuint LoadProgram() {
160     const char* v_shader_src = SHADER(
161         attribute vec2 a_position;
162         varying vec2 v_texcoord;
163         void main() {
164           gl_Position = vec4(a_position, 0.0, 1.0);
165           v_texcoord = (a_position + 1.0) * 0.5;
166         }
167     );
168     const char* f_shader_src = SHADER(
169         precision mediump float;
170         uniform sampler2D u_texture;
171         varying vec2 v_texcoord;
172         void main() {
173           gl_FragColor = texture2D(u_texture, v_texcoord);
174         }
175     );
176     return GLTestHelper::LoadProgram(v_shader_src, f_shader_src);
177   }
178
179   GLuint LoadTexture(GLenum format) {
180     switch (format) {
181       case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return LoadTextureDXT1(false);
182       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return LoadTextureDXT1(true);
183       case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return LoadTextureDXT3();
184       case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return LoadTextureDXT5();
185       default: NOTREACHED();
186     }
187     return 0;
188   }
189
190  private:
191   GLManager gl_;
192 };
193
194 // The test draws a texture in the given format and verifies that the drawn
195 // pixels are of the same color as the texture.
196 // The texture consists of 4x4 blocks of texels (same as DXT), one for each
197 // color defined in kPalette.
198 TEST_P(CompressedTextureTest, Draw) {
199   GLenum format = GetParam();
200
201   // This test is only valid if compressed texture extension is supported.
202   const char* ext = extension(format);
203   if (!GLTestHelper::HasExtension(ext))
204     return;
205
206   // Load shader program.
207   GLuint program = LoadProgram();
208   ASSERT_NE(program, 0u);
209   GLint position_loc = glGetAttribLocation(program, "a_position");
210   GLint texture_loc = glGetUniformLocation(program, "u_texture");
211   ASSERT_NE(position_loc, -1);
212   ASSERT_NE(texture_loc, -1);
213   glUseProgram(program);
214
215   // Load geometry.
216   GLuint vbo = GLTestHelper::SetupUnitQuad(position_loc);
217   ASSERT_NE(vbo, 0u);
218
219   // Load texture.
220   GLuint texture = LoadTexture(format);
221   ASSERT_NE(texture, 0u);
222   glActiveTexture(GL_TEXTURE0);
223   glBindTexture(GL_TEXTURE_2D, texture);
224   glUniform1i(texture_loc, 0);
225
226   // Draw.
227   glDrawArrays(GL_TRIANGLES, 0, 6);
228   glFlush();
229
230   // Verify results.
231   int origin[] = {0, 0};
232   uint8 expected_rgba[] = {0, 0, 0, 255};
233   for (unsigned i = 0; i < kPaletteSize; ++i) {
234     origin[0] = kBlockSize * i;
235     ToRGB888(kPalette[i], expected_rgba);
236     EXPECT_TRUE(GLTestHelper::CheckPixels(origin[0], origin[1],
237                                           kBlockSize, kBlockSize,
238                                           0, expected_rgba));
239   }
240   GLTestHelper::CheckGLError("CompressedTextureTest.Draw", __LINE__);
241 }
242
243 static const GLenum kFormats[] = {
244   GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
245   GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
246   GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
247   GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
248 };
249 INSTANTIATE_TEST_CASE_P(Format,
250                         CompressedTextureTest,
251                         ::testing::ValuesIn(kFormats));
252
253 }  // namespace gpu