diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-02 06:04:28 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-02 06:04:28 +0000 |
commit | d2b8b21984aa349f3fffbeddaa0265e631476d4d (patch) | |
tree | 2b9825ba379fb62de24f9aa9744879ba09f45aa5 | |
parent | 339350bdaf6fde5bf48b3ebc0fc9e8f90e23fba8 (diff) | |
download | chromium_src-d2b8b21984aa349f3fffbeddaa0265e631476d4d.zip chromium_src-d2b8b21984aa349f3fffbeddaa0265e631476d4d.tar.gz chromium_src-d2b8b21984aa349f3fffbeddaa0265e631476d4d.tar.bz2 |
Add Occlusion Query test to gl_tests
TEST=none
BUG=none
R=zmo@chromium.org
Review URL: http://codereview.chromium.org/10174024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@134871 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | gpu/command_buffer/tests/gl_manager.cc | 5 | ||||
-rw-r--r-- | gpu/command_buffer/tests/gl_test_utils.cc | 170 | ||||
-rw-r--r-- | gpu/command_buffer/tests/gl_test_utils.h | 25 | ||||
-rw-r--r-- | gpu/command_buffer/tests/gl_unittests.cc | 4 | ||||
-rw-r--r-- | gpu/command_buffer/tests/occlusion_query_unittests.cc | 172 | ||||
-rw-r--r-- | gpu/gpu_common.gypi | 25 |
6 files changed, 393 insertions, 8 deletions
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc index 48c15bf2..3629fe6 100644 --- a/gpu/command_buffer/tests/gl_manager.cc +++ b/gpu/command_buffer/tests/gl_manager.cc @@ -22,8 +22,9 @@ namespace gpu { GLManager::GLManager(gles2::MailboxManager* mailbox_manager, gfx::GLShareGroup* share_group) - : mailbox_manager_(mailbox_manager), - share_group_(share_group) { + : mailbox_manager_( + mailbox_manager ? mailbox_manager : new gles2::MailboxManager), + share_group_(share_group ? share_group : new gfx::GLShareGroup) { } GLManager::~GLManager() { diff --git a/gpu/command_buffer/tests/gl_test_utils.cc b/gpu/command_buffer/tests/gl_test_utils.cc new file mode 100644 index 0000000..82e6222 --- /dev/null +++ b/gpu/command_buffer/tests/gl_test_utils.cc @@ -0,0 +1,170 @@ +// Copyright (c) 2012 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 "gpu/command_buffer/tests/gl_test_utils.h" +#include <string> +#include <stdio.h> +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "testing/gtest/include/gtest/gtest.h" + +bool GLTestHelper::HasExtension(const char* extension) { + std::string extensions( + reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); + return extensions.find(extension) != std::string::npos; +} + +bool GLTestHelper::CheckGLError(const char* msg, int line) { + bool success = true; + GLenum error = GL_NO_ERROR; + while ((error = glGetError()) != GL_NO_ERROR) { + success = false; + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), error) + << "GL ERROR in " << msg << " at line " << line << " : " << error; + } + return success; +} + +GLuint GLTestHelper::LoadShader(GLenum type, const char* shaderSrc) { + GLuint shader = glCreateShader(type); + // Load the shader source + glShaderSource(shader, 1, &shaderSrc, NULL); + // Compile the shader + glCompileShader(shader); + // Check the compile status + GLint value = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &value); + if (value == 0) { + char buffer[1024]; + GLsizei length = 0; + glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer); + std::string log(buffer, length); + EXPECT_EQ(1, value) << "Error compiling shader: " << log; + glDeleteShader(shader); + shader = 0; + } + return shader; +} + +GLuint GLTestHelper::SetupProgram( + GLuint vertex_shader, GLuint fragment_shader) { + // Create the program object + GLuint program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + // Link the program + glLinkProgram(program); + // Check the link status + GLint linked = 0; + glGetProgramiv(program, GL_LINK_STATUS, &linked); + if (linked == 0) { + char buffer[1024]; + GLsizei length = 0; + glGetProgramInfoLog(program, sizeof(buffer), &length, buffer); + std::string log(buffer, length); + EXPECT_EQ(1, linked) << "Error linking program: " << log; + glDeleteProgram(program); + program = 0; + } + return program; +} + +GLuint GLTestHelper::LoadProgram( + const char* vertex_shader_source, + const char* fragment_shader_source) { + GLuint vertex_shader = LoadShader( + GL_VERTEX_SHADER, vertex_shader_source); + GLuint fragment_shader = LoadShader( + GL_FRAGMENT_SHADER, fragment_shader_source); + if (!vertex_shader || !fragment_shader) { + return 0; + } + return SetupProgram(vertex_shader, fragment_shader); +} + +namespace { + +void Set16BitValue(uint8 dest[2], uint16 value) { + dest[0] = value & 0xFFu; + dest[1] = value >> 8; +} + +void Set32BitValue(uint8 dest[4], uint32 value) { + dest[0] = (value >> 0) & 0xFFu; + dest[1] = (value >> 8) & 0xFFu; + dest[2] = (value >> 16) & 0xFFu; + dest[3] = (value >> 24) & 0xFFu; +} + +struct BitmapHeaderFile { + uint8 magic[2]; + uint8 size[4]; + uint8 reserved[4]; + uint8 offset[4]; +}; + +struct BitmapInfoHeader{ + uint8 size[4]; + uint8 width[4]; + uint8 height[4]; + uint8 planes[2]; + uint8 bit_count[2]; + uint8 compression[4]; + uint8 size_image[4]; + uint8 x_pels_per_meter[4]; + uint8 y_pels_per_meter[4]; + uint8 clr_used[4]; + uint8 clr_important[4]; +}; + +} + +bool GLTestHelper::SaveBackbufferAsBMP( + const char* filename, int width, int height) { + FILE* fp = fopen(filename, "wb"); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + int num_pixels = width * height; + int size = num_pixels * 4; + scoped_array<uint8> data(new uint8[size]); + uint8* pixels = data.get(); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // RGBA to BGRA + for (int ii = 0; ii < num_pixels; ++ii) { + int offset = ii * 4; + uint8 t = pixels[offset + 0]; + pixels[offset + 0] = pixels[offset + 2]; + pixels[offset + 2] = t; + } + + BitmapHeaderFile bhf; + BitmapInfoHeader bih; + + bhf.magic[0] = 'B'; + bhf.magic[1] = 'M'; + Set32BitValue(bhf.size, 0); + Set32BitValue(bhf.reserved, 0); + Set32BitValue(bhf.offset, sizeof(bhf) + sizeof(bih)); + + Set32BitValue(bih.size, sizeof(bih)); + Set32BitValue(bih.width, width); + Set32BitValue(bih.height, height); + Set16BitValue(bih.planes, 1); + Set16BitValue(bih.bit_count, 32); + Set32BitValue(bih.compression, 0); + Set32BitValue(bih.x_pels_per_meter, 0); + Set32BitValue(bih.y_pels_per_meter, 0); + Set32BitValue(bih.clr_used, 0); + Set32BitValue(bih.clr_important, 0); + + fwrite(&bhf, sizeof(bhf), 1, fp); + fwrite(&bih, sizeof(bih), 1, fp); + fwrite(pixels, size, 1, fp); + fclose(fp); + + return true; +} + + + diff --git a/gpu/command_buffer/tests/gl_test_utils.h b/gpu/command_buffer/tests/gl_test_utils.h new file mode 100644 index 0000000..c5c6ec9 --- /dev/null +++ b/gpu/command_buffer/tests/gl_test_utils.h @@ -0,0 +1,25 @@ +// Copyright (c) 2012 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. + +// Helper functions for GL. + +#ifndef GPU_COMMAND_BUFFER_TESTS_GL_TEST_UTILS_H_ +#define GPU_COMMAND_BUFFER_TESTS_GL_TEST_UTILS_H_ + +#include <GLES2/gl2.h> + +class GLTestHelper { + public: + static bool HasExtension(const char* extension); + static bool CheckGLError(const char* msg, int line); + static GLuint LoadShader(GLenum type, const char* shaderSrc); + static GLuint SetupProgram(GLuint vertex_shader, GLuint fragment_shader); + static GLuint LoadProgram( + const char* vertex_shader_source, + const char* fragment_shader_source); + static bool SaveBackbufferAsBMP(const char* filename, int width, int height); +}; + +#endif // GPU_COMMAND_BUFFER_TESTS_GL_TEST_UTILS_H_ + diff --git a/gpu/command_buffer/tests/gl_unittests.cc b/gpu/command_buffer/tests/gl_unittests.cc index 921f5f2f..afd3488 100644 --- a/gpu/command_buffer/tests/gl_unittests.cc +++ b/gpu/command_buffer/tests/gl_unittests.cc @@ -9,17 +9,15 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> -#include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/tests/gl_manager.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/gl/gl_share_group.h" namespace gpu { class GLTest : public testing::Test { protected: - GLTest() : gl_(new gles2::MailboxManager, new gfx::GLShareGroup) { + GLTest() : gl_(NULL, NULL) { } virtual void SetUp() { diff --git a/gpu/command_buffer/tests/occlusion_query_unittests.cc b/gpu/command_buffer/tests/occlusion_query_unittests.cc new file mode 100644 index 0000000..75902e98 --- /dev/null +++ b/gpu/command_buffer/tests/occlusion_query_unittests.cc @@ -0,0 +1,172 @@ +// Copyright (c) 2012 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. + +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include "gpu/command_buffer/tests/gl_manager.h" +#include "gpu/command_buffer/tests/gl_test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { + +class OcclusionQueryTest : public testing::Test { + protected: + OcclusionQueryTest() + : gl_(NULL, NULL) { + } + + virtual void SetUp() { + gl_.Initialize(gfx::Size(512, 512)); + } + + virtual void TearDown() { + gl_.Destroy(); + } + + void DrawRect(float x, float z, float scale, float* color); + + GLManager gl_; + + GLint position_loc_; + GLint matrix_loc_; + GLint color_loc_; +}; + +static void SetMatrix(float x, float z, float scale, float* matrix) { + matrix[0] = scale; + matrix[1] = 0.0f; + matrix[2] = 0.0f; + matrix[3] = 0.0f; + + matrix[4] = 0.0f; + matrix[5] = scale; + matrix[6] = 0.0f; + matrix[7] = 0.0f; + + matrix[8] = 0.0f; + matrix[9] = 0.0f; + matrix[10] = scale; + matrix[11] = 0.0f; + + matrix[12] = x; + matrix[13] = 0.0f; + matrix[14] = z; + matrix[15] = 1.0f; +} + +void OcclusionQueryTest::DrawRect(float x, float z, float scale, float* color) { + GLfloat matrix[16]; + + SetMatrix(x, z, scale, matrix); + + // Set up the model matrix + glUniformMatrix4fv(matrix_loc_, 1, GL_FALSE, matrix); + glUniform4fv(color_loc_, 1, color); + + glDrawArrays(GL_TRIANGLES, 0, 6); +} + +TEST_F(OcclusionQueryTest, Occlusion) { + if (!GLTestHelper::HasExtension("GL_EXT_occlusion_query_boolean")) { + return; + } + + static const char* v_shader_str = + "uniform mat4 worldMatrix;\n" + "attribute vec3 g_Position;\n" + "void main()\n" + "{\n" + " gl_Position = worldMatrix *\n" + " vec4(g_Position.x, g_Position.y, g_Position.z, 1.0);\n" + "}\n"; + static const char* f_shader_str = + "precision mediump float;" + "uniform vec4 color;\n" + "void main()\n" + "{\n" + " gl_FragColor = color;\n" + "}\n"; + + GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str); + + position_loc_ = glGetAttribLocation(program, "g_Position"); + matrix_loc_ = glGetUniformLocation(program, "worldMatrix"); + color_loc_ = glGetUniformLocation(program, "color"); + + GLuint vbo = 0; + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + static float vertices[] = { + 1, 1, 0.0, + -1, 1, 0.0, + -1, -1, 0.0, + 1, 1, 0.0, + -1, -1, 0.0, + 1, -1, 0.0, + }; + glBufferData(GL_ARRAY_BUFFER, + sizeof(vertices), + NULL, + GL_STATIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); + + GLuint query = 0; + glGenQueriesEXT(1, &query); + + glEnable(GL_DEPTH_TEST); + glClearColor(0.0f, 0.1f, 0.2f, 1.0f); + + // Use the program object + glUseProgram(program); + + // Load the vertex data + glEnableVertexAttribArray(position_loc_); + glVertexAttribPointer(position_loc_, 3, GL_FLOAT, GL_FALSE, 0, 0); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + static float red[] = { 1.0f, 0.0f, 0.0f, 1.0f }; + DrawRect(0, 0.0f, 0.50f, red); + + glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query); + static float blue[] = { 0.0f, 0.0f, 1.0f, 1.0f }; + DrawRect(-0.125f, 0.1f, 0.25f, blue); + glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); + + glFinish(); + + GLuint query_status = 0; + GLuint result = 0; + glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &result); + EXPECT_TRUE(result); + glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &query_status); + EXPECT_FALSE(query_status); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + DrawRect(1, 0.0f, 0.50f, red); + + glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query); + DrawRect(-0.125f, 0.1f, 0.25f, blue); + glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); + + glFinish(); + + query_status = 0; + result = 0; + glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &result); + EXPECT_TRUE(result); + glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &query_status); + EXPECT_TRUE(query_status); + + GLTestHelper::CheckGLError("no errors", __LINE__); +} + +} // namespace gpu + + diff --git a/gpu/gpu_common.gypi b/gpu/gpu_common.gypi index 0de1c3e..16fa5ba 100644 --- a/gpu/gpu_common.gypi +++ b/gpu/gpu_common.gypi @@ -196,6 +196,27 @@ ], }, { + 'target_name': 'gl_unittests', + 'type': 'static_library', + 'dependencies': [ + '../base/base.gyp:base', + '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + '../testing/gmock.gyp:gmock', + '../testing/gtest.gyp:gtest', + 'gles2_implementation_client_side_arrays', + ], + 'defines': [ + 'GLES2_C_LIB_IMPLEMENTATION', + ], + 'sources': [ + 'command_buffer/tests/gl_test_utils.cc', + 'command_buffer/tests/gl_test_utils.h', + 'command_buffer/tests/gl_texture_mailbox_unittests.cc', + 'command_buffer/tests/gl_unittests.cc', + 'command_buffer/tests/occlusion_query_unittests.cc', + ], + }, + { 'target_name': 'gl_tests', 'type': 'executable', 'dependencies': [ @@ -204,7 +225,6 @@ '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', '../third_party/angle/src/build_angle.gyp:translator_glsl', - '../ui/gfx/gl/gl.gyp:gl', '../ui/ui.gyp:ui', 'command_buffer/command_buffer.gyp:gles2_utils', 'command_buffer_client', @@ -214,6 +234,7 @@ 'gpu_unittest_utils', 'gles2_implementation_client_side_arrays', 'gles2_cmd_helper', + 'gl_unittests', ], 'defines': [ 'GLES2_C_LIB_IMPLEMENTATION', @@ -223,8 +244,6 @@ 'command_buffer/tests/gl_tests_main.cc', 'command_buffer/tests/gl_manager.cc', 'command_buffer/tests/gl_manager.h', - 'command_buffer/tests/gl_texture_mailbox_unittests.cc', - 'command_buffer/tests/gl_unittests.cc', ], }, { |