blob: a8c9a9b9885f4502dc92842d3964ee815c490675 [file] [log] [blame]
Geoff Langf9a6f082015-01-22 13:32:49 -05001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// QueryGL.cpp: Implements the class methods for QueryGL.
8
9#include "libANGLE/renderer/gl/QueryGL.h"
10
11#include "common/debug.h"
Geoff Langf0aa8422015-09-29 15:08:34 -040012#include "libANGLE/renderer/gl/FunctionsGL.h"
13#include "libANGLE/renderer/gl/StateManagerGL.h"
14
15namespace
16{
17
18GLuint MergeQueryResults(GLenum type, GLuint currentResult, GLuint newResult)
19{
20 switch (type)
21 {
22 case GL_ANY_SAMPLES_PASSED:
23 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
24 return (currentResult == GL_TRUE || newResult == GL_TRUE) ? GL_TRUE : GL_FALSE;
25
26 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
27 return currentResult + newResult;
28
29 default:
30 UNREACHABLE();
31 return 0;
32 }
33}
34
35} // anonymous namespace
Geoff Langf9a6f082015-01-22 13:32:49 -050036
37namespace rx
38{
39
Geoff Langf0aa8422015-09-29 15:08:34 -040040QueryGL::QueryGL(GLenum type, const FunctionsGL *functions, StateManagerGL *stateManager)
41 : QueryImpl(type),
42 mType(type),
43 mFunctions(functions),
44 mStateManager(stateManager),
45 mActiveQuery(0),
46 mPendingQueries(),
47 mResultSum(0)
48{
49}
Geoff Langf9a6f082015-01-22 13:32:49 -050050
51QueryGL::~QueryGL()
Geoff Langf0aa8422015-09-29 15:08:34 -040052{
53 mStateManager->deleteQuery(mActiveQuery);
54 mStateManager->onDeleteQueryObject(this);
55 while (!mPendingQueries.empty())
56 {
57 mStateManager->deleteQuery(mPendingQueries.front());
58 mPendingQueries.pop_front();
59 }
60}
Geoff Langf9a6f082015-01-22 13:32:49 -050061
62gl::Error QueryGL::begin()
63{
Geoff Langf0aa8422015-09-29 15:08:34 -040064 mResultSum = 0;
65 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -050066}
67
68gl::Error QueryGL::end()
69{
Geoff Langf0aa8422015-09-29 15:08:34 -040070 return pause();
Geoff Langf9a6f082015-01-22 13:32:49 -050071}
72
73gl::Error QueryGL::getResult(GLuint *params)
74{
Geoff Langf0aa8422015-09-29 15:08:34 -040075 ASSERT(mActiveQuery == 0);
76
77 gl::Error error = flush(true);
78 if (error.isError())
79 {
80 return error;
81 }
82
83 ASSERT(mPendingQueries.empty());
84 *params = mResultSum;
85
86 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -050087}
88
89gl::Error QueryGL::isResultAvailable(GLuint *available)
90{
Geoff Langf0aa8422015-09-29 15:08:34 -040091 ASSERT(mActiveQuery == 0);
92
93 gl::Error error = flush(false);
94 if (error.isError())
95 {
96 return error;
97 }
98
99 *available = mPendingQueries.empty() ? GL_TRUE : GL_FALSE;
100 return gl::Error(GL_NO_ERROR);
101}
102
103gl::Error QueryGL::pause()
104{
105 if (mActiveQuery != 0)
106 {
107 mStateManager->endQuery(mType, mActiveQuery);
108
109 mPendingQueries.push_back(mActiveQuery);
110 mActiveQuery = 0;
111 }
112
113 // Flush to make sure the pending queries don't add up too much.
114 gl::Error error = flush(false);
115 if (error.isError())
116 {
117 return error;
118 }
119
120 return gl::Error(GL_NO_ERROR);
121}
122
123gl::Error QueryGL::resume()
124{
125 if (mActiveQuery == 0)
126 {
127 // Flush to make sure the pending queries don't add up too much.
128 gl::Error error = flush(false);
129 if (error.isError())
130 {
131 return error;
132 }
133
134 mFunctions->genQueries(1, &mActiveQuery);
135 mStateManager->beginQuery(mType, mActiveQuery);
136 }
137
138 return gl::Error(GL_NO_ERROR);
139}
140
141gl::Error QueryGL::flush(bool force)
142{
143 while (!mPendingQueries.empty())
144 {
145 GLuint id = mPendingQueries.front();
146 if (!force)
147 {
148 GLuint resultAvailable = 0;
149 mFunctions->getQueryObjectuiv(id, GL_QUERY_RESULT_AVAILABLE, &resultAvailable);
150 if (resultAvailable == GL_FALSE)
151 {
152 return gl::Error(GL_NO_ERROR);
153 }
154 }
155
156 GLuint result = 0;
157 mFunctions->getQueryObjectuiv(id, GL_QUERY_RESULT, &result);
158 mResultSum = MergeQueryResults(mType, mResultSum, result);
159
160 mStateManager->deleteQuery(id);
161
162 mPendingQueries.pop_front();
163 }
164
165 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500166}
167
168}