• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <GLES2/gl2extchromium.h>
8 
9 #include "base/threading/platform_thread.h"
10 #include "gpu/command_buffer/tests/gl_manager.h"
11 #include "gpu/command_buffer/tests/gl_test_utils.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace gpu {
16 
17 class QueryTest : public testing::Test {
18  protected:
SetUp()19   virtual void SetUp() {
20     gl_.Initialize(GLManager::Options());
21   }
22 
TearDown()23   virtual void TearDown() {
24     gl_.Destroy();
25   }
26 
27   GLManager gl_;
28 };
29 
TEST_F(QueryTest,MultipleQueries)30 TEST_F(QueryTest, MultipleQueries) {
31   EXPECT_TRUE(GLTestHelper::HasExtension("GL_CHROMIUM_get_error_query"));
32   EXPECT_TRUE(GLTestHelper::HasExtension(
33                   "GL_CHROMIUM_command_buffer_latency_query"));
34 
35   GLuint error_query = 0;
36   GLuint commands_issue_query = 0;
37   glGenQueriesEXT(1, &error_query);
38   glGenQueriesEXT(1, &commands_issue_query);
39 
40   GLuint available;
41   GLuint result;
42 
43   base::TimeTicks before = base::TimeTicks::HighResNow();
44 
45   // Begin two queries of different types
46   glBeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, commands_issue_query);
47   glBeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, error_query);
48 
49   glEnable(GL_TEXTURE_2D);  // Generates an INVALID_ENUM error
50 
51   // End the two queries
52   glEndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
53   glEndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
54 
55   glFinish();
56 
57   base::TimeTicks after = base::TimeTicks::HighResNow();
58 
59   // Check that we got result on both queries.
60 
61   available = 0;
62   result = 0;
63   glGetQueryObjectuivEXT(commands_issue_query,
64                          GL_QUERY_RESULT_AVAILABLE_EXT,
65                          &available);
66   EXPECT_TRUE(available);
67   glGetQueryObjectuivEXT(commands_issue_query, GL_QUERY_RESULT_EXT, &result);
68   // Sanity check - the resulting delta is shorter than the time it took to
69   // run this test.
70   EXPECT_LT(result, base::TimeDelta(after - before).InMicroseconds());
71 
72   result = 0;
73   available = 0;
74   glGetQueryObjectuivEXT(error_query,
75                          GL_QUERY_RESULT_AVAILABLE_EXT,
76                          &available);
77   EXPECT_TRUE(available);
78   glGetQueryObjectuivEXT(error_query, GL_QUERY_RESULT_EXT, &result);
79   EXPECT_EQ(static_cast<uint32>(GL_INVALID_ENUM), result);
80 }
81 
TEST_F(QueryTest,GetErrorBasic)82 TEST_F(QueryTest, GetErrorBasic) {
83   EXPECT_TRUE(GLTestHelper::HasExtension("GL_CHROMIUM_get_error_query"));
84 
85   GLuint query = 0;
86   glGenQueriesEXT(1, &query);
87 
88   GLuint query_status = 0;
89   GLuint result = 0;
90 
91   glBeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, query);
92   glEnable(GL_TEXTURE_2D);  // Generates an INVALID_ENUM error
93   glEndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
94 
95   glFinish();
96 
97   query_status = 0;
98   result = 0;
99   glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &result);
100   EXPECT_TRUE(result);
101   glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &query_status);
102   EXPECT_EQ(static_cast<uint32>(GL_INVALID_ENUM), query_status);
103 }
104 
TEST_F(QueryTest,DISABLED_LatencyQueryBasic)105 TEST_F(QueryTest, DISABLED_LatencyQueryBasic) {
106   EXPECT_TRUE(GLTestHelper::HasExtension(
107                   "GL_CHROMIUM_command_buffer_latency_query"));
108 
109   GLuint query = 0;
110   glGenQueriesEXT(1, &query);
111 
112   GLuint query_result = 0;
113   GLuint available = 0;
114 
115   // First test a query with a ~1ms "latency".
116   const unsigned int kExpectedLatencyMicroseconds = 2000;
117   const unsigned int kTimePrecisionMicroseconds = 1000;
118 
119   glBeginQueryEXT(GL_LATENCY_QUERY_CHROMIUM, query);
120   // Usually, we want to measure gpu-side latency, but we fake it by
121   // adding client side latency for our test because it's easier.
122   base::PlatformThread::Sleep(
123       base::TimeDelta::FromMicroseconds(kExpectedLatencyMicroseconds));
124   glEndQueryEXT(GL_LATENCY_QUERY_CHROMIUM);
125 
126   glFinish();
127 
128   query_result = 0;
129   available = 0;
130   glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
131   EXPECT_TRUE(available);
132   glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &query_result);
133   EXPECT_GE(query_result, kExpectedLatencyMicroseconds
134                           - kTimePrecisionMicroseconds);
135   EXPECT_LE(query_result, kExpectedLatencyMicroseconds
136                           + kTimePrecisionMicroseconds);
137 
138   // Then test a query with the lowest latency possible.
139   glBeginQueryEXT(GL_LATENCY_QUERY_CHROMIUM, query);
140   glEndQueryEXT(GL_LATENCY_QUERY_CHROMIUM);
141 
142   glFinish();
143 
144   query_result = 0;
145   available = 0;
146   glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
147   EXPECT_TRUE(available);
148   glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &query_result);
149 
150   EXPECT_LE(query_result, kTimePrecisionMicroseconds);
151 }
152 
TEST_F(QueryTest,CommandsCompleted)153 TEST_F(QueryTest, CommandsCompleted) {
154   if (!GLTestHelper::HasExtension("GL_CHROMIUM_sync_query")) {
155     LOG(INFO) << "GL_CHROMIUM_sync_query not supported. Skipping test...";
156     return;
157   }
158 
159   GLuint query;
160   glGenQueriesEXT(1, &query);
161   glBeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, query);
162   glClearColor(0.0, 0.0, 1.0, 1.0);
163   glClear(GL_COLOR_BUFFER_BIT);
164   glEndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
165   glFlush();
166   GLuint result = 0;
167   glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
168   EXPECT_EQ(0u, result);
169   glDeleteQueriesEXT(1, &query);
170   GLTestHelper::CheckGLError("no errors", __LINE__);
171 }
172 
TEST_F(QueryTest,CommandsCompletedWithFinish)173 TEST_F(QueryTest, CommandsCompletedWithFinish) {
174   if (!GLTestHelper::HasExtension("GL_CHROMIUM_sync_query")) {
175     LOG(INFO) << "GL_CHROMIUM_sync_query not supported. Skipping test...";
176     return;
177   }
178 
179   GLuint query;
180   glGenQueriesEXT(1, &query);
181   glBeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, query);
182   glClearColor(0.0, 0.0, 1.0, 1.0);
183   glClear(GL_COLOR_BUFFER_BIT);
184   glEndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
185   glFinish();
186   GLuint result = 0;
187   glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &result);
188   EXPECT_EQ(1u, result);
189   glDeleteQueriesEXT(1, &query);
190   GLTestHelper::CheckGLError("no errors", __LINE__);
191 }
192 
193 }  // namespace gpu
194 
195 
196