15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2.h>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2ext.h>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/tests/gl_manager.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/tests/gl_test_utils.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OcclusionQueryTest : public testing::Test {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLManager::Options options;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    options.size = gfx::Size(512, 512);
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gl_.Initialize(options);
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gl_.Destroy();
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DrawRect(float x, float z, float scale, float* color);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLManager gl_;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint position_loc_;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint matrix_loc_;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint color_loc_;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void SetMatrix(float x, float z, float scale, float* matrix) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[0] = scale;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[1] = 0.0f;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[2] = 0.0f;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[3] = 0.0f;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[4] = 0.0f;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[5] = scale;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[6] = 0.0f;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[7] = 0.0f;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[8] = 0.0f;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[9] = 0.0f;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[10] = scale;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[11] = 0.0f;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[12] = x;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[13] = 0.0f;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[14] = z;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix[15] = 1.0f;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OcclusionQueryTest::DrawRect(float x, float z, float scale, float* color) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLfloat matrix[16];
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetMatrix(x, z, scale, matrix);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up the model matrix
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glUniformMatrix4fv(matrix_loc_, 1, GL_FALSE, matrix);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glUniform4fv(color_loc_, 1, color);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glDrawArrays(GL_TRIANGLES, 0, 6);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(OcclusionQueryTest, Occlusion) {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_MACOSX)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GLTestHelper::HasExtension("GL_EXT_occlusion_query_boolean"))
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "GL_EXT_occlusion_query_boolean is required on OSX";
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GLTestHelper::HasExtension("GL_EXT_occlusion_query_boolean")) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* v_shader_str =
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "uniform mat4 worldMatrix;\n"
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "attribute vec3 g_Position;\n"
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "void main()\n"
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "{\n"
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "   gl_Position = worldMatrix *\n"
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "                 vec4(g_Position.x, g_Position.y, g_Position.z, 1.0);\n"
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "}\n";
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* f_shader_str =
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "precision mediump float;"
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "uniform vec4 color;\n"
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "void main()\n"
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "{\n"
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  gl_FragColor = color;\n"
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "}\n";
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  position_loc_ = glGetAttribLocation(program, "g_Position");
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  matrix_loc_ = glGetUniformLocation(program, "worldMatrix");
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_loc_ = glGetUniformLocation(program, "color");
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLTestHelper::SetupUnitQuad(position_loc_);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint query = 0;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGenQueriesEXT(1, &query);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glEnable(GL_DEPTH_TEST);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glClearColor(0.0f, 0.1f, 0.2f, 1.0f);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use the program object
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glUseProgram(program);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static float red[] = { 1.0f, 0.0f, 0.0f, 1.0f };
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawRect(0, 0.0f, 0.50f, red);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static float blue[] = { 0.0f, 0.0f, 1.0f, 1.0f };
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawRect(-0.125f, 0.1f, 0.25f, blue);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glFinish();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint query_status = 0;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint result = 0;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &result);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &query_status);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(query_status);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawRect(1, 0.0f, 0.50f, red);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawRect(-0.125f, 0.1f, 0.25f, blue);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glFinish();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  query_status = 0;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = 0;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &result);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &query_status);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(query_status);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLTestHelper::CheckGLError("no errors", __LINE__);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
152