155856b16629cd2836166094710a47ef25ab62d4cJamie Madill//
255856b16629cd2836166094710a47ef25ab62d4cJamie Madill// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
355856b16629cd2836166094710a47ef25ab62d4cJamie Madill// Use of this source code is governed by a BSD-style license that can be
455856b16629cd2836166094710a47ef25ab62d4cJamie Madill// found in the LICENSE file.
555856b16629cd2836166094710a47ef25ab62d4cJamie Madill//
655856b16629cd2836166094710a47ef25ab62d4cJamie Madill
755856b16629cd2836166094710a47ef25ab62d4cJamie Madill// queryconversions.cpp: Implementation of state query cast conversions
855856b16629cd2836166094710a47ef25ab62d4cJamie Madill
955856b16629cd2836166094710a47ef25ab62d4cJamie Madill#include "libGLESv2/Context.h"
1055856b16629cd2836166094710a47ef25ab62d4cJamie Madill#include "common/utilities.h"
1155856b16629cd2836166094710a47ef25ab62d4cJamie Madill
1255856b16629cd2836166094710a47ef25ab62d4cJamie Madillnamespace gl
1355856b16629cd2836166094710a47ef25ab62d4cJamie Madill{
1455856b16629cd2836166094710a47ef25ab62d4cJamie Madill
1555856b16629cd2836166094710a47ef25ab62d4cJamie Madill// Helper class for converting a GL type to a GLenum:
1655856b16629cd2836166094710a47ef25ab62d4cJamie Madill// We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap.
1755856b16629cd2836166094710a47ef25ab62d4cJamie Madill// We restrict our use to CastStateValue, where it eliminates duplicate parameters.
1855856b16629cd2836166094710a47ef25ab62d4cJamie Madill
1955856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate <typename GLType>
2055856b16629cd2836166094710a47ef25ab62d4cJamie Madillstruct CastStateValueEnum { static GLenum mEnumForType; };
2155856b16629cd2836166094710a47ef25ab62d4cJamie Madill
2255856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate <> GLenum CastStateValueEnum<GLint>::mEnumForType      = GL_INT;
2355856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate <> GLenum CastStateValueEnum<GLuint>::mEnumForType     = GL_UNSIGNED_INT;
2455856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate <> GLenum CastStateValueEnum<GLboolean>::mEnumForType  = GL_BOOL;
2555856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate <> GLenum CastStateValueEnum<GLint64>::mEnumForType    = GL_INT_64_ANGLEX;
2655856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate <> GLenum CastStateValueEnum<GLfloat>::mEnumForType    = GL_FLOAT;
2755856b16629cd2836166094710a47ef25ab62d4cJamie Madill
2855856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate <typename QueryT, typename NativeT>
2955856b16629cd2836166094710a47ef25ab62d4cJamie MadillQueryT CastStateValueToInt(GLenum pname, NativeT value)
3055856b16629cd2836166094710a47ef25ab62d4cJamie Madill{
3155856b16629cd2836166094710a47ef25ab62d4cJamie Madill    GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType;
3255856b16629cd2836166094710a47ef25ab62d4cJamie Madill    GLenum nativeType = CastStateValueEnum<NativeT>::mEnumForType;
3355856b16629cd2836166094710a47ef25ab62d4cJamie Madill
3455856b16629cd2836166094710a47ef25ab62d4cJamie Madill    if (nativeType == GL_FLOAT)
3555856b16629cd2836166094710a47ef25ab62d4cJamie Madill    {
3655856b16629cd2836166094710a47ef25ab62d4cJamie Madill        // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from Table 4.5
3755856b16629cd2836166094710a47ef25ab62d4cJamie Madill        if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
3855856b16629cd2836166094710a47ef25ab62d4cJamie Madill        {
3955856b16629cd2836166094710a47ef25ab62d4cJamie Madill            return static_cast<QueryT>((static_cast<GLfloat>(0xFFFFFFFF) * value - 1.0f) / 2.0f);
4055856b16629cd2836166094710a47ef25ab62d4cJamie Madill        }
4155856b16629cd2836166094710a47ef25ab62d4cJamie Madill        else
4255856b16629cd2836166094710a47ef25ab62d4cJamie Madill        {
4355856b16629cd2836166094710a47ef25ab62d4cJamie Madill            return gl::iround<QueryT>(value);
4455856b16629cd2836166094710a47ef25ab62d4cJamie Madill        }
4555856b16629cd2836166094710a47ef25ab62d4cJamie Madill    }
4655856b16629cd2836166094710a47ef25ab62d4cJamie Madill
4755856b16629cd2836166094710a47ef25ab62d4cJamie Madill    // Clamp 64-bit int values when casting to int
4855856b16629cd2836166094710a47ef25ab62d4cJamie Madill    if (nativeType == GL_INT_64_ANGLEX && queryType == GL_INT)
4955856b16629cd2836166094710a47ef25ab62d4cJamie Madill    {
5055856b16629cd2836166094710a47ef25ab62d4cJamie Madill        GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::min());
5155856b16629cd2836166094710a47ef25ab62d4cJamie Madill        GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::max());
5255856b16629cd2836166094710a47ef25ab62d4cJamie Madill        GLint64 clampedValue = std::max(std::min(static_cast<GLint64>(value), maxIntValue), minIntValue);
5355856b16629cd2836166094710a47ef25ab62d4cJamie Madill        return static_cast<QueryT>(clampedValue);
5455856b16629cd2836166094710a47ef25ab62d4cJamie Madill    }
5555856b16629cd2836166094710a47ef25ab62d4cJamie Madill
5655856b16629cd2836166094710a47ef25ab62d4cJamie Madill    return static_cast<QueryT>(value);
5755856b16629cd2836166094710a47ef25ab62d4cJamie Madill}
5855856b16629cd2836166094710a47ef25ab62d4cJamie Madill
5955856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate <typename QueryT, typename NativeT>
6055856b16629cd2836166094710a47ef25ab62d4cJamie MadillQueryT CastStateValue(GLenum pname, NativeT value)
6155856b16629cd2836166094710a47ef25ab62d4cJamie Madill{
6255856b16629cd2836166094710a47ef25ab62d4cJamie Madill    GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType;
6355856b16629cd2836166094710a47ef25ab62d4cJamie Madill
6455856b16629cd2836166094710a47ef25ab62d4cJamie Madill    switch (queryType)
6555856b16629cd2836166094710a47ef25ab62d4cJamie Madill    {
6655856b16629cd2836166094710a47ef25ab62d4cJamie Madill      case GL_INT:              return CastStateValueToInt<QueryT, NativeT>(pname, value);
6755856b16629cd2836166094710a47ef25ab62d4cJamie Madill      case GL_INT_64_ANGLEX:    return CastStateValueToInt<QueryT, NativeT>(pname, value);
6855856b16629cd2836166094710a47ef25ab62d4cJamie Madill      case GL_FLOAT:            return static_cast<QueryT>(value);
6955856b16629cd2836166094710a47ef25ab62d4cJamie Madill      case GL_BOOL:             return (value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
7055856b16629cd2836166094710a47ef25ab62d4cJamie Madill      default: UNREACHABLE();   return 0;
7155856b16629cd2836166094710a47ef25ab62d4cJamie Madill    }
7255856b16629cd2836166094710a47ef25ab62d4cJamie Madill}
7355856b16629cd2836166094710a47ef25ab62d4cJamie Madill
7455856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate <typename QueryT>
7555856b16629cd2836166094710a47ef25ab62d4cJamie Madillvoid CastStateValues(Context *context, GLenum nativeType, GLenum pname,
7655856b16629cd2836166094710a47ef25ab62d4cJamie Madill                     unsigned int numParams, QueryT *outParams)
7755856b16629cd2836166094710a47ef25ab62d4cJamie Madill{
7855856b16629cd2836166094710a47ef25ab62d4cJamie Madill    if (nativeType == GL_INT)
7955856b16629cd2836166094710a47ef25ab62d4cJamie Madill    {
8055856b16629cd2836166094710a47ef25ab62d4cJamie Madill        GLint *intParams = NULL;
8155856b16629cd2836166094710a47ef25ab62d4cJamie Madill        intParams = new GLint[numParams];
8255856b16629cd2836166094710a47ef25ab62d4cJamie Madill
8355856b16629cd2836166094710a47ef25ab62d4cJamie Madill        context->getIntegerv(pname, intParams);
8455856b16629cd2836166094710a47ef25ab62d4cJamie Madill
8555856b16629cd2836166094710a47ef25ab62d4cJamie Madill        for (unsigned int i = 0; i < numParams; ++i)
8655856b16629cd2836166094710a47ef25ab62d4cJamie Madill        {
8755856b16629cd2836166094710a47ef25ab62d4cJamie Madill            outParams[i] = CastStateValue<QueryT>(pname, intParams[i]);
8855856b16629cd2836166094710a47ef25ab62d4cJamie Madill        }
8955856b16629cd2836166094710a47ef25ab62d4cJamie Madill
9055856b16629cd2836166094710a47ef25ab62d4cJamie Madill        delete [] intParams;
9155856b16629cd2836166094710a47ef25ab62d4cJamie Madill    }
9255856b16629cd2836166094710a47ef25ab62d4cJamie Madill    else if (nativeType == GL_BOOL)
9355856b16629cd2836166094710a47ef25ab62d4cJamie Madill    {
9455856b16629cd2836166094710a47ef25ab62d4cJamie Madill        GLboolean *boolParams = NULL;
9555856b16629cd2836166094710a47ef25ab62d4cJamie Madill        boolParams = new GLboolean[numParams];
9655856b16629cd2836166094710a47ef25ab62d4cJamie Madill
9755856b16629cd2836166094710a47ef25ab62d4cJamie Madill        context->getBooleanv(pname, boolParams);
9855856b16629cd2836166094710a47ef25ab62d4cJamie Madill
9955856b16629cd2836166094710a47ef25ab62d4cJamie Madill        for (unsigned int i = 0; i < numParams; ++i)
10055856b16629cd2836166094710a47ef25ab62d4cJamie Madill        {
10155856b16629cd2836166094710a47ef25ab62d4cJamie Madill            outParams[i] = (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
10255856b16629cd2836166094710a47ef25ab62d4cJamie Madill        }
10355856b16629cd2836166094710a47ef25ab62d4cJamie Madill
10455856b16629cd2836166094710a47ef25ab62d4cJamie Madill        delete [] boolParams;
10555856b16629cd2836166094710a47ef25ab62d4cJamie Madill    }
10655856b16629cd2836166094710a47ef25ab62d4cJamie Madill    else if (nativeType == GL_FLOAT)
10755856b16629cd2836166094710a47ef25ab62d4cJamie Madill    {
10855856b16629cd2836166094710a47ef25ab62d4cJamie Madill        GLfloat *floatParams = NULL;
10955856b16629cd2836166094710a47ef25ab62d4cJamie Madill        floatParams = new GLfloat[numParams];
11055856b16629cd2836166094710a47ef25ab62d4cJamie Madill
11155856b16629cd2836166094710a47ef25ab62d4cJamie Madill        context->getFloatv(pname, floatParams);
11255856b16629cd2836166094710a47ef25ab62d4cJamie Madill
11355856b16629cd2836166094710a47ef25ab62d4cJamie Madill        for (unsigned int i = 0; i < numParams; ++i)
11455856b16629cd2836166094710a47ef25ab62d4cJamie Madill        {
11555856b16629cd2836166094710a47ef25ab62d4cJamie Madill            outParams[i] = CastStateValue<QueryT>(pname, floatParams[i]);
11655856b16629cd2836166094710a47ef25ab62d4cJamie Madill        }
11755856b16629cd2836166094710a47ef25ab62d4cJamie Madill
11855856b16629cd2836166094710a47ef25ab62d4cJamie Madill        delete [] floatParams;
11955856b16629cd2836166094710a47ef25ab62d4cJamie Madill    }
12055856b16629cd2836166094710a47ef25ab62d4cJamie Madill    else if (nativeType == GL_INT_64_ANGLEX)
12155856b16629cd2836166094710a47ef25ab62d4cJamie Madill    {
12255856b16629cd2836166094710a47ef25ab62d4cJamie Madill        GLint64 *int64Params = NULL;
12355856b16629cd2836166094710a47ef25ab62d4cJamie Madill        int64Params = new GLint64[numParams];
12455856b16629cd2836166094710a47ef25ab62d4cJamie Madill
12555856b16629cd2836166094710a47ef25ab62d4cJamie Madill        context->getInteger64v(pname, int64Params);
12655856b16629cd2836166094710a47ef25ab62d4cJamie Madill
12755856b16629cd2836166094710a47ef25ab62d4cJamie Madill        for (unsigned int i = 0; i < numParams; ++i)
12855856b16629cd2836166094710a47ef25ab62d4cJamie Madill        {
12955856b16629cd2836166094710a47ef25ab62d4cJamie Madill            outParams[i] = CastStateValue<QueryT>(pname, int64Params[i]);
13055856b16629cd2836166094710a47ef25ab62d4cJamie Madill        }
13155856b16629cd2836166094710a47ef25ab62d4cJamie Madill
13255856b16629cd2836166094710a47ef25ab62d4cJamie Madill        delete [] int64Params;
13355856b16629cd2836166094710a47ef25ab62d4cJamie Madill    }
13455856b16629cd2836166094710a47ef25ab62d4cJamie Madill    else UNREACHABLE();
13555856b16629cd2836166094710a47ef25ab62d4cJamie Madill}
13655856b16629cd2836166094710a47ef25ab62d4cJamie Madill
13755856b16629cd2836166094710a47ef25ab62d4cJamie Madill// Explicit template instantiation (how we export template functions in different files)
13855856b16629cd2836166094710a47ef25ab62d4cJamie Madill// The calls below will make CastStateValues successfully link with the GL state query types
13955856b16629cd2836166094710a47ef25ab62d4cJamie Madill// The GL state query API types are: bool, int, uint, float, int64
14055856b16629cd2836166094710a47ef25ab62d4cJamie Madill
14155856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate void CastStateValues<GLboolean>(Context *, GLenum, GLenum, unsigned int, GLboolean *);
14255856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate void CastStateValues<GLint>(Context *, GLenum, GLenum, unsigned int, GLint *);
14355856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate void CastStateValues<GLuint>(Context *, GLenum, GLenum, unsigned int, GLuint *);
14455856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate void CastStateValues<GLfloat>(Context *, GLenum, GLenum, unsigned int, GLfloat *);
14555856b16629cd2836166094710a47ef25ab62d4cJamie Madilltemplate void CastStateValues<GLint64>(Context *, GLenum, GLenum, unsigned int, GLint64 *);
14655856b16629cd2836166094710a47ef25ab62d4cJamie Madill
14755856b16629cd2836166094710a47ef25ab62d4cJamie Madill}
148