123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- // Copyright 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <GLES2/gl2.h>
- #include <GLES2/gl2ext.h>
- #include <GLES2/gl2extchromium.h>
- #include <stdint.h>
- #include "gpu/command_buffer/tests/gl_manager.h"
- #include "gpu/command_buffer/tests/gl_test_utils.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #define SHADER(src) #src
- namespace gpu {
- static const uint16_t kRedMask = 0xF800;
- static const uint16_t kGreenMask = 0x07E0;
- static const uint16_t kBlueMask = 0x001F;
- // Color palette in 565 format.
- static const uint16_t kPalette[] = {
- kGreenMask | kBlueMask, // Cyan.
- kBlueMask | kRedMask, // Magenta.
- kRedMask | kGreenMask, // Yellow.
- 0x0000, // Black.
- kRedMask, // Red.
- kGreenMask, // Green.
- kBlueMask, // Blue.
- 0xFFFF, // White.
- };
- static const unsigned kBlockSize = 4;
- static const unsigned kPaletteSize = sizeof(kPalette) / sizeof(kPalette[0]);
- static const unsigned kTextureWidth = kBlockSize * kPaletteSize;
- static const unsigned kTextureHeight = kBlockSize;
- static const char* extension(GLenum format) {
- switch(format) {
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- return "GL_ANGLE_texture_compression_dxt1";
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- return "GL_ANGLE_texture_compression_dxt3";
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- return "GL_ANGLE_texture_compression_dxt5";
- default:
- NOTREACHED();
- }
- return nullptr;
- }
- // Index that chooses the given colors (color_0 and color_1),
- // not the interpolated colors (color_2 and color_3).
- static const uint16_t kColor0 = 0x0000;
- static const uint16_t kColor1 = 0x5555;
- static GLuint LoadCompressedTexture(const void* data,
- GLsizeiptr size,
- GLenum format,
- GLsizei width,
- GLsizei height) {
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glCompressedTexImage2D(
- GL_TEXTURE_2D, 0, format, width, height, 0, size, data);
- return texture;
- }
- GLuint LoadTextureDXT1(bool alpha) {
- const unsigned kStride = 4;
- uint16_t data[kStride * kPaletteSize];
- for (unsigned i = 0; i < kPaletteSize; ++i) {
- // Each iteration defines a 4x4 block of texture.
- unsigned j = kStride * i;
- data[j++] = kPalette[i]; // color_0.
- data[j++] = kPalette[i]; // color_1.
- data[j++] = kColor0; // color index.
- data[j++] = kColor1; // color index.
- }
- GLenum format = alpha ?
- GL_COMPRESSED_RGBA_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
- return LoadCompressedTexture(
- data, sizeof(data), format, kTextureWidth, kTextureHeight);
- }
- GLuint LoadTextureDXT3() {
- const unsigned kStride = 8;
- const uint16_t kOpaque = 0xFFFF;
- uint16_t data[kStride * kPaletteSize];
- for (unsigned i = 0; i < kPaletteSize; ++i) {
- // Each iteration defines a 4x4 block of texture.
- unsigned j = kStride * i;
- data[j++] = kOpaque; // alpha row 0.
- data[j++] = kOpaque; // alpha row 1.
- data[j++] = kOpaque; // alpha row 2.
- data[j++] = kOpaque; // alpha row 3.
- data[j++] = kPalette[i]; // color_0.
- data[j++] = kPalette[i]; // color_1.
- data[j++] = kColor0; // color index.
- data[j++] = kColor1; // color index.
- }
- return LoadCompressedTexture(data,
- sizeof(data),
- GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
- kTextureWidth,
- kTextureHeight);
- }
- GLuint LoadTextureDXT5() {
- const unsigned kStride = 8;
- const uint16_t kClear = 0x0000;
- const uint16_t kAlpha7 = 0xFFFF; // Opaque alpha index.
- uint16_t data[kStride * kPaletteSize];
- for (unsigned i = 0; i < kPaletteSize; ++i) {
- // Each iteration defines a 4x4 block of texture.
- unsigned j = kStride * i;
- data[j++] = kClear; // alpha_0 | alpha_1.
- data[j++] = kAlpha7; // alpha index.
- data[j++] = kAlpha7; // alpha index.
- data[j++] = kAlpha7; // alpha index.
- data[j++] = kPalette[i]; // color_0.
- data[j++] = kPalette[i]; // color_1.
- data[j++] = kColor0; // color index.
- data[j++] = kColor1; // color index.
- }
- return LoadCompressedTexture(data,
- sizeof(data),
- GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
- kTextureWidth,
- kTextureHeight);
- }
- static void ToRGB888(uint16_t rgb565, uint8_t rgb888[]) {
- uint8_t r5 = (rgb565 & kRedMask) >> 11;
- uint8_t g6 = (rgb565 & kGreenMask) >> 5;
- uint8_t b5 = (rgb565 & kBlueMask);
- // Replicate upper bits to lower empty bits.
- rgb888[0] = (r5 << 3) | (r5 >> 2);
- rgb888[1] = (g6 << 2) | (g6 >> 4);
- rgb888[2] = (b5 << 3) | (b5 >> 2);
- }
- class CompressedTextureTest : public ::testing::TestWithParam<GLenum> {
- protected:
- void SetUp() override {
- GLManager::Options options;
- options.size = gfx::Size(kTextureWidth, kTextureHeight);
- gl_.Initialize(options);
- }
- void TearDown() override { gl_.Destroy(); }
- GLuint LoadProgram() {
- const char* v_shader_src = SHADER(
- attribute vec2 a_position;
- varying vec2 v_texcoord;
- void main() {
- gl_Position = vec4(a_position, 0.0, 1.0);
- v_texcoord = (a_position + 1.0) * 0.5;
- }
- );
- const char* f_shader_src = SHADER(
- precision mediump float;
- uniform sampler2D u_texture;
- varying vec2 v_texcoord;
- void main() {
- gl_FragColor = texture2D(u_texture, v_texcoord);
- }
- );
- return GLTestHelper::LoadProgram(v_shader_src, f_shader_src);
- }
- GLuint LoadTexture(GLenum format) {
- switch (format) {
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return LoadTextureDXT1(false);
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return LoadTextureDXT1(true);
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return LoadTextureDXT3();
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return LoadTextureDXT5();
- default: NOTREACHED();
- }
- return 0;
- }
- private:
- GLManager gl_;
- };
- // The test draws a texture in the given format and verifies that the drawn
- // pixels are of the same color as the texture.
- // The texture consists of 4x4 blocks of texels (same as DXT), one for each
- // color defined in kPalette.
- TEST_P(CompressedTextureTest, Draw) {
- GLenum format = GetParam();
- // This test is only valid if compressed texture extension is supported.
- const char* ext = extension(format);
- if (!GLTestHelper::HasExtension(ext))
- return;
- // Load shader program.
- GLuint program = LoadProgram();
- ASSERT_NE(program, 0u);
- GLint position_loc = glGetAttribLocation(program, "a_position");
- GLint texture_loc = glGetUniformLocation(program, "u_texture");
- ASSERT_NE(position_loc, -1);
- ASSERT_NE(texture_loc, -1);
- glUseProgram(program);
- // Load geometry.
- GLuint vbo = GLTestHelper::SetupUnitQuad(position_loc);
- ASSERT_NE(vbo, 0u);
- // Load texture.
- GLuint texture = LoadTexture(format);
- ASSERT_NE(texture, 0u);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture);
- glUniform1i(texture_loc, 0);
- // Draw.
- glDrawArrays(GL_TRIANGLES, 0, 6);
- glFlush();
- // Verify results.
- int origin[] = {0, 0};
- uint8_t expected_rgba[] = {0, 0, 0, 255};
- for (unsigned i = 0; i < kPaletteSize; ++i) {
- origin[0] = kBlockSize * i;
- ToRGB888(kPalette[i], expected_rgba);
- EXPECT_TRUE(GLTestHelper::CheckPixels(origin[0], origin[1], kBlockSize,
- kBlockSize, 0, expected_rgba,
- nullptr));
- }
- GLTestHelper::CheckGLError("CompressedTextureTest.Draw", __LINE__);
- }
- static const GLenum kFormats[] = {
- GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
- GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
- GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
- GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
- };
- INSTANTIATE_TEST_SUITE_P(Format,
- CompressedTextureTest,
- ::testing::ValuesIn(kFormats));
- } // namespace gpu
|