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.
6 #include <GLES2/gl2ext.h>
7 #include <GLES2/gl2extchromium.h>
9 #include "gpu/command_buffer/tests/gl_manager.h"
10 #include "gpu/command_buffer/tests/gl_test_utils.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 #define SHADER(Src) #Src
18 class GLVirtualContextsTest
: public testing::Test
{
20 static const int kSize0
= 4;
21 static const int kSize1
= 8;
22 static const int kSize2
= 16;
24 static const GLfloat kFloatRed
[4];
25 static const GLfloat kFloatGreen
[4];
26 static const uint8 kExpectedRed
[4];
27 static const uint8 kExpectedGreen
[4];
29 void SetUp() override
{
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
);
41 void TearDown() override
{
44 gl_real_shared_
.Destroy();
48 GLuint
SetupColoredVertexProgram() {
49 static const char* v_shader_str
= SHADER(
50 attribute vec4 a_position
;
51 attribute vec4 a_color
;
55 gl_Position
= a_position
;
60 static const char* f_shader_str
= SHADER(
61 precision mediump
float;
65 gl_FragColor
= v_color
;
69 GLuint program
= GLTestHelper::LoadProgram(v_shader_str
, f_shader_str
);
70 glUseProgram(program
);
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
);
83 GLManager gl_real_shared_
;
88 const GLfloat
GLVirtualContextsTest::kFloatRed
[4] = {
89 1.0f
, 0.0f
, 0.0f
, 1.0f
,
91 const GLfloat
GLVirtualContextsTest::kFloatGreen
[4] = {
92 0.0f
, 1.0f
, 0.0f
, 1.0f
,
94 const uint8
GLVirtualContextsTest::kExpectedRed
[4] = {
97 const uint8
GLVirtualContextsTest::kExpectedGreen
[4] = {
103 void SetupSimpleShader(const uint8
* color
) {
104 static const char* v_shader_str
= SHADER(
105 attribute vec4 a_Position
;
108 gl_Position
= a_Position
;
112 static const char* f_shader_str
= SHADER(
113 precision mediump
float;
114 uniform vec4 u_color
;
117 gl_FragColor
= u_color
;
121 GLuint program
= GLTestHelper::LoadProgram(v_shader_str
, f_shader_str
);
122 glUseProgram(program
);
124 GLuint position_loc
= glGetAttribLocation(program
, "a_Position");
126 GLTestHelper::SetupUnitQuad(position_loc
);
128 GLuint color_loc
= glGetUniformLocation(program
, "u_color");
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);
145 } // anonymous namespace
147 // http://crbug.com/281565
148 TEST_F(GLVirtualContextsTest
, Basic
) {
154 const int kNumTests
= 3;
156 { kSize0
, { 255, 0, 0, 0, }, &gl_real_
, },
157 { kSize1
, { 0, 255, 0, 0, }, &gl1_
, },
158 { kSize2
, { 0, 0, 255, 0, }, &gl2_
, },
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
);
168 for (int ii
= 0; ii
< kNumTests
; ++ii
) {
169 const TestInfo
& test
= tests
[ii
];
170 GLManager
* gl_manager
= test
.manager
;
171 gl_manager
->MakeCurrent();
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
));
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__
);
191 // http://crbug.com/363407
192 TEST_F(GLVirtualContextsTest
, VertexArrayObjectRestore
) {
193 GLuint vao1
= 0, vao2
= 0;
196 // Set up red quad in vao1.
197 glGenVertexArraysOES(1, &vao1
);
198 glBindVertexArrayOES(vao1
);
199 SetUpColoredUnitQuad(kFloatRed
);
203 // Set up green quad in vao2.
204 glGenVertexArraysOES(1, &vao2
);
205 glBindVertexArrayOES(vao2
);
206 SetUpColoredUnitQuad(kFloatGreen
);
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
));
214 GLTestHelper::CheckGLError("no errors", __LINE__
);
217 // Test to ensure that vao2 is still the active VAO for this context.
218 glDrawArrays(GL_TRIANGLES
, 0, 6);
220 GLTestHelper::CheckPixels(0, 0, kSize2
, kSize2
, 0, kExpectedGreen
));
222 GLTestHelper::CheckGLError("no errors", __LINE__
);
225 // http://crbug.com/363407
226 TEST_F(GLVirtualContextsTest
, VertexArrayObjectRestoreRebind
) {
227 GLuint vao1
= 0, vao2
= 0;
230 // Set up red quad in vao1.
231 glGenVertexArraysOES(1, &vao1
);
232 glBindVertexArrayOES(vao1
);
233 SetUpColoredUnitQuad(kFloatRed
);
237 // Set up green quad in new vao2.
238 glGenVertexArraysOES(1, &vao2
);
239 glBindVertexArrayOES(vao2
);
240 SetUpColoredUnitQuad(kFloatGreen
);
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
));
251 GLTestHelper::CheckGLError("no errors", __LINE__
);
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);
260 GLTestHelper::CheckPixels(0, 0, kSize2
, kSize2
, 0, kExpectedGreen
));
263 GLTestHelper::CheckGLError("no errors", __LINE__
);
266 // http://crbug.com/363407
267 TEST_F(GLVirtualContextsTest
, VertexArrayObjectRestoreDefault
) {
269 // Set up red quad in default VAO.
270 SetUpColoredUnitQuad(kFloatRed
);
274 // Set up green quad in default VAO.
275 SetUpColoredUnitQuad(kFloatGreen
);
278 // Gen & bind a non-default VAO.
280 glGenVertexArraysOES(1, &vao
);
281 glBindVertexArrayOES(vao
);
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
));
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);
297 GLTestHelper::CheckPixels(0, 0, kSize2
, kSize2
, 0, kExpectedGreen
));
300 GLTestHelper::CheckGLError("no errors", __LINE__
);
303 TEST_F(GLVirtualContextsTest
, VirtualQueries
) {
304 const GLenum query_targets
[] = {
305 GL_ANY_SAMPLES_PASSED_EXT
,
306 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
,
307 GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM
,
308 GL_COMMANDS_COMPLETED_CHROMIUM
,
309 GL_COMMANDS_ISSUED_CHROMIUM
,
310 GL_GET_ERROR_QUERY_CHROMIUM
,
311 GL_LATENCY_QUERY_CHROMIUM
,
315 for (GLenum query_target
: query_targets
) {
318 glGenQueriesEXT(1, &query1
);
319 glBeginQueryEXT(query_target
, query1
);
320 const GLenum begin_error
= glGetError();
321 if (GL_INVALID_OPERATION
== begin_error
) {
322 // Not supported, simply skip.
323 glDeleteQueriesEXT(1, &query1
);
326 ASSERT_TRUE(GL_NO_ERROR
== begin_error
);
330 glGenQueriesEXT(1, &query2
);
331 glBeginQueryEXT(query_target
, query2
);
332 EXPECT_TRUE(GL_NO_ERROR
== glGetError())
333 << "Virtualized Query " << query_target
<< " failed.";
336 glEndQueryEXT(query_target
);
339 GLuint query1_available
= 0;
340 glGetQueryObjectuivEXT(query1
, GL_QUERY_RESULT_AVAILABLE_EXT
,
342 EXPECT_TRUE(query1_available
);
344 glDeleteQueriesEXT(1, &query1
);
345 GLTestHelper::CheckGLError("no errors", __LINE__
);
348 glEndQueryEXT(query_target
);
351 GLuint query2_available
= 0;
352 glGetQueryObjectuivEXT(query2
, GL_QUERY_RESULT_AVAILABLE_EXT
,
354 EXPECT_TRUE(query2_available
);
356 glDeleteQueriesEXT(1, &query2
);
357 GLTestHelper::CheckGLError("no errors", __LINE__
);