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