• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 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 // queryutils.cpp: Utilities for querying values from GL objects
8 
9 #include "libANGLE/queryutils.h"
10 
11 #include <algorithm>
12 
13 #include "common/utilities.h"
14 
15 #include "libANGLE/Buffer.h"
16 #include "libANGLE/Config.h"
17 #include "libANGLE/Context.h"
18 #include "libANGLE/Display.h"
19 #include "libANGLE/EGLSync.h"
20 #include "libANGLE/Fence.h"
21 #include "libANGLE/Framebuffer.h"
22 #include "libANGLE/GLES1State.h"
23 #include "libANGLE/MemoryObject.h"
24 #include "libANGLE/Program.h"
25 #include "libANGLE/Renderbuffer.h"
26 #include "libANGLE/Sampler.h"
27 #include "libANGLE/Shader.h"
28 #include "libANGLE/Surface.h"
29 #include "libANGLE/Texture.h"
30 #include "libANGLE/Uniform.h"
31 #include "libANGLE/VertexAttribute.h"
32 #include "libANGLE/queryconversions.h"
33 
34 namespace gl
35 {
36 
37 namespace
38 {
39 
40 template <bool isPureInteger>
ConvertToColor(const GLfloat * params)41 ColorGeneric ConvertToColor(const GLfloat *params)
42 {
43     if (isPureInteger)
44     {
45         UNREACHABLE();
46         return ColorGeneric(ColorI());
47     }
48     else
49     {
50         return ColorGeneric(ColorF::fromData(params));
51     }
52 }
53 
54 template <bool isPureInteger>
ConvertToColor(const GLint * params)55 ColorGeneric ConvertToColor(const GLint *params)
56 {
57     if (isPureInteger)
58     {
59         return ColorGeneric(ColorI(params[0], params[1], params[2], params[3]));
60     }
61     else
62     {
63         return ColorGeneric(ColorF(normalizedToFloat(params[0]), normalizedToFloat(params[1]),
64                                    normalizedToFloat(params[2]), normalizedToFloat(params[3])));
65     }
66 }
67 
68 template <bool isPureInteger>
ConvertToColor(const GLuint * params)69 ColorGeneric ConvertToColor(const GLuint *params)
70 {
71     if (isPureInteger)
72     {
73         return ColorGeneric(ColorUI(params[0], params[1], params[2], params[3]));
74     }
75     else
76     {
77         UNREACHABLE();
78         return ColorGeneric(ColorF());
79     }
80 }
81 
82 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLfloat * outParams)83 void ConvertFromColor(const ColorGeneric &color, GLfloat *outParams)
84 {
85     if (isPureInteger)
86     {
87         UNREACHABLE();
88     }
89     else
90     {
91         color.colorF.writeData(outParams);
92     }
93 }
94 
95 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLint * outParams)96 void ConvertFromColor(const ColorGeneric &color, GLint *outParams)
97 {
98     if (isPureInteger)
99     {
100         outParams[0] = color.colorI.red;
101         outParams[1] = color.colorI.green;
102         outParams[2] = color.colorI.blue;
103         outParams[3] = color.colorI.alpha;
104     }
105     else
106     {
107         outParams[0] = floatToNormalized<GLint>(color.colorF.red);
108         outParams[1] = floatToNormalized<GLint>(color.colorF.green);
109         outParams[2] = floatToNormalized<GLint>(color.colorF.blue);
110         outParams[3] = floatToNormalized<GLint>(color.colorF.alpha);
111     }
112 }
113 
114 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLuint * outParams)115 void ConvertFromColor(const ColorGeneric &color, GLuint *outParams)
116 {
117     if (isPureInteger)
118     {
119         constexpr unsigned int kMinValue = 0;
120 
121         outParams[0] = std::max(color.colorUI.red, kMinValue);
122         outParams[1] = std::max(color.colorUI.green, kMinValue);
123         outParams[2] = std::max(color.colorUI.blue, kMinValue);
124         outParams[3] = std::max(color.colorUI.alpha, kMinValue);
125     }
126     else
127     {
128         UNREACHABLE();
129     }
130 }
131 
132 template <typename ParamType>
QueryTexLevelParameterBase(const Texture * texture,TextureTarget target,GLint level,GLenum pname,ParamType * params)133 void QueryTexLevelParameterBase(const Texture *texture,
134                                 TextureTarget target,
135                                 GLint level,
136                                 GLenum pname,
137                                 ParamType *params)
138 {
139     ASSERT(texture != nullptr);
140     const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info;
141 
142     switch (pname)
143     {
144         case GL_TEXTURE_RED_TYPE:
145             *params = CastFromGLintStateValue<ParamType>(
146                 pname, info->redBits ? info->componentType : GL_NONE);
147             break;
148         case GL_TEXTURE_GREEN_TYPE:
149             *params = CastFromGLintStateValue<ParamType>(
150                 pname, info->greenBits ? info->componentType : GL_NONE);
151             break;
152         case GL_TEXTURE_BLUE_TYPE:
153             *params = CastFromGLintStateValue<ParamType>(
154                 pname, info->blueBits ? info->componentType : GL_NONE);
155             break;
156         case GL_TEXTURE_ALPHA_TYPE:
157             *params = CastFromGLintStateValue<ParamType>(
158                 pname, info->alphaBits ? info->componentType : GL_NONE);
159             break;
160         case GL_TEXTURE_DEPTH_TYPE:
161             *params = CastFromGLintStateValue<ParamType>(
162                 pname, info->depthBits ? info->componentType : GL_NONE);
163             break;
164         case GL_TEXTURE_RED_SIZE:
165             *params = CastFromGLintStateValue<ParamType>(pname, info->redBits);
166             break;
167         case GL_TEXTURE_GREEN_SIZE:
168             *params = CastFromGLintStateValue<ParamType>(pname, info->greenBits);
169             break;
170         case GL_TEXTURE_BLUE_SIZE:
171             *params = CastFromGLintStateValue<ParamType>(pname, info->blueBits);
172             break;
173         case GL_TEXTURE_ALPHA_SIZE:
174             *params = CastFromGLintStateValue<ParamType>(pname, info->alphaBits);
175             break;
176         case GL_TEXTURE_DEPTH_SIZE:
177             *params = CastFromGLintStateValue<ParamType>(pname, info->depthBits);
178             break;
179         case GL_TEXTURE_STENCIL_SIZE:
180             *params = CastFromGLintStateValue<ParamType>(pname, info->stencilBits);
181             break;
182         case GL_TEXTURE_SHARED_SIZE:
183             *params = CastFromGLintStateValue<ParamType>(pname, info->sharedBits);
184             break;
185         case GL_TEXTURE_INTERNAL_FORMAT:
186             *params = CastFromGLintStateValue<ParamType>(
187                 pname, info->internalFormat ? info->internalFormat : GL_RGBA);
188             break;
189         case GL_TEXTURE_WIDTH:
190             *params = CastFromGLintStateValue<ParamType>(
191                 pname, static_cast<uint32_t>(texture->getWidth(target, level)));
192             break;
193         case GL_TEXTURE_HEIGHT:
194             *params = CastFromGLintStateValue<ParamType>(
195                 pname, static_cast<uint32_t>(texture->getHeight(target, level)));
196             break;
197         case GL_TEXTURE_DEPTH:
198             *params = CastFromGLintStateValue<ParamType>(
199                 pname, static_cast<uint32_t>(texture->getDepth(target, level)));
200             break;
201         case GL_TEXTURE_SAMPLES:
202             *params = CastFromStateValue<ParamType>(pname, texture->getSamples(target, level));
203             break;
204         case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
205             *params = CastFromStateValue<ParamType>(
206                 pname, static_cast<GLint>(texture->getFixedSampleLocations(target, level)));
207             break;
208         case GL_TEXTURE_COMPRESSED:
209             *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(info->compressed));
210             break;
211         case GL_MEMORY_SIZE_ANGLE:
212             *params =
213                 CastFromStateValue<ParamType>(pname, texture->getLevelMemorySize(target, level));
214             break;
215         case GL_RESOURCE_INITIALIZED_ANGLE:
216             *params = CastFromGLintStateValue<ParamType>(
217                 pname, texture->initState(ImageIndex::MakeFromTarget(target, level)) ==
218                            InitState::Initialized);
219             break;
220         case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
221             *params = CastFromStateValue<ParamType>(
222                 pname, static_cast<GLint>(texture->getBuffer().id().value));
223             break;
224         case GL_TEXTURE_BUFFER_OFFSET:
225             *params = CastFromStateValue<ParamType>(
226                 pname, static_cast<GLint>(texture->getBuffer().getOffset()));
227             break;
228         case GL_TEXTURE_BUFFER_SIZE:
229             *params = CastFromStateValue<ParamType>(
230                 pname, static_cast<GLint>(GetBoundBufferAvailableSize(texture->getBuffer())));
231             break;
232         default:
233             UNREACHABLE();
234             break;
235     }
236 }
237 
238 // This function is needed to handle fixed_point data.
239 // It can be used when some pname need special conversion from int/float/bool to fixed_point.
240 template <bool isGLfixed, typename QueryT, typename ParamType>
CastFromSpecialValue(GLenum pname,const ParamType param)241 QueryT CastFromSpecialValue(GLenum pname, const ParamType param)
242 {
243     if (isGLfixed)
244     {
245         return static_cast<QueryT>(ConvertFloatToFixed(CastFromStateValue<GLfloat>(pname, param)));
246     }
247     else
248     {
249         return CastFromStateValue<QueryT>(pname, param);
250     }
251 }
252 
253 template <bool isPureInteger, bool isGLfixed, typename ParamType>
QueryTexParameterBase(const Context * context,const Texture * texture,GLenum pname,ParamType * params)254 void QueryTexParameterBase(const Context *context,
255                            const Texture *texture,
256                            GLenum pname,
257                            ParamType *params)
258 {
259     ASSERT(texture != nullptr);
260 
261     switch (pname)
262     {
263         case GL_TEXTURE_MAG_FILTER:
264             *params = CastFromGLintStateValue<ParamType>(pname, texture->getMagFilter());
265             break;
266         case GL_TEXTURE_MIN_FILTER:
267             *params = CastFromGLintStateValue<ParamType>(pname, texture->getMinFilter());
268             break;
269         case GL_TEXTURE_WRAP_S:
270             *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapS());
271             break;
272         case GL_TEXTURE_WRAP_T:
273             *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapT());
274             break;
275         case GL_TEXTURE_WRAP_R:
276             *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapR());
277             break;
278         case GL_TEXTURE_IMMUTABLE_FORMAT:
279             *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableFormat());
280             break;
281         case GL_TEXTURE_IMMUTABLE_LEVELS:
282             *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableLevels());
283             break;
284         case GL_TEXTURE_USAGE_ANGLE:
285             *params = CastFromGLintStateValue<ParamType>(pname, texture->getUsage());
286             break;
287         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
288             *params =
289                 CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxAnisotropy());
290             break;
291         case GL_TEXTURE_SWIZZLE_R:
292             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleRed());
293             break;
294         case GL_TEXTURE_SWIZZLE_G:
295             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleGreen());
296             break;
297         case GL_TEXTURE_SWIZZLE_B:
298             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleBlue());
299             break;
300         case GL_TEXTURE_SWIZZLE_A:
301             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleAlpha());
302             break;
303         case GL_TEXTURE_BASE_LEVEL:
304             *params = CastFromGLintStateValue<ParamType>(pname, texture->getBaseLevel());
305             break;
306         case GL_TEXTURE_MAX_LEVEL:
307             *params = CastFromGLintStateValue<ParamType>(pname, texture->getMaxLevel());
308             break;
309         case GL_TEXTURE_MIN_LOD:
310             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMinLod());
311             break;
312         case GL_TEXTURE_MAX_LOD:
313             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxLod());
314             break;
315         case GL_TEXTURE_COMPARE_MODE:
316             *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareMode());
317             break;
318         case GL_TEXTURE_COMPARE_FUNC:
319             *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareFunc());
320             break;
321         case GL_TEXTURE_SRGB_DECODE_EXT:
322             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBDecode());
323             break;
324         case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
325             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBOverride());
326             break;
327         case GL_DEPTH_STENCIL_TEXTURE_MODE:
328             *params =
329                 CastFromGLintStateValue<ParamType>(pname, texture->getDepthStencilTextureMode());
330             break;
331         case GL_TEXTURE_CROP_RECT_OES:
332         {
333             const gl::Rectangle &crop = texture->getCrop();
334             params[0]                 = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.x);
335             params[1]                 = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.y);
336             params[2] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.width);
337             params[3] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.height);
338             break;
339         }
340         case GL_GENERATE_MIPMAP:
341             *params = CastFromGLintStateValue<ParamType>(pname, texture->getGenerateMipmapHint());
342             break;
343         case GL_MEMORY_SIZE_ANGLE:
344             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMemorySize());
345             break;
346         case GL_TEXTURE_BORDER_COLOR:
347             ConvertFromColor<isPureInteger>(texture->getBorderColor(), params);
348             break;
349         case GL_TEXTURE_NATIVE_ID_ANGLE:
350             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getNativeID());
351             break;
352         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
353             *params = CastFromGLintStateValue<ParamType>(
354                 pname, texture->getImplementationColorReadFormat(context));
355             break;
356         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
357             *params = CastFromGLintStateValue<ParamType>(
358                 pname, texture->getImplementationColorReadType(context));
359             break;
360         case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
361             *params =
362                 CastFromGLintStateValue<ParamType>(pname, GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE);
363             break;
364         case GL_RESOURCE_INITIALIZED_ANGLE:
365             *params = CastFromGLintStateValue<ParamType>(
366                 pname, texture->initState() == InitState::Initialized);
367             break;
368         case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
369             *params = CastFromGLintStateValue<ParamType>(
370                 pname, texture->getRequiredTextureImageUnits(context));
371             break;
372         case GL_TEXTURE_PROTECTED_EXT:
373             *params = CastFromGLintStateValue<ParamType>(pname, texture->hasProtectedContent());
374             break;
375         default:
376             UNREACHABLE();
377             break;
378     }
379 }
380 
381 // this function is needed to handle OES_FIXED_POINT.
382 // Some pname values can take in GLfixed values and may need to be converted
383 template <bool isGLfixed, typename ReturnType, typename ParamType>
ConvertTexParam(GLenum pname,const ParamType param)384 ReturnType ConvertTexParam(GLenum pname, const ParamType param)
385 {
386     if (isGLfixed)
387     {
388         return CastQueryValueTo<ReturnType>(pname,
389                                             ConvertFixedToFloat(static_cast<GLfixed>(param)));
390     }
391     else
392     {
393         return CastQueryValueTo<ReturnType>(pname, param);
394     }
395 }
396 
397 template <bool isPureInteger, bool isGLfixed, typename ParamType>
SetTexParameterBase(Context * context,Texture * texture,GLenum pname,const ParamType * params)398 void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ParamType *params)
399 {
400     ASSERT(texture != nullptr);
401 
402     switch (pname)
403     {
404         case GL_TEXTURE_WRAP_S:
405             texture->setWrapS(context, ConvertToGLenum(pname, params[0]));
406             break;
407         case GL_TEXTURE_WRAP_T:
408             texture->setWrapT(context, ConvertToGLenum(pname, params[0]));
409             break;
410         case GL_TEXTURE_WRAP_R:
411             texture->setWrapR(context, ConvertToGLenum(pname, params[0]));
412             break;
413         case GL_TEXTURE_MIN_FILTER:
414             texture->setMinFilter(context, ConvertToGLenum(pname, params[0]));
415             break;
416         case GL_TEXTURE_MAG_FILTER:
417             texture->setMagFilter(context, ConvertToGLenum(pname, params[0]));
418             break;
419         case GL_TEXTURE_USAGE_ANGLE:
420             texture->setUsage(context, ConvertToGLenum(pname, params[0]));
421             break;
422         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
423             texture->setMaxAnisotropy(context,
424                                       ConvertTexParam<isGLfixed, GLfloat>(pname, params[0]));
425             break;
426         case GL_TEXTURE_COMPARE_MODE:
427             texture->setCompareMode(context, ConvertToGLenum(pname, params[0]));
428             break;
429         case GL_TEXTURE_COMPARE_FUNC:
430             texture->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
431             break;
432         case GL_TEXTURE_SWIZZLE_R:
433             texture->setSwizzleRed(context, ConvertToGLenum(pname, params[0]));
434             break;
435         case GL_TEXTURE_SWIZZLE_G:
436             texture->setSwizzleGreen(context, ConvertToGLenum(pname, params[0]));
437             break;
438         case GL_TEXTURE_SWIZZLE_B:
439             texture->setSwizzleBlue(context, ConvertToGLenum(pname, params[0]));
440             break;
441         case GL_TEXTURE_SWIZZLE_A:
442             texture->setSwizzleAlpha(context, ConvertToGLenum(pname, params[0]));
443             break;
444         case GL_TEXTURE_BASE_LEVEL:
445         {
446             (void)(texture->setBaseLevel(
447                 context, clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0]))));
448             break;
449         }
450         case GL_TEXTURE_MAX_LEVEL:
451             texture->setMaxLevel(context,
452                                  clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0])));
453             break;
454         case GL_TEXTURE_MIN_LOD:
455             texture->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
456             break;
457         case GL_TEXTURE_MAX_LOD:
458             texture->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
459             break;
460         case GL_DEPTH_STENCIL_TEXTURE_MODE:
461             texture->setDepthStencilTextureMode(context, ConvertToGLenum(pname, params[0]));
462             break;
463         case GL_TEXTURE_SRGB_DECODE_EXT:
464             texture->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
465             break;
466         case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
467             texture->setSRGBOverride(context, ConvertToGLenum(pname, params[0]));
468             break;
469         case GL_TEXTURE_CROP_RECT_OES:
470             texture->setCrop(gl::Rectangle(ConvertTexParam<isGLfixed, GLint>(pname, params[0]),
471                                            ConvertTexParam<isGLfixed, GLint>(pname, params[1]),
472                                            ConvertTexParam<isGLfixed, GLint>(pname, params[2]),
473                                            ConvertTexParam<isGLfixed, GLint>(pname, params[3])));
474             break;
475         case GL_GENERATE_MIPMAP:
476             texture->setGenerateMipmapHint(ConvertToGLenum(params[0]));
477             break;
478         case GL_TEXTURE_BORDER_COLOR:
479             texture->setBorderColor(context, ConvertToColor<isPureInteger>(params));
480             break;
481         case GL_RESOURCE_INITIALIZED_ANGLE:
482             texture->setInitState(ConvertToBool(params[0]) ? InitState::Initialized
483                                                            : InitState::MayNeedInit);
484             break;
485         case GL_TEXTURE_PROTECTED_EXT:
486             texture->setProtectedContent(context, (params[0] == GL_TRUE));
487             break;
488         default:
489             UNREACHABLE();
490             break;
491     }
492 }
493 
494 template <bool isPureInteger, typename ParamType>
QuerySamplerParameterBase(const Sampler * sampler,GLenum pname,ParamType * params)495 void QuerySamplerParameterBase(const Sampler *sampler, GLenum pname, ParamType *params)
496 {
497     switch (pname)
498     {
499         case GL_TEXTURE_MIN_FILTER:
500             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMinFilter());
501             break;
502         case GL_TEXTURE_MAG_FILTER:
503             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMagFilter());
504             break;
505         case GL_TEXTURE_WRAP_S:
506             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapS());
507             break;
508         case GL_TEXTURE_WRAP_T:
509             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapT());
510             break;
511         case GL_TEXTURE_WRAP_R:
512             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapR());
513             break;
514         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
515             *params = CastFromStateValue<ParamType>(pname, sampler->getMaxAnisotropy());
516             break;
517         case GL_TEXTURE_MIN_LOD:
518             *params = CastFromStateValue<ParamType>(pname, sampler->getMinLod());
519             break;
520         case GL_TEXTURE_MAX_LOD:
521             *params = CastFromStateValue<ParamType>(pname, sampler->getMaxLod());
522             break;
523         case GL_TEXTURE_COMPARE_MODE:
524             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareMode());
525             break;
526         case GL_TEXTURE_COMPARE_FUNC:
527             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareFunc());
528             break;
529         case GL_TEXTURE_SRGB_DECODE_EXT:
530             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getSRGBDecode());
531             break;
532         case GL_TEXTURE_BORDER_COLOR:
533             ConvertFromColor<isPureInteger>(sampler->getBorderColor(), params);
534             break;
535         default:
536             UNREACHABLE();
537             break;
538     }
539 }
540 
541 template <bool isPureInteger, typename ParamType>
SetSamplerParameterBase(Context * context,Sampler * sampler,GLenum pname,const ParamType * params)542 void SetSamplerParameterBase(Context *context,
543                              Sampler *sampler,
544                              GLenum pname,
545                              const ParamType *params)
546 {
547     switch (pname)
548     {
549         case GL_TEXTURE_WRAP_S:
550             sampler->setWrapS(context, ConvertToGLenum(pname, params[0]));
551             break;
552         case GL_TEXTURE_WRAP_T:
553             sampler->setWrapT(context, ConvertToGLenum(pname, params[0]));
554             break;
555         case GL_TEXTURE_WRAP_R:
556             sampler->setWrapR(context, ConvertToGLenum(pname, params[0]));
557             break;
558         case GL_TEXTURE_MIN_FILTER:
559             sampler->setMinFilter(context, ConvertToGLenum(pname, params[0]));
560             break;
561         case GL_TEXTURE_MAG_FILTER:
562             sampler->setMagFilter(context, ConvertToGLenum(pname, params[0]));
563             break;
564         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
565             sampler->setMaxAnisotropy(context, CastQueryValueTo<GLfloat>(pname, params[0]));
566             break;
567         case GL_TEXTURE_COMPARE_MODE:
568             sampler->setCompareMode(context, ConvertToGLenum(pname, params[0]));
569             break;
570         case GL_TEXTURE_COMPARE_FUNC:
571             sampler->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
572             break;
573         case GL_TEXTURE_MIN_LOD:
574             sampler->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
575             break;
576         case GL_TEXTURE_MAX_LOD:
577             sampler->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
578             break;
579         case GL_TEXTURE_SRGB_DECODE_EXT:
580             sampler->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
581             break;
582         case GL_TEXTURE_BORDER_COLOR:
583             sampler->setBorderColor(context, ConvertToColor<isPureInteger>(params));
584             break;
585         default:
586             UNREACHABLE();
587             break;
588     }
589 
590     sampler->onStateChange(angle::SubjectMessage::ContentsChanged);
591 }
592 
593 // Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
594 template <typename ParamType, typename CurrentDataType, size_t CurrentValueCount>
QueryVertexAttribBase(const VertexAttribute & attrib,const VertexBinding & binding,const CurrentDataType (& currentValueData)[CurrentValueCount],GLenum pname,ParamType * params)595 void QueryVertexAttribBase(const VertexAttribute &attrib,
596                            const VertexBinding &binding,
597                            const CurrentDataType (&currentValueData)[CurrentValueCount],
598                            GLenum pname,
599                            ParamType *params)
600 {
601     switch (pname)
602     {
603         case GL_CURRENT_VERTEX_ATTRIB:
604             for (size_t i = 0; i < CurrentValueCount; ++i)
605             {
606                 params[i] = CastFromStateValue<ParamType>(pname, currentValueData[i]);
607             }
608             break;
609         case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
610             *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.enabled));
611             break;
612         case GL_VERTEX_ATTRIB_ARRAY_SIZE:
613             *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->channelCount);
614             break;
615         case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
616             *params = CastFromGLintStateValue<ParamType>(pname, attrib.vertexAttribArrayStride);
617             break;
618         case GL_VERTEX_ATTRIB_ARRAY_TYPE:
619             *params = CastFromGLintStateValue<ParamType>(
620                 pname, gl::ToGLenum(attrib.format->vertexAttribType));
621             break;
622         case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
623             *params =
624                 CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.format->isNorm()));
625             break;
626         case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
627             *params = CastFromGLintStateValue<ParamType>(pname, binding.getBuffer().id().value);
628             break;
629         case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
630             *params = CastFromStateValue<ParamType>(pname, binding.getDivisor());
631             break;
632         case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
633             *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->isPureInt());
634             break;
635         case GL_VERTEX_ATTRIB_BINDING:
636             *params = CastFromGLintStateValue<ParamType>(pname, attrib.bindingIndex);
637             break;
638         case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
639             *params = CastFromGLintStateValue<ParamType>(pname, attrib.relativeOffset);
640             break;
641         default:
642             UNREACHABLE();
643             break;
644     }
645 }
646 
647 template <typename ParamType>
QueryBufferParameterBase(const Buffer * buffer,GLenum pname,ParamType * params)648 void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params)
649 {
650     ASSERT(buffer != nullptr);
651 
652     switch (pname)
653     {
654         case GL_BUFFER_USAGE:
655             *params = CastFromGLintStateValue<ParamType>(pname, ToGLenum(buffer->getUsage()));
656             break;
657         case GL_BUFFER_SIZE:
658             *params = CastFromStateValue<ParamType>(pname, buffer->getSize());
659             break;
660         case GL_BUFFER_ACCESS_FLAGS:
661             *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccessFlags());
662             break;
663         case GL_BUFFER_ACCESS_OES:
664             *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccess());
665             break;
666         case GL_BUFFER_MAPPED:
667             *params = CastFromStateValue<ParamType>(pname, buffer->isMapped());
668             break;
669         case GL_BUFFER_MAP_OFFSET:
670             *params = CastFromStateValue<ParamType>(pname, buffer->getMapOffset());
671             break;
672         case GL_BUFFER_MAP_LENGTH:
673             *params = CastFromStateValue<ParamType>(pname, buffer->getMapLength());
674             break;
675         case GL_MEMORY_SIZE_ANGLE:
676             *params = CastFromStateValue<ParamType>(pname, buffer->getMemorySize());
677             break;
678         case GL_BUFFER_IMMUTABLE_STORAGE_EXT:
679             *params = CastFromStateValue<ParamType>(pname, buffer->isImmutable());
680             break;
681         case GL_BUFFER_STORAGE_FLAGS_EXT:
682             *params = CastFromGLintStateValue<ParamType>(pname, buffer->getStorageExtUsageFlags());
683             break;
684         case GL_RESOURCE_INITIALIZED_ANGLE:
685             *params = CastFromStateValue<ParamType>(
686                 pname, ConvertToGLBoolean(buffer->initState() == InitState::Initialized));
687             break;
688         default:
689             UNREACHABLE();
690             break;
691     }
692 }
693 
GetCommonVariableProperty(const sh::ShaderVariable & var,GLenum prop)694 GLint GetCommonVariableProperty(const sh::ShaderVariable &var, GLenum prop)
695 {
696     switch (prop)
697     {
698         case GL_TYPE:
699             return clampCast<GLint>(var.type);
700 
701         case GL_ARRAY_SIZE:
702             // Queryable variables are guaranteed not to be arrays of arrays or arrays of structs,
703             // see GLES 3.1 spec section 7.3.1.1 page 77.
704             return clampCast<GLint>(var.getBasicTypeElementCount());
705 
706         case GL_NAME_LENGTH:
707             // ES31 spec p84: This counts the terminating null char.
708             return clampCast<GLint>(var.name.size() + 1u);
709 
710         default:
711             UNREACHABLE();
712             return GL_INVALID_VALUE;
713     }
714 }
715 
GetInputResourceProperty(const Program * program,GLuint index,GLenum prop)716 GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop)
717 {
718     const sh::ShaderVariable &variable = program->getInputResource(index);
719 
720     switch (prop)
721     {
722         case GL_TYPE:
723         case GL_ARRAY_SIZE:
724             return GetCommonVariableProperty(variable, prop);
725 
726         case GL_NAME_LENGTH:
727             return clampCast<GLint>(program->getInputResourceName(index).size() + 1u);
728 
729         case GL_LOCATION:
730             return variable.isBuiltIn() ? GL_INVALID_INDEX : variable.location;
731 
732         // The query is targeted at the set of active input variables used by the first shader stage
733         // of program. If program contains multiple shader stages then input variables from any
734         // stage other than the first will not be enumerated. Since we found the variable to get
735         // this far, we know it exists in the first attached shader stage.
736         case GL_REFERENCED_BY_VERTEX_SHADER:
737             return program->getState().getFirstAttachedShaderStageType() == ShaderType::Vertex;
738         case GL_REFERENCED_BY_FRAGMENT_SHADER:
739             return program->getState().getFirstAttachedShaderStageType() == ShaderType::Fragment;
740         case GL_REFERENCED_BY_COMPUTE_SHADER:
741             return program->getState().getFirstAttachedShaderStageType() == ShaderType::Compute;
742         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
743             return program->getState().getFirstAttachedShaderStageType() == ShaderType::Geometry;
744         case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
745             return program->getState().getFirstAttachedShaderStageType() == ShaderType::TessControl;
746         case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
747             return program->getState().getFirstAttachedShaderStageType() ==
748                    ShaderType::TessEvaluation;
749         case GL_IS_PER_PATCH_EXT:
750             return variable.isPatch;
751 
752         default:
753             UNREACHABLE();
754             return GL_INVALID_VALUE;
755     }
756 }
757 
GetOutputResourceProperty(const Program * program,GLuint index,const GLenum prop)758 GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLenum prop)
759 {
760     const sh::ShaderVariable &outputVariable = program->getOutputResource(index);
761 
762     switch (prop)
763     {
764         case GL_TYPE:
765         case GL_ARRAY_SIZE:
766             return GetCommonVariableProperty(outputVariable, prop);
767 
768         case GL_NAME_LENGTH:
769             return clampCast<GLint>(program->getOutputResourceName(index).size() + 1u);
770 
771         case GL_LOCATION:
772             return outputVariable.location;
773 
774         case GL_LOCATION_INDEX_EXT:
775             // EXT_blend_func_extended
776             if (program->getState().getLastAttachedShaderStageType() == gl::ShaderType::Fragment)
777             {
778                 return program->getFragDataIndex(outputVariable.name);
779             }
780             return GL_INVALID_INDEX;
781 
782         // The set of active user-defined outputs from the final shader stage in this program. If
783         // the final stage is a Fragment Shader, then this represents the fragment outputs that get
784         // written to individual color buffers. If the program only contains a Compute Shader, then
785         // there are no user-defined outputs.
786         case GL_REFERENCED_BY_VERTEX_SHADER:
787             return program->getState().getLastAttachedShaderStageType() == ShaderType::Vertex;
788         case GL_REFERENCED_BY_FRAGMENT_SHADER:
789             return program->getState().getLastAttachedShaderStageType() == ShaderType::Fragment;
790         case GL_REFERENCED_BY_COMPUTE_SHADER:
791             return program->getState().getLastAttachedShaderStageType() == ShaderType::Compute;
792         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
793             return program->getState().getLastAttachedShaderStageType() == ShaderType::Geometry;
794         case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
795             return program->getState().getLastAttachedShaderStageType() == ShaderType::TessControl;
796         case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
797             return program->getState().getLastAttachedShaderStageType() ==
798                    ShaderType::TessEvaluation;
799         case GL_IS_PER_PATCH_EXT:
800             return outputVariable.isPatch;
801 
802         default:
803             UNREACHABLE();
804             return GL_INVALID_VALUE;
805     }
806 }
807 
GetTransformFeedbackVaryingResourceProperty(const Program * program,GLuint index,const GLenum prop)808 GLint GetTransformFeedbackVaryingResourceProperty(const Program *program,
809                                                   GLuint index,
810                                                   const GLenum prop)
811 {
812     const auto &tfVariable = program->getTransformFeedbackVaryingResource(index);
813     switch (prop)
814     {
815         case GL_TYPE:
816             return clampCast<GLint>(tfVariable.type);
817 
818         case GL_ARRAY_SIZE:
819             return clampCast<GLint>(tfVariable.size());
820 
821         case GL_NAME_LENGTH:
822             return clampCast<GLint>(tfVariable.nameWithArrayIndex().size() + 1);
823 
824         default:
825             UNREACHABLE();
826             return GL_INVALID_VALUE;
827     }
828 }
829 
QueryProgramInterfaceActiveResources(const Program * program,GLenum programInterface)830 GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface)
831 {
832     switch (programInterface)
833     {
834         case GL_PROGRAM_INPUT:
835             return clampCast<GLint>(program->getState().getProgramInputs().size());
836 
837         case GL_PROGRAM_OUTPUT:
838             return clampCast<GLint>(program->getState().getOutputVariables().size());
839 
840         case GL_UNIFORM:
841             return clampCast<GLint>(program->getState().getUniforms().size());
842 
843         case GL_UNIFORM_BLOCK:
844             return clampCast<GLint>(program->getState().getUniformBlocks().size());
845 
846         case GL_ATOMIC_COUNTER_BUFFER:
847             return clampCast<GLint>(program->getState().getAtomicCounterBuffers().size());
848 
849         case GL_BUFFER_VARIABLE:
850             return clampCast<GLint>(program->getState().getBufferVariables().size());
851 
852         case GL_SHADER_STORAGE_BLOCK:
853             return clampCast<GLint>(program->getState().getShaderStorageBlocks().size());
854 
855         case GL_TRANSFORM_FEEDBACK_VARYING:
856             return clampCast<GLint>(program->getTransformFeedbackVaryingCount());
857 
858         default:
859             UNREACHABLE();
860             return 0;
861     }
862 }
863 
864 template <typename T, typename M>
FindMaxSize(const std::vector<T> & resources,M member)865 GLint FindMaxSize(const std::vector<T> &resources, M member)
866 {
867     GLint max = 0;
868     for (const T &resource : resources)
869     {
870         max = std::max(max, clampCast<GLint>((resource.*member).size()));
871     }
872     return max;
873 }
874 
QueryProgramInterfaceMaxNameLength(const Program * program,GLenum programInterface)875 GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programInterface)
876 {
877     GLint maxNameLength = 0;
878     switch (programInterface)
879     {
880         case GL_PROGRAM_INPUT:
881             maxNameLength = program->getInputResourceMaxNameSize();
882             break;
883 
884         case GL_PROGRAM_OUTPUT:
885             maxNameLength = program->getOutputResourceMaxNameSize();
886             break;
887 
888         case GL_UNIFORM:
889             maxNameLength = FindMaxSize(program->getState().getUniforms(), &LinkedUniform::name);
890             break;
891 
892         case GL_UNIFORM_BLOCK:
893             return program->getActiveUniformBlockMaxNameLength();
894 
895         case GL_BUFFER_VARIABLE:
896             maxNameLength =
897                 FindMaxSize(program->getState().getBufferVariables(), &BufferVariable::name);
898             break;
899 
900         case GL_SHADER_STORAGE_BLOCK:
901             return program->getActiveShaderStorageBlockMaxNameLength();
902 
903         case GL_TRANSFORM_FEEDBACK_VARYING:
904             return clampCast<GLint>(program->getTransformFeedbackVaryingMaxLength());
905 
906         default:
907             UNREACHABLE();
908             return 0;
909     }
910     // This length includes an extra character for the null terminator.
911     return (maxNameLength == 0 ? 0 : maxNameLength + 1);
912 }
913 
QueryProgramInterfaceMaxNumActiveVariables(const Program * program,GLenum programInterface)914 GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum programInterface)
915 {
916     switch (programInterface)
917     {
918         case GL_UNIFORM_BLOCK:
919             return FindMaxSize(program->getState().getUniformBlocks(),
920                                &InterfaceBlock::memberIndexes);
921         case GL_ATOMIC_COUNTER_BUFFER:
922             return FindMaxSize(program->getState().getAtomicCounterBuffers(),
923                                &AtomicCounterBuffer::memberIndexes);
924 
925         case GL_SHADER_STORAGE_BLOCK:
926             return FindMaxSize(program->getState().getShaderStorageBlocks(),
927                                &InterfaceBlock::memberIndexes);
928 
929         default:
930             UNREACHABLE();
931             return 0;
932     }
933 }
934 
GetUniformPropertyEnum(GLenum prop)935 GLenum GetUniformPropertyEnum(GLenum prop)
936 {
937     switch (prop)
938     {
939         case GL_UNIFORM_TYPE:
940             return GL_TYPE;
941         case GL_UNIFORM_SIZE:
942             return GL_ARRAY_SIZE;
943         case GL_UNIFORM_NAME_LENGTH:
944             return GL_NAME_LENGTH;
945         case GL_UNIFORM_BLOCK_INDEX:
946             return GL_BLOCK_INDEX;
947         case GL_UNIFORM_OFFSET:
948             return GL_OFFSET;
949         case GL_UNIFORM_ARRAY_STRIDE:
950             return GL_ARRAY_STRIDE;
951         case GL_UNIFORM_MATRIX_STRIDE:
952             return GL_MATRIX_STRIDE;
953         case GL_UNIFORM_IS_ROW_MAJOR:
954             return GL_IS_ROW_MAJOR;
955 
956         default:
957             return prop;
958     }
959 }
960 
GetUniformBlockPropertyEnum(GLenum prop)961 GLenum GetUniformBlockPropertyEnum(GLenum prop)
962 {
963     switch (prop)
964     {
965         case GL_UNIFORM_BLOCK_BINDING:
966             return GL_BUFFER_BINDING;
967 
968         case GL_UNIFORM_BLOCK_DATA_SIZE:
969             return GL_BUFFER_DATA_SIZE;
970 
971         case GL_UNIFORM_BLOCK_NAME_LENGTH:
972             return GL_NAME_LENGTH;
973 
974         case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
975             return GL_NUM_ACTIVE_VARIABLES;
976 
977         case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
978             return GL_ACTIVE_VARIABLES;
979 
980         case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
981             return GL_REFERENCED_BY_VERTEX_SHADER;
982 
983         case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
984             return GL_REFERENCED_BY_FRAGMENT_SHADER;
985 
986         default:
987             return prop;
988     }
989 }
990 
GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer & buffer,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)991 void GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer &buffer,
992                                              GLenum pname,
993                                              GLint *params,
994                                              GLsizei bufSize,
995                                              GLsizei *outputPosition)
996 
997 {
998     switch (pname)
999     {
1000         case GL_BUFFER_BINDING:
1001             params[(*outputPosition)++] = buffer.binding;
1002             break;
1003         case GL_BUFFER_DATA_SIZE:
1004             params[(*outputPosition)++] = clampCast<GLint>(buffer.dataSize);
1005             break;
1006         case GL_NUM_ACTIVE_VARIABLES:
1007             params[(*outputPosition)++] = buffer.numActiveVariables();
1008             break;
1009         case GL_ACTIVE_VARIABLES:
1010             for (size_t memberIndex = 0;
1011                  memberIndex < buffer.memberIndexes.size() && *outputPosition < bufSize;
1012                  ++memberIndex)
1013             {
1014                 params[(*outputPosition)++] = clampCast<GLint>(buffer.memberIndexes[memberIndex]);
1015             }
1016             break;
1017         case GL_REFERENCED_BY_VERTEX_SHADER:
1018             params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Vertex));
1019             break;
1020         case GL_REFERENCED_BY_FRAGMENT_SHADER:
1021             params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Fragment));
1022             break;
1023         case GL_REFERENCED_BY_COMPUTE_SHADER:
1024             params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Compute));
1025             break;
1026         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
1027             params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Geometry));
1028             break;
1029         case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
1030             params[(*outputPosition)++] =
1031                 static_cast<GLint>(buffer.isActive(ShaderType::TessControl));
1032             break;
1033         case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
1034             params[(*outputPosition)++] =
1035                 static_cast<GLint>(buffer.isActive(ShaderType::TessEvaluation));
1036             break;
1037         default:
1038             UNREACHABLE();
1039             break;
1040     }
1041 }
1042 
GetInterfaceBlockResourceProperty(const InterfaceBlock & block,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)1043 void GetInterfaceBlockResourceProperty(const InterfaceBlock &block,
1044                                        GLenum pname,
1045                                        GLint *params,
1046                                        GLsizei bufSize,
1047                                        GLsizei *outputPosition)
1048 {
1049     if (pname == GL_NAME_LENGTH)
1050     {
1051         params[(*outputPosition)++] = clampCast<GLint>(block.nameWithArrayIndex().size() + 1);
1052         return;
1053     }
1054     GetShaderVariableBufferResourceProperty(block, pname, params, bufSize, outputPosition);
1055 }
1056 
GetUniformBlockResourceProperty(const Program * program,GLuint blockIndex,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)1057 void GetUniformBlockResourceProperty(const Program *program,
1058                                      GLuint blockIndex,
1059                                      GLenum pname,
1060                                      GLint *params,
1061                                      GLsizei bufSize,
1062                                      GLsizei *outputPosition)
1063 
1064 {
1065     ASSERT(*outputPosition < bufSize);
1066     const auto &block = program->getUniformBlockByIndex(blockIndex);
1067     GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
1068 }
1069 
GetShaderStorageBlockResourceProperty(const Program * program,GLuint blockIndex,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)1070 void GetShaderStorageBlockResourceProperty(const Program *program,
1071                                            GLuint blockIndex,
1072                                            GLenum pname,
1073                                            GLint *params,
1074                                            GLsizei bufSize,
1075                                            GLsizei *outputPosition)
1076 
1077 {
1078     ASSERT(*outputPosition < bufSize);
1079     const auto &block = program->getShaderStorageBlockByIndex(blockIndex);
1080     GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
1081 }
1082 
GetAtomicCounterBufferResourceProperty(const Program * program,GLuint index,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)1083 void GetAtomicCounterBufferResourceProperty(const Program *program,
1084                                             GLuint index,
1085                                             GLenum pname,
1086                                             GLint *params,
1087                                             GLsizei bufSize,
1088                                             GLsizei *outputPosition)
1089 
1090 {
1091     ASSERT(*outputPosition < bufSize);
1092     const auto &buffer = program->getState().getAtomicCounterBuffers()[index];
1093     GetShaderVariableBufferResourceProperty(buffer, pname, params, bufSize, outputPosition);
1094 }
1095 
IsTextureEnvEnumParameter(TextureEnvParameter pname)1096 bool IsTextureEnvEnumParameter(TextureEnvParameter pname)
1097 {
1098     switch (pname)
1099     {
1100         case TextureEnvParameter::Mode:
1101         case TextureEnvParameter::CombineRgb:
1102         case TextureEnvParameter::CombineAlpha:
1103         case TextureEnvParameter::Src0Rgb:
1104         case TextureEnvParameter::Src1Rgb:
1105         case TextureEnvParameter::Src2Rgb:
1106         case TextureEnvParameter::Src0Alpha:
1107         case TextureEnvParameter::Src1Alpha:
1108         case TextureEnvParameter::Src2Alpha:
1109         case TextureEnvParameter::Op0Rgb:
1110         case TextureEnvParameter::Op1Rgb:
1111         case TextureEnvParameter::Op2Rgb:
1112         case TextureEnvParameter::Op0Alpha:
1113         case TextureEnvParameter::Op1Alpha:
1114         case TextureEnvParameter::Op2Alpha:
1115         case TextureEnvParameter::PointCoordReplace:
1116             return true;
1117         default:
1118             return false;
1119     }
1120 }
1121 
GetShaderProgramId(ProgramPipeline * programPipeline,ShaderType shaderType,GLint * params)1122 void GetShaderProgramId(ProgramPipeline *programPipeline, ShaderType shaderType, GLint *params)
1123 {
1124     ASSERT(params);
1125 
1126     *params = 0;
1127     if (programPipeline)
1128     {
1129         const Program *program = programPipeline->getShaderProgram(shaderType);
1130         if (program)
1131         {
1132             *params = program->id().value;
1133         }
1134     }
1135 }
1136 
1137 }  // namespace
1138 
QueryFramebufferAttachmentParameteriv(const Context * context,const Framebuffer * framebuffer,GLenum attachment,GLenum pname,GLint * params)1139 void QueryFramebufferAttachmentParameteriv(const Context *context,
1140                                            const Framebuffer *framebuffer,
1141                                            GLenum attachment,
1142                                            GLenum pname,
1143                                            GLint *params)
1144 {
1145     ASSERT(framebuffer);
1146 
1147     const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
1148 
1149     if (attachmentObject == nullptr)
1150     {
1151         // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
1152         // is NONE, then querying any other pname will generate INVALID_ENUM.
1153 
1154         // ES 3.0.2 spec pg 235 states that if the attachment type is none,
1155         // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
1156         // INVALID_OPERATION for all other pnames
1157 
1158         switch (pname)
1159         {
1160             case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1161                 *params = GL_NONE;
1162                 break;
1163 
1164             case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1165                 *params = 0;
1166                 break;
1167 
1168             default:
1169                 UNREACHABLE();
1170                 break;
1171         }
1172 
1173         return;
1174     }
1175 
1176     switch (pname)
1177     {
1178         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1179             *params = attachmentObject->type();
1180             break;
1181 
1182         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1183             *params = attachmentObject->id();
1184             break;
1185 
1186         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
1187             *params = attachmentObject->mipLevel();
1188             break;
1189 
1190         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
1191         {
1192             TextureTarget face = attachmentObject->cubeMapFace();
1193             if (face != TextureTarget::InvalidEnum)
1194             {
1195                 *params = ToGLenum(attachmentObject->cubeMapFace());
1196             }
1197             else
1198             {
1199                 // This happens when the attachment isn't a texture cube map face
1200                 *params = GL_NONE;
1201             }
1202         }
1203         break;
1204 
1205         case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
1206             *params = attachmentObject->getRedSize();
1207             break;
1208 
1209         case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
1210             *params = attachmentObject->getGreenSize();
1211             break;
1212 
1213         case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
1214             *params = attachmentObject->getBlueSize();
1215             break;
1216 
1217         case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
1218             *params = attachmentObject->getAlphaSize();
1219             break;
1220 
1221         case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
1222             *params = attachmentObject->getDepthSize();
1223             break;
1224 
1225         case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
1226             *params = attachmentObject->getStencilSize();
1227             break;
1228 
1229         case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
1230             *params = attachmentObject->getComponentType();
1231             break;
1232 
1233         case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
1234             *params = attachmentObject->getColorEncoding();
1235             break;
1236 
1237         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
1238             *params = attachmentObject->layer();
1239             break;
1240 
1241         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
1242             *params = attachmentObject->getNumViews();
1243             break;
1244 
1245         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
1246             *params = attachmentObject->getBaseViewIndex();
1247             break;
1248 
1249         case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
1250             *params = attachmentObject->isLayered();
1251             break;
1252 
1253         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT:
1254             if (attachmentObject->type() == GL_TEXTURE)
1255             {
1256                 *params = attachmentObject->getSamples();
1257             }
1258             else
1259             {
1260                 *params = 0;
1261             }
1262             break;
1263 
1264         default:
1265             UNREACHABLE();
1266             break;
1267     }
1268 }
1269 
QueryBufferParameteriv(const Buffer * buffer,GLenum pname,GLint * params)1270 void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params)
1271 {
1272     QueryBufferParameterBase(buffer, pname, params);
1273 }
1274 
QueryBufferParameteri64v(const Buffer * buffer,GLenum pname,GLint64 * params)1275 void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params)
1276 {
1277     QueryBufferParameterBase(buffer, pname, params);
1278 }
1279 
QueryBufferPointerv(const Buffer * buffer,GLenum pname,void ** params)1280 void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params)
1281 {
1282     switch (pname)
1283     {
1284         case GL_BUFFER_MAP_POINTER:
1285             *params = buffer->getMapPointer();
1286             break;
1287 
1288         default:
1289             UNREACHABLE();
1290             break;
1291     }
1292 }
1293 
QueryProgramiv(Context * context,const Program * program,GLenum pname,GLint * params)1294 void QueryProgramiv(Context *context, const Program *program, GLenum pname, GLint *params)
1295 {
1296     ASSERT(program != nullptr || pname == GL_COMPLETION_STATUS_KHR);
1297 
1298     switch (pname)
1299     {
1300         case GL_DELETE_STATUS:
1301             *params = program->isFlaggedForDeletion();
1302             return;
1303         case GL_LINK_STATUS:
1304             *params = program->isLinked();
1305             return;
1306         case GL_COMPLETION_STATUS_KHR:
1307             if (context->isContextLost())
1308             {
1309                 *params = GL_TRUE;
1310             }
1311             else
1312             {
1313                 *params = program->isLinking() ? GL_FALSE : GL_TRUE;
1314             }
1315             return;
1316         case GL_VALIDATE_STATUS:
1317             *params = program->isValidated();
1318             return;
1319         case GL_INFO_LOG_LENGTH:
1320             *params = program->getExecutable().getInfoLogLength();
1321             return;
1322         case GL_ATTACHED_SHADERS:
1323             *params = program->getAttachedShadersCount();
1324             return;
1325         case GL_ACTIVE_ATTRIBUTES:
1326             *params = program->getActiveAttributeCount();
1327             return;
1328         case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1329             *params = program->getActiveAttributeMaxLength();
1330             return;
1331         case GL_ACTIVE_UNIFORMS:
1332             *params = program->getActiveUniformCount();
1333             return;
1334         case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1335             *params = program->getActiveUniformMaxLength();
1336             return;
1337         case GL_PROGRAM_BINARY_LENGTH_OES:
1338             *params = context->getCaps().programBinaryFormats.empty()
1339                           ? 0
1340                           : program->getBinaryLength(context);
1341             return;
1342         case GL_ACTIVE_UNIFORM_BLOCKS:
1343             *params = program->getActiveUniformBlockCount();
1344             return;
1345         case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
1346             *params = program->getActiveUniformBlockMaxNameLength();
1347             break;
1348         case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
1349             *params = program->getTransformFeedbackBufferMode();
1350             break;
1351         case GL_TRANSFORM_FEEDBACK_VARYINGS:
1352             *params = clampCast<GLint>(program->getTransformFeedbackVaryingCount());
1353             break;
1354         case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
1355             *params = program->getTransformFeedbackVaryingMaxLength();
1356             break;
1357         case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1358             *params = program->getBinaryRetrievableHint();
1359             break;
1360         case GL_PROGRAM_SEPARABLE:
1361             // From es31cSeparateShaderObjsTests.cpp:
1362             // ProgramParameteri PROGRAM_SEPARABLE
1363             // NOTE: The query for PROGRAM_SEPARABLE must query latched
1364             //       state. In other words, the state of the binary after
1365             //       it was linked. So in the tests below, the queries
1366             //       should return the default state GL_FALSE since the
1367             //       program has no linked binary.
1368             *params = program->isSeparable() && program->isLinked();
1369             break;
1370         case GL_COMPUTE_WORK_GROUP_SIZE:
1371         {
1372             const sh::WorkGroupSize &localSize = program->getComputeShaderLocalSize();
1373             params[0]                          = localSize[0];
1374             params[1]                          = localSize[1];
1375             params[2]                          = localSize[2];
1376         }
1377         break;
1378         case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
1379             *params = program->getActiveAtomicCounterBufferCount();
1380             break;
1381         case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
1382             *params = ToGLenum(program->getGeometryShaderInputPrimitiveType());
1383             break;
1384         case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
1385             *params = ToGLenum(program->getGeometryShaderOutputPrimitiveType());
1386             break;
1387         case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
1388             *params = program->getGeometryShaderMaxVertices();
1389             break;
1390         case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
1391             *params = program->getGeometryShaderInvocations();
1392             break;
1393         case GL_TESS_CONTROL_OUTPUT_VERTICES_EXT:
1394             *params = program->getTessControlShaderVertices();
1395             break;
1396         case GL_TESS_GEN_MODE_EXT:
1397             *params = program->getTessGenMode();
1398             break;
1399         case GL_TESS_GEN_SPACING_EXT:
1400             *params = program->getTessGenSpacing() ? program->getTessGenSpacing() : GL_EQUAL;
1401             break;
1402         case GL_TESS_GEN_VERTEX_ORDER:
1403             *params = program->getTessGenVertexOrder() ? program->getTessGenVertexOrder() : GL_CCW;
1404             break;
1405         case GL_TESS_GEN_POINT_MODE_EXT:
1406             *params = program->getTessGenPointMode() ? GL_TRUE : GL_FALSE;
1407             break;
1408         default:
1409             UNREACHABLE();
1410             break;
1411     }
1412 }
1413 
QueryRenderbufferiv(const Context * context,const Renderbuffer * renderbuffer,GLenum pname,GLint * params)1414 void QueryRenderbufferiv(const Context *context,
1415                          const Renderbuffer *renderbuffer,
1416                          GLenum pname,
1417                          GLint *params)
1418 {
1419     ASSERT(renderbuffer != nullptr);
1420 
1421     switch (pname)
1422     {
1423         case GL_RENDERBUFFER_WIDTH:
1424             *params = renderbuffer->getWidth();
1425             break;
1426         case GL_RENDERBUFFER_HEIGHT:
1427             *params = renderbuffer->getHeight();
1428             break;
1429         case GL_RENDERBUFFER_INTERNAL_FORMAT:
1430             // Special case the WebGL 1 DEPTH_STENCIL format.
1431             if (context->isWebGL1() &&
1432                 renderbuffer->getFormat().info->internalFormat == GL_DEPTH24_STENCIL8)
1433             {
1434                 *params = GL_DEPTH_STENCIL;
1435             }
1436             else
1437             {
1438                 *params = renderbuffer->getFormat().info->internalFormat;
1439             }
1440             break;
1441         case GL_RENDERBUFFER_RED_SIZE:
1442             *params = renderbuffer->getRedSize();
1443             break;
1444         case GL_RENDERBUFFER_GREEN_SIZE:
1445             *params = renderbuffer->getGreenSize();
1446             break;
1447         case GL_RENDERBUFFER_BLUE_SIZE:
1448             *params = renderbuffer->getBlueSize();
1449             break;
1450         case GL_RENDERBUFFER_ALPHA_SIZE:
1451             *params = renderbuffer->getAlphaSize();
1452             break;
1453         case GL_RENDERBUFFER_DEPTH_SIZE:
1454             *params = renderbuffer->getDepthSize();
1455             break;
1456         case GL_RENDERBUFFER_STENCIL_SIZE:
1457             *params = renderbuffer->getStencilSize();
1458             break;
1459         case GL_RENDERBUFFER_SAMPLES_ANGLE:
1460             *params = renderbuffer->getState().getSamples();
1461             break;
1462         case GL_MEMORY_SIZE_ANGLE:
1463             *params = renderbuffer->getMemorySize();
1464             break;
1465         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1466             *params = static_cast<GLint>(renderbuffer->getImplementationColorReadFormat(context));
1467             break;
1468         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1469             *params = static_cast<GLint>(renderbuffer->getImplementationColorReadType(context));
1470             break;
1471         case GL_RESOURCE_INITIALIZED_ANGLE:
1472             *params = (renderbuffer->initState(ImageIndex()) == InitState::Initialized);
1473             break;
1474         default:
1475             UNREACHABLE();
1476             break;
1477     }
1478 }
1479 
QueryShaderiv(const Context * context,Shader * shader,GLenum pname,GLint * params)1480 void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params)
1481 {
1482     ASSERT(shader != nullptr || pname == GL_COMPLETION_STATUS_KHR);
1483 
1484     switch (pname)
1485     {
1486         case GL_SHADER_TYPE:
1487             *params = static_cast<GLint>(ToGLenum(shader->getType()));
1488             return;
1489         case GL_DELETE_STATUS:
1490             *params = shader->isFlaggedForDeletion();
1491             return;
1492         case GL_COMPILE_STATUS:
1493             *params = shader->isCompiled() ? GL_TRUE : GL_FALSE;
1494             return;
1495         case GL_COMPLETION_STATUS_KHR:
1496             if (context->isContextLost())
1497             {
1498                 *params = GL_TRUE;
1499             }
1500             else
1501             {
1502                 *params = shader->isCompleted() ? GL_TRUE : GL_FALSE;
1503             }
1504             return;
1505         case GL_INFO_LOG_LENGTH:
1506             *params = shader->getInfoLogLength();
1507             return;
1508         case GL_SHADER_SOURCE_LENGTH:
1509             *params = shader->getSourceLength();
1510             return;
1511         case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
1512             *params = shader->getTranslatedSourceWithDebugInfoLength();
1513             return;
1514         default:
1515             UNREACHABLE();
1516             break;
1517     }
1518 }
1519 
QueryTexLevelParameterfv(const Texture * texture,TextureTarget target,GLint level,GLenum pname,GLfloat * params)1520 void QueryTexLevelParameterfv(const Texture *texture,
1521                               TextureTarget target,
1522                               GLint level,
1523                               GLenum pname,
1524                               GLfloat *params)
1525 {
1526     QueryTexLevelParameterBase(texture, target, level, pname, params);
1527 }
1528 
QueryTexLevelParameteriv(const Texture * texture,TextureTarget target,GLint level,GLenum pname,GLint * params)1529 void QueryTexLevelParameteriv(const Texture *texture,
1530                               TextureTarget target,
1531                               GLint level,
1532                               GLenum pname,
1533                               GLint *params)
1534 {
1535     QueryTexLevelParameterBase(texture, target, level, pname, params);
1536 }
1537 
QueryTexParameterfv(const Context * context,const Texture * texture,GLenum pname,GLfloat * params)1538 void QueryTexParameterfv(const Context *context,
1539                          const Texture *texture,
1540                          GLenum pname,
1541                          GLfloat *params)
1542 {
1543     QueryTexParameterBase<false, false>(context, texture, pname, params);
1544 }
1545 
QueryTexParameterxv(const Context * context,const Texture * texture,GLenum pname,GLfixed * params)1546 void QueryTexParameterxv(const Context *context,
1547                          const Texture *texture,
1548                          GLenum pname,
1549                          GLfixed *params)
1550 {
1551     QueryTexParameterBase<false, true>(context, texture, pname, params);
1552 }
1553 
QueryTexParameteriv(const Context * context,const Texture * texture,GLenum pname,GLint * params)1554 void QueryTexParameteriv(const Context *context,
1555                          const Texture *texture,
1556                          GLenum pname,
1557                          GLint *params)
1558 {
1559     QueryTexParameterBase<false, false>(context, texture, pname, params);
1560 }
1561 
QueryTexParameterIiv(const Context * context,const Texture * texture,GLenum pname,GLint * params)1562 void QueryTexParameterIiv(const Context *context,
1563                           const Texture *texture,
1564                           GLenum pname,
1565                           GLint *params)
1566 {
1567     QueryTexParameterBase<true, false>(context, texture, pname, params);
1568 }
1569 
QueryTexParameterIuiv(const Context * context,const Texture * texture,GLenum pname,GLuint * params)1570 void QueryTexParameterIuiv(const Context *context,
1571                            const Texture *texture,
1572                            GLenum pname,
1573                            GLuint *params)
1574 {
1575     QueryTexParameterBase<true, false>(context, texture, pname, params);
1576 }
1577 
QuerySamplerParameterfv(const Sampler * sampler,GLenum pname,GLfloat * params)1578 void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params)
1579 {
1580     QuerySamplerParameterBase<false>(sampler, pname, params);
1581 }
1582 
QuerySamplerParameteriv(const Sampler * sampler,GLenum pname,GLint * params)1583 void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params)
1584 {
1585     QuerySamplerParameterBase<false>(sampler, pname, params);
1586 }
1587 
QuerySamplerParameterIiv(const Sampler * sampler,GLenum pname,GLint * params)1588 void QuerySamplerParameterIiv(const Sampler *sampler, GLenum pname, GLint *params)
1589 {
1590     QuerySamplerParameterBase<true>(sampler, pname, params);
1591 }
1592 
QuerySamplerParameterIuiv(const Sampler * sampler,GLenum pname,GLuint * params)1593 void QuerySamplerParameterIuiv(const Sampler *sampler, GLenum pname, GLuint *params)
1594 {
1595     QuerySamplerParameterBase<true>(sampler, pname, params);
1596 }
1597 
QueryVertexAttribfv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLfloat * params)1598 void QueryVertexAttribfv(const VertexAttribute &attrib,
1599                          const VertexBinding &binding,
1600                          const VertexAttribCurrentValueData &currentValueData,
1601                          GLenum pname,
1602                          GLfloat *params)
1603 {
1604     QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
1605 }
1606 
QueryVertexAttribiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLint * params)1607 void QueryVertexAttribiv(const VertexAttribute &attrib,
1608                          const VertexBinding &binding,
1609                          const VertexAttribCurrentValueData &currentValueData,
1610                          GLenum pname,
1611                          GLint *params)
1612 {
1613     QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
1614 }
1615 
QueryVertexAttribPointerv(const VertexAttribute & attrib,GLenum pname,void ** pointer)1616 void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer)
1617 {
1618     switch (pname)
1619     {
1620         case GL_VERTEX_ATTRIB_ARRAY_POINTER:
1621             *pointer = const_cast<void *>(attrib.pointer);
1622             break;
1623 
1624         default:
1625             UNREACHABLE();
1626             break;
1627     }
1628 }
1629 
QueryVertexAttribIiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLint * params)1630 void QueryVertexAttribIiv(const VertexAttribute &attrib,
1631                           const VertexBinding &binding,
1632                           const VertexAttribCurrentValueData &currentValueData,
1633                           GLenum pname,
1634                           GLint *params)
1635 {
1636     QueryVertexAttribBase(attrib, binding, currentValueData.Values.IntValues, pname, params);
1637 }
1638 
QueryVertexAttribIuiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLuint * params)1639 void QueryVertexAttribIuiv(const VertexAttribute &attrib,
1640                            const VertexBinding &binding,
1641                            const VertexAttribCurrentValueData &currentValueData,
1642                            GLenum pname,
1643                            GLuint *params)
1644 {
1645     QueryVertexAttribBase(attrib, binding, currentValueData.Values.UnsignedIntValues, pname,
1646                           params);
1647 }
1648 
QueryActiveUniformBlockiv(const Program * program,UniformBlockIndex uniformBlockIndex,GLenum pname,GLint * params)1649 void QueryActiveUniformBlockiv(const Program *program,
1650                                UniformBlockIndex uniformBlockIndex,
1651                                GLenum pname,
1652                                GLint *params)
1653 {
1654     GLenum prop = GetUniformBlockPropertyEnum(pname);
1655     QueryProgramResourceiv(program, GL_UNIFORM_BLOCK, uniformBlockIndex, 1, &prop,
1656                            std::numeric_limits<GLsizei>::max(), nullptr, params);
1657 }
1658 
QueryInternalFormativ(const TextureCaps & format,GLenum pname,GLsizei bufSize,GLint * params)1659 void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params)
1660 {
1661     switch (pname)
1662     {
1663         case GL_NUM_SAMPLE_COUNTS:
1664             if (bufSize != 0)
1665             {
1666                 *params = clampCast<GLint>(format.sampleCounts.size());
1667             }
1668             break;
1669 
1670         case GL_SAMPLES:
1671         {
1672             size_t returnCount   = std::min<size_t>(bufSize, format.sampleCounts.size());
1673             auto sampleReverseIt = format.sampleCounts.rbegin();
1674             for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex)
1675             {
1676                 params[sampleIndex] = *sampleReverseIt++;
1677             }
1678         }
1679         break;
1680 
1681         default:
1682             UNREACHABLE();
1683             break;
1684     }
1685 }
1686 
QueryFramebufferParameteriv(const Framebuffer * framebuffer,GLenum pname,GLint * params)1687 void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params)
1688 {
1689     ASSERT(framebuffer);
1690 
1691     switch (pname)
1692     {
1693         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1694             *params = framebuffer->getDefaultWidth();
1695             break;
1696         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1697             *params = framebuffer->getDefaultHeight();
1698             break;
1699         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1700             *params = framebuffer->getDefaultSamples();
1701             break;
1702         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1703             *params = ConvertToGLBoolean(framebuffer->getDefaultFixedSampleLocations());
1704             break;
1705         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1706             *params = framebuffer->getDefaultLayers();
1707             break;
1708         case GL_FRAMEBUFFER_FLIP_Y_MESA:
1709             *params = ConvertToGLBoolean(framebuffer->getFlipY());
1710             break;
1711         default:
1712             UNREACHABLE();
1713             break;
1714     }
1715 }
1716 
QuerySynciv(const Context * context,const Sync * sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)1717 angle::Result QuerySynciv(const Context *context,
1718                           const Sync *sync,
1719                           GLenum pname,
1720                           GLsizei bufSize,
1721                           GLsizei *length,
1722                           GLint *values)
1723 {
1724     ASSERT(sync != nullptr || pname == GL_SYNC_STATUS);
1725 
1726     // All queries return one value, exit early if the buffer can't fit anything.
1727     if (bufSize < 1)
1728     {
1729         if (length != nullptr)
1730         {
1731             *length = 0;
1732         }
1733         return angle::Result::Continue;
1734     }
1735 
1736     switch (pname)
1737     {
1738         case GL_OBJECT_TYPE:
1739             *values = clampCast<GLint>(GL_SYNC_FENCE);
1740             break;
1741         case GL_SYNC_CONDITION:
1742             *values = clampCast<GLint>(sync->getCondition());
1743             break;
1744         case GL_SYNC_FLAGS:
1745             *values = clampCast<GLint>(sync->getFlags());
1746             break;
1747         case GL_SYNC_STATUS:
1748             if (context->isContextLost())
1749             {
1750                 *values = GL_SIGNALED;
1751             }
1752             else
1753             {
1754                 ANGLE_TRY(sync->getStatus(context, values));
1755             }
1756             break;
1757 
1758         default:
1759             UNREACHABLE();
1760             break;
1761     }
1762 
1763     if (length != nullptr)
1764     {
1765         *length = 1;
1766     }
1767 
1768     return angle::Result::Continue;
1769 }
1770 
SetTexParameterx(Context * context,Texture * texture,GLenum pname,GLfixed param)1771 void SetTexParameterx(Context *context, Texture *texture, GLenum pname, GLfixed param)
1772 {
1773     SetTexParameterBase<false, true>(context, texture, pname, &param);
1774 }
1775 
SetTexParameterxv(Context * context,Texture * texture,GLenum pname,const GLfixed * params)1776 void SetTexParameterxv(Context *context, Texture *texture, GLenum pname, const GLfixed *params)
1777 {
1778     SetTexParameterBase<false, true>(context, texture, pname, params);
1779 }
1780 
SetTexParameterf(Context * context,Texture * texture,GLenum pname,GLfloat param)1781 void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param)
1782 {
1783     SetTexParameterBase<false, false>(context, texture, pname, &param);
1784 }
1785 
SetTexParameterfv(Context * context,Texture * texture,GLenum pname,const GLfloat * params)1786 void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params)
1787 {
1788     SetTexParameterBase<false, false>(context, texture, pname, params);
1789 }
1790 
SetTexParameteri(Context * context,Texture * texture,GLenum pname,GLint param)1791 void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param)
1792 {
1793     SetTexParameterBase<false, false>(context, texture, pname, &param);
1794 }
1795 
SetTexParameteriv(Context * context,Texture * texture,GLenum pname,const GLint * params)1796 void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params)
1797 {
1798     SetTexParameterBase<false, false>(context, texture, pname, params);
1799 }
1800 
SetTexParameterIiv(Context * context,Texture * texture,GLenum pname,const GLint * params)1801 void SetTexParameterIiv(Context *context, Texture *texture, GLenum pname, const GLint *params)
1802 {
1803     SetTexParameterBase<true, false>(context, texture, pname, params);
1804 }
1805 
SetTexParameterIuiv(Context * context,Texture * texture,GLenum pname,const GLuint * params)1806 void SetTexParameterIuiv(Context *context, Texture *texture, GLenum pname, const GLuint *params)
1807 {
1808     SetTexParameterBase<true, false>(context, texture, pname, params);
1809 }
1810 
SetSamplerParameterf(Context * context,Sampler * sampler,GLenum pname,GLfloat param)1811 void SetSamplerParameterf(Context *context, Sampler *sampler, GLenum pname, GLfloat param)
1812 {
1813     SetSamplerParameterBase<false>(context, sampler, pname, &param);
1814 }
1815 
SetSamplerParameterfv(Context * context,Sampler * sampler,GLenum pname,const GLfloat * params)1816 void SetSamplerParameterfv(Context *context, Sampler *sampler, GLenum pname, const GLfloat *params)
1817 {
1818     SetSamplerParameterBase<false>(context, sampler, pname, params);
1819 }
1820 
SetSamplerParameteri(Context * context,Sampler * sampler,GLenum pname,GLint param)1821 void SetSamplerParameteri(Context *context, Sampler *sampler, GLenum pname, GLint param)
1822 {
1823     SetSamplerParameterBase<false>(context, sampler, pname, &param);
1824 }
1825 
SetSamplerParameteriv(Context * context,Sampler * sampler,GLenum pname,const GLint * params)1826 void SetSamplerParameteriv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
1827 {
1828     SetSamplerParameterBase<false>(context, sampler, pname, params);
1829 }
1830 
SetSamplerParameterIiv(Context * context,Sampler * sampler,GLenum pname,const GLint * params)1831 void SetSamplerParameterIiv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
1832 {
1833     SetSamplerParameterBase<true>(context, sampler, pname, params);
1834 }
1835 
SetSamplerParameterIuiv(Context * context,Sampler * sampler,GLenum pname,const GLuint * params)1836 void SetSamplerParameterIuiv(Context *context, Sampler *sampler, GLenum pname, const GLuint *params)
1837 {
1838     SetSamplerParameterBase<true>(context, sampler, pname, params);
1839 }
1840 
SetFramebufferParameteri(const Context * context,Framebuffer * framebuffer,GLenum pname,GLint param)1841 void SetFramebufferParameteri(const Context *context,
1842                               Framebuffer *framebuffer,
1843                               GLenum pname,
1844                               GLint param)
1845 {
1846     ASSERT(framebuffer);
1847 
1848     switch (pname)
1849     {
1850         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1851             framebuffer->setDefaultWidth(context, param);
1852             break;
1853         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1854             framebuffer->setDefaultHeight(context, param);
1855             break;
1856         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1857             framebuffer->setDefaultSamples(context, param);
1858             break;
1859         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1860             framebuffer->setDefaultFixedSampleLocations(context, ConvertToBool(param));
1861             break;
1862         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1863             framebuffer->setDefaultLayers(param);
1864             break;
1865         case GL_FRAMEBUFFER_FLIP_Y_MESA:
1866             framebuffer->setFlipY(ConvertToBool(param));
1867             break;
1868         default:
1869             UNREACHABLE();
1870             break;
1871     }
1872 }
1873 
SetProgramParameteri(Program * program,GLenum pname,GLint value)1874 void SetProgramParameteri(Program *program, GLenum pname, GLint value)
1875 {
1876     ASSERT(program);
1877 
1878     switch (pname)
1879     {
1880         case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1881             program->setBinaryRetrievableHint(ConvertToBool(value));
1882             break;
1883         case GL_PROGRAM_SEPARABLE:
1884             program->setSeparable(ConvertToBool(value));
1885             break;
1886         default:
1887             UNREACHABLE();
1888             break;
1889     }
1890 }
1891 
GetUniformResourceProperty(const Program * program,GLuint index,const GLenum prop)1892 GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop)
1893 {
1894     const auto &uniform = program->getUniformByIndex(index);
1895     GLenum resourceProp = GetUniformPropertyEnum(prop);
1896     switch (resourceProp)
1897     {
1898         case GL_TYPE:
1899         case GL_ARRAY_SIZE:
1900         case GL_NAME_LENGTH:
1901             return GetCommonVariableProperty(uniform, resourceProp);
1902 
1903         case GL_LOCATION:
1904             return program->getUniformLocation(uniform.name).value;
1905 
1906         case GL_BLOCK_INDEX:
1907             return (uniform.isAtomicCounter() ? -1 : uniform.bufferIndex);
1908 
1909         case GL_OFFSET:
1910             return uniform.blockInfo.offset;
1911 
1912         case GL_ARRAY_STRIDE:
1913             return uniform.blockInfo.arrayStride;
1914 
1915         case GL_MATRIX_STRIDE:
1916             return uniform.blockInfo.matrixStride;
1917 
1918         case GL_IS_ROW_MAJOR:
1919             return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
1920 
1921         case GL_REFERENCED_BY_VERTEX_SHADER:
1922             return uniform.isActive(ShaderType::Vertex);
1923 
1924         case GL_REFERENCED_BY_FRAGMENT_SHADER:
1925             return uniform.isActive(ShaderType::Fragment);
1926 
1927         case GL_REFERENCED_BY_COMPUTE_SHADER:
1928             return uniform.isActive(ShaderType::Compute);
1929 
1930         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
1931             return uniform.isActive(ShaderType::Geometry);
1932 
1933         case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
1934             return uniform.isActive(ShaderType::TessControl);
1935 
1936         case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
1937             return uniform.isActive(ShaderType::TessEvaluation);
1938 
1939         case GL_ATOMIC_COUNTER_BUFFER_INDEX:
1940             return (uniform.isAtomicCounter() ? uniform.bufferIndex : -1);
1941 
1942         default:
1943             UNREACHABLE();
1944             return 0;
1945     }
1946 }
1947 
GetBufferVariableResourceProperty(const Program * program,GLuint index,const GLenum prop)1948 GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop)
1949 {
1950     const BufferVariable &bufferVariable = program->getBufferVariableByIndex(index);
1951     switch (prop)
1952     {
1953         case GL_TYPE:
1954         case GL_ARRAY_SIZE:
1955         case GL_NAME_LENGTH:
1956             return GetCommonVariableProperty(bufferVariable, prop);
1957 
1958         case GL_BLOCK_INDEX:
1959             return bufferVariable.bufferIndex;
1960 
1961         case GL_OFFSET:
1962             return bufferVariable.blockInfo.offset;
1963 
1964         case GL_ARRAY_STRIDE:
1965             return bufferVariable.blockInfo.arrayStride;
1966 
1967         case GL_MATRIX_STRIDE:
1968             return bufferVariable.blockInfo.matrixStride;
1969 
1970         case GL_IS_ROW_MAJOR:
1971             return static_cast<GLint>(bufferVariable.blockInfo.isRowMajorMatrix);
1972 
1973         case GL_REFERENCED_BY_VERTEX_SHADER:
1974             return bufferVariable.isActive(ShaderType::Vertex);
1975 
1976         case GL_REFERENCED_BY_FRAGMENT_SHADER:
1977             return bufferVariable.isActive(ShaderType::Fragment);
1978 
1979         case GL_REFERENCED_BY_COMPUTE_SHADER:
1980             return bufferVariable.isActive(ShaderType::Compute);
1981 
1982         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
1983             return bufferVariable.isActive(ShaderType::Geometry);
1984 
1985         case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
1986             return bufferVariable.isActive(ShaderType::TessControl);
1987 
1988         case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
1989             return bufferVariable.isActive(ShaderType::TessEvaluation);
1990 
1991         case GL_TOP_LEVEL_ARRAY_SIZE:
1992             return bufferVariable.topLevelArraySize;
1993 
1994         case GL_TOP_LEVEL_ARRAY_STRIDE:
1995             return bufferVariable.blockInfo.topLevelArrayStride;
1996 
1997         default:
1998             UNREACHABLE();
1999             return 0;
2000     }
2001 }
2002 
QueryProgramResourceIndex(const Program * program,GLenum programInterface,const GLchar * name)2003 GLuint QueryProgramResourceIndex(const Program *program,
2004                                  GLenum programInterface,
2005                                  const GLchar *name)
2006 {
2007     switch (programInterface)
2008     {
2009         case GL_PROGRAM_INPUT:
2010             return program->getInputResourceIndex(name);
2011 
2012         case GL_PROGRAM_OUTPUT:
2013             return program->getOutputResourceIndex(name);
2014 
2015         case GL_UNIFORM:
2016             return program->getState().getUniformIndexFromName(name);
2017 
2018         case GL_BUFFER_VARIABLE:
2019             return program->getState().getBufferVariableIndexFromName(name);
2020 
2021         case GL_SHADER_STORAGE_BLOCK:
2022             return program->getShaderStorageBlockIndex(name);
2023 
2024         case GL_UNIFORM_BLOCK:
2025             return program->getUniformBlockIndex(name);
2026 
2027         case GL_TRANSFORM_FEEDBACK_VARYING:
2028             return program->getTransformFeedbackVaryingResourceIndex(name);
2029 
2030         default:
2031             UNREACHABLE();
2032             return GL_INVALID_INDEX;
2033     }
2034 }
2035 
QueryProgramResourceName(const Program * program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,GLchar * name)2036 void QueryProgramResourceName(const Program *program,
2037                               GLenum programInterface,
2038                               GLuint index,
2039                               GLsizei bufSize,
2040                               GLsizei *length,
2041                               GLchar *name)
2042 {
2043     switch (programInterface)
2044     {
2045         case GL_PROGRAM_INPUT:
2046             program->getInputResourceName(index, bufSize, length, name);
2047             break;
2048 
2049         case GL_PROGRAM_OUTPUT:
2050             program->getOutputResourceName(index, bufSize, length, name);
2051             break;
2052 
2053         case GL_UNIFORM:
2054             program->getUniformResourceName(index, bufSize, length, name);
2055             break;
2056 
2057         case GL_BUFFER_VARIABLE:
2058             program->getBufferVariableResourceName(index, bufSize, length, name);
2059             break;
2060 
2061         case GL_SHADER_STORAGE_BLOCK:
2062             program->getActiveShaderStorageBlockName(index, bufSize, length, name);
2063             break;
2064 
2065         case GL_UNIFORM_BLOCK:
2066             program->getActiveUniformBlockName({index}, bufSize, length, name);
2067             break;
2068 
2069         case GL_TRANSFORM_FEEDBACK_VARYING:
2070             program->getTransformFeedbackVarying(index, bufSize, length, nullptr, nullptr, name);
2071             break;
2072 
2073         default:
2074             UNREACHABLE();
2075     }
2076 }
2077 
QueryProgramResourceLocation(const Program * program,GLenum programInterface,const GLchar * name)2078 GLint QueryProgramResourceLocation(const Program *program,
2079                                    GLenum programInterface,
2080                                    const GLchar *name)
2081 {
2082     switch (programInterface)
2083     {
2084         case GL_PROGRAM_INPUT:
2085             return program->getInputResourceLocation(name);
2086 
2087         case GL_PROGRAM_OUTPUT:
2088             return program->getOutputResourceLocation(name);
2089 
2090         case GL_UNIFORM:
2091             return program->getUniformLocation(name).value;
2092 
2093         default:
2094             UNREACHABLE();
2095             return -1;
2096     }
2097 }
2098 
QueryProgramResourceiv(const Program * program,GLenum programInterface,UniformBlockIndex index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)2099 void QueryProgramResourceiv(const Program *program,
2100                             GLenum programInterface,
2101                             UniformBlockIndex index,
2102                             GLsizei propCount,
2103                             const GLenum *props,
2104                             GLsizei bufSize,
2105                             GLsizei *length,
2106                             GLint *params)
2107 {
2108     if (!program->isLinked())
2109     {
2110         return;
2111     }
2112 
2113     if (length != nullptr)
2114     {
2115         *length = 0;
2116     }
2117 
2118     if (bufSize == 0)
2119     {
2120         // No room to write the results
2121         return;
2122     }
2123 
2124     GLsizei pos = 0;
2125     for (GLsizei i = 0; i < propCount; i++)
2126     {
2127         switch (programInterface)
2128         {
2129             case GL_PROGRAM_INPUT:
2130                 params[i] = GetInputResourceProperty(program, index.value, props[i]);
2131                 ++pos;
2132                 break;
2133 
2134             case GL_PROGRAM_OUTPUT:
2135                 params[i] = GetOutputResourceProperty(program, index.value, props[i]);
2136                 ++pos;
2137                 break;
2138 
2139             case GL_UNIFORM:
2140                 params[i] = GetUniformResourceProperty(program, index.value, props[i]);
2141                 ++pos;
2142                 break;
2143 
2144             case GL_BUFFER_VARIABLE:
2145                 params[i] = GetBufferVariableResourceProperty(program, index.value, props[i]);
2146                 ++pos;
2147                 break;
2148 
2149             case GL_UNIFORM_BLOCK:
2150                 GetUniformBlockResourceProperty(program, index.value, props[i], params, bufSize,
2151                                                 &pos);
2152                 break;
2153 
2154             case GL_SHADER_STORAGE_BLOCK:
2155                 GetShaderStorageBlockResourceProperty(program, index.value, props[i], params,
2156                                                       bufSize, &pos);
2157                 break;
2158 
2159             case GL_ATOMIC_COUNTER_BUFFER:
2160                 GetAtomicCounterBufferResourceProperty(program, index.value, props[i], params,
2161                                                        bufSize, &pos);
2162                 break;
2163 
2164             case GL_TRANSFORM_FEEDBACK_VARYING:
2165                 params[i] =
2166                     GetTransformFeedbackVaryingResourceProperty(program, index.value, props[i]);
2167                 ++pos;
2168                 break;
2169 
2170             default:
2171                 UNREACHABLE();
2172                 params[i] = GL_INVALID_VALUE;
2173         }
2174         if (pos == bufSize)
2175         {
2176             // Most properties return one value, but GL_ACTIVE_VARIABLES returns an array of values.
2177             // This checks not to break buffer bounds for such case.
2178             break;
2179         }
2180     }
2181 
2182     if (length != nullptr)
2183     {
2184         *length = pos;
2185     }
2186 }
2187 
QueryProgramInterfaceiv(const Program * program,GLenum programInterface,GLenum pname,GLint * params)2188 void QueryProgramInterfaceiv(const Program *program,
2189                              GLenum programInterface,
2190                              GLenum pname,
2191                              GLint *params)
2192 {
2193     switch (pname)
2194     {
2195         case GL_ACTIVE_RESOURCES:
2196             *params = QueryProgramInterfaceActiveResources(program, programInterface);
2197             break;
2198 
2199         case GL_MAX_NAME_LENGTH:
2200             *params = QueryProgramInterfaceMaxNameLength(program, programInterface);
2201             break;
2202 
2203         case GL_MAX_NUM_ACTIVE_VARIABLES:
2204             *params = QueryProgramInterfaceMaxNumActiveVariables(program, programInterface);
2205             break;
2206 
2207         default:
2208             UNREACHABLE();
2209     }
2210 }
2211 
SetMemoryObjectParameteriv(const Context * context,MemoryObject * memoryObject,GLenum pname,const GLint * params)2212 angle::Result SetMemoryObjectParameteriv(const Context *context,
2213                                          MemoryObject *memoryObject,
2214                                          GLenum pname,
2215                                          const GLint *params)
2216 {
2217     switch (pname)
2218     {
2219         case GL_DEDICATED_MEMORY_OBJECT_EXT:
2220             ANGLE_TRY(memoryObject->setDedicatedMemory(context, ConvertToBool(params[0])));
2221             break;
2222 
2223         case GL_PROTECTED_MEMORY_OBJECT_EXT:
2224             ANGLE_TRY(memoryObject->setProtectedMemory(context, ConvertToBool(params[0])));
2225             break;
2226 
2227         default:
2228             UNREACHABLE();
2229     }
2230 
2231     return angle::Result::Continue;
2232 }
2233 
QueryMemoryObjectParameteriv(const MemoryObject * memoryObject,GLenum pname,GLint * params)2234 void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname, GLint *params)
2235 {
2236     switch (pname)
2237     {
2238         case GL_DEDICATED_MEMORY_OBJECT_EXT:
2239             *params = memoryObject->isDedicatedMemory();
2240             break;
2241 
2242         case GL_PROTECTED_MEMORY_OBJECT_EXT:
2243             *params = memoryObject->isProtectedMemory();
2244             break;
2245 
2246         default:
2247             UNREACHABLE();
2248     }
2249 }
2250 
ParamToVertexArrayType(GLenum param)2251 ClientVertexArrayType ParamToVertexArrayType(GLenum param)
2252 {
2253     switch (param)
2254     {
2255         case GL_VERTEX_ARRAY:
2256         case GL_VERTEX_ARRAY_BUFFER_BINDING:
2257         case GL_VERTEX_ARRAY_STRIDE:
2258         case GL_VERTEX_ARRAY_SIZE:
2259         case GL_VERTEX_ARRAY_TYPE:
2260         case GL_VERTEX_ARRAY_POINTER:
2261             return ClientVertexArrayType::Vertex;
2262         case GL_NORMAL_ARRAY:
2263         case GL_NORMAL_ARRAY_BUFFER_BINDING:
2264         case GL_NORMAL_ARRAY_STRIDE:
2265         case GL_NORMAL_ARRAY_TYPE:
2266         case GL_NORMAL_ARRAY_POINTER:
2267             return ClientVertexArrayType::Normal;
2268         case GL_COLOR_ARRAY:
2269         case GL_COLOR_ARRAY_BUFFER_BINDING:
2270         case GL_COLOR_ARRAY_STRIDE:
2271         case GL_COLOR_ARRAY_SIZE:
2272         case GL_COLOR_ARRAY_TYPE:
2273         case GL_COLOR_ARRAY_POINTER:
2274             return ClientVertexArrayType::Color;
2275         case GL_POINT_SIZE_ARRAY_OES:
2276         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2277         case GL_POINT_SIZE_ARRAY_STRIDE_OES:
2278         case GL_POINT_SIZE_ARRAY_TYPE_OES:
2279         case GL_POINT_SIZE_ARRAY_POINTER_OES:
2280             return ClientVertexArrayType::PointSize;
2281         case GL_TEXTURE_COORD_ARRAY:
2282         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2283         case GL_TEXTURE_COORD_ARRAY_STRIDE:
2284         case GL_TEXTURE_COORD_ARRAY_SIZE:
2285         case GL_TEXTURE_COORD_ARRAY_TYPE:
2286         case GL_TEXTURE_COORD_ARRAY_POINTER:
2287             return ClientVertexArrayType::TextureCoord;
2288         default:
2289             UNREACHABLE();
2290             return ClientVertexArrayType::InvalidEnum;
2291     }
2292 }
2293 
SetLightModelParameters(GLES1State * state,GLenum pname,const GLfloat * params)2294 void SetLightModelParameters(GLES1State *state, GLenum pname, const GLfloat *params)
2295 {
2296     LightModelParameters &lightModel = state->lightModelParameters();
2297 
2298     switch (pname)
2299     {
2300         case GL_LIGHT_MODEL_AMBIENT:
2301             lightModel.color = ColorF::fromData(params);
2302             break;
2303         case GL_LIGHT_MODEL_TWO_SIDE:
2304             lightModel.twoSided = *params == 1.0f ? true : false;
2305             break;
2306         default:
2307             break;
2308     }
2309 }
2310 
GetLightModelParameters(const GLES1State * state,GLenum pname,GLfloat * params)2311 void GetLightModelParameters(const GLES1State *state, GLenum pname, GLfloat *params)
2312 {
2313     const LightModelParameters &lightModel = state->lightModelParameters();
2314 
2315     switch (pname)
2316     {
2317         case GL_LIGHT_MODEL_TWO_SIDE:
2318             *params = lightModel.twoSided ? 1.0f : 0.0f;
2319             break;
2320         case GL_LIGHT_MODEL_AMBIENT:
2321             lightModel.color.writeData(params);
2322             break;
2323         default:
2324             break;
2325     }
2326 }
2327 
IsLightModelTwoSided(const GLES1State * state)2328 bool IsLightModelTwoSided(const GLES1State *state)
2329 {
2330     return state->lightModelParameters().twoSided;
2331 }
2332 
SetLightParameters(GLES1State * state,GLenum light,LightParameter pname,const GLfloat * params)2333 void SetLightParameters(GLES1State *state,
2334                         GLenum light,
2335                         LightParameter pname,
2336                         const GLfloat *params)
2337 {
2338     uint32_t lightIndex = light - GL_LIGHT0;
2339 
2340     LightParameters &lightParams = state->lightParameters(lightIndex);
2341 
2342     switch (pname)
2343     {
2344         case LightParameter::Ambient:
2345             lightParams.ambient = ColorF::fromData(params);
2346             break;
2347         case LightParameter::Diffuse:
2348             lightParams.diffuse = ColorF::fromData(params);
2349             break;
2350         case LightParameter::Specular:
2351             lightParams.specular = ColorF::fromData(params);
2352             break;
2353         case LightParameter::Position:
2354         {
2355             angle::Mat4 mv = state->getModelviewMatrix();
2356             angle::Vector4 transformedPos =
2357                 mv.product(angle::Vector4(params[0], params[1], params[2], params[3]));
2358             lightParams.position[0] = transformedPos[0];
2359             lightParams.position[1] = transformedPos[1];
2360             lightParams.position[2] = transformedPos[2];
2361             lightParams.position[3] = transformedPos[3];
2362         }
2363         break;
2364         case LightParameter::SpotDirection:
2365         {
2366             angle::Mat4 mv = state->getModelviewMatrix();
2367             angle::Vector4 transformedPos =
2368                 mv.product(angle::Vector4(params[0], params[1], params[2], 0.0f));
2369             lightParams.direction[0] = transformedPos[0];
2370             lightParams.direction[1] = transformedPos[1];
2371             lightParams.direction[2] = transformedPos[2];
2372         }
2373         break;
2374         case LightParameter::SpotExponent:
2375             lightParams.spotlightExponent = *params;
2376             break;
2377         case LightParameter::SpotCutoff:
2378             lightParams.spotlightCutoffAngle = *params;
2379             break;
2380         case LightParameter::ConstantAttenuation:
2381             lightParams.attenuationConst = *params;
2382             break;
2383         case LightParameter::LinearAttenuation:
2384             lightParams.attenuationLinear = *params;
2385             break;
2386         case LightParameter::QuadraticAttenuation:
2387             lightParams.attenuationQuadratic = *params;
2388             break;
2389         default:
2390             return;
2391     }
2392 }
2393 
GetLightParameters(const GLES1State * state,GLenum light,LightParameter pname,GLfloat * params)2394 void GetLightParameters(const GLES1State *state,
2395                         GLenum light,
2396                         LightParameter pname,
2397                         GLfloat *params)
2398 {
2399     uint32_t lightIndex                = light - GL_LIGHT0;
2400     const LightParameters &lightParams = state->lightParameters(lightIndex);
2401 
2402     switch (pname)
2403     {
2404         case LightParameter::Ambient:
2405             lightParams.ambient.writeData(params);
2406             break;
2407         case LightParameter::Diffuse:
2408             lightParams.diffuse.writeData(params);
2409             break;
2410         case LightParameter::Specular:
2411             lightParams.specular.writeData(params);
2412             break;
2413         case LightParameter::Position:
2414             memcpy(params, lightParams.position.data(), 4 * sizeof(GLfloat));
2415             break;
2416         case LightParameter::SpotDirection:
2417             memcpy(params, lightParams.direction.data(), 3 * sizeof(GLfloat));
2418             break;
2419         case LightParameter::SpotExponent:
2420             *params = lightParams.spotlightExponent;
2421             break;
2422         case LightParameter::SpotCutoff:
2423             *params = lightParams.spotlightCutoffAngle;
2424             break;
2425         case LightParameter::ConstantAttenuation:
2426             *params = lightParams.attenuationConst;
2427             break;
2428         case LightParameter::LinearAttenuation:
2429             *params = lightParams.attenuationLinear;
2430             break;
2431         case LightParameter::QuadraticAttenuation:
2432             *params = lightParams.attenuationQuadratic;
2433             break;
2434         default:
2435             break;
2436     }
2437 }
2438 
SetMaterialParameters(GLES1State * state,GLenum face,MaterialParameter pname,const GLfloat * params)2439 void SetMaterialParameters(GLES1State *state,
2440                            GLenum face,
2441                            MaterialParameter pname,
2442                            const GLfloat *params)
2443 {
2444     MaterialParameters &material = state->materialParameters();
2445     switch (pname)
2446     {
2447         case MaterialParameter::Ambient:
2448             material.ambient = ColorF::fromData(params);
2449             break;
2450         case MaterialParameter::Diffuse:
2451             material.diffuse = ColorF::fromData(params);
2452             break;
2453         case MaterialParameter::AmbientAndDiffuse:
2454             material.ambient = ColorF::fromData(params);
2455             material.diffuse = ColorF::fromData(params);
2456             break;
2457         case MaterialParameter::Specular:
2458             material.specular = ColorF::fromData(params);
2459             break;
2460         case MaterialParameter::Emission:
2461             material.emissive = ColorF::fromData(params);
2462             break;
2463         case MaterialParameter::Shininess:
2464             material.specularExponent = *params;
2465             break;
2466         default:
2467             return;
2468     }
2469 }
2470 
GetMaterialParameters(const GLES1State * state,GLenum face,MaterialParameter pname,GLfloat * params)2471 void GetMaterialParameters(const GLES1State *state,
2472                            GLenum face,
2473                            MaterialParameter pname,
2474                            GLfloat *params)
2475 {
2476     const ColorF &currentColor         = state->getCurrentColor();
2477     const MaterialParameters &material = state->materialParameters();
2478     const bool colorMaterialEnabled    = state->isColorMaterialEnabled();
2479 
2480     switch (pname)
2481     {
2482         case MaterialParameter::Ambient:
2483             if (colorMaterialEnabled)
2484             {
2485                 currentColor.writeData(params);
2486             }
2487             else
2488             {
2489                 material.ambient.writeData(params);
2490             }
2491             break;
2492         case MaterialParameter::Diffuse:
2493             if (colorMaterialEnabled)
2494             {
2495                 currentColor.writeData(params);
2496             }
2497             else
2498             {
2499                 material.diffuse.writeData(params);
2500             }
2501             break;
2502         case MaterialParameter::Specular:
2503             material.specular.writeData(params);
2504             break;
2505         case MaterialParameter::Emission:
2506             material.emissive.writeData(params);
2507             break;
2508         case MaterialParameter::Shininess:
2509             *params = material.specularExponent;
2510             break;
2511         default:
2512             return;
2513     }
2514 }
2515 
GetLightModelParameterCount(GLenum pname)2516 unsigned int GetLightModelParameterCount(GLenum pname)
2517 {
2518     switch (pname)
2519     {
2520         case GL_LIGHT_MODEL_AMBIENT:
2521             return 4;
2522         case GL_LIGHT_MODEL_TWO_SIDE:
2523             return 1;
2524         default:
2525             UNREACHABLE();
2526             return 0;
2527     }
2528 }
2529 
GetLightParameterCount(LightParameter pname)2530 unsigned int GetLightParameterCount(LightParameter pname)
2531 {
2532     switch (pname)
2533     {
2534         case LightParameter::Ambient:
2535         case LightParameter::Diffuse:
2536         case LightParameter::AmbientAndDiffuse:
2537         case LightParameter::Specular:
2538         case LightParameter::Position:
2539             return 4;
2540         case LightParameter::SpotDirection:
2541             return 3;
2542         case LightParameter::SpotExponent:
2543         case LightParameter::SpotCutoff:
2544         case LightParameter::ConstantAttenuation:
2545         case LightParameter::LinearAttenuation:
2546         case LightParameter::QuadraticAttenuation:
2547             return 1;
2548         default:
2549             UNREACHABLE();
2550             return 0;
2551     }
2552 }
2553 
GetMaterialParameterCount(MaterialParameter pname)2554 unsigned int GetMaterialParameterCount(MaterialParameter pname)
2555 {
2556     switch (pname)
2557     {
2558         case MaterialParameter::Ambient:
2559         case MaterialParameter::Diffuse:
2560         case MaterialParameter::AmbientAndDiffuse:
2561         case MaterialParameter::Specular:
2562         case MaterialParameter::Emission:
2563             return 4;
2564         case MaterialParameter::Shininess:
2565             return 1;
2566         default:
2567             UNREACHABLE();
2568             return 0;
2569     }
2570 }
2571 
SetFogParameters(GLES1State * state,GLenum pname,const GLfloat * params)2572 void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params)
2573 {
2574     FogParameters &fog = state->fogParameters();
2575     switch (pname)
2576     {
2577         case GL_FOG_MODE:
2578             fog.mode = FromGLenum<FogMode>(static_cast<GLenum>(params[0]));
2579             break;
2580         case GL_FOG_DENSITY:
2581             fog.density = params[0];
2582             break;
2583         case GL_FOG_START:
2584             fog.start = params[0];
2585             break;
2586         case GL_FOG_END:
2587             fog.end = params[0];
2588             break;
2589         case GL_FOG_COLOR:
2590             fog.color = ColorF::fromData(params);
2591             break;
2592         default:
2593             return;
2594     }
2595 }
2596 
GetFogParameters(const GLES1State * state,GLenum pname,GLfloat * params)2597 void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params)
2598 {
2599     const FogParameters &fog = state->fogParameters();
2600     switch (pname)
2601     {
2602         case GL_FOG_MODE:
2603             params[0] = static_cast<GLfloat>(ToGLenum(fog.mode));
2604             break;
2605         case GL_FOG_DENSITY:
2606             params[0] = fog.density;
2607             break;
2608         case GL_FOG_START:
2609             params[0] = fog.start;
2610             break;
2611         case GL_FOG_END:
2612             params[0] = fog.end;
2613             break;
2614         case GL_FOG_COLOR:
2615             fog.color.writeData(params);
2616             break;
2617         default:
2618             return;
2619     }
2620 }
2621 
GetFogParameterCount(GLenum pname)2622 unsigned int GetFogParameterCount(GLenum pname)
2623 {
2624     switch (pname)
2625     {
2626         case GL_FOG_MODE:
2627         case GL_FOG_DENSITY:
2628         case GL_FOG_START:
2629         case GL_FOG_END:
2630             return 1;
2631         case GL_FOG_COLOR:
2632             return 4;
2633         default:
2634             return 0;
2635     }
2636 }
2637 
GetTextureEnvParameterCount(TextureEnvParameter pname)2638 unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname)
2639 {
2640     switch (pname)
2641     {
2642         case TextureEnvParameter::Mode:
2643         case TextureEnvParameter::CombineRgb:
2644         case TextureEnvParameter::CombineAlpha:
2645         case TextureEnvParameter::Src0Rgb:
2646         case TextureEnvParameter::Src1Rgb:
2647         case TextureEnvParameter::Src2Rgb:
2648         case TextureEnvParameter::Src0Alpha:
2649         case TextureEnvParameter::Src1Alpha:
2650         case TextureEnvParameter::Src2Alpha:
2651         case TextureEnvParameter::Op0Rgb:
2652         case TextureEnvParameter::Op1Rgb:
2653         case TextureEnvParameter::Op2Rgb:
2654         case TextureEnvParameter::Op0Alpha:
2655         case TextureEnvParameter::Op1Alpha:
2656         case TextureEnvParameter::Op2Alpha:
2657         case TextureEnvParameter::RgbScale:
2658         case TextureEnvParameter::AlphaScale:
2659         case TextureEnvParameter::PointCoordReplace:
2660             return 1;
2661         case TextureEnvParameter::Color:
2662             return 4;
2663         default:
2664             return 0;
2665     }
2666 }
2667 
ConvertTextureEnvFromInt(TextureEnvParameter pname,const GLint * input,GLfloat * output)2668 void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output)
2669 {
2670     if (IsTextureEnvEnumParameter(pname))
2671     {
2672         ConvertGLenumValue(input[0], output);
2673         return;
2674     }
2675 
2676     switch (pname)
2677     {
2678         case TextureEnvParameter::RgbScale:
2679         case TextureEnvParameter::AlphaScale:
2680             output[0] = static_cast<GLfloat>(input[0]);
2681             break;
2682         case TextureEnvParameter::Color:
2683             for (int i = 0; i < 4; i++)
2684             {
2685                 output[i] = input[i] / 255.0f;
2686             }
2687             break;
2688         default:
2689             UNREACHABLE();
2690             break;
2691     }
2692 }
2693 
ConvertTextureEnvFromFixed(TextureEnvParameter pname,const GLfixed * input,GLfloat * output)2694 void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output)
2695 {
2696     if (IsTextureEnvEnumParameter(pname))
2697     {
2698         ConvertGLenumValue(input[0], output);
2699         return;
2700     }
2701 
2702     switch (pname)
2703     {
2704         case TextureEnvParameter::RgbScale:
2705         case TextureEnvParameter::AlphaScale:
2706             output[0] = ConvertFixedToFloat(input[0]);
2707             break;
2708         case TextureEnvParameter::Color:
2709             for (int i = 0; i < 4; i++)
2710             {
2711                 output[i] = ConvertFixedToFloat(input[i]);
2712             }
2713             break;
2714         default:
2715             UNREACHABLE();
2716             break;
2717     }
2718 }
2719 
ConvertTextureEnvToInt(TextureEnvParameter pname,const GLfloat * input,GLint * output)2720 void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output)
2721 {
2722     if (IsTextureEnvEnumParameter(pname))
2723     {
2724         ConvertGLenumValue(input[0], output);
2725         return;
2726     }
2727 
2728     switch (pname)
2729     {
2730         case TextureEnvParameter::RgbScale:
2731         case TextureEnvParameter::AlphaScale:
2732             output[0] = static_cast<GLint>(input[0]);
2733             break;
2734         case TextureEnvParameter::Color:
2735             for (int i = 0; i < 4; i++)
2736             {
2737                 output[i] = static_cast<GLint>(input[i] * 255.0f);
2738             }
2739             break;
2740         default:
2741             UNREACHABLE();
2742             break;
2743     }
2744 }
2745 
ConvertTextureEnvToFixed(TextureEnvParameter pname,const GLfloat * input,GLfixed * output)2746 void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output)
2747 {
2748     if (IsTextureEnvEnumParameter(pname))
2749     {
2750         ConvertGLenumValue(input[0], output);
2751         return;
2752     }
2753 
2754     switch (pname)
2755     {
2756         case TextureEnvParameter::RgbScale:
2757         case TextureEnvParameter::AlphaScale:
2758             output[0] = ConvertFloatToFixed(input[0]);
2759             break;
2760         case TextureEnvParameter::Color:
2761             for (int i = 0; i < 4; i++)
2762             {
2763                 output[i] = ConvertFloatToFixed(input[i]);
2764             }
2765             break;
2766         default:
2767             UNREACHABLE();
2768             break;
2769     }
2770 }
2771 
SetTextureEnv(unsigned int unit,GLES1State * state,TextureEnvTarget target,TextureEnvParameter pname,const GLfloat * params)2772 void SetTextureEnv(unsigned int unit,
2773                    GLES1State *state,
2774                    TextureEnvTarget target,
2775                    TextureEnvParameter pname,
2776                    const GLfloat *params)
2777 {
2778     TextureEnvironmentParameters &env = state->textureEnvironment(unit);
2779     GLenum asEnum                     = ConvertToGLenum(params[0]);
2780 
2781     switch (target)
2782     {
2783         case TextureEnvTarget::Env:
2784             switch (pname)
2785             {
2786                 case TextureEnvParameter::Mode:
2787                     env.mode = FromGLenum<TextureEnvMode>(asEnum);
2788                     break;
2789                 case TextureEnvParameter::CombineRgb:
2790                     env.combineRgb = FromGLenum<TextureCombine>(asEnum);
2791                     break;
2792                 case TextureEnvParameter::CombineAlpha:
2793                     env.combineAlpha = FromGLenum<TextureCombine>(asEnum);
2794                     break;
2795                 case TextureEnvParameter::Src0Rgb:
2796                     env.src0Rgb = FromGLenum<TextureSrc>(asEnum);
2797                     break;
2798                 case TextureEnvParameter::Src1Rgb:
2799                     env.src1Rgb = FromGLenum<TextureSrc>(asEnum);
2800                     break;
2801                 case TextureEnvParameter::Src2Rgb:
2802                     env.src2Rgb = FromGLenum<TextureSrc>(asEnum);
2803                     break;
2804                 case TextureEnvParameter::Src0Alpha:
2805                     env.src0Alpha = FromGLenum<TextureSrc>(asEnum);
2806                     break;
2807                 case TextureEnvParameter::Src1Alpha:
2808                     env.src1Alpha = FromGLenum<TextureSrc>(asEnum);
2809                     break;
2810                 case TextureEnvParameter::Src2Alpha:
2811                     env.src2Alpha = FromGLenum<TextureSrc>(asEnum);
2812                     break;
2813                 case TextureEnvParameter::Op0Rgb:
2814                     env.op0Rgb = FromGLenum<TextureOp>(asEnum);
2815                     break;
2816                 case TextureEnvParameter::Op1Rgb:
2817                     env.op1Rgb = FromGLenum<TextureOp>(asEnum);
2818                     break;
2819                 case TextureEnvParameter::Op2Rgb:
2820                     env.op2Rgb = FromGLenum<TextureOp>(asEnum);
2821                     break;
2822                 case TextureEnvParameter::Op0Alpha:
2823                     env.op0Alpha = FromGLenum<TextureOp>(asEnum);
2824                     break;
2825                 case TextureEnvParameter::Op1Alpha:
2826                     env.op1Alpha = FromGLenum<TextureOp>(asEnum);
2827                     break;
2828                 case TextureEnvParameter::Op2Alpha:
2829                     env.op2Alpha = FromGLenum<TextureOp>(asEnum);
2830                     break;
2831                 case TextureEnvParameter::Color:
2832                     env.color = ColorF::fromData(params);
2833                     break;
2834                 case TextureEnvParameter::RgbScale:
2835                     env.rgbScale = params[0];
2836                     break;
2837                 case TextureEnvParameter::AlphaScale:
2838                     env.alphaScale = params[0];
2839                     break;
2840                 default:
2841                     UNREACHABLE();
2842                     break;
2843             }
2844             break;
2845         case TextureEnvTarget::PointSprite:
2846             switch (pname)
2847             {
2848                 case TextureEnvParameter::PointCoordReplace:
2849                     env.pointSpriteCoordReplace = static_cast<bool>(params[0]);
2850                     break;
2851                 default:
2852                     UNREACHABLE();
2853                     break;
2854             }
2855             break;
2856         default:
2857             UNREACHABLE();
2858             break;
2859     }
2860 }
2861 
GetTextureEnv(unsigned int unit,const GLES1State * state,TextureEnvTarget target,TextureEnvParameter pname,GLfloat * params)2862 void GetTextureEnv(unsigned int unit,
2863                    const GLES1State *state,
2864                    TextureEnvTarget target,
2865                    TextureEnvParameter pname,
2866                    GLfloat *params)
2867 {
2868     const TextureEnvironmentParameters &env = state->textureEnvironment(unit);
2869 
2870     switch (target)
2871     {
2872         case TextureEnvTarget::Env:
2873             switch (pname)
2874             {
2875                 case TextureEnvParameter::Mode:
2876                     ConvertPackedEnum(env.mode, params);
2877                     break;
2878                 case TextureEnvParameter::CombineRgb:
2879                     ConvertPackedEnum(env.combineRgb, params);
2880                     break;
2881                 case TextureEnvParameter::CombineAlpha:
2882                     ConvertPackedEnum(env.combineAlpha, params);
2883                     break;
2884                 case TextureEnvParameter::Src0Rgb:
2885                     ConvertPackedEnum(env.src0Rgb, params);
2886                     break;
2887                 case TextureEnvParameter::Src1Rgb:
2888                     ConvertPackedEnum(env.src1Rgb, params);
2889                     break;
2890                 case TextureEnvParameter::Src2Rgb:
2891                     ConvertPackedEnum(env.src2Rgb, params);
2892                     break;
2893                 case TextureEnvParameter::Src0Alpha:
2894                     ConvertPackedEnum(env.src0Alpha, params);
2895                     break;
2896                 case TextureEnvParameter::Src1Alpha:
2897                     ConvertPackedEnum(env.src1Alpha, params);
2898                     break;
2899                 case TextureEnvParameter::Src2Alpha:
2900                     ConvertPackedEnum(env.src2Alpha, params);
2901                     break;
2902                 case TextureEnvParameter::Op0Rgb:
2903                     ConvertPackedEnum(env.op0Rgb, params);
2904                     break;
2905                 case TextureEnvParameter::Op1Rgb:
2906                     ConvertPackedEnum(env.op1Rgb, params);
2907                     break;
2908                 case TextureEnvParameter::Op2Rgb:
2909                     ConvertPackedEnum(env.op2Rgb, params);
2910                     break;
2911                 case TextureEnvParameter::Op0Alpha:
2912                     ConvertPackedEnum(env.op0Alpha, params);
2913                     break;
2914                 case TextureEnvParameter::Op1Alpha:
2915                     ConvertPackedEnum(env.op1Alpha, params);
2916                     break;
2917                 case TextureEnvParameter::Op2Alpha:
2918                     ConvertPackedEnum(env.op2Alpha, params);
2919                     break;
2920                 case TextureEnvParameter::Color:
2921                     env.color.writeData(params);
2922                     break;
2923                 case TextureEnvParameter::RgbScale:
2924                     *params = env.rgbScale;
2925                     break;
2926                 case TextureEnvParameter::AlphaScale:
2927                     *params = env.alphaScale;
2928                     break;
2929                 default:
2930                     UNREACHABLE();
2931                     break;
2932             }
2933             break;
2934         case TextureEnvTarget::PointSprite:
2935             switch (pname)
2936             {
2937                 case TextureEnvParameter::PointCoordReplace:
2938                     *params = static_cast<GLfloat>(env.pointSpriteCoordReplace);
2939                     break;
2940                 default:
2941                     UNREACHABLE();
2942                     break;
2943             }
2944             break;
2945         default:
2946             UNREACHABLE();
2947             break;
2948     }
2949 }
2950 
GetPointParameterCount(PointParameter pname)2951 unsigned int GetPointParameterCount(PointParameter pname)
2952 {
2953     switch (pname)
2954     {
2955         case PointParameter::PointSizeMin:
2956         case PointParameter::PointSizeMax:
2957         case PointParameter::PointFadeThresholdSize:
2958             return 1;
2959         case PointParameter::PointDistanceAttenuation:
2960             return 3;
2961         default:
2962             return 0;
2963     }
2964 }
2965 
SetPointParameter(GLES1State * state,PointParameter pname,const GLfloat * params)2966 void SetPointParameter(GLES1State *state, PointParameter pname, const GLfloat *params)
2967 {
2968 
2969     PointParameters &pointParams = state->pointParameters();
2970 
2971     switch (pname)
2972     {
2973         case PointParameter::PointSizeMin:
2974             pointParams.pointSizeMin = params[0];
2975             break;
2976         case PointParameter::PointSizeMax:
2977             pointParams.pointSizeMax = params[0];
2978             break;
2979         case PointParameter::PointFadeThresholdSize:
2980             pointParams.pointFadeThresholdSize = params[0];
2981             break;
2982         case PointParameter::PointDistanceAttenuation:
2983             for (unsigned int i = 0; i < 3; i++)
2984             {
2985                 pointParams.pointDistanceAttenuation[i] = params[i];
2986             }
2987             break;
2988         default:
2989             UNREACHABLE();
2990     }
2991 }
2992 
GetPointParameter(const GLES1State * state,PointParameter pname,GLfloat * params)2993 void GetPointParameter(const GLES1State *state, PointParameter pname, GLfloat *params)
2994 {
2995     const PointParameters &pointParams = state->pointParameters();
2996 
2997     switch (pname)
2998     {
2999         case PointParameter::PointSizeMin:
3000             params[0] = pointParams.pointSizeMin;
3001             break;
3002         case PointParameter::PointSizeMax:
3003             params[0] = pointParams.pointSizeMax;
3004             break;
3005         case PointParameter::PointFadeThresholdSize:
3006             params[0] = pointParams.pointFadeThresholdSize;
3007             break;
3008         case PointParameter::PointDistanceAttenuation:
3009             for (unsigned int i = 0; i < 3; i++)
3010             {
3011                 params[i] = pointParams.pointDistanceAttenuation[i];
3012             }
3013             break;
3014         default:
3015             UNREACHABLE();
3016     }
3017 }
3018 
SetPointSize(GLES1State * state,GLfloat size)3019 void SetPointSize(GLES1State *state, GLfloat size)
3020 {
3021     PointParameters &params = state->pointParameters();
3022     params.pointSize        = size;
3023 }
3024 
GetPointSize(const GLES1State * state,GLfloat * sizeOut)3025 void GetPointSize(const GLES1State *state, GLfloat *sizeOut)
3026 {
3027     const PointParameters &params = state->pointParameters();
3028     *sizeOut                      = params.pointSize;
3029 }
3030 
GetTexParameterCount(GLenum pname)3031 unsigned int GetTexParameterCount(GLenum pname)
3032 {
3033     switch (pname)
3034     {
3035         case GL_TEXTURE_CROP_RECT_OES:
3036         case GL_TEXTURE_BORDER_COLOR:
3037             return 4;
3038         case GL_TEXTURE_MAG_FILTER:
3039         case GL_TEXTURE_MIN_FILTER:
3040         case GL_TEXTURE_WRAP_S:
3041         case GL_TEXTURE_WRAP_T:
3042         case GL_TEXTURE_USAGE_ANGLE:
3043         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3044         case GL_TEXTURE_IMMUTABLE_FORMAT:
3045         case GL_TEXTURE_WRAP_R:
3046         case GL_TEXTURE_IMMUTABLE_LEVELS:
3047         case GL_TEXTURE_SWIZZLE_R:
3048         case GL_TEXTURE_SWIZZLE_G:
3049         case GL_TEXTURE_SWIZZLE_B:
3050         case GL_TEXTURE_SWIZZLE_A:
3051         case GL_TEXTURE_BASE_LEVEL:
3052         case GL_TEXTURE_MAX_LEVEL:
3053         case GL_TEXTURE_MIN_LOD:
3054         case GL_TEXTURE_MAX_LOD:
3055         case GL_TEXTURE_COMPARE_MODE:
3056         case GL_TEXTURE_COMPARE_FUNC:
3057         case GL_TEXTURE_SRGB_DECODE_EXT:
3058         case GL_DEPTH_STENCIL_TEXTURE_MODE:
3059         case GL_TEXTURE_NATIVE_ID_ANGLE:
3060             return 1;
3061         default:
3062             return 0;
3063     }
3064 }
3065 
GetQueryParameterInfo(const State & glState,GLenum pname,GLenum * type,unsigned int * numParams)3066 bool GetQueryParameterInfo(const State &glState,
3067                            GLenum pname,
3068                            GLenum *type,
3069                            unsigned int *numParams)
3070 {
3071     const Caps &caps             = glState.getCaps();
3072     const Extensions &extensions = glState.getExtensions();
3073     GLint clientMajorVersion     = glState.getClientMajorVersion();
3074     EGLenum clientType           = glState.getClientType();
3075 
3076     // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
3077     // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
3078     // to the fact that it is stored internally as a float, and so would require conversion
3079     // if returned from Context::getIntegerv. Since this conversion is already implemented
3080     // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
3081     // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
3082     // application.
3083     switch (pname)
3084     {
3085         case GL_COMPRESSED_TEXTURE_FORMATS:
3086         {
3087             *type      = GL_INT;
3088             *numParams = static_cast<unsigned int>(caps.compressedTextureFormats.size());
3089             return true;
3090         }
3091         case GL_SHADER_BINARY_FORMATS:
3092         {
3093             *type      = GL_INT;
3094             *numParams = static_cast<unsigned int>(caps.shaderBinaryFormats.size());
3095             return true;
3096         }
3097 
3098         case GL_MAX_VERTEX_ATTRIBS:
3099         case GL_MAX_VERTEX_UNIFORM_VECTORS:
3100         case GL_MAX_VARYING_VECTORS:
3101         case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
3102         case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
3103         case GL_MAX_TEXTURE_IMAGE_UNITS:
3104         case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
3105         case GL_MAX_RENDERBUFFER_SIZE:
3106         case GL_NUM_SHADER_BINARY_FORMATS:
3107         case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
3108         case GL_ARRAY_BUFFER_BINDING:
3109         case GL_FRAMEBUFFER_BINDING:  // GL_FRAMEBUFFER_BINDING now equivalent to
3110                                       // GL_DRAW_FRAMEBUFFER_BINDING
3111         case GL_RENDERBUFFER_BINDING:
3112         case GL_CURRENT_PROGRAM:
3113         case GL_PACK_ALIGNMENT:
3114         case GL_UNPACK_ALIGNMENT:
3115         case GL_GENERATE_MIPMAP_HINT:
3116         case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
3117         case GL_RED_BITS:
3118         case GL_GREEN_BITS:
3119         case GL_BLUE_BITS:
3120         case GL_ALPHA_BITS:
3121         case GL_DEPTH_BITS:
3122         case GL_STENCIL_BITS:
3123         case GL_ELEMENT_ARRAY_BUFFER_BINDING:
3124         case GL_CULL_FACE_MODE:
3125         case GL_FRONT_FACE:
3126         case GL_ACTIVE_TEXTURE:
3127         case GL_STENCIL_FUNC:
3128         case GL_STENCIL_VALUE_MASK:
3129         case GL_STENCIL_REF:
3130         case GL_STENCIL_FAIL:
3131         case GL_STENCIL_PASS_DEPTH_FAIL:
3132         case GL_STENCIL_PASS_DEPTH_PASS:
3133         case GL_STENCIL_BACK_FUNC:
3134         case GL_STENCIL_BACK_VALUE_MASK:
3135         case GL_STENCIL_BACK_REF:
3136         case GL_STENCIL_BACK_FAIL:
3137         case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
3138         case GL_STENCIL_BACK_PASS_DEPTH_PASS:
3139         case GL_DEPTH_FUNC:
3140         case GL_BLEND_SRC_RGB:
3141         case GL_BLEND_SRC_ALPHA:
3142         case GL_BLEND_DST_RGB:
3143         case GL_BLEND_DST_ALPHA:
3144         case GL_BLEND_EQUATION_RGB:
3145         case GL_BLEND_EQUATION_ALPHA:
3146         case GL_STENCIL_WRITEMASK:
3147         case GL_STENCIL_BACK_WRITEMASK:
3148         case GL_STENCIL_CLEAR_VALUE:
3149         case GL_SUBPIXEL_BITS:
3150         case GL_MAX_TEXTURE_SIZE:
3151         case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
3152         case GL_SAMPLE_BUFFERS:
3153         case GL_SAMPLES:
3154         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
3155         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3156         case GL_TEXTURE_BINDING_2D:
3157         case GL_TEXTURE_BINDING_CUBE_MAP:
3158         case GL_RESET_NOTIFICATION_STRATEGY_EXT:
3159         {
3160             *type      = GL_INT;
3161             *numParams = 1;
3162             return true;
3163         }
3164         case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
3165         {
3166             if (!extensions.packReverseRowOrderANGLE)
3167             {
3168                 return false;
3169             }
3170             *type      = GL_INT;
3171             *numParams = 1;
3172             return true;
3173         }
3174         case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
3175         case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
3176         {
3177             if (!extensions.textureRectangleANGLE)
3178             {
3179                 return false;
3180             }
3181             *type      = GL_INT;
3182             *numParams = 1;
3183             return true;
3184         }
3185         case GL_MAX_DRAW_BUFFERS_EXT:
3186         case GL_MAX_COLOR_ATTACHMENTS_EXT:
3187         {
3188             if ((clientMajorVersion < 3) && !extensions.drawBuffersEXT)
3189             {
3190                 return false;
3191             }
3192             *type      = GL_INT;
3193             *numParams = 1;
3194             return true;
3195         }
3196         case GL_MAX_VIEWPORT_DIMS:
3197         {
3198             *type      = GL_INT;
3199             *numParams = 2;
3200             return true;
3201         }
3202         case GL_VIEWPORT:
3203         case GL_SCISSOR_BOX:
3204         {
3205             *type      = GL_INT;
3206             *numParams = 4;
3207             return true;
3208         }
3209         case GL_SHADER_COMPILER:
3210         case GL_SAMPLE_COVERAGE_INVERT:
3211         case GL_DEPTH_WRITEMASK:
3212         case GL_CULL_FACE:                 // CULL_FACE through DITHER are natural to IsEnabled,
3213         case GL_POLYGON_OFFSET_FILL:       // but can be retrieved through the Get{Type}v queries.
3214         case GL_SAMPLE_ALPHA_TO_COVERAGE:  // For this purpose, they are treated here as
3215                                            // bool-natural
3216         case GL_SAMPLE_COVERAGE:
3217         case GL_SCISSOR_TEST:
3218         case GL_STENCIL_TEST:
3219         case GL_DEPTH_TEST:
3220         case GL_BLEND:
3221         case GL_DITHER:
3222         case GL_CONTEXT_ROBUST_ACCESS_EXT:
3223         {
3224             *type      = GL_BOOL;
3225             *numParams = 1;
3226             return true;
3227         }
3228         case GL_COLOR_WRITEMASK:
3229         {
3230             *type      = GL_BOOL;
3231             *numParams = 4;
3232             return true;
3233         }
3234         case GL_POLYGON_OFFSET_FACTOR:
3235         case GL_POLYGON_OFFSET_UNITS:
3236         case GL_SAMPLE_COVERAGE_VALUE:
3237         case GL_DEPTH_CLEAR_VALUE:
3238         case GL_LINE_WIDTH:
3239         {
3240             *type      = GL_FLOAT;
3241             *numParams = 1;
3242             return true;
3243         }
3244         case GL_ALIASED_LINE_WIDTH_RANGE:
3245         case GL_ALIASED_POINT_SIZE_RANGE:
3246         case GL_DEPTH_RANGE:
3247         {
3248             *type      = GL_FLOAT;
3249             *numParams = 2;
3250             return true;
3251         }
3252         case GL_COLOR_CLEAR_VALUE:
3253         case GL_BLEND_COLOR:
3254         {
3255             *type      = GL_FLOAT;
3256             *numParams = 4;
3257             return true;
3258         }
3259         case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
3260             if (!extensions.textureFilterAnisotropicEXT)
3261             {
3262                 return false;
3263             }
3264             *type      = GL_FLOAT;
3265             *numParams = 1;
3266             return true;
3267         case GL_TIMESTAMP_EXT:
3268             if (!extensions.disjointTimerQueryEXT)
3269             {
3270                 return false;
3271             }
3272             *type      = GL_INT_64_ANGLEX;
3273             *numParams = 1;
3274             return true;
3275         case GL_GPU_DISJOINT_EXT:
3276             if (!extensions.disjointTimerQueryEXT)
3277             {
3278                 return false;
3279             }
3280             *type      = GL_INT;
3281             *numParams = 1;
3282             return true;
3283         case GL_COVERAGE_MODULATION_CHROMIUM:
3284             if (!extensions.framebufferMixedSamplesCHROMIUM)
3285             {
3286                 return false;
3287             }
3288             *type      = GL_INT;
3289             *numParams = 1;
3290             return true;
3291         case GL_TEXTURE_BINDING_EXTERNAL_OES:
3292             if (!extensions.EGLStreamConsumerExternalNV && !extensions.EGLImageExternalOES)
3293             {
3294                 return false;
3295             }
3296             *type      = GL_INT;
3297             *numParams = 1;
3298             return true;
3299         case GL_MAX_CLIP_DISTANCES_EXT:  // case GL_MAX_CLIP_PLANES
3300             if (clientMajorVersion < 2)
3301             {
3302                 break;
3303             }
3304             if (!extensions.clipDistanceAPPLE && !extensions.clipCullDistanceEXT)
3305             {
3306                 // NOTE(hqle): if client version is 1. GL_MAX_CLIP_DISTANCES_EXT is equal
3307                 // to GL_MAX_CLIP_PLANES which is a valid enum.
3308                 return false;
3309             }
3310             *type      = GL_INT;
3311             *numParams = 1;
3312             return true;
3313         case GL_MAX_CULL_DISTANCES_EXT:
3314         case GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT:
3315             if (!extensions.clipCullDistanceEXT)
3316             {
3317                 return false;
3318             }
3319             *type      = GL_INT;
3320             *numParams = 1;
3321             return true;
3322         case GL_CLIP_ORIGIN_EXT:
3323         case GL_CLIP_DEPTH_MODE_EXT:
3324             if (!extensions.clipControlEXT)
3325             {
3326                 return false;
3327             }
3328             *type      = GL_INT;
3329             *numParams = 1;
3330             return true;
3331         case GL_PRIMITIVE_BOUNDING_BOX:
3332             if (!extensions.primitiveBoundingBoxAny())
3333             {
3334                 return false;
3335             }
3336             *type      = GL_FLOAT;
3337             *numParams = 8;
3338             return true;
3339     }
3340 
3341     if (clientType == EGL_OPENGL_API ||
3342         (clientType == EGL_OPENGL_ES_API && glState.getClientVersion() >= Version(3, 2)))
3343     {
3344         switch (pname)
3345         {
3346             case GL_CONTEXT_FLAGS:
3347             {
3348                 *type      = GL_INT;
3349                 *numParams = 1;
3350                 return true;
3351             }
3352         }
3353     }
3354 
3355     if (clientType == EGL_OPENGL_API)
3356     {
3357         switch (pname)
3358         {
3359             case GL_CONTEXT_PROFILE_MASK:
3360             {
3361                 *type      = GL_INT;
3362                 *numParams = 1;
3363                 return true;
3364             }
3365         }
3366     }
3367 
3368     if (extensions.debugKHR)
3369     {
3370         switch (pname)
3371         {
3372             case GL_DEBUG_LOGGED_MESSAGES:
3373             case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
3374             case GL_DEBUG_GROUP_STACK_DEPTH:
3375             case GL_MAX_DEBUG_MESSAGE_LENGTH:
3376             case GL_MAX_DEBUG_LOGGED_MESSAGES:
3377             case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
3378             case GL_MAX_LABEL_LENGTH:
3379                 *type      = GL_INT;
3380                 *numParams = 1;
3381                 return true;
3382 
3383             case GL_DEBUG_OUTPUT_SYNCHRONOUS:
3384             case GL_DEBUG_OUTPUT:
3385                 *type      = GL_BOOL;
3386                 *numParams = 1;
3387                 return true;
3388         }
3389     }
3390 
3391     if (extensions.multisampleCompatibilityEXT)
3392     {
3393         switch (pname)
3394         {
3395             case GL_MULTISAMPLE_EXT:
3396             case GL_SAMPLE_ALPHA_TO_ONE_EXT:
3397                 *type      = GL_BOOL;
3398                 *numParams = 1;
3399                 return true;
3400         }
3401     }
3402 
3403     if (extensions.bindGeneratesResourceCHROMIUM)
3404     {
3405         switch (pname)
3406         {
3407             case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
3408                 *type      = GL_BOOL;
3409                 *numParams = 1;
3410                 return true;
3411         }
3412     }
3413 
3414     if (extensions.clientArraysANGLE)
3415     {
3416         switch (pname)
3417         {
3418             case GL_CLIENT_ARRAYS_ANGLE:
3419                 *type      = GL_BOOL;
3420                 *numParams = 1;
3421                 return true;
3422         }
3423     }
3424 
3425     if (extensions.sRGBWriteControlEXT)
3426     {
3427         switch (pname)
3428         {
3429             case GL_FRAMEBUFFER_SRGB_EXT:
3430                 *type      = GL_BOOL;
3431                 *numParams = 1;
3432                 return true;
3433         }
3434     }
3435 
3436     if (extensions.robustResourceInitializationANGLE &&
3437         pname == GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
3438     {
3439         *type      = GL_BOOL;
3440         *numParams = 1;
3441         return true;
3442     }
3443 
3444     if (extensions.programCacheControlANGLE && pname == GL_PROGRAM_CACHE_ENABLED_ANGLE)
3445     {
3446         *type      = GL_BOOL;
3447         *numParams = 1;
3448         return true;
3449     }
3450 
3451     if (extensions.parallelShaderCompileKHR && pname == GL_MAX_SHADER_COMPILER_THREADS_KHR)
3452     {
3453         *type      = GL_INT;
3454         *numParams = 1;
3455         return true;
3456     }
3457 
3458     if (extensions.blendFuncExtendedEXT && pname == GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT)
3459     {
3460         *type      = GL_INT;
3461         *numParams = 1;
3462         return true;
3463     }
3464 
3465     if (extensions.robustFragmentShaderOutputANGLE &&
3466         pname == GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE)
3467     {
3468         *type      = GL_BOOL;
3469         *numParams = 1;
3470         return true;
3471     }
3472 
3473     // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
3474     switch (pname)
3475     {
3476         // GL_DRAW_FRAMEBUFFER_BINDING equivalent to GL_FRAMEBUFFER_BINDING
3477         case GL_READ_FRAMEBUFFER_BINDING:
3478             if ((clientMajorVersion < 3) && !extensions.framebufferBlitAny())
3479             {
3480                 return false;
3481             }
3482             *type      = GL_INT;
3483             *numParams = 1;
3484             return true;
3485 
3486         case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
3487             if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
3488             {
3489                 return false;
3490             }
3491             *type      = GL_INT;
3492             *numParams = 1;
3493             return true;
3494 
3495         case GL_PROGRAM_BINARY_FORMATS_OES:
3496             if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
3497             {
3498                 return false;
3499             }
3500             *type      = GL_INT;
3501             *numParams = static_cast<unsigned int>(caps.programBinaryFormats.size());
3502             return true;
3503 
3504         case GL_PACK_ROW_LENGTH:
3505         case GL_PACK_SKIP_ROWS:
3506         case GL_PACK_SKIP_PIXELS:
3507             if ((clientMajorVersion < 3) && !extensions.packSubimageNV)
3508             {
3509                 return false;
3510             }
3511             *type      = GL_INT;
3512             *numParams = 1;
3513             return true;
3514         case GL_UNPACK_ROW_LENGTH:
3515         case GL_UNPACK_SKIP_ROWS:
3516         case GL_UNPACK_SKIP_PIXELS:
3517             if ((clientMajorVersion < 3) && !extensions.unpackSubimageEXT)
3518             {
3519                 return false;
3520             }
3521             *type      = GL_INT;
3522             *numParams = 1;
3523             return true;
3524         case GL_VERTEX_ARRAY_BINDING:
3525             if ((clientMajorVersion < 3) && !extensions.vertexArrayObjectOES)
3526             {
3527                 return false;
3528             }
3529             *type      = GL_INT;
3530             *numParams = 1;
3531             return true;
3532         case GL_PIXEL_PACK_BUFFER_BINDING:
3533         case GL_PIXEL_UNPACK_BUFFER_BINDING:
3534             if ((clientMajorVersion < 3) && !extensions.pixelBufferObjectNV)
3535             {
3536                 return false;
3537             }
3538             *type      = GL_INT;
3539             *numParams = 1;
3540             return true;
3541         case GL_MAX_SAMPLES:
3542         {
3543             static_assert(GL_MAX_SAMPLES_ANGLE == GL_MAX_SAMPLES,
3544                           "GL_MAX_SAMPLES_ANGLE not equal to GL_MAX_SAMPLES");
3545             if ((clientMajorVersion < 3) && !(extensions.framebufferMultisampleANGLE ||
3546                                               extensions.multisampledRenderToTextureEXT))
3547             {
3548                 return false;
3549             }
3550             *type      = GL_INT;
3551             *numParams = 1;
3552             return true;
3553 
3554             case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
3555                 if ((clientMajorVersion < 3) && !extensions.standardDerivativesOES)
3556                 {
3557                     return false;
3558                 }
3559                 *type      = GL_INT;
3560                 *numParams = 1;
3561                 return true;
3562         }
3563         case GL_TEXTURE_BINDING_3D:
3564             if ((clientMajorVersion < 3) && !extensions.texture3DOES)
3565             {
3566                 return false;
3567             }
3568             *type      = GL_INT;
3569             *numParams = 1;
3570             return true;
3571         case GL_MAX_3D_TEXTURE_SIZE:
3572             if ((clientMajorVersion < 3) && !extensions.texture3DOES)
3573             {
3574                 return false;
3575             }
3576             *type      = GL_INT;
3577             *numParams = 1;
3578             return true;
3579     }
3580 
3581     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
3582     {
3583         if ((glState.getClientVersion() < Version(3, 0)) && !extensions.drawBuffersEXT)
3584         {
3585             return false;
3586         }
3587         *type      = GL_INT;
3588         *numParams = 1;
3589         return true;
3590     }
3591 
3592     if ((extensions.multiview2OVR || extensions.multiviewOVR) && pname == GL_MAX_VIEWS_OVR)
3593     {
3594         *type      = GL_INT;
3595         *numParams = 1;
3596         return true;
3597     }
3598 
3599     if (glState.getClientVersion() < Version(2, 0))
3600     {
3601         switch (pname)
3602         {
3603             case GL_ALPHA_TEST_FUNC:
3604             case GL_CLIENT_ACTIVE_TEXTURE:
3605             case GL_MATRIX_MODE:
3606             case GL_MAX_TEXTURE_UNITS:
3607             case GL_MAX_MODELVIEW_STACK_DEPTH:
3608             case GL_MAX_PROJECTION_STACK_DEPTH:
3609             case GL_MAX_TEXTURE_STACK_DEPTH:
3610             case GL_MAX_LIGHTS:
3611             case GL_MAX_CLIP_PLANES:
3612             case GL_VERTEX_ARRAY_STRIDE:
3613             case GL_NORMAL_ARRAY_STRIDE:
3614             case GL_COLOR_ARRAY_STRIDE:
3615             case GL_TEXTURE_COORD_ARRAY_STRIDE:
3616             case GL_VERTEX_ARRAY_SIZE:
3617             case GL_COLOR_ARRAY_SIZE:
3618             case GL_TEXTURE_COORD_ARRAY_SIZE:
3619             case GL_VERTEX_ARRAY_TYPE:
3620             case GL_NORMAL_ARRAY_TYPE:
3621             case GL_COLOR_ARRAY_TYPE:
3622             case GL_TEXTURE_COORD_ARRAY_TYPE:
3623             case GL_VERTEX_ARRAY_BUFFER_BINDING:
3624             case GL_NORMAL_ARRAY_BUFFER_BINDING:
3625             case GL_COLOR_ARRAY_BUFFER_BINDING:
3626             case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
3627             case GL_POINT_SIZE_ARRAY_STRIDE_OES:
3628             case GL_POINT_SIZE_ARRAY_TYPE_OES:
3629             case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
3630             case GL_SHADE_MODEL:
3631             case GL_MODELVIEW_STACK_DEPTH:
3632             case GL_PROJECTION_STACK_DEPTH:
3633             case GL_TEXTURE_STACK_DEPTH:
3634             case GL_LOGIC_OP_MODE:
3635             case GL_BLEND_SRC:
3636             case GL_BLEND_DST:
3637             case GL_PERSPECTIVE_CORRECTION_HINT:
3638             case GL_POINT_SMOOTH_HINT:
3639             case GL_LINE_SMOOTH_HINT:
3640             case GL_FOG_HINT:
3641                 *type      = GL_INT;
3642                 *numParams = 1;
3643                 return true;
3644             case GL_ALPHA_TEST_REF:
3645             case GL_FOG_DENSITY:
3646             case GL_FOG_START:
3647             case GL_FOG_END:
3648             case GL_FOG_MODE:
3649             case GL_POINT_SIZE:
3650             case GL_POINT_SIZE_MIN:
3651             case GL_POINT_SIZE_MAX:
3652             case GL_POINT_FADE_THRESHOLD_SIZE:
3653                 *type      = GL_FLOAT;
3654                 *numParams = 1;
3655                 return true;
3656             case GL_SMOOTH_POINT_SIZE_RANGE:
3657             case GL_SMOOTH_LINE_WIDTH_RANGE:
3658                 *type      = GL_FLOAT;
3659                 *numParams = 2;
3660                 return true;
3661             case GL_CURRENT_COLOR:
3662             case GL_CURRENT_TEXTURE_COORDS:
3663             case GL_LIGHT_MODEL_AMBIENT:
3664             case GL_FOG_COLOR:
3665                 *type      = GL_FLOAT;
3666                 *numParams = 4;
3667                 return true;
3668             case GL_CURRENT_NORMAL:
3669             case GL_POINT_DISTANCE_ATTENUATION:
3670                 *type      = GL_FLOAT;
3671                 *numParams = 3;
3672                 return true;
3673             case GL_MODELVIEW_MATRIX:
3674             case GL_PROJECTION_MATRIX:
3675             case GL_TEXTURE_MATRIX:
3676                 *type      = GL_FLOAT;
3677                 *numParams = 16;
3678                 return true;
3679             case GL_LIGHT_MODEL_TWO_SIDE:
3680                 *type      = GL_BOOL;
3681                 *numParams = 1;
3682                 return true;
3683         }
3684     }
3685 
3686     if (glState.getClientVersion() < Version(3, 0))
3687     {
3688         return false;
3689     }
3690 
3691     // Check for ES3.0+ parameter names
3692     switch (pname)
3693     {
3694         case GL_MAX_UNIFORM_BUFFER_BINDINGS:
3695         case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
3696         case GL_UNIFORM_BUFFER_BINDING:
3697         case GL_TRANSFORM_FEEDBACK_BINDING:
3698         case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
3699         case GL_COPY_READ_BUFFER_BINDING:
3700         case GL_COPY_WRITE_BUFFER_BINDING:
3701         case GL_SAMPLER_BINDING:
3702         case GL_READ_BUFFER:
3703         case GL_TEXTURE_BINDING_3D:
3704         case GL_TEXTURE_BINDING_2D_ARRAY:
3705         case GL_MAX_ARRAY_TEXTURE_LAYERS:
3706         case GL_MAX_VERTEX_UNIFORM_BLOCKS:
3707         case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
3708         case GL_MAX_COMBINED_UNIFORM_BLOCKS:
3709         case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
3710         case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
3711         case GL_MAX_VARYING_COMPONENTS:
3712         case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
3713         case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
3714         case GL_MIN_PROGRAM_TEXEL_OFFSET:
3715         case GL_MAX_PROGRAM_TEXEL_OFFSET:
3716         case GL_NUM_EXTENSIONS:
3717         case GL_MAJOR_VERSION:
3718         case GL_MINOR_VERSION:
3719         case GL_MAX_ELEMENTS_INDICES:
3720         case GL_MAX_ELEMENTS_VERTICES:
3721         case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
3722         case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
3723         case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
3724         case GL_UNPACK_IMAGE_HEIGHT:
3725         case GL_UNPACK_SKIP_IMAGES:
3726         case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES:
3727         {
3728             *type      = GL_INT;
3729             *numParams = 1;
3730             return true;
3731         }
3732 
3733         case GL_MAX_ELEMENT_INDEX:
3734         case GL_MAX_UNIFORM_BLOCK_SIZE:
3735         case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
3736         case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
3737         case GL_MAX_SERVER_WAIT_TIMEOUT:
3738         {
3739             *type      = GL_INT_64_ANGLEX;
3740             *numParams = 1;
3741             return true;
3742         }
3743 
3744         case GL_TRANSFORM_FEEDBACK_ACTIVE:
3745         case GL_TRANSFORM_FEEDBACK_PAUSED:
3746         case GL_PRIMITIVE_RESTART_FIXED_INDEX:
3747         case GL_RASTERIZER_DISCARD:
3748         {
3749             *type      = GL_BOOL;
3750             *numParams = 1;
3751             return true;
3752         }
3753 
3754         case GL_MAX_TEXTURE_LOD_BIAS:
3755         case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES:
3756         case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES:
3757         {
3758             *type      = GL_FLOAT;
3759             *numParams = 1;
3760             return true;
3761         }
3762     }
3763 
3764     if (extensions.requestExtensionANGLE)
3765     {
3766         switch (pname)
3767         {
3768             case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
3769                 *type      = GL_INT;
3770                 *numParams = 1;
3771                 return true;
3772         }
3773     }
3774 
3775     if (extensions.textureMultisampleANGLE)
3776     {
3777         switch (pname)
3778         {
3779             case GL_MAX_COLOR_TEXTURE_SAMPLES_ANGLE:
3780             case GL_MAX_INTEGER_SAMPLES_ANGLE:
3781             case GL_MAX_DEPTH_TEXTURE_SAMPLES_ANGLE:
3782             case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ANGLE:
3783             case GL_MAX_SAMPLE_MASK_WORDS:
3784                 *type      = GL_INT;
3785                 *numParams = 1;
3786                 return true;
3787         }
3788     }
3789 
3790     if (extensions.textureCubeMapArrayAny())
3791     {
3792         switch (pname)
3793         {
3794             case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
3795                 *type      = GL_INT;
3796                 *numParams = 1;
3797                 return true;
3798         }
3799     }
3800 
3801     if (extensions.textureBufferAny())
3802     {
3803         switch (pname)
3804         {
3805             case GL_TEXTURE_BUFFER_BINDING:
3806             case GL_TEXTURE_BINDING_BUFFER:
3807             case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
3808             case GL_MAX_TEXTURE_BUFFER_SIZE:
3809                 *type      = GL_INT;
3810                 *numParams = 1;
3811                 return true;
3812         }
3813     }
3814 
3815     if (glState.getClientVersion() < Version(3, 1))
3816     {
3817         return false;
3818     }
3819 
3820     // Check for ES3.1+ parameter names
3821     switch (pname)
3822     {
3823         case GL_ATOMIC_COUNTER_BUFFER_BINDING:
3824         case GL_DRAW_INDIRECT_BUFFER_BINDING:
3825         case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
3826         case GL_MAX_FRAMEBUFFER_WIDTH:
3827         case GL_MAX_FRAMEBUFFER_HEIGHT:
3828         case GL_MAX_FRAMEBUFFER_SAMPLES:
3829         case GL_MAX_SAMPLE_MASK_WORDS:
3830         case GL_MAX_COLOR_TEXTURE_SAMPLES:
3831         case GL_MAX_DEPTH_TEXTURE_SAMPLES:
3832         case GL_MAX_INTEGER_SAMPLES:
3833         case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
3834         case GL_MAX_VERTEX_ATTRIB_BINDINGS:
3835         case GL_MAX_VERTEX_ATTRIB_STRIDE:
3836         case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
3837         case GL_MAX_VERTEX_ATOMIC_COUNTERS:
3838         case GL_MAX_VERTEX_IMAGE_UNIFORMS:
3839         case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
3840         case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
3841         case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
3842         case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
3843         case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
3844         case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
3845         case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
3846         case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
3847         case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
3848         case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
3849         case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
3850         case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
3851         case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
3852         case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
3853         case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
3854         case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
3855         case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
3856         case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
3857         case GL_MAX_UNIFORM_LOCATIONS:
3858         case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
3859         case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
3860         case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
3861         case GL_MAX_COMBINED_ATOMIC_COUNTERS:
3862         case GL_MAX_IMAGE_UNITS:
3863         case GL_MAX_COMBINED_IMAGE_UNIFORMS:
3864         case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
3865         case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
3866         case GL_SHADER_STORAGE_BUFFER_BINDING:
3867         case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
3868         case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
3869         case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
3870         case GL_PROGRAM_PIPELINE_BINDING:
3871             *type      = GL_INT;
3872             *numParams = 1;
3873             return true;
3874         case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
3875             *type      = GL_INT_64_ANGLEX;
3876             *numParams = 1;
3877             return true;
3878         case GL_SAMPLE_MASK:
3879         case GL_SAMPLE_SHADING:
3880             *type      = GL_BOOL;
3881             *numParams = 1;
3882             return true;
3883         case GL_MIN_SAMPLE_SHADING_VALUE:
3884             *type      = GL_FLOAT;
3885             *numParams = 1;
3886             return true;
3887     }
3888 
3889     if (extensions.geometryShaderAny())
3890     {
3891         switch (pname)
3892         {
3893             case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
3894             case GL_LAYER_PROVOKING_VERTEX_EXT:
3895             case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
3896             case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
3897             case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
3898             case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
3899             case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
3900             case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
3901             case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
3902             case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
3903             case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
3904             case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
3905             case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
3906             case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
3907             case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
3908                 *type      = GL_INT;
3909                 *numParams = 1;
3910                 return true;
3911         }
3912     }
3913 
3914     if (extensions.tessellationShaderEXT)
3915     {
3916         switch (pname)
3917         {
3918             case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
3919                 *type      = GL_BOOL;
3920                 *numParams = 1;
3921                 return true;
3922             case GL_PATCH_VERTICES:
3923             case GL_MAX_PATCH_VERTICES_EXT:
3924             case GL_MAX_TESS_GEN_LEVEL_EXT:
3925             case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
3926             case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
3927             case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT:
3928             case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT:
3929             case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT:
3930             case GL_MAX_TESS_PATCH_COMPONENTS_EXT:
3931             case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT:
3932             case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT:
3933             case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT:
3934             case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT:
3935             case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT:
3936             case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT:
3937             case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
3938             case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
3939             case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT:
3940             case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT:
3941             case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT:
3942             case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT:
3943             case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT:
3944             case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT:
3945             case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT:
3946             case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT:
3947                 *type      = GL_INT;
3948                 *numParams = 1;
3949                 return true;
3950         }
3951     }
3952 
3953     return false;
3954 }
3955 
QueryProgramPipelineiv(const Context * context,ProgramPipeline * programPipeline,GLenum pname,GLint * params)3956 void QueryProgramPipelineiv(const Context *context,
3957                             ProgramPipeline *programPipeline,
3958                             GLenum pname,
3959                             GLint *params)
3960 {
3961     if (!params)
3962     {
3963         // Can't write the result anywhere, so just return immediately.
3964         return;
3965     }
3966 
3967     switch (pname)
3968     {
3969         case GL_ACTIVE_PROGRAM:
3970         {
3971             // the name of the active program object of the program pipeline object is returned in
3972             // params
3973             *params = 0;
3974             if (programPipeline)
3975             {
3976                 const Program *program = programPipeline->getActiveShaderProgram();
3977                 if (program)
3978                 {
3979                     *params = program->id().value;
3980                 }
3981             }
3982             break;
3983         }
3984 
3985         case GL_VERTEX_SHADER:
3986         {
3987             // the name of the current program object for the vertex shader type of the program
3988             // pipeline object is returned in params
3989             GetShaderProgramId(programPipeline, ShaderType::Vertex, params);
3990             break;
3991         }
3992 
3993         case GL_FRAGMENT_SHADER:
3994         {
3995             // the name of the current program object for the fragment shader type of the program
3996             // pipeline object is returned in params
3997             GetShaderProgramId(programPipeline, ShaderType::Fragment, params);
3998             break;
3999         }
4000 
4001         case GL_TESS_CONTROL_SHADER:
4002         {
4003             // the name of the current program object for the tessellation control shader type of
4004             // the program pipeline object is returned in params
4005             GetShaderProgramId(programPipeline, ShaderType::TessControl, params);
4006             break;
4007         }
4008 
4009         case GL_TESS_EVALUATION_SHADER:
4010         {
4011             // the name of the current program object for the tessellation evaluation shader type of
4012             // the program pipeline object is returned in params
4013             GetShaderProgramId(programPipeline, ShaderType::TessEvaluation, params);
4014             break;
4015         }
4016 
4017         case GL_COMPUTE_SHADER:
4018         {
4019             // the name of the current program object for the compute shader type of the program
4020             // pipeline object is returned in params
4021             GetShaderProgramId(programPipeline, ShaderType::Compute, params);
4022             break;
4023         }
4024 
4025         case GL_GEOMETRY_SHADER:
4026         {
4027             // the name of the current program object for the geometry shader type of the program
4028             // pipeline object is returned in params
4029             GetShaderProgramId(programPipeline, ShaderType::Geometry, params);
4030             break;
4031         }
4032 
4033         case GL_INFO_LOG_LENGTH:
4034         {
4035             // the length of the info log, including the null terminator, is returned in params. If
4036             // there is no info log, zero is returned.
4037             *params = 0;
4038             if (programPipeline)
4039             {
4040                 *params = programPipeline->getExecutable().getInfoLogLength();
4041             }
4042             break;
4043         }
4044 
4045         case GL_VALIDATE_STATUS:
4046         {
4047             // the validation status of pipeline, as determined by glValidateProgramPipeline, is
4048             // returned in params
4049             *params = 0;
4050             if (programPipeline)
4051             {
4052                 *params = programPipeline->isValid();
4053             }
4054             break;
4055         }
4056 
4057         default:
4058             break;
4059     }
4060 }
4061 
4062 }  // namespace gl
4063 
4064 namespace egl
4065 {
4066 
QueryConfigAttrib(const Config * config,EGLint attribute,EGLint * value)4067 void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value)
4068 {
4069     ASSERT(config != nullptr);
4070     switch (attribute)
4071     {
4072         case EGL_BUFFER_SIZE:
4073             *value = config->bufferSize;
4074             break;
4075         case EGL_ALPHA_SIZE:
4076             *value = config->alphaSize;
4077             break;
4078         case EGL_BLUE_SIZE:
4079             *value = config->blueSize;
4080             break;
4081         case EGL_GREEN_SIZE:
4082             *value = config->greenSize;
4083             break;
4084         case EGL_RED_SIZE:
4085             *value = config->redSize;
4086             break;
4087         case EGL_DEPTH_SIZE:
4088             *value = config->depthSize;
4089             break;
4090         case EGL_STENCIL_SIZE:
4091             *value = config->stencilSize;
4092             break;
4093         case EGL_CONFIG_CAVEAT:
4094             *value = config->configCaveat;
4095             break;
4096         case EGL_CONFIG_ID:
4097             *value = config->configID;
4098             break;
4099         case EGL_LEVEL:
4100             *value = config->level;
4101             break;
4102         case EGL_NATIVE_RENDERABLE:
4103             *value = config->nativeRenderable;
4104             break;
4105         case EGL_NATIVE_VISUAL_ID:
4106             *value = config->nativeVisualID;
4107             break;
4108         case EGL_NATIVE_VISUAL_TYPE:
4109             *value = config->nativeVisualType;
4110             break;
4111         case EGL_SAMPLES:
4112             *value = config->samples;
4113             break;
4114         case EGL_SAMPLE_BUFFERS:
4115             *value = config->sampleBuffers;
4116             break;
4117         case EGL_SURFACE_TYPE:
4118             *value = config->surfaceType;
4119             break;
4120         case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
4121             *value = config->bindToTextureTarget;
4122             break;
4123         case EGL_TRANSPARENT_TYPE:
4124             *value = config->transparentType;
4125             break;
4126         case EGL_TRANSPARENT_BLUE_VALUE:
4127             *value = config->transparentBlueValue;
4128             break;
4129         case EGL_TRANSPARENT_GREEN_VALUE:
4130             *value = config->transparentGreenValue;
4131             break;
4132         case EGL_TRANSPARENT_RED_VALUE:
4133             *value = config->transparentRedValue;
4134             break;
4135         case EGL_BIND_TO_TEXTURE_RGB:
4136             *value = config->bindToTextureRGB;
4137             break;
4138         case EGL_BIND_TO_TEXTURE_RGBA:
4139             *value = config->bindToTextureRGBA;
4140             break;
4141         case EGL_MIN_SWAP_INTERVAL:
4142             *value = config->minSwapInterval;
4143             break;
4144         case EGL_MAX_SWAP_INTERVAL:
4145             *value = config->maxSwapInterval;
4146             break;
4147         case EGL_LUMINANCE_SIZE:
4148             *value = config->luminanceSize;
4149             break;
4150         case EGL_ALPHA_MASK_SIZE:
4151             *value = config->alphaMaskSize;
4152             break;
4153         case EGL_COLOR_BUFFER_TYPE:
4154             *value = config->colorBufferType;
4155             break;
4156         case EGL_RENDERABLE_TYPE:
4157             *value = config->renderableType;
4158             break;
4159         case EGL_MATCH_NATIVE_PIXMAP:
4160             *value = false;
4161             UNIMPLEMENTED();
4162             break;
4163         case EGL_CONFORMANT:
4164             *value = config->conformant;
4165             break;
4166         case EGL_MAX_PBUFFER_WIDTH:
4167             *value = config->maxPBufferWidth;
4168             break;
4169         case EGL_MAX_PBUFFER_HEIGHT:
4170             *value = config->maxPBufferHeight;
4171             break;
4172         case EGL_MAX_PBUFFER_PIXELS:
4173             *value = config->maxPBufferPixels;
4174             break;
4175         case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
4176             *value = config->optimalOrientation;
4177             break;
4178         case EGL_COLOR_COMPONENT_TYPE_EXT:
4179             *value = config->colorComponentType;
4180             break;
4181         case EGL_RECORDABLE_ANDROID:
4182             *value = config->recordable;
4183             break;
4184         case EGL_FRAMEBUFFER_TARGET_ANDROID:
4185             *value = config->framebufferTarget;
4186             break;
4187         case EGL_MATCH_FORMAT_KHR:
4188             *value = config->matchFormat;
4189             break;
4190         default:
4191             UNREACHABLE();
4192             break;
4193     }
4194 }
4195 
QueryContextAttrib(const gl::Context * context,EGLint attribute,EGLint * value)4196 void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value)
4197 {
4198     switch (attribute)
4199     {
4200         case EGL_CONFIG_ID:
4201             if (context->getConfig() != EGL_NO_CONFIG_KHR)
4202             {
4203                 *value = context->getConfig()->configID;
4204             }
4205             else
4206             {
4207                 *value = 0;
4208             }
4209             break;
4210         case EGL_CONTEXT_CLIENT_TYPE:
4211             *value = context->getClientType();
4212             break;
4213         case EGL_CONTEXT_CLIENT_VERSION:
4214             *value = context->getClientMajorVersion();
4215             break;
4216         case EGL_RENDER_BUFFER:
4217             *value = context->getRenderBuffer();
4218             break;
4219         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
4220             *value = context->isRobustResourceInitEnabled();
4221             break;
4222         case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
4223             *value = static_cast<EGLint>(context->getContextPriority());
4224             break;
4225         case EGL_PROTECTED_CONTENT_EXT:
4226             *value = context->getState().hasProtectedContent();
4227             break;
4228         default:
4229             UNREACHABLE();
4230             break;
4231     }
4232 }
4233 
QuerySurfaceAttrib(const Display * display,const gl::Context * context,Surface * surface,EGLint attribute,EGLint * value)4234 egl::Error QuerySurfaceAttrib(const Display *display,
4235                               const gl::Context *context,
4236                               Surface *surface,
4237                               EGLint attribute,
4238                               EGLint *value)
4239 {
4240     switch (attribute)
4241     {
4242         case EGL_GL_COLORSPACE:
4243             *value = surface->getGLColorspace();
4244             break;
4245         case EGL_VG_ALPHA_FORMAT:
4246             *value = surface->getVGAlphaFormat();
4247             break;
4248         case EGL_VG_COLORSPACE:
4249             *value = surface->getVGColorspace();
4250             break;
4251         case EGL_CONFIG_ID:
4252             *value = surface->getConfig()->configID;
4253             break;
4254         case EGL_HEIGHT:
4255             ANGLE_TRY(surface->getUserHeight(display, value));
4256             break;
4257         case EGL_HORIZONTAL_RESOLUTION:
4258             *value = surface->getHorizontalResolution();
4259             break;
4260         case EGL_LARGEST_PBUFFER:
4261             // The EGL spec states that value is not written if the surface is not a pbuffer
4262             if (surface->getType() == EGL_PBUFFER_BIT)
4263             {
4264                 *value = surface->getLargestPbuffer();
4265             }
4266             break;
4267         case EGL_MIPMAP_TEXTURE:
4268             // The EGL spec states that value is not written if the surface is not a pbuffer
4269             if (surface->getType() == EGL_PBUFFER_BIT)
4270             {
4271                 *value = surface->getMipmapTexture();
4272             }
4273             break;
4274         case EGL_MIPMAP_LEVEL:
4275             // The EGL spec states that value is not written if the surface is not a pbuffer
4276             if (surface->getType() == EGL_PBUFFER_BIT)
4277             {
4278                 *value = surface->getMipmapLevel();
4279             }
4280             break;
4281         case EGL_MULTISAMPLE_RESOLVE:
4282             *value = surface->getMultisampleResolve();
4283             break;
4284         case EGL_PIXEL_ASPECT_RATIO:
4285             *value = surface->getPixelAspectRatio();
4286             break;
4287         case EGL_RENDER_BUFFER:
4288             *value = surface->getRenderBuffer();
4289             break;
4290         case EGL_SWAP_BEHAVIOR:
4291             *value = surface->getSwapBehavior();
4292             break;
4293         case EGL_TEXTURE_FORMAT:
4294             // The EGL spec states that value is not written if the surface is not a pbuffer
4295             if (surface->getType() == EGL_PBUFFER_BIT)
4296             {
4297                 *value = ToEGLenum(surface->getTextureFormat());
4298             }
4299             break;
4300         case EGL_TEXTURE_TARGET:
4301             // The EGL spec states that value is not written if the surface is not a pbuffer
4302             if (surface->getType() == EGL_PBUFFER_BIT)
4303             {
4304                 *value = surface->getTextureTarget();
4305             }
4306             break;
4307         case EGL_VERTICAL_RESOLUTION:
4308             *value = surface->getVerticalResolution();
4309             break;
4310         case EGL_WIDTH:
4311             ANGLE_TRY(surface->getUserWidth(display, value));
4312             break;
4313         case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
4314             *value = surface->isPostSubBufferSupported();
4315             break;
4316         case EGL_FIXED_SIZE_ANGLE:
4317             *value = surface->isFixedSize();
4318             break;
4319         case EGL_SURFACE_ORIENTATION_ANGLE:
4320             *value = surface->getOrientation();
4321             break;
4322         case EGL_DIRECT_COMPOSITION_ANGLE:
4323             *value = surface->directComposition();
4324             break;
4325         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
4326             *value = surface->isRobustResourceInitEnabled();
4327             break;
4328         case EGL_TIMESTAMPS_ANDROID:
4329             *value = surface->isTimestampsEnabled();
4330             break;
4331         case EGL_BUFFER_AGE_EXT:
4332             ANGLE_TRY(surface->getBufferAge(context, value));
4333             break;
4334         case EGL_BITMAP_PITCH_KHR:
4335             *value = surface->getBitmapPitch();
4336             break;
4337         case EGL_BITMAP_ORIGIN_KHR:
4338             *value = surface->getBitmapOrigin();
4339             break;
4340         case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
4341             *value = surface->getRedOffset();
4342             break;
4343         case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
4344             *value = surface->getGreenOffset();
4345             break;
4346         case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
4347             *value = surface->getBlueOffset();
4348             break;
4349         case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
4350             *value = surface->getAlphaOffset();
4351             break;
4352         case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
4353             *value = surface->getLuminanceOffset();
4354             break;
4355         case EGL_BITMAP_PIXEL_SIZE_KHR:
4356             *value = surface->getBitmapPixelSize();
4357             break;
4358         case EGL_PROTECTED_CONTENT_EXT:
4359             *value = surface->hasProtectedContent();
4360             break;
4361         default:
4362             UNREACHABLE();
4363             break;
4364     }
4365     return NoError();
4366 }
4367 
QuerySurfaceAttrib64KHR(const Display * display,const gl::Context * context,const Surface * surface,EGLint attribute,EGLAttribKHR * value)4368 egl::Error QuerySurfaceAttrib64KHR(const Display *display,
4369                                    const gl::Context *context,
4370                                    const Surface *surface,
4371                                    EGLint attribute,
4372                                    EGLAttribKHR *value)
4373 {
4374     switch (attribute)
4375     {
4376         case EGL_BITMAP_PITCH_KHR:
4377             *value = static_cast<EGLAttribKHR>(surface->getBitmapPitch());
4378             break;
4379         case EGL_BITMAP_ORIGIN_KHR:
4380             *value = static_cast<EGLAttribKHR>(surface->getBitmapOrigin());
4381             break;
4382         case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
4383             *value = static_cast<EGLAttribKHR>(surface->getRedOffset());
4384             break;
4385         case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
4386             *value = static_cast<EGLAttribKHR>(surface->getGreenOffset());
4387             break;
4388         case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
4389             *value = static_cast<EGLAttribKHR>(surface->getBlueOffset());
4390             break;
4391         case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
4392             *value = static_cast<EGLAttribKHR>(surface->getAlphaOffset());
4393             break;
4394         case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
4395             *value = static_cast<EGLAttribKHR>(surface->getLuminanceOffset());
4396             break;
4397         case EGL_BITMAP_PIXEL_SIZE_KHR:
4398             *value = static_cast<EGLAttribKHR>(surface->getBitmapPixelSize());
4399             break;
4400         case EGL_BITMAP_POINTER_KHR:
4401             *value = surface->getBitmapPointer();
4402             break;
4403         default:
4404             UNREACHABLE();
4405             break;
4406     }
4407     return NoError();
4408 }
4409 
SetSurfaceAttrib(Surface * surface,EGLint attribute,EGLint value)4410 egl::Error SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value)
4411 {
4412     switch (attribute)
4413     {
4414         case EGL_MIPMAP_LEVEL:
4415             surface->setMipmapLevel(value);
4416             break;
4417         case EGL_MULTISAMPLE_RESOLVE:
4418             surface->setMultisampleResolve(value);
4419             break;
4420         case EGL_SWAP_BEHAVIOR:
4421             surface->setSwapBehavior(value);
4422             break;
4423         case EGL_WIDTH:
4424             surface->setFixedWidth(value);
4425             break;
4426         case EGL_HEIGHT:
4427             surface->setFixedHeight(value);
4428             break;
4429         case EGL_TIMESTAMPS_ANDROID:
4430             surface->setTimestampsEnabled(value != EGL_FALSE);
4431             break;
4432         case EGL_RENDER_BUFFER:
4433             return surface->setRenderBuffer(value);
4434         default:
4435             UNREACHABLE();
4436             break;
4437     }
4438     return NoError();
4439 }
4440 
GetSyncAttrib(Display * display,Sync * sync,EGLint attribute,EGLint * value)4441 Error GetSyncAttrib(Display *display, Sync *sync, EGLint attribute, EGLint *value)
4442 {
4443     switch (attribute)
4444     {
4445         case EGL_SYNC_TYPE_KHR:
4446             *value = sync->getType();
4447             return NoError();
4448 
4449         case EGL_SYNC_STATUS_KHR:
4450             return sync->getStatus(display, value);
4451 
4452         case EGL_SYNC_CONDITION_KHR:
4453             *value = sync->getCondition();
4454             return NoError();
4455 
4456         default:
4457             break;
4458     }
4459 
4460     UNREACHABLE();
4461     return NoError();
4462 }
4463 }  // namespace egl
4464