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 |