| Index: client/deps/glbench/src/yuvtest.cc
|
| diff --git a/client/deps/glbench/src/yuvtest.cc b/client/deps/glbench/src/yuvtest.cc
|
| index 4a2207912f86d96785c31783a73006242d33f05a..2ae23ab4d2d85effeeee348150f43f515696e918 100644
|
| --- a/client/deps/glbench/src/yuvtest.cc
|
| +++ b/client/deps/glbench/src/yuvtest.cc
|
| @@ -6,6 +6,7 @@
|
| #include <sys/mman.h>
|
|
|
| #include "base/logging.h"
|
| +#include "base/scoped_ptr.h"
|
|
|
| #include "main.h"
|
| #include "testbase.h"
|
| @@ -16,21 +17,54 @@ namespace glbench {
|
|
|
| class YuvToRgbTest : public DrawArraysTestFunc {
|
| public:
|
| - YuvToRgbTest(int type, const char* name) : type_(type), name_(name) {}
|
| - virtual ~YuvToRgbTest() {}
|
| + YuvToRgbTest() {
|
| + memset(textures_, 0, sizeof(textures_));
|
| + }
|
| + virtual ~YuvToRgbTest() {
|
| + glDeleteTextures(arraysize(textures_), textures_);
|
| + }
|
| virtual bool Run();
|
|
|
| + enum YuvTestFlavor {
|
| + YUV_PLANAR_ONE_TEXTURE_SLOW,
|
| + YUV_PLANAR_ONE_TEXTURE_FASTER,
|
| + YUV_PLANAR_THREE_TEXTURES,
|
| + YUV_SEMIPLANAR_TWO_TEXTURES,
|
| + };
|
| +
|
| private:
|
| - int type_;
|
| - const char* name_;
|
| + GLuint textures_[6];
|
| + YuvTestFlavor flavor_;
|
| + GLuint YuvToRgbShaderProgram(GLuint vertex_buffer, int width, int height);
|
| + bool SetupTextures();
|
| DISALLOW_COPY_AND_ASSIGN(YuvToRgbTest);
|
| };
|
|
|
|
|
| -GLuint YuvToRgbShaderProgram(int type, GLuint vertex_buffer,
|
| - int width, int height) {
|
| - const char *vertex = type == 1 ? YUV2RGB_VERTEX_1 : YUV2RGB_VERTEX_2;
|
| - const char *fragment = type == 1 ? YUV2RGB_FRAGMENT_1 : YUV2RGB_FRAGMENT_2;
|
| +GLuint YuvToRgbTest::YuvToRgbShaderProgram(GLuint vertex_buffer,
|
| + int width, int height) {
|
| + const char *vertex = NULL;
|
| + const char *fragment = NULL;
|
| +
|
| + switch (flavor_) {
|
| + case YUV_PLANAR_ONE_TEXTURE_SLOW:
|
| + vertex = YUV2RGB_VERTEX_1;
|
| + fragment = YUV2RGB_FRAGMENT_1;
|
| + break;
|
| + case YUV_PLANAR_ONE_TEXTURE_FASTER:
|
| + vertex = YUV2RGB_VERTEX_2;
|
| + fragment = YUV2RGB_FRAGMENT_2;
|
| + break;
|
| + case YUV_PLANAR_THREE_TEXTURES:
|
| + vertex = YUV2RGB_VERTEX_34;
|
| + fragment = YUV2RGB_FRAGMENT_3;
|
| + break;
|
| + case YUV_SEMIPLANAR_TWO_TEXTURES:
|
| + vertex = YUV2RGB_VERTEX_34;
|
| + fragment = YUV2RGB_FRAGMENT_4;
|
| + break;
|
| + }
|
| +
|
| size_t size_vertex = 0;
|
| size_t size_fragment = 0;
|
| char *yuv_to_rgb_vertex = static_cast<char *>(
|
| @@ -53,14 +87,38 @@ GLuint YuvToRgbShaderProgram(int type, GLuint vertex_buffer,
|
|
|
| int imageWidthUniform = glGetUniformLocation(program, "imageWidth");
|
| int imageHeightUniform = glGetUniformLocation(program, "imageHeight");
|
| +
|
| int textureSampler = glGetUniformLocation(program, "textureSampler");
|
| int evenLinesSampler = glGetUniformLocation(program, "paritySampler");
|
| + int ySampler = glGetUniformLocation(program, "ySampler");
|
| + int uSampler = glGetUniformLocation(program, "uSampler");
|
| + int vSampler = glGetUniformLocation(program, "vSampler");
|
| + int uvSampler = glGetUniformLocation(program, "uvSampler");
|
|
|
| glUniform1f(imageWidthUniform, width);
|
| glUniform1f(imageHeightUniform, height);
|
| glUniform1i(textureSampler, 0);
|
| glUniform1i(evenLinesSampler, 1);
|
|
|
| + glUniform1i(ySampler, 2);
|
| + glUniform1i(uSampler, 3);
|
| + glUniform1i(vSampler, 4);
|
| + glUniform1i(uvSampler, 5);
|
| +
|
| + {
|
| + // This is used only if USE_UNIFORM_MATRIX is enabled in fragment
|
| + // shaders.
|
| + float c[] = {
|
| + 1.0, 1.0, 1.0, 0.0,
|
| + 0.0, -0.344, 1.772, 0.0,
|
| + 1.402, -0.714, 0.0, 0.0,
|
| + -0.701, 0.529, -0.886, 1.0
|
| + };
|
| + int conversion = glGetUniformLocation(program, "conversion");
|
| + glUniformMatrix4fv(conversion, 1, GL_FALSE, c);
|
| + assert(glGetError() == 0);
|
| + }
|
| +
|
| int attribute_index = glGetAttribLocation(program, "c");
|
| glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
|
| glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
|
| @@ -76,21 +134,15 @@ done:
|
| }
|
|
|
|
|
| -bool YuvToRgbTest::Run() {
|
| +bool YuvToRgbTest::SetupTextures() {
|
| + bool ret = false;
|
| size_t size = 0;
|
| - GLuint texture[2];
|
| - GLuint program = 0;
|
| - GLuint vertex_buffer = 0;
|
| - GLfloat vertices[8] = {
|
| - 0.f, 0.f,
|
| - 1.f, 0.f,
|
| - 0.f, 1.f,
|
| - 1.f, 1.f,
|
| - };
|
| char evenodd[2] = {0, 255};
|
| - const int pixel_height = YUV2RGB_HEIGHT * 2 / 3;
|
| -
|
| - char *pixels = static_cast<char *>(MmapFile(YUV2RGB_NAME, &size));
|
| + char* pixels = static_cast<char *>(MmapFile(YUV2RGB_NAME, &size));
|
| + const int luma_size = YUV2RGB_WIDTH * YUV2RGB_PIXEL_HEIGHT;
|
| + const int chroma_size = YUV2RGB_WIDTH/2 * YUV2RGB_PIXEL_HEIGHT/2;
|
| + const char* u_plane = pixels + luma_size;
|
| + const char* v_plane = pixels + luma_size + chroma_size;
|
| if (!pixels) {
|
| printf("# Could not open image file: %s\n", YUV2RGB_NAME);
|
| goto done;
|
| @@ -101,46 +153,112 @@ bool YuvToRgbTest::Run() {
|
| goto done;
|
| }
|
|
|
| - glGenTextures(2, texture);
|
| + glGenTextures(arraysize(textures_), textures_);
|
| glActiveTexture(GL_TEXTURE0);
|
| - glBindTexture(GL_TEXTURE_2D, texture[0]);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| + glBindTexture(GL_TEXTURE_2D, textures_[0]);
|
| glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, YUV2RGB_WIDTH, YUV2RGB_HEIGHT,
|
| 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels);
|
|
|
| glActiveTexture(GL_TEXTURE1);
|
| - glBindTexture(GL_TEXTURE_2D, texture[1]);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| + glBindTexture(GL_TEXTURE_2D, textures_[1]);
|
| glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 1,
|
| 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, evenodd);
|
|
|
| - glViewport(-YUV2RGB_WIDTH, -pixel_height, YUV2RGB_WIDTH*2, pixel_height * 2);
|
| - vertex_buffer = SetupVBO(GL_ARRAY_BUFFER, sizeof(vertices), vertices);
|
| + glActiveTexture(GL_TEXTURE2);
|
| + glBindTexture(GL_TEXTURE_2D, textures_[2]);
|
| + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
|
| + YUV2RGB_WIDTH, YUV2RGB_PIXEL_HEIGHT,
|
| + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels);
|
| +
|
| + glActiveTexture(GL_TEXTURE3);
|
| + glBindTexture(GL_TEXTURE_2D, textures_[3]);
|
| + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
|
| + YUV2RGB_WIDTH/2, YUV2RGB_PIXEL_HEIGHT/2,
|
| + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, u_plane);
|
| +
|
| + glActiveTexture(GL_TEXTURE4);
|
| + glBindTexture(GL_TEXTURE_2D, textures_[4]);
|
| + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
|
| + YUV2RGB_WIDTH/2, YUV2RGB_PIXEL_HEIGHT/2,
|
| + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, v_plane);
|
| +
|
| + {
|
| + scoped_array<char> buf_uv(new char[chroma_size * 2]);
|
| + char* buf_uv_ptr = buf_uv.get();
|
| + for (int i = 0; i < chroma_size; i++) {
|
| + *buf_uv_ptr++ = u_plane[i];
|
| + *buf_uv_ptr++ = v_plane[i];
|
| + }
|
|
|
| - program = YuvToRgbShaderProgram(type_, vertex_buffer,
|
| - YUV2RGB_WIDTH, pixel_height);
|
| + glActiveTexture(GL_TEXTURE5);
|
| + glBindTexture(GL_TEXTURE_2D, textures_[5]);
|
| + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
|
| + YUV2RGB_WIDTH/2, YUV2RGB_PIXEL_HEIGHT/2,
|
| + 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buf_uv.get());
|
| + }
|
|
|
| - if (program) {
|
| - FillRateTestNormalSubWindow(name_, std::min(YUV2RGB_WIDTH, g_width),
|
| - std::min(pixel_height, g_height));
|
| - } else {
|
| - printf("# Could not set up YUV shader.\n");
|
| + for (unsigned int i = 0; i < arraysize(textures_); i++) {
|
| + glActiveTexture(GL_TEXTURE0 + i);
|
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| }
|
|
|
| + ret = true;
|
| +
|
| done:
|
| - glDeleteProgram(program);
|
| - glDeleteTextures(2, texture);
|
| - glDeleteBuffers(1, &vertex_buffer);
|
| munmap(pixels, size);
|
| + return ret;
|
| +}
|
| +
|
| +
|
| +bool YuvToRgbTest::Run() {
|
| + GLuint program = 0;
|
| + GLuint vertex_buffer = 0;
|
| + GLfloat vertices[8] = {
|
| + 0.f, 0.f,
|
| + 1.f, 0.f,
|
| + 0.f, 1.f,
|
| + 1.f, 1.f,
|
| + };
|
| + vertex_buffer = SetupVBO(GL_ARRAY_BUFFER, sizeof(vertices), vertices);
|
| +
|
| + if (!SetupTextures())
|
| + return false;
|
| +
|
| + glViewport(-YUV2RGB_WIDTH, -YUV2RGB_PIXEL_HEIGHT,
|
| + YUV2RGB_WIDTH*2, YUV2RGB_PIXEL_HEIGHT * 2);
|
| +
|
| + YuvTestFlavor flavors[] = {
|
| + YUV_PLANAR_ONE_TEXTURE_SLOW, YUV_PLANAR_ONE_TEXTURE_FASTER,
|
| + YUV_PLANAR_THREE_TEXTURES, YUV_SEMIPLANAR_TWO_TEXTURES
|
| + };
|
| + const char* flavor_names[] = {
|
| + "yuv_shader_1", "yuv_shader_2", "yuv_shader_3", "yuv_shader_4"
|
| + };
|
| + for (unsigned int f = 0; f < arraysize(flavors); f++) {
|
| + flavor_ = flavors[f];
|
| +
|
| + program = YuvToRgbShaderProgram(vertex_buffer,
|
| + YUV2RGB_WIDTH, YUV2RGB_PIXEL_HEIGHT);
|
| + if (program) {
|
| + FillRateTestNormalSubWindow(flavor_names[f],
|
| + std::min(YUV2RGB_WIDTH, g_width),
|
| + std::min(YUV2RGB_PIXEL_HEIGHT, g_height));
|
| + } else {
|
| + printf("# Could not set up YUV shader.\n");
|
| + }
|
| +
|
| + glDeleteProgram(program);
|
| + }
|
| +
|
| + glDeleteBuffers(1, &vertex_buffer);
|
|
|
| return true;
|
| }
|
|
|
|
|
| -TestBase* GetYuvToRgbTest(int type, const char* name) {
|
| - return new YuvToRgbTest(type, name);
|
| +TestBase* GetYuvToRgbTest() {
|
| + return new YuvToRgbTest();
|
| }
|
|
|
| } // namespace glbench
|
|
|