• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_HWUI_QUERY_H
18 #define ANDROID_HWUI_QUERY_H
19 
20 #include <GLES3/gl3.h>
21 
22 #include "Extensions.h"
23 
24 namespace android {
25 namespace uirenderer {
26 
27 /**
28  * A Query instance can be used to perform occlusion queries. If the device
29  * does not support occlusion queries, the result of a query will always be
30  * 0 and the result will always be marked available.
31  *
32  * To run an occlusion query successfully, you must start end end the query:
33  *
34  * Query query;
35  * query.begin();
36  * // execute OpenGL calls
37  * query.end();
38  * GLuint result = query.getResult();
39  */
40 class Query {
41 public:
42     /**
43      * Possible query targets.
44      */
45     enum Target {
46         /**
47          * Indicates if any sample passed the depth & stencil tests.
48          */
49         kTargetSamples = GL_ANY_SAMPLES_PASSED,
50         /**
51          * Indicates if any sample passed the depth & stencil tests.
52          * The implementation may choose to use a less precise version
53          * of the test, potentially resulting in false positives.
54          */
55         kTargetConservativeSamples = GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
56     };
57 
58     /**
59      * Creates a new query with the specified target. The default
60      * target is kTargetSamples (of GL_ANY_SAMPLES_PASSED in OpenGL.)
61      */
mActive(false)62     Query(Target target = kTargetSamples): mActive(false), mTarget(target),
63             mCanQuery(Extensions::getInstance().hasOcclusionQueries()),
64             mQuery(0) {
65     }
66 
~Query()67     ~Query() {
68         if (mQuery) {
69             glDeleteQueries(1, &mQuery);
70         }
71     }
72 
73     /**
74      * Begins the query. If the query has already begun or if the device
75      * does not support occlusion queries, calling this method as no effect.
76      * After calling this method successfully, the query is marked active.
77      */
begin()78     void begin() {
79         if (!mActive && mCanQuery) {
80             if (!mQuery) {
81                 glGenQueries(1, &mQuery);
82             }
83 
84             glBeginQuery(mTarget, mQuery);
85             mActive = true;
86         }
87     }
88 
89     /**
90      * Ends the query. If the query has already begun or if the device
91      * does not support occlusion queries, calling this method as no effect.
92      * After calling this method successfully, the query is marked inactive.
93      */
end()94     void end() {
95         if (mQuery && mActive) {
96             glEndQuery(mTarget);
97             mActive = false;
98         }
99     }
100 
101     /**
102      * Returns true if the query is active, false otherwise.
103      */
isActive()104     bool isActive() {
105         return mActive;
106     }
107 
108     /**
109      * Returns true if the result of the query is available,
110      * false otherwise. Calling getResult() before the result
111      * is available may result in the calling thread being blocked.
112      * If the device does not support queries, this method always
113      * returns true.
114      */
isResultAvailable()115     bool isResultAvailable() {
116         if (!mQuery) return true;
117 
118         GLuint result;
119         glGetQueryObjectuiv(mQuery, GL_QUERY_RESULT_AVAILABLE, &result);
120         return result == GL_TRUE;
121     }
122 
123     /**
124      * Returns the result of the query. If the device does not
125      * support queries this method will return 0.
126      *
127      * Calling this method implicitely calls end() if the query
128      * is currently active.
129      */
getResult()130     GLuint getResult() {
131         if (!mQuery) return 0;
132 
133         end();
134 
135         GLuint result;
136         glGetQueryObjectuiv(mQuery, GL_QUERY_RESULT, &result);
137         return result;
138     }
139 
140 
141 private:
142     bool mActive;
143     GLenum mTarget;
144     bool mCanQuery;
145     GLuint mQuery;
146 
147 }; // class Query
148 
149 }; // namespace uirenderer
150 }; // namespace android
151 
152 #endif // ANDROID_HWUI_QUERY_H
153