1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <GLES2/gl2.h> 6 #include <GLES2/gl2ext.h> 7 8 #include "gpu/command_buffer/tests/gl_manager.h" 9 #include "gpu/command_buffer/tests/gl_test_utils.h" 10 #include "testing/gmock/include/gmock/gmock.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 14 #define SHADER(Src) #Src 15 16 namespace gpu { 17 18 class GLVirtualContextsTest : public testing::Test { 19 protected: 20 static const int kSize0 = 4; 21 static const int kSize1 = 8; 22 static const int kSize2 = 16; 23 24 static const GLfloat kFloatRed[4]; 25 static const GLfloat kFloatGreen[4]; 26 static const uint8 kExpectedRed[4]; 27 static const uint8 kExpectedGreen[4]; 28 29 virtual void SetUp() { 30 GLManager::Options options; 31 options.size = gfx::Size(kSize0, kSize0); 32 gl_real_.Initialize(options); 33 gl_real_shared_.Initialize(options); 34 options.virtual_manager = &gl_real_shared_; 35 options.size = gfx::Size(kSize1, kSize1); 36 gl1_.Initialize(options); 37 options.size = gfx::Size(kSize2, kSize2); 38 gl2_.Initialize(options); 39 } 40 41 virtual void TearDown() { 42 gl1_.Destroy(); 43 gl2_.Destroy(); 44 gl_real_shared_.Destroy(); 45 gl_real_.Destroy(); 46 } 47 48 GLuint SetupColoredVertexProgram() { 49 static const char* v_shader_str = SHADER( 50 attribute vec4 a_position; 51 attribute vec4 a_color; 52 varying vec4 v_color; 53 void main() 54 { 55 gl_Position = a_position; 56 v_color = a_color; 57 } 58 ); 59 60 static const char* f_shader_str = SHADER( 61 precision mediump float; 62 varying vec4 v_color; 63 void main() 64 { 65 gl_FragColor = v_color; 66 } 67 ); 68 69 GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str); 70 glUseProgram(program); 71 return program; 72 } 73 74 void SetUpColoredUnitQuad(const GLfloat* color) { 75 GLuint program1 = SetupColoredVertexProgram(); 76 GLuint position_loc1 = glGetAttribLocation(program1, "a_position"); 77 GLuint color_loc1 = glGetAttribLocation(program1, "a_color"); 78 GLTestHelper::SetupUnitQuad(position_loc1); 79 GLTestHelper::SetupColorsForUnitQuad(color_loc1, color, GL_STATIC_DRAW); 80 } 81 82 GLManager gl_real_; 83 GLManager gl_real_shared_; 84 GLManager gl1_; 85 GLManager gl2_; 86 }; 87 88 const GLfloat GLVirtualContextsTest::kFloatRed[4] = { 89 1.0f, 0.0f, 0.0f, 1.0f, 90 }; 91 const GLfloat GLVirtualContextsTest::kFloatGreen[4] = { 92 0.0f, 1.0f, 0.0f, 1.0f, 93 }; 94 const uint8 GLVirtualContextsTest::kExpectedRed[4] = { 95 255, 0, 0, 255, 96 }; 97 const uint8 GLVirtualContextsTest::kExpectedGreen[4] = { 98 0, 255, 0, 255, 99 }; 100 101 namespace { 102 103 void SetupSimpleShader(const uint8* color) { 104 static const char* v_shader_str = SHADER( 105 attribute vec4 a_Position; 106 void main() 107 { 108 gl_Position = a_Position; 109 } 110 ); 111 112 static const char* f_shader_str = SHADER( 113 precision mediump float; 114 uniform vec4 u_color; 115 void main() 116 { 117 gl_FragColor = u_color; 118 } 119 ); 120 121 GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str); 122 glUseProgram(program); 123 124 GLuint position_loc = glGetAttribLocation(program, "a_Position"); 125 126 GLTestHelper::SetupUnitQuad(position_loc); 127 128 GLuint color_loc = glGetUniformLocation(program, "u_color"); 129 glUniform4f( 130 color_loc, 131 color[0] / 255.0f, 132 color[1] / 255.0f, 133 color[2] / 255.0f, 134 color[3] / 255.0f); 135 } 136 137 void TestDraw(int size) { 138 uint8 expected_clear[] = { 127, 0, 255, 0, }; 139 glClearColor(0.5f, 0.0f, 1.0f, 0.0f); 140 glClear(GL_COLOR_BUFFER_BIT); 141 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, size, size, 1, expected_clear)); 142 glDrawArrays(GL_TRIANGLES, 0, 6); 143 } 144 145 } // anonymous namespace 146 147 // http://crbug.com/281565 148 TEST_F(GLVirtualContextsTest, Basic) { 149 struct TestInfo { 150 int size; 151 uint8 color[4]; 152 GLManager* manager; 153 }; 154 const int kNumTests = 3; 155 TestInfo tests[] = { 156 { kSize0, { 255, 0, 0, 0, }, &gl_real_, }, 157 { kSize1, { 0, 255, 0, 0, }, &gl1_, }, 158 { kSize2, { 0, 0, 255, 0, }, &gl2_, }, 159 }; 160 161 for (int ii = 0; ii < kNumTests; ++ii) { 162 const TestInfo& test = tests[ii]; 163 GLManager* gl_manager = test.manager; 164 gl_manager->MakeCurrent(); 165 SetupSimpleShader(test.color); 166 } 167 168 for (int ii = 0; ii < kNumTests; ++ii) { 169 const TestInfo& test = tests[ii]; 170 GLManager* gl_manager = test.manager; 171 gl_manager->MakeCurrent(); 172 TestDraw(test.size); 173 } 174 175 for (int ii = 0; ii < kNumTests; ++ii) { 176 const TestInfo& test = tests[ii]; 177 GLManager* gl_manager = test.manager; 178 gl_manager->MakeCurrent(); 179 EXPECT_TRUE(GLTestHelper::CheckPixels( 180 0, 0, test.size, test.size, 0, test.color)); 181 } 182 183 for (int ii = 0; ii < kNumTests; ++ii) { 184 const TestInfo& test = tests[ii]; 185 GLManager* gl_manager = test.manager; 186 gl_manager->MakeCurrent(); 187 GLTestHelper::CheckGLError("no errors", __LINE__); 188 } 189 } 190 191 // http://crbug.com/363407 192 TEST_F(GLVirtualContextsTest, VertexArrayObjectRestore) { 193 GLuint vao1 = 0, vao2 = 0; 194 195 gl1_.MakeCurrent(); 196 // Set up red quad in vao1. 197 glGenVertexArraysOES(1, &vao1); 198 glBindVertexArrayOES(vao1); 199 SetUpColoredUnitQuad(kFloatRed); 200 glFinish(); 201 202 gl2_.MakeCurrent(); 203 // Set up green quad in vao2. 204 glGenVertexArraysOES(1, &vao2); 205 glBindVertexArrayOES(vao2); 206 SetUpColoredUnitQuad(kFloatGreen); 207 glFinish(); 208 209 gl1_.MakeCurrent(); 210 // Test to ensure that vao1 is still the active VAO for this context. 211 glDrawArrays(GL_TRIANGLES, 0, 6); 212 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed)); 213 glFinish(); 214 GLTestHelper::CheckGLError("no errors", __LINE__); 215 216 gl2_.MakeCurrent(); 217 // Test to ensure that vao2 is still the active VAO for this context. 218 glDrawArrays(GL_TRIANGLES, 0, 6); 219 EXPECT_TRUE( 220 GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen)); 221 glFinish(); 222 GLTestHelper::CheckGLError("no errors", __LINE__); 223 } 224 225 // http://crbug.com/363407 226 TEST_F(GLVirtualContextsTest, VertexArrayObjectRestoreRebind) { 227 GLuint vao1 = 0, vao2 = 0; 228 229 gl1_.MakeCurrent(); 230 // Set up red quad in vao1. 231 glGenVertexArraysOES(1, &vao1); 232 glBindVertexArrayOES(vao1); 233 SetUpColoredUnitQuad(kFloatRed); 234 glFinish(); 235 236 gl2_.MakeCurrent(); 237 // Set up green quad in new vao2. 238 glGenVertexArraysOES(1, &vao2); 239 glBindVertexArrayOES(vao2); 240 SetUpColoredUnitQuad(kFloatGreen); 241 glFinish(); 242 243 gl1_.MakeCurrent(); 244 // Test to ensure that vao1 hasn't been corrupted after rebinding. 245 // Bind 0 is required so that bind vao1 is not optimized away in the service. 246 glBindVertexArrayOES(0); 247 glBindVertexArrayOES(vao1); 248 glDrawArrays(GL_TRIANGLES, 0, 6); 249 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed)); 250 glFinish(); 251 GLTestHelper::CheckGLError("no errors", __LINE__); 252 253 gl2_.MakeCurrent(); 254 // Test to ensure that vao1 hasn't been corrupted after rebinding. 255 // Bind 0 is required so that bind vao2 is not optimized away in the service. 256 glBindVertexArrayOES(0); 257 glBindVertexArrayOES(vao2); 258 glDrawArrays(GL_TRIANGLES, 0, 6); 259 EXPECT_TRUE( 260 GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen)); 261 glFinish(); 262 263 GLTestHelper::CheckGLError("no errors", __LINE__); 264 } 265 266 // http://crbug.com/363407 267 TEST_F(GLVirtualContextsTest, VertexArrayObjectRestoreDefault) { 268 gl1_.MakeCurrent(); 269 // Set up red quad in default VAO. 270 SetUpColoredUnitQuad(kFloatRed); 271 glFinish(); 272 273 gl2_.MakeCurrent(); 274 // Set up green quad in default VAO. 275 SetUpColoredUnitQuad(kFloatGreen); 276 glFinish(); 277 278 // Gen & bind a non-default VAO. 279 GLuint vao; 280 glGenVertexArraysOES(1, &vao); 281 glBindVertexArrayOES(vao); 282 glFinish(); 283 284 gl1_.MakeCurrent(); 285 // Test to ensure that default VAO on gl1_ is still valid. 286 glDrawArrays(GL_TRIANGLES, 0, 6); 287 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed)); 288 glFinish(); 289 290 gl2_.MakeCurrent(); 291 // Test to ensure that default VAO on gl2_ is still valid. 292 // This tests that a default VAO is restored even when it's not currently 293 // bound during the context switch. 294 glBindVertexArrayOES(0); 295 glDrawArrays(GL_TRIANGLES, 0, 6); 296 EXPECT_TRUE( 297 GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen)); 298 glFinish(); 299 300 GLTestHelper::CheckGLError("no errors", __LINE__); 301 } 302 303 } // namespace gpu 304 305