This source file includes following definitions.
- extension
- LoadCompressedTexture
- LoadTextureDXT1
- LoadTextureDXT3
- LoadTextureDXT5
- ToRGB888
- SetUp
- TearDown
- LoadProgram
- LoadTexture
- TEST_P
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES2/gl2extchromium.h>
#include "base/basictypes.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 kRedMask = 0xF800;
static const uint16 kGreenMask = 0x07E0;
static const uint16 kBlueMask = 0x001F;
static const uint16 kPalette[] = {
kGreenMask | kBlueMask,
kBlueMask | kRedMask,
kRedMask | kGreenMask,
0x0000,
kRedMask,
kGreenMask,
kBlueMask,
0xFFFF,
};
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_EXT_texture_compression_dxt1";
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
return "GL_CHROMIUM_texture_compression_dxt3";
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
return "GL_CHROMIUM_texture_compression_dxt5";
default:
NOTREACHED();
}
return NULL;
}
static const uint16 kColor0 = 0x0000;
static const uint16 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 data[kStride * kPaletteSize];
for (unsigned i = 0; i < kPaletteSize; ++i) {
unsigned j = kStride * i;
data[j++] = kPalette[i];
data[j++] = kPalette[i];
data[j++] = kColor0;
data[j++] = kColor1;
}
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 kOpaque = 0xFFFF;
uint16 data[kStride * kPaletteSize];
for (unsigned i = 0; i < kPaletteSize; ++i) {
unsigned j = kStride * i;
data[j++] = kOpaque;
data[j++] = kOpaque;
data[j++] = kOpaque;
data[j++] = kOpaque;
data[j++] = kPalette[i];
data[j++] = kPalette[i];
data[j++] = kColor0;
data[j++] = kColor1;
}
return LoadCompressedTexture(data,
sizeof(data),
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
kTextureWidth,
kTextureHeight);
}
GLuint LoadTextureDXT5() {
const unsigned kStride = 8;
const uint16 kClear = 0x0000;
const uint16 kAlpha7 = 0xFFFF;
uint16 data[kStride * kPaletteSize];
for (unsigned i = 0; i < kPaletteSize; ++i) {
unsigned j = kStride * i;
data[j++] = kClear;
data[j++] = kAlpha7;
data[j++] = kAlpha7;
data[j++] = kAlpha7;
data[j++] = kPalette[i];
data[j++] = kPalette[i];
data[j++] = kColor0;
data[j++] = kColor1;
}
return LoadCompressedTexture(data,
sizeof(data),
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
kTextureWidth,
kTextureHeight);
}
static void ToRGB888(uint16 rgb565, uint8 rgb888[]) {
uint8 r5 = (rgb565 & kRedMask) >> 11;
uint8 g6 = (rgb565 & kGreenMask) >> 5;
uint8 b5 = (rgb565 & kBlueMask);
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:
virtual void SetUp() {
GLManager::Options options;
options.size = gfx::Size(kTextureWidth, kTextureHeight);
gl_.Initialize(options);
}
virtual void TearDown() {
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_;
};
TEST_P(CompressedTextureTest, Draw) {
GLenum format = GetParam();
const char* ext = extension(format);
if (!GLTestHelper::HasExtension(ext))
return;
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);
GLuint vbo = GLTestHelper::SetupUnitQuad(position_loc);
ASSERT_NE(vbo, 0u);
GLuint texture = LoadTexture(format);
ASSERT_NE(texture, 0u);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(texture_loc, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
glFlush();
int origin[] = {0, 0};
uint8 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));
}
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_CASE_P(Format,
CompressedTextureTest,
::testing::ValuesIn(kFormats));
}