1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker // QueryGL.cpp: Implements the class methods for QueryGL.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/QueryGL.h"
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/ContextGL.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/FunctionsGL.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/StateManagerGL.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/renderergl_utils.h"
17*8975f5c5SAndroid Build Coastguard Worker
18*8975f5c5SAndroid Build Coastguard Worker namespace
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker
MergeQueryResults(gl::QueryType type,GLuint64 currentResult,GLuint64 newResult)21*8975f5c5SAndroid Build Coastguard Worker GLuint64 MergeQueryResults(gl::QueryType type, GLuint64 currentResult, GLuint64 newResult)
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker switch (type)
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker case gl::QueryType::AnySamples:
26*8975f5c5SAndroid Build Coastguard Worker case gl::QueryType::AnySamplesConservative:
27*8975f5c5SAndroid Build Coastguard Worker return (currentResult == GL_TRUE || newResult == GL_TRUE) ? GL_TRUE : GL_FALSE;
28*8975f5c5SAndroid Build Coastguard Worker
29*8975f5c5SAndroid Build Coastguard Worker case gl::QueryType::TransformFeedbackPrimitivesWritten:
30*8975f5c5SAndroid Build Coastguard Worker return currentResult + newResult;
31*8975f5c5SAndroid Build Coastguard Worker
32*8975f5c5SAndroid Build Coastguard Worker case gl::QueryType::TimeElapsed:
33*8975f5c5SAndroid Build Coastguard Worker return currentResult + newResult;
34*8975f5c5SAndroid Build Coastguard Worker
35*8975f5c5SAndroid Build Coastguard Worker case gl::QueryType::Timestamp:
36*8975f5c5SAndroid Build Coastguard Worker return newResult;
37*8975f5c5SAndroid Build Coastguard Worker
38*8975f5c5SAndroid Build Coastguard Worker case gl::QueryType::PrimitivesGenerated:
39*8975f5c5SAndroid Build Coastguard Worker return currentResult + newResult;
40*8975f5c5SAndroid Build Coastguard Worker
41*8975f5c5SAndroid Build Coastguard Worker default:
42*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
43*8975f5c5SAndroid Build Coastguard Worker return 0;
44*8975f5c5SAndroid Build Coastguard Worker }
45*8975f5c5SAndroid Build Coastguard Worker }
46*8975f5c5SAndroid Build Coastguard Worker
47*8975f5c5SAndroid Build Coastguard Worker // Some drivers tend to hang when flushing pending queries. Wait until this number of queries have
48*8975f5c5SAndroid Build Coastguard Worker // added up before checking if results are ready.
49*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kPauseResumeFlushThreshold = 5;
50*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
51*8975f5c5SAndroid Build Coastguard Worker
52*8975f5c5SAndroid Build Coastguard Worker namespace rx
53*8975f5c5SAndroid Build Coastguard Worker {
54*8975f5c5SAndroid Build Coastguard Worker
QueryGL(gl::QueryType type)55*8975f5c5SAndroid Build Coastguard Worker QueryGL::QueryGL(gl::QueryType type) : QueryImpl(type) {}
56*8975f5c5SAndroid Build Coastguard Worker
~QueryGL()57*8975f5c5SAndroid Build Coastguard Worker QueryGL::~QueryGL() {}
58*8975f5c5SAndroid Build Coastguard Worker
StandardQueryGL(gl::QueryType type,const FunctionsGL * functions,StateManagerGL * stateManager)59*8975f5c5SAndroid Build Coastguard Worker StandardQueryGL::StandardQueryGL(gl::QueryType type,
60*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions,
61*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager)
62*8975f5c5SAndroid Build Coastguard Worker : QueryGL(type),
63*8975f5c5SAndroid Build Coastguard Worker mFunctions(functions),
64*8975f5c5SAndroid Build Coastguard Worker mStateManager(stateManager),
65*8975f5c5SAndroid Build Coastguard Worker mActiveQuery(0),
66*8975f5c5SAndroid Build Coastguard Worker mPendingQueries(),
67*8975f5c5SAndroid Build Coastguard Worker mResultSum(0)
68*8975f5c5SAndroid Build Coastguard Worker {}
69*8975f5c5SAndroid Build Coastguard Worker
~StandardQueryGL()70*8975f5c5SAndroid Build Coastguard Worker StandardQueryGL::~StandardQueryGL()
71*8975f5c5SAndroid Build Coastguard Worker {
72*8975f5c5SAndroid Build Coastguard Worker clearInternalQueries();
73*8975f5c5SAndroid Build Coastguard Worker }
74*8975f5c5SAndroid Build Coastguard Worker
clearInternalQueries()75*8975f5c5SAndroid Build Coastguard Worker void StandardQueryGL::clearInternalQueries()
76*8975f5c5SAndroid Build Coastguard Worker {
77*8975f5c5SAndroid Build Coastguard Worker if (mActiveQuery != 0)
78*8975f5c5SAndroid Build Coastguard Worker {
79*8975f5c5SAndroid Build Coastguard Worker mStateManager->endQuery(mType, this, mActiveQuery);
80*8975f5c5SAndroid Build Coastguard Worker mFunctions->deleteQueries(1, &mActiveQuery);
81*8975f5c5SAndroid Build Coastguard Worker mActiveQuery = 0;
82*8975f5c5SAndroid Build Coastguard Worker }
83*8975f5c5SAndroid Build Coastguard Worker
84*8975f5c5SAndroid Build Coastguard Worker while (!mPendingQueries.empty())
85*8975f5c5SAndroid Build Coastguard Worker {
86*8975f5c5SAndroid Build Coastguard Worker GLuint id = mPendingQueries.front();
87*8975f5c5SAndroid Build Coastguard Worker mFunctions->deleteQueries(1, &id);
88*8975f5c5SAndroid Build Coastguard Worker mPendingQueries.pop_front();
89*8975f5c5SAndroid Build Coastguard Worker }
90*8975f5c5SAndroid Build Coastguard Worker }
91*8975f5c5SAndroid Build Coastguard Worker
begin(const gl::Context * context)92*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::begin(const gl::Context *context)
93*8975f5c5SAndroid Build Coastguard Worker {
94*8975f5c5SAndroid Build Coastguard Worker clearInternalQueries();
95*8975f5c5SAndroid Build Coastguard Worker mResultSum = 0;
96*8975f5c5SAndroid Build Coastguard Worker return resume(context);
97*8975f5c5SAndroid Build Coastguard Worker }
98*8975f5c5SAndroid Build Coastguard Worker
end(const gl::Context * context)99*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::end(const gl::Context *context)
100*8975f5c5SAndroid Build Coastguard Worker {
101*8975f5c5SAndroid Build Coastguard Worker return pause(context);
102*8975f5c5SAndroid Build Coastguard Worker }
103*8975f5c5SAndroid Build Coastguard Worker
queryCounter(const gl::Context * context)104*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::queryCounter(const gl::Context *context)
105*8975f5c5SAndroid Build Coastguard Worker {
106*8975f5c5SAndroid Build Coastguard Worker ASSERT(mType == gl::QueryType::Timestamp);
107*8975f5c5SAndroid Build Coastguard Worker
108*8975f5c5SAndroid Build Coastguard Worker // Directly create a query for the timestamp and add it to the pending query queue, as timestamp
109*8975f5c5SAndroid Build Coastguard Worker // queries do not have the traditional begin/end block and never need to be paused/resumed
110*8975f5c5SAndroid Build Coastguard Worker GLuint query;
111*8975f5c5SAndroid Build Coastguard Worker mFunctions->genQueries(1, &query);
112*8975f5c5SAndroid Build Coastguard Worker mFunctions->queryCounter(query, GL_TIMESTAMP);
113*8975f5c5SAndroid Build Coastguard Worker mPendingQueries.push_back(query);
114*8975f5c5SAndroid Build Coastguard Worker
115*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
116*8975f5c5SAndroid Build Coastguard Worker }
117*8975f5c5SAndroid Build Coastguard Worker
118*8975f5c5SAndroid Build Coastguard Worker template <typename T>
getResultBase(const gl::Context * context,T * params)119*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::getResultBase(const gl::Context *context, T *params)
120*8975f5c5SAndroid Build Coastguard Worker {
121*8975f5c5SAndroid Build Coastguard Worker ASSERT(mActiveQuery == 0);
122*8975f5c5SAndroid Build Coastguard Worker
123*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(flush(context, true));
124*8975f5c5SAndroid Build Coastguard Worker ASSERT(mPendingQueries.empty());
125*8975f5c5SAndroid Build Coastguard Worker *params = static_cast<T>(mResultSum);
126*8975f5c5SAndroid Build Coastguard Worker
127*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
128*8975f5c5SAndroid Build Coastguard Worker }
129*8975f5c5SAndroid Build Coastguard Worker
getResult(const gl::Context * context,GLint * params)130*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::getResult(const gl::Context *context, GLint *params)
131*8975f5c5SAndroid Build Coastguard Worker {
132*8975f5c5SAndroid Build Coastguard Worker return getResultBase(context, params);
133*8975f5c5SAndroid Build Coastguard Worker }
134*8975f5c5SAndroid Build Coastguard Worker
getResult(const gl::Context * context,GLuint * params)135*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::getResult(const gl::Context *context, GLuint *params)
136*8975f5c5SAndroid Build Coastguard Worker {
137*8975f5c5SAndroid Build Coastguard Worker return getResultBase(context, params);
138*8975f5c5SAndroid Build Coastguard Worker }
139*8975f5c5SAndroid Build Coastguard Worker
getResult(const gl::Context * context,GLint64 * params)140*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::getResult(const gl::Context *context, GLint64 *params)
141*8975f5c5SAndroid Build Coastguard Worker {
142*8975f5c5SAndroid Build Coastguard Worker return getResultBase(context, params);
143*8975f5c5SAndroid Build Coastguard Worker }
144*8975f5c5SAndroid Build Coastguard Worker
getResult(const gl::Context * context,GLuint64 * params)145*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::getResult(const gl::Context *context, GLuint64 *params)
146*8975f5c5SAndroid Build Coastguard Worker {
147*8975f5c5SAndroid Build Coastguard Worker return getResultBase(context, params);
148*8975f5c5SAndroid Build Coastguard Worker }
149*8975f5c5SAndroid Build Coastguard Worker
isResultAvailable(const gl::Context * context,bool * available)150*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::isResultAvailable(const gl::Context *context, bool *available)
151*8975f5c5SAndroid Build Coastguard Worker {
152*8975f5c5SAndroid Build Coastguard Worker ASSERT(mActiveQuery == 0);
153*8975f5c5SAndroid Build Coastguard Worker
154*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(flush(context, false));
155*8975f5c5SAndroid Build Coastguard Worker *available = mPendingQueries.empty();
156*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
157*8975f5c5SAndroid Build Coastguard Worker }
158*8975f5c5SAndroid Build Coastguard Worker
pause(const gl::Context * context)159*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::pause(const gl::Context *context)
160*8975f5c5SAndroid Build Coastguard Worker {
161*8975f5c5SAndroid Build Coastguard Worker if (mActiveQuery != 0)
162*8975f5c5SAndroid Build Coastguard Worker {
163*8975f5c5SAndroid Build Coastguard Worker mStateManager->endQuery(mType, this, mActiveQuery);
164*8975f5c5SAndroid Build Coastguard Worker
165*8975f5c5SAndroid Build Coastguard Worker mPendingQueries.push_back(mActiveQuery);
166*8975f5c5SAndroid Build Coastguard Worker mActiveQuery = 0;
167*8975f5c5SAndroid Build Coastguard Worker }
168*8975f5c5SAndroid Build Coastguard Worker
169*8975f5c5SAndroid Build Coastguard Worker // Flush to make sure the pending queries don't add up too much.
170*8975f5c5SAndroid Build Coastguard Worker if (mPendingQueries.size() >= kPauseResumeFlushThreshold)
171*8975f5c5SAndroid Build Coastguard Worker {
172*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(flush(context, false));
173*8975f5c5SAndroid Build Coastguard Worker }
174*8975f5c5SAndroid Build Coastguard Worker
175*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
176*8975f5c5SAndroid Build Coastguard Worker }
177*8975f5c5SAndroid Build Coastguard Worker
resume(const gl::Context * context)178*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::resume(const gl::Context *context)
179*8975f5c5SAndroid Build Coastguard Worker {
180*8975f5c5SAndroid Build Coastguard Worker if (mActiveQuery == 0)
181*8975f5c5SAndroid Build Coastguard Worker {
182*8975f5c5SAndroid Build Coastguard Worker // Flush to make sure the pending queries don't add up too much.
183*8975f5c5SAndroid Build Coastguard Worker if (mPendingQueries.size() >= kPauseResumeFlushThreshold)
184*8975f5c5SAndroid Build Coastguard Worker {
185*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(flush(context, false));
186*8975f5c5SAndroid Build Coastguard Worker }
187*8975f5c5SAndroid Build Coastguard Worker
188*8975f5c5SAndroid Build Coastguard Worker mFunctions->genQueries(1, &mActiveQuery);
189*8975f5c5SAndroid Build Coastguard Worker mStateManager->beginQuery(mType, this, mActiveQuery);
190*8975f5c5SAndroid Build Coastguard Worker
191*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
192*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
193*8975f5c5SAndroid Build Coastguard Worker }
194*8975f5c5SAndroid Build Coastguard Worker
195*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
196*8975f5c5SAndroid Build Coastguard Worker }
197*8975f5c5SAndroid Build Coastguard Worker
flush(const gl::Context * context,bool force)198*8975f5c5SAndroid Build Coastguard Worker angle::Result StandardQueryGL::flush(const gl::Context *context, bool force)
199*8975f5c5SAndroid Build Coastguard Worker {
200*8975f5c5SAndroid Build Coastguard Worker while (!mPendingQueries.empty())
201*8975f5c5SAndroid Build Coastguard Worker {
202*8975f5c5SAndroid Build Coastguard Worker GLuint id = mPendingQueries.front();
203*8975f5c5SAndroid Build Coastguard Worker if (!force)
204*8975f5c5SAndroid Build Coastguard Worker {
205*8975f5c5SAndroid Build Coastguard Worker GLuint resultAvailable = 0;
206*8975f5c5SAndroid Build Coastguard Worker mFunctions->getQueryObjectuiv(id, GL_QUERY_RESULT_AVAILABLE, &resultAvailable);
207*8975f5c5SAndroid Build Coastguard Worker if (resultAvailable == GL_FALSE)
208*8975f5c5SAndroid Build Coastguard Worker {
209*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
210*8975f5c5SAndroid Build Coastguard Worker }
211*8975f5c5SAndroid Build Coastguard Worker }
212*8975f5c5SAndroid Build Coastguard Worker
213*8975f5c5SAndroid Build Coastguard Worker // Even though getQueryObjectui64v was introduced for timer queries, there is nothing in the
214*8975f5c5SAndroid Build Coastguard Worker // standard that says that it doesn't work for any other queries. It also passes on all the
215*8975f5c5SAndroid Build Coastguard Worker // trybots, so we use it if it is available
216*8975f5c5SAndroid Build Coastguard Worker if (mFunctions->getQueryObjectui64v != nullptr)
217*8975f5c5SAndroid Build Coastguard Worker {
218*8975f5c5SAndroid Build Coastguard Worker GLuint64 result = 0;
219*8975f5c5SAndroid Build Coastguard Worker mFunctions->getQueryObjectui64v(id, GL_QUERY_RESULT, &result);
220*8975f5c5SAndroid Build Coastguard Worker mResultSum = MergeQueryResults(mType, mResultSum, result);
221*8975f5c5SAndroid Build Coastguard Worker }
222*8975f5c5SAndroid Build Coastguard Worker else
223*8975f5c5SAndroid Build Coastguard Worker {
224*8975f5c5SAndroid Build Coastguard Worker GLuint result = 0;
225*8975f5c5SAndroid Build Coastguard Worker mFunctions->getQueryObjectuiv(id, GL_QUERY_RESULT, &result);
226*8975f5c5SAndroid Build Coastguard Worker mResultSum = MergeQueryResults(mType, mResultSum, static_cast<GLuint64>(result));
227*8975f5c5SAndroid Build Coastguard Worker }
228*8975f5c5SAndroid Build Coastguard Worker
229*8975f5c5SAndroid Build Coastguard Worker mFunctions->deleteQueries(1, &id);
230*8975f5c5SAndroid Build Coastguard Worker
231*8975f5c5SAndroid Build Coastguard Worker mPendingQueries.pop_front();
232*8975f5c5SAndroid Build Coastguard Worker }
233*8975f5c5SAndroid Build Coastguard Worker
234*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
235*8975f5c5SAndroid Build Coastguard Worker }
236*8975f5c5SAndroid Build Coastguard Worker
237*8975f5c5SAndroid Build Coastguard Worker class SyncProviderGL
238*8975f5c5SAndroid Build Coastguard Worker {
239*8975f5c5SAndroid Build Coastguard Worker public:
~SyncProviderGL()240*8975f5c5SAndroid Build Coastguard Worker virtual ~SyncProviderGL() {}
init(const gl::Context * context,gl::QueryType queryType)241*8975f5c5SAndroid Build Coastguard Worker virtual angle::Result init(const gl::Context *context, gl::QueryType queryType)
242*8975f5c5SAndroid Build Coastguard Worker {
243*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
244*8975f5c5SAndroid Build Coastguard Worker }
245*8975f5c5SAndroid Build Coastguard Worker virtual angle::Result flush(const gl::Context *context, bool force, bool *finished) = 0;
246*8975f5c5SAndroid Build Coastguard Worker };
247*8975f5c5SAndroid Build Coastguard Worker
248*8975f5c5SAndroid Build Coastguard Worker class SyncProviderGLSync : public SyncProviderGL
249*8975f5c5SAndroid Build Coastguard Worker {
250*8975f5c5SAndroid Build Coastguard Worker public:
SyncProviderGLSync(const FunctionsGL * functions)251*8975f5c5SAndroid Build Coastguard Worker SyncProviderGLSync(const FunctionsGL *functions) : mFunctions(functions), mSync(nullptr) {}
252*8975f5c5SAndroid Build Coastguard Worker
~SyncProviderGLSync()253*8975f5c5SAndroid Build Coastguard Worker ~SyncProviderGLSync() override { mFunctions->deleteSync(mSync); }
254*8975f5c5SAndroid Build Coastguard Worker
init(const gl::Context * context,gl::QueryType type)255*8975f5c5SAndroid Build Coastguard Worker angle::Result init(const gl::Context *context, gl::QueryType type) override
256*8975f5c5SAndroid Build Coastguard Worker {
257*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
258*8975f5c5SAndroid Build Coastguard Worker mSync = mFunctions->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
259*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK(contextGL, mSync != 0, "glFenceSync failed to create a GLsync object.",
260*8975f5c5SAndroid Build Coastguard Worker GL_OUT_OF_MEMORY);
261*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
262*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
263*8975f5c5SAndroid Build Coastguard Worker }
264*8975f5c5SAndroid Build Coastguard Worker
flush(const gl::Context * context,bool force,bool * finished)265*8975f5c5SAndroid Build Coastguard Worker angle::Result flush(const gl::Context *context, bool force, bool *finished) override
266*8975f5c5SAndroid Build Coastguard Worker {
267*8975f5c5SAndroid Build Coastguard Worker if (force)
268*8975f5c5SAndroid Build Coastguard Worker {
269*8975f5c5SAndroid Build Coastguard Worker mFunctions->clientWaitSync(mSync, 0, 0);
270*8975f5c5SAndroid Build Coastguard Worker *finished = true;
271*8975f5c5SAndroid Build Coastguard Worker }
272*8975f5c5SAndroid Build Coastguard Worker else
273*8975f5c5SAndroid Build Coastguard Worker {
274*8975f5c5SAndroid Build Coastguard Worker GLint value = 0;
275*8975f5c5SAndroid Build Coastguard Worker mFunctions->getSynciv(mSync, GL_SYNC_STATUS, 1, nullptr, &value);
276*8975f5c5SAndroid Build Coastguard Worker *finished = (value == GL_SIGNALED);
277*8975f5c5SAndroid Build Coastguard Worker }
278*8975f5c5SAndroid Build Coastguard Worker
279*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
280*8975f5c5SAndroid Build Coastguard Worker }
281*8975f5c5SAndroid Build Coastguard Worker
282*8975f5c5SAndroid Build Coastguard Worker private:
283*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *mFunctions;
284*8975f5c5SAndroid Build Coastguard Worker GLsync mSync;
285*8975f5c5SAndroid Build Coastguard Worker };
286*8975f5c5SAndroid Build Coastguard Worker
287*8975f5c5SAndroid Build Coastguard Worker class SyncProviderGLQuery : public SyncProviderGL
288*8975f5c5SAndroid Build Coastguard Worker {
289*8975f5c5SAndroid Build Coastguard Worker public:
SyncProviderGLQuery(const FunctionsGL * functions)290*8975f5c5SAndroid Build Coastguard Worker SyncProviderGLQuery(const FunctionsGL *functions) : mFunctions(functions), mQuery(0) {}
291*8975f5c5SAndroid Build Coastguard Worker
init(const gl::Context * context,gl::QueryType type)292*8975f5c5SAndroid Build Coastguard Worker angle::Result init(const gl::Context *context, gl::QueryType type) override
293*8975f5c5SAndroid Build Coastguard Worker {
294*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
295*8975f5c5SAndroid Build Coastguard Worker
296*8975f5c5SAndroid Build Coastguard Worker mFunctions->genQueries(1, &mQuery);
297*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->pauseQuery(context, type));
298*8975f5c5SAndroid Build Coastguard Worker mFunctions->beginQuery(ToGLenum(type), mQuery);
299*8975f5c5SAndroid Build Coastguard Worker mFunctions->endQuery(ToGLenum(type));
300*8975f5c5SAndroid Build Coastguard Worker return stateManager->resumeQuery(context, type);
301*8975f5c5SAndroid Build Coastguard Worker }
302*8975f5c5SAndroid Build Coastguard Worker
~SyncProviderGLQuery()303*8975f5c5SAndroid Build Coastguard Worker ~SyncProviderGLQuery() override { mFunctions->deleteQueries(1, &mQuery); }
304*8975f5c5SAndroid Build Coastguard Worker
flush(const gl::Context * context,bool force,bool * finished)305*8975f5c5SAndroid Build Coastguard Worker angle::Result flush(const gl::Context *context, bool force, bool *finished) override
306*8975f5c5SAndroid Build Coastguard Worker {
307*8975f5c5SAndroid Build Coastguard Worker if (force)
308*8975f5c5SAndroid Build Coastguard Worker {
309*8975f5c5SAndroid Build Coastguard Worker GLint result = 0;
310*8975f5c5SAndroid Build Coastguard Worker mFunctions->getQueryObjectiv(mQuery, GL_QUERY_RESULT, &result);
311*8975f5c5SAndroid Build Coastguard Worker *finished = true;
312*8975f5c5SAndroid Build Coastguard Worker }
313*8975f5c5SAndroid Build Coastguard Worker else
314*8975f5c5SAndroid Build Coastguard Worker {
315*8975f5c5SAndroid Build Coastguard Worker GLint available = 0;
316*8975f5c5SAndroid Build Coastguard Worker mFunctions->getQueryObjectiv(mQuery, GL_QUERY_RESULT_AVAILABLE, &available);
317*8975f5c5SAndroid Build Coastguard Worker *finished = (available == GL_TRUE);
318*8975f5c5SAndroid Build Coastguard Worker }
319*8975f5c5SAndroid Build Coastguard Worker
320*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
321*8975f5c5SAndroid Build Coastguard Worker }
322*8975f5c5SAndroid Build Coastguard Worker
323*8975f5c5SAndroid Build Coastguard Worker private:
324*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *mFunctions;
325*8975f5c5SAndroid Build Coastguard Worker GLuint mQuery;
326*8975f5c5SAndroid Build Coastguard Worker };
327*8975f5c5SAndroid Build Coastguard Worker
SyncQueryGL(gl::QueryType type,const FunctionsGL * functions)328*8975f5c5SAndroid Build Coastguard Worker SyncQueryGL::SyncQueryGL(gl::QueryType type, const FunctionsGL *functions)
329*8975f5c5SAndroid Build Coastguard Worker : QueryGL(type), mFunctions(functions), mSyncProvider(nullptr), mFinished(false)
330*8975f5c5SAndroid Build Coastguard Worker {
331*8975f5c5SAndroid Build Coastguard Worker ASSERT(IsSupported(mFunctions));
332*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == gl::QueryType::CommandsCompleted);
333*8975f5c5SAndroid Build Coastguard Worker }
334*8975f5c5SAndroid Build Coastguard Worker
~SyncQueryGL()335*8975f5c5SAndroid Build Coastguard Worker SyncQueryGL::~SyncQueryGL() {}
336*8975f5c5SAndroid Build Coastguard Worker
IsSupported(const FunctionsGL * functions)337*8975f5c5SAndroid Build Coastguard Worker bool SyncQueryGL::IsSupported(const FunctionsGL *functions)
338*8975f5c5SAndroid Build Coastguard Worker {
339*8975f5c5SAndroid Build Coastguard Worker return nativegl::SupportsFenceSync(functions) || nativegl::SupportsOcclusionQueries(functions);
340*8975f5c5SAndroid Build Coastguard Worker }
341*8975f5c5SAndroid Build Coastguard Worker
begin(const gl::Context * context)342*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::begin(const gl::Context *context)
343*8975f5c5SAndroid Build Coastguard Worker {
344*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
345*8975f5c5SAndroid Build Coastguard Worker }
346*8975f5c5SAndroid Build Coastguard Worker
end(const gl::Context * context)347*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::end(const gl::Context *context)
348*8975f5c5SAndroid Build Coastguard Worker {
349*8975f5c5SAndroid Build Coastguard Worker if (nativegl::SupportsFenceSync(mFunctions))
350*8975f5c5SAndroid Build Coastguard Worker {
351*8975f5c5SAndroid Build Coastguard Worker mSyncProvider.reset(new SyncProviderGLSync(mFunctions));
352*8975f5c5SAndroid Build Coastguard Worker }
353*8975f5c5SAndroid Build Coastguard Worker else if (nativegl::SupportsOcclusionQueries(mFunctions))
354*8975f5c5SAndroid Build Coastguard Worker {
355*8975f5c5SAndroid Build Coastguard Worker mSyncProvider.reset(new SyncProviderGLQuery(mFunctions));
356*8975f5c5SAndroid Build Coastguard Worker }
357*8975f5c5SAndroid Build Coastguard Worker else
358*8975f5c5SAndroid Build Coastguard Worker {
359*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_UNREACHABLE(GetImplAs<ContextGL>(context));
360*8975f5c5SAndroid Build Coastguard Worker }
361*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mSyncProvider->init(context, gl::QueryType::AnySamples));
362*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
363*8975f5c5SAndroid Build Coastguard Worker }
364*8975f5c5SAndroid Build Coastguard Worker
queryCounter(const gl::Context * context)365*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::queryCounter(const gl::Context *context)
366*8975f5c5SAndroid Build Coastguard Worker {
367*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
368*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
369*8975f5c5SAndroid Build Coastguard Worker }
370*8975f5c5SAndroid Build Coastguard Worker
getResult(const gl::Context * context,GLint * params)371*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::getResult(const gl::Context *context, GLint *params)
372*8975f5c5SAndroid Build Coastguard Worker {
373*8975f5c5SAndroid Build Coastguard Worker return getResultBase(context, params);
374*8975f5c5SAndroid Build Coastguard Worker }
375*8975f5c5SAndroid Build Coastguard Worker
getResult(const gl::Context * context,GLuint * params)376*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::getResult(const gl::Context *context, GLuint *params)
377*8975f5c5SAndroid Build Coastguard Worker {
378*8975f5c5SAndroid Build Coastguard Worker return getResultBase(context, params);
379*8975f5c5SAndroid Build Coastguard Worker }
380*8975f5c5SAndroid Build Coastguard Worker
getResult(const gl::Context * context,GLint64 * params)381*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::getResult(const gl::Context *context, GLint64 *params)
382*8975f5c5SAndroid Build Coastguard Worker {
383*8975f5c5SAndroid Build Coastguard Worker return getResultBase(context, params);
384*8975f5c5SAndroid Build Coastguard Worker }
385*8975f5c5SAndroid Build Coastguard Worker
getResult(const gl::Context * context,GLuint64 * params)386*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::getResult(const gl::Context *context, GLuint64 *params)
387*8975f5c5SAndroid Build Coastguard Worker {
388*8975f5c5SAndroid Build Coastguard Worker return getResultBase(context, params);
389*8975f5c5SAndroid Build Coastguard Worker }
390*8975f5c5SAndroid Build Coastguard Worker
isResultAvailable(const gl::Context * context,bool * available)391*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::isResultAvailable(const gl::Context *context, bool *available)
392*8975f5c5SAndroid Build Coastguard Worker {
393*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(flush(context, false));
394*8975f5c5SAndroid Build Coastguard Worker *available = mFinished;
395*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
396*8975f5c5SAndroid Build Coastguard Worker }
397*8975f5c5SAndroid Build Coastguard Worker
pause(const gl::Context * context)398*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::pause(const gl::Context *context)
399*8975f5c5SAndroid Build Coastguard Worker {
400*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
401*8975f5c5SAndroid Build Coastguard Worker }
402*8975f5c5SAndroid Build Coastguard Worker
resume(const gl::Context * context)403*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::resume(const gl::Context *context)
404*8975f5c5SAndroid Build Coastguard Worker {
405*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
406*8975f5c5SAndroid Build Coastguard Worker }
407*8975f5c5SAndroid Build Coastguard Worker
flush(const gl::Context * context,bool force)408*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::flush(const gl::Context *context, bool force)
409*8975f5c5SAndroid Build Coastguard Worker {
410*8975f5c5SAndroid Build Coastguard Worker if (mSyncProvider == nullptr)
411*8975f5c5SAndroid Build Coastguard Worker {
412*8975f5c5SAndroid Build Coastguard Worker ASSERT(mFinished);
413*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
414*8975f5c5SAndroid Build Coastguard Worker }
415*8975f5c5SAndroid Build Coastguard Worker
416*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mSyncProvider->flush(context, force, &mFinished));
417*8975f5c5SAndroid Build Coastguard Worker if (mFinished)
418*8975f5c5SAndroid Build Coastguard Worker {
419*8975f5c5SAndroid Build Coastguard Worker mSyncProvider.reset();
420*8975f5c5SAndroid Build Coastguard Worker }
421*8975f5c5SAndroid Build Coastguard Worker
422*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
423*8975f5c5SAndroid Build Coastguard Worker }
424*8975f5c5SAndroid Build Coastguard Worker
425*8975f5c5SAndroid Build Coastguard Worker template <typename T>
getResultBase(const gl::Context * context,T * params)426*8975f5c5SAndroid Build Coastguard Worker angle::Result SyncQueryGL::getResultBase(const gl::Context *context, T *params)
427*8975f5c5SAndroid Build Coastguard Worker {
428*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(flush(context, true));
429*8975f5c5SAndroid Build Coastguard Worker *params = static_cast<T>(mFinished ? GL_TRUE : GL_FALSE);
430*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
431*8975f5c5SAndroid Build Coastguard Worker }
432*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
433