Home | History | Annotate | Download | only in libGLESv2
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 //
      7 
      8 // queryconversions.cpp: Implementation of state query cast conversions
      9 
     10 #include "libGLESv2/Context.h"
     11 #include "common/utilities.h"
     12 
     13 namespace gl
     14 {
     15 
     16 // Helper class for converting a GL type to a GLenum:
     17 // We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap.
     18 // We restrict our use to CastStateValue, where it eliminates duplicate parameters.
     19 
     20 template <typename GLType>
     21 struct CastStateValueEnum { static GLenum mEnumForType; };
     22 
     23 template <> GLenum CastStateValueEnum<GLint>::mEnumForType      = GL_INT;
     24 template <> GLenum CastStateValueEnum<GLuint>::mEnumForType     = GL_UNSIGNED_INT;
     25 template <> GLenum CastStateValueEnum<GLboolean>::mEnumForType  = GL_BOOL;
     26 template <> GLenum CastStateValueEnum<GLint64>::mEnumForType    = GL_INT_64_ANGLEX;
     27 template <> GLenum CastStateValueEnum<GLfloat>::mEnumForType    = GL_FLOAT;
     28 
     29 template <typename QueryT, typename NativeT>
     30 QueryT CastStateValueToInt(GLenum pname, NativeT value)
     31 {
     32     GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType;
     33     GLenum nativeType = CastStateValueEnum<NativeT>::mEnumForType;
     34 
     35     if (nativeType == GL_FLOAT)
     36     {
     37         // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from Table 4.5
     38         if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
     39         {
     40             return static_cast<QueryT>((static_cast<GLfloat>(0xFFFFFFFF) * value - 1.0f) / 2.0f);
     41         }
     42         else
     43         {
     44             return gl::iround<QueryT>(value);
     45         }
     46     }
     47 
     48     // Clamp 64-bit int values when casting to int
     49     if (nativeType == GL_INT_64_ANGLEX && queryType == GL_INT)
     50     {
     51         GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::min());
     52         GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::max());
     53         GLint64 clampedValue = std::max(std::min(static_cast<GLint64>(value), maxIntValue), minIntValue);
     54         return static_cast<QueryT>(clampedValue);
     55     }
     56 
     57     return static_cast<QueryT>(value);
     58 }
     59 
     60 template <typename QueryT, typename NativeT>
     61 QueryT CastStateValue(GLenum pname, NativeT value)
     62 {
     63     GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType;
     64 
     65     switch (queryType)
     66     {
     67       case GL_INT:              return CastStateValueToInt<QueryT, NativeT>(pname, value);
     68       case GL_INT_64_ANGLEX:    return CastStateValueToInt<QueryT, NativeT>(pname, value);
     69       case GL_FLOAT:            return static_cast<QueryT>(value);
     70       case GL_BOOL:             return (value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
     71       default: UNREACHABLE();   return 0;
     72     }
     73 }
     74 
     75 template <typename QueryT>
     76 void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
     77                      unsigned int numParams, QueryT *outParams)
     78 {
     79     if (nativeType == GL_INT)
     80     {
     81         GLint *intParams = NULL;
     82         intParams = new GLint[numParams];
     83 
     84         context->getIntegerv(pname, intParams);
     85 
     86         for (unsigned int i = 0; i < numParams; ++i)
     87         {
     88             outParams[i] = CastStateValue<QueryT>(pname, intParams[i]);
     89         }
     90 
     91         delete [] intParams;
     92     }
     93     else if (nativeType == GL_BOOL)
     94     {
     95         GLboolean *boolParams = NULL;
     96         boolParams = new GLboolean[numParams];
     97 
     98         context->getBooleanv(pname, boolParams);
     99 
    100         for (unsigned int i = 0; i < numParams; ++i)
    101         {
    102             outParams[i] = (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1));
    103         }
    104 
    105         delete [] boolParams;
    106     }
    107     else if (nativeType == GL_FLOAT)
    108     {
    109         GLfloat *floatParams = NULL;
    110         floatParams = new GLfloat[numParams];
    111 
    112         context->getFloatv(pname, floatParams);
    113 
    114         for (unsigned int i = 0; i < numParams; ++i)
    115         {
    116             outParams[i] = CastStateValue<QueryT>(pname, floatParams[i]);
    117         }
    118 
    119         delete [] floatParams;
    120     }
    121     else if (nativeType == GL_INT_64_ANGLEX)
    122     {
    123         GLint64 *int64Params = NULL;
    124         int64Params = new GLint64[numParams];
    125 
    126         context->getInteger64v(pname, int64Params);
    127 
    128         for (unsigned int i = 0; i < numParams; ++i)
    129         {
    130             outParams[i] = CastStateValue<QueryT>(pname, int64Params[i]);
    131         }
    132 
    133         delete [] int64Params;
    134     }
    135     else UNREACHABLE();
    136 }
    137 
    138 // Explicit template instantiation (how we export template functions in different files)
    139 // The calls below will make CastStateValues successfully link with the GL state query types
    140 // The GL state query API types are: bool, int, uint, float, int64
    141 
    142 template void CastStateValues<GLboolean>(Context *, GLenum, GLenum, unsigned int, GLboolean *);
    143 template void CastStateValues<GLint>(Context *, GLenum, GLenum, unsigned int, GLint *);
    144 template void CastStateValues<GLuint>(Context *, GLenum, GLenum, unsigned int, GLuint *);
    145 template void CastStateValues<GLfloat>(Context *, GLenum, GLenum, unsigned int, GLfloat *);
    146 template void CastStateValues<GLint64>(Context *, GLenum, GLenum, unsigned int, GLint64 *);
    147 
    148 }
    149