• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2014 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 // queryconversions.cpp: Implementation of state query cast conversions
8 
9 #include "libANGLE/queryconversions.h"
10 
11 #include <vector>
12 
13 #include "common/utilities.h"
14 #include "libANGLE/Context.h"
15 
16 namespace gl
17 {
18 
19 namespace
20 {
21 
ExpandFloatToInteger(GLfloat value)22 GLint64 ExpandFloatToInteger(GLfloat value)
23 {
24     return static_cast<GLint64>((static_cast<double>(0xFFFFFFFFULL) * value - 1.0) / 2.0);
25 }
26 
27 template <typename QueryT, typename NativeT>
CastFromStateValueToInt(GLenum pname,NativeT value)28 QueryT CastFromStateValueToInt(GLenum pname, NativeT value)
29 {
30     GLenum nativeType = GLTypeToGLenum<NativeT>::value;
31 
32     if (nativeType == GL_FLOAT)
33     {
34         // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from
35         // Table 4.5
36         switch (pname)
37         {
38             case GL_DEPTH_RANGE:
39             case GL_COLOR_CLEAR_VALUE:
40             case GL_DEPTH_CLEAR_VALUE:
41             case GL_BLEND_COLOR:
42             // GLES1 emulation:
43             // Also, several GLES1.x values need to be converted to integer with
44             // ExpandFloatToInteger rather than rounding. See GLES 1.1 spec 6.1.2 "Data
45             // Conversions".
46             case GL_ALPHA_TEST_REF:
47             case GL_CURRENT_COLOR:
48                 return clampCast<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value)));
49             default:
50                 return clampCast<QueryT>(std::round(value));
51         }
52     }
53 
54     return clampCast<QueryT>(value);
55 }
56 
57 template <typename QueryT, typename NativeT>
CastFromStateValueToFloat(GLenum pname,NativeT value)58 QueryT CastFromStateValueToFloat(GLenum pname, NativeT value)
59 {
60     switch (pname)
61     {
62         // For mask values, their floating-point values should be positive, not -1.
63         case GL_STENCIL_VALUE_MASK:
64         case GL_STENCIL_BACK_VALUE_MASK:
65         case GL_STENCIL_WRITEMASK:
66         case GL_STENCIL_BACK_WRITEMASK:
67             return static_cast<QueryT>(static_cast<GLuint>(value));
68         default:
69             return static_cast<QueryT>(value);
70     }
71 }
72 
73 template <typename NativeT, typename QueryT>
CastQueryValueToInt(GLenum pname,QueryT value)74 NativeT CastQueryValueToInt(GLenum pname, QueryT value)
75 {
76     GLenum queryType = GLTypeToGLenum<QueryT>::value;
77 
78     if (queryType == GL_FLOAT)
79     {
80         // ARM devices cast float to uint differently than Intel.
81         // Basically, any negative floating point number becomes 0
82         // when converted to unsigned int. Instead, convert to a signed
83         // int and then convert to unsigned int to "preserve the value"
84         // E.g. common case for tests is to pass in -1 as an invalid query
85         // value. If cast to a unsigned int it becomes 0 (GL_NONE) and is now
86         // a valid enum and negative tests fail. But converting to int
87         // and then to final unsigned int gives us 4294967295 (0xffffffff)
88         // which is what we want.
89         return static_cast<NativeT>(static_cast<GLint64>(std::round(value)));
90     }
91 
92     return static_cast<NativeT>(value);
93 }
94 
95 }  // anonymous namespace
96 
97 template <typename QueryT, typename InternalT>
CastFromGLintStateValue(GLenum pname,InternalT value)98 QueryT CastFromGLintStateValue(GLenum pname, InternalT value)
99 {
100     return CastFromStateValue<QueryT, GLint>(pname, clampCast<GLint, InternalT>(value));
101 }
102 
103 template GLfloat CastFromGLintStateValue<GLfloat, GLenum>(GLenum pname, GLenum value);
104 template GLint CastFromGLintStateValue<GLint, GLenum>(GLenum pname, GLenum value);
105 template GLint64 CastFromGLintStateValue<GLint64, GLenum>(GLenum pname, GLenum value);
106 template GLuint CastFromGLintStateValue<GLuint, GLenum>(GLenum pname, GLenum value);
107 template GLuint CastFromGLintStateValue<GLuint, GLint>(GLenum pname, GLint value);
108 template GLfloat CastFromGLintStateValue<GLfloat, GLint>(GLenum pname, GLint value);
109 template GLint CastFromGLintStateValue<GLint, GLint>(GLenum pname, GLint value);
110 template GLfloat CastFromGLintStateValue<GLfloat, bool>(GLenum pname, bool value);
111 template GLuint CastFromGLintStateValue<GLuint, bool>(GLenum pname, bool value);
112 template GLint CastFromGLintStateValue<GLint, bool>(GLenum pname, bool value);
113 template GLfloat CastFromGLintStateValue<GLfloat, GLfloat>(GLenum pname, GLfloat value);
114 template GLint CastFromGLintStateValue<GLint, GLfloat>(GLenum pname, GLfloat value);
115 template GLuint CastFromGLintStateValue<GLuint, GLfloat>(GLenum pname, GLfloat value);
116 
117 template <typename QueryT, typename NativeT>
CastFromStateValue(GLenum pname,NativeT value)118 QueryT CastFromStateValue(GLenum pname, NativeT value)
119 {
120     GLenum queryType = GLTypeToGLenum<QueryT>::value;
121 
122     switch (queryType)
123     {
124         case GL_INT:
125         case GL_INT_64_ANGLEX:
126         case GL_UNSIGNED_INT:
127         case GL_UINT_64_ANGLEX:
128             return CastFromStateValueToInt<QueryT, NativeT>(pname, value);
129         case GL_FLOAT:
130             return CastFromStateValueToFloat<QueryT, NativeT>(pname, value);
131         case GL_BOOL:
132             return static_cast<QueryT>(value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
133         default:
134             UNREACHABLE();
135             return 0;
136     }
137 }
138 template GLint CastFromStateValue<GLint, GLint>(GLenum pname, GLint value);
139 template GLint CastFromStateValue<GLint, GLint64>(GLenum pname, GLint64 value);
140 template GLint64 CastFromStateValue<GLint64, GLint>(GLenum pname, GLint value);
141 template GLint64 CastFromStateValue<GLint64, GLint64>(GLenum pname, GLint64 value);
142 template GLfloat CastFromStateValue<GLfloat, GLint>(GLenum pname, GLint value);
143 template GLfloat CastFromStateValue<GLfloat, GLuint>(GLenum pname, GLuint value);
144 template GLfloat CastFromStateValue<GLfloat, GLfloat>(GLenum pname, GLfloat value);
145 template GLint CastFromStateValue<GLint, GLfloat>(GLenum pname, GLfloat value);
146 template GLuint CastFromStateValue<GLuint, GLfloat>(GLenum pname, GLfloat value);
147 template GLuint CastFromStateValue<GLuint, GLint>(GLenum pname, GLint value);
148 template GLuint CastFromStateValue<GLuint, GLuint>(GLenum pname, GLuint value);
149 template GLint CastFromStateValue<GLint, GLboolean>(GLenum pname, GLboolean value);
150 template GLint64 CastFromStateValue<GLint64, GLboolean>(GLenum pname, GLboolean value);
151 template GLint CastFromStateValue<GLint, GLuint>(GLenum pname, GLuint value);
152 template GLint64 CastFromStateValue<GLint64, GLuint>(GLenum pname, GLuint value);
153 template GLuint64 CastFromStateValue<GLuint64, GLuint>(GLenum pname, GLuint value);
154 
155 template <typename NativeT, typename QueryT>
CastQueryValueTo(GLenum pname,QueryT value)156 NativeT CastQueryValueTo(GLenum pname, QueryT value)
157 {
158     GLenum nativeType = GLTypeToGLenum<NativeT>::value;
159 
160     switch (nativeType)
161     {
162         case GL_INT:
163         case GL_INT_64_ANGLEX:
164         case GL_UNSIGNED_INT:
165         case GL_UINT_64_ANGLEX:
166             return CastQueryValueToInt<NativeT, QueryT>(pname, value);
167         case GL_FLOAT:
168             return static_cast<NativeT>(value);
169         case GL_BOOL:
170             return static_cast<NativeT>(value == static_cast<QueryT>(0) ? GL_FALSE : GL_TRUE);
171         default:
172             UNREACHABLE();
173             return 0;
174     }
175 }
176 
177 template GLint CastQueryValueTo<GLint, GLfloat>(GLenum pname, GLfloat value);
178 template GLboolean CastQueryValueTo<GLboolean, GLint>(GLenum pname, GLint value);
179 template GLint CastQueryValueTo<GLint, GLint>(GLenum pname, GLint value);
180 template GLint CastQueryValueTo<GLint, GLuint>(GLenum pname, GLuint value);
181 template GLfloat CastQueryValueTo<GLfloat, GLint>(GLenum pname, GLint value);
182 template GLfloat CastQueryValueTo<GLfloat, GLuint>(GLenum pname, GLuint value);
183 template GLfloat CastQueryValueTo<GLfloat, GLfloat>(GLenum pname, GLfloat value);
184 template GLuint CastQueryValueTo<GLuint, GLint>(GLenum pname, GLint value);
185 template GLuint CastQueryValueTo<GLuint, GLuint>(GLenum pname, GLuint value);
186 template GLuint CastQueryValueTo<GLuint, GLfloat>(GLenum pname, GLfloat value);
187 
188 template <typename QueryT>
CastStateValues(const Context * context,GLenum nativeType,GLenum pname,unsigned int numParams,QueryT * outParams)189 void CastStateValues(const Context *context,
190                      GLenum nativeType,
191                      GLenum pname,
192                      unsigned int numParams,
193                      QueryT *outParams)
194 {
195     if (nativeType == GL_INT)
196     {
197         std::vector<GLint> intParams(numParams, 0);
198         context->getIntegervImpl(pname, intParams.data());
199 
200         for (unsigned int i = 0; i < numParams; ++i)
201         {
202             outParams[i] = CastFromStateValue<QueryT>(pname, intParams[i]);
203         }
204     }
205     else if (nativeType == GL_BOOL)
206     {
207         std::vector<GLboolean> boolParams(numParams, GL_FALSE);
208         context->getBooleanvImpl(pname, boolParams.data());
209 
210         for (unsigned int i = 0; i < numParams; ++i)
211         {
212             outParams[i] =
213                 (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
214         }
215     }
216     else if (nativeType == GL_FLOAT)
217     {
218         std::vector<GLfloat> floatParams(numParams, 0.0f);
219         context->getFloatvImpl(pname, floatParams.data());
220 
221         for (unsigned int i = 0; i < numParams; ++i)
222         {
223             outParams[i] = CastFromStateValue<QueryT>(pname, floatParams[i]);
224         }
225     }
226     else if (nativeType == GL_INT_64_ANGLEX)
227     {
228         std::vector<GLint64> int64Params(numParams, 0);
229         context->getInteger64vImpl(pname, int64Params.data());
230 
231         for (unsigned int i = 0; i < numParams; ++i)
232         {
233             outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]);
234         }
235     }
236     else
237     {
238         WARN() << "Application querying parameter that does not exist.";
239     }
240 }
241 
242 // Explicit template instantiation (how we export template functions in different files)
243 // The calls below will make CastStateValues successfully link with the GL state query types
244 // The GL state query API types are: bool, int, uint, float, int64, uint64
245 
246 template void CastStateValues<GLboolean>(const Context *,
247                                          GLenum,
248                                          GLenum,
249                                          unsigned int,
250                                          GLboolean *);
251 template void CastStateValues<GLint>(const Context *, GLenum, GLenum, unsigned int, GLint *);
252 template void CastStateValues<GLuint>(const Context *, GLenum, GLenum, unsigned int, GLuint *);
253 template void CastStateValues<GLfloat>(const Context *, GLenum, GLenum, unsigned int, GLfloat *);
254 template void CastStateValues<GLint64>(const Context *, GLenum, GLenum, unsigned int, GLint64 *);
255 
256 template <typename QueryT>
CastIndexedStateValues(Context * context,GLenum nativeType,GLenum pname,GLuint index,unsigned int numParams,QueryT * outParams)257 void CastIndexedStateValues(Context *context,
258                             GLenum nativeType,
259                             GLenum pname,
260                             GLuint index,
261                             unsigned int numParams,
262                             QueryT *outParams)
263 {
264     if (nativeType == GL_INT)
265     {
266         std::vector<GLint> intParams(numParams, 0);
267         context->getIntegeri_v(pname, index, intParams.data());
268 
269         for (unsigned int i = 0; i < numParams; ++i)
270         {
271             outParams[i] = CastFromStateValue<QueryT>(pname, intParams[i]);
272         }
273     }
274     else if (nativeType == GL_BOOL)
275     {
276         std::vector<GLboolean> boolParams(numParams, GL_FALSE);
277         context->getBooleani_v(pname, index, boolParams.data());
278 
279         for (unsigned int i = 0; i < numParams; ++i)
280         {
281             outParams[i] =
282                 (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
283         }
284     }
285     else if (nativeType == GL_INT_64_ANGLEX)
286     {
287         std::vector<GLint64> int64Params(numParams, 0);
288         context->getInteger64i_v(pname, index, int64Params.data());
289 
290         for (unsigned int i = 0; i < numParams; ++i)
291         {
292             outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]);
293         }
294     }
295     else
296         UNREACHABLE();
297 }
298 
299 template void CastIndexedStateValues<GLboolean>(Context *,
300                                                 GLenum,
301                                                 GLenum,
302                                                 GLuint index,
303                                                 unsigned int,
304                                                 GLboolean *);
305 template void CastIndexedStateValues<GLint>(Context *,
306                                             GLenum,
307                                             GLenum,
308                                             GLuint index,
309                                             unsigned int,
310                                             GLint *);
311 template void CastIndexedStateValues<GLuint>(Context *,
312                                              GLenum,
313                                              GLenum,
314                                              GLuint index,
315                                              unsigned int,
316                                              GLuint *);
317 template void CastIndexedStateValues<GLfloat>(Context *,
318                                               GLenum,
319                                               GLenum,
320                                               GLuint index,
321                                               unsigned int,
322                                               GLfloat *);
323 template void CastIndexedStateValues<GLint64>(Context *,
324                                               GLenum,
325                                               GLenum,
326                                               GLuint index,
327                                               unsigned int,
328                                               GLint64 *);
329 }  // namespace gl
330