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