Home | History | Annotate | Download | only in gl
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      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 
      9 #include "GrGLUtil.h"
     10 #include "SkMatrix.h"
     11 #include <stdio.h>
     12 
     13 void GrGLClearErr(const GrGLInterface* gl) {
     14     while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {}
     15 }
     16 
     17 namespace {
     18 const char *get_error_string(uint32_t err) {
     19     switch (err) {
     20     case GR_GL_NO_ERROR:
     21         return "";
     22     case GR_GL_INVALID_ENUM:
     23         return "Invalid Enum";
     24     case GR_GL_INVALID_VALUE:
     25         return "Invalid Value";
     26     case GR_GL_INVALID_OPERATION:
     27         return "Invalid Operation";
     28     case GR_GL_OUT_OF_MEMORY:
     29         return "Out of Memory";
     30     case GR_GL_CONTEXT_LOST:
     31         return "Context Lost";
     32     }
     33     return "Unknown";
     34 }
     35 }
     36 
     37 void GrGLCheckErr(const GrGLInterface* gl,
     38                   const char* location,
     39                   const char* call) {
     40     uint32_t err = GR_GL_GET_ERROR(gl);
     41     if (GR_GL_NO_ERROR != err) {
     42         SkDebugf("---- glGetError 0x%x(%s)", err, get_error_string(err));
     43         if (location) {
     44             SkDebugf(" at\n\t%s", location);
     45         }
     46         if (call) {
     47             SkDebugf("\n\t\t%s", call);
     48         }
     49         SkDebugf("\n");
     50     }
     51 }
     52 
     53 ///////////////////////////////////////////////////////////////////////////////
     54 
     55 #if GR_GL_LOG_CALLS
     56     bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
     57 #endif
     58 
     59 #if GR_GL_CHECK_ERROR
     60     bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
     61 #endif
     62 
     63 ///////////////////////////////////////////////////////////////////////////////
     64 
     65 GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
     66     if (NULL == versionString) {
     67         SkDebugf("NULL GL version string.");
     68         return kNone_GrGLStandard;
     69     }
     70 
     71     int major, minor;
     72 
     73     // check for desktop
     74     int n = sscanf(versionString, "%d.%d", &major, &minor);
     75     if (2 == n) {
     76         return kGL_GrGLStandard;
     77     }
     78 
     79     // check for ES 1
     80     char profile[2];
     81     n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
     82     if (4 == n) {
     83         // we no longer support ES1.
     84         return kNone_GrGLStandard;
     85     }
     86 
     87     // check for ES2
     88     n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
     89     if (2 == n) {
     90         return kGLES_GrGLStandard;
     91     }
     92     return kNone_GrGLStandard;
     93 }
     94 
     95 bool GrGLIsMesaFromVersionString(const char* versionString) {
     96     int major, minor, mesaMajor, mesaMinor;
     97 
     98     GrGLStandard standard = GrGLGetStandardInUseFromString(versionString);
     99 
    100     if (standard == kGL_GrGLStandard) {
    101         int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    102         return 4 == n;
    103     }
    104     else {
    105         int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    106         return 4 == n;
    107     }
    108     return false;
    109 }
    110 
    111 bool GrGLIsChromiumFromRendererString(const char* rendererString) {
    112     return 0 == strcmp(rendererString, "Chromium");
    113 }
    114 
    115 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
    116     if (NULL == versionString) {
    117         SkDebugf("NULL GL version string.");
    118         return GR_GL_INVALID_VER;
    119     }
    120 
    121     int major, minor;
    122 
    123     // check for mesa
    124     int mesaMajor, mesaMinor;
    125     int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    126     if (4 == n) {
    127         return GR_GL_VER(major, minor);
    128     }
    129 
    130     n = sscanf(versionString, "%d.%d", &major, &minor);
    131     if (2 == n) {
    132         return GR_GL_VER(major, minor);
    133     }
    134 
    135     char profile[2];
    136     n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
    137                &major, &minor);
    138     if (4 == n) {
    139         return GR_GL_VER(major, minor);
    140     }
    141 
    142     n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    143     if (2 == n) {
    144         return GR_GL_VER(major, minor);
    145     }
    146 
    147     return GR_GL_INVALID_VER;
    148 }
    149 
    150 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
    151     if (NULL == versionString) {
    152         SkDebugf("NULL GLSL version string.");
    153         return GR_GLSL_INVALID_VER;
    154     }
    155 
    156     int major, minor;
    157 
    158     int n = sscanf(versionString, "%d.%d", &major, &minor);
    159     if (2 == n) {
    160         return GR_GLSL_VER(major, minor);
    161     }
    162 
    163     n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
    164     if (2 == n) {
    165         return GR_GLSL_VER(major, minor);
    166     }
    167 
    168 #ifdef SK_BUILD_FOR_ANDROID
    169     // android hack until the gpu vender updates their drivers
    170     n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
    171     if (2 == n) {
    172         return GR_GLSL_VER(major, minor);
    173     }
    174 #endif
    175 
    176     return GR_GLSL_INVALID_VER;
    177 }
    178 
    179 GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
    180     if (vendorString) {
    181         if (0 == strcmp(vendorString, "ARM")) {
    182             return kARM_GrGLVendor;
    183         }
    184         if (0 == strcmp(vendorString, "Imagination Technologies")) {
    185             return kImagination_GrGLVendor;
    186         }
    187         if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
    188             return kIntel_GrGLVendor;
    189         }
    190         if (0 == strcmp(vendorString, "Qualcomm")) {
    191             return kQualcomm_GrGLVendor;
    192         }
    193         if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
    194             return kNVIDIA_GrGLVendor;
    195         }
    196     }
    197     return kOther_GrGLVendor;
    198 }
    199 
    200 GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
    201     if (rendererString) {
    202         if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
    203             return kTegra3_GrGLRenderer;
    204         } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
    205             return kTegra2_GrGLRenderer;
    206         }
    207         int lastDigit;
    208         int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
    209         if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
    210             return kPowerVR54x_GrGLRenderer;
    211         }
    212         static const char kPowerVRRogueStr[] = "PowerVR Rogue";
    213         if (0 == strncmp(rendererString, kPowerVRRogueStr,
    214                          SK_ARRAY_COUNT(kPowerVRRogueStr)-1)) {
    215             return kPowerVRRogue_GrGLRenderer;
    216         }
    217         int adrenoNumber;
    218         n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
    219         if (1 == n) {
    220             if (adrenoNumber >= 300) {
    221                 if (adrenoNumber < 400) {
    222                     return kAdreno3xx_GrGLRenderer;
    223                 }
    224                 if (adrenoNumber < 500) {
    225                     return kAdreno4xx_GrGLRenderer;
    226                 }
    227             }
    228         }
    229     }
    230     return kOther_GrGLRenderer;
    231 }
    232 
    233 GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
    234     const GrGLubyte* v;
    235     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
    236     return GrGLGetVersionFromString((const char*) v);
    237 }
    238 
    239 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
    240     const GrGLubyte* v;
    241     GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
    242     return GrGLGetGLSLVersionFromString((const char*) v);
    243 }
    244 
    245 GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
    246     const GrGLubyte* v;
    247     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
    248     return GrGLGetVendorFromString((const char*) v);
    249 }
    250 
    251 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
    252     const GrGLubyte* v;
    253     GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
    254     return GrGLGetRendererFromString((const char*) v);
    255 }
    256 
    257 template<> void GrGLGetMatrix<3>(GrGLfloat* dest, const SkMatrix& src) {
    258     // Col 0
    259     dest[0] = SkScalarToFloat(src[SkMatrix::kMScaleX]);
    260     dest[1] = SkScalarToFloat(src[SkMatrix::kMSkewY]);
    261     dest[2] = SkScalarToFloat(src[SkMatrix::kMPersp0]);
    262 
    263     // Col 1
    264     dest[3] = SkScalarToFloat(src[SkMatrix::kMSkewX]);
    265     dest[4] = SkScalarToFloat(src[SkMatrix::kMScaleY]);
    266     dest[5] = SkScalarToFloat(src[SkMatrix::kMPersp1]);
    267 
    268     // Col 2
    269     dest[6] = SkScalarToFloat(src[SkMatrix::kMTransX]);
    270     dest[7] = SkScalarToFloat(src[SkMatrix::kMTransY]);
    271     dest[8] = SkScalarToFloat(src[SkMatrix::kMPersp2]);
    272 }
    273 
    274 template<> void GrGLGetMatrix<4>(GrGLfloat* dest, const SkMatrix& src) {
    275     // Col 0
    276     dest[0]  = SkScalarToFloat(src[SkMatrix::kMScaleX]);
    277     dest[1]  = SkScalarToFloat(src[SkMatrix::kMSkewY]);
    278     dest[2]  = 0;
    279     dest[3]  = SkScalarToFloat(src[SkMatrix::kMPersp0]);
    280 
    281     // Col 1
    282     dest[4]  = SkScalarToFloat(src[SkMatrix::kMSkewX]);
    283     dest[5]  = SkScalarToFloat(src[SkMatrix::kMScaleY]);
    284     dest[6]  = 0;
    285     dest[7]  = SkScalarToFloat(src[SkMatrix::kMPersp1]);
    286 
    287     // Col 2
    288     dest[8]  = 0;
    289     dest[9]  = 0;
    290     dest[10] = 1;
    291     dest[11] = 0;
    292 
    293     // Col 3
    294     dest[12] = SkScalarToFloat(src[SkMatrix::kMTransX]);
    295     dest[13] = SkScalarToFloat(src[SkMatrix::kMTransY]);
    296     dest[14] = 0;
    297     dest[15] = SkScalarToFloat(src[SkMatrix::kMPersp2]);
    298 }
    299 
    300 GrGLenum GrToGLStencilFunc(GrStencilFunc basicFunc) {
    301     static const GrGLenum gTable[] = {
    302         GR_GL_ALWAYS,           // kAlways_StencilFunc
    303         GR_GL_NEVER,            // kNever_StencilFunc
    304         GR_GL_GREATER,          // kGreater_StencilFunc
    305         GR_GL_GEQUAL,           // kGEqual_StencilFunc
    306         GR_GL_LESS,             // kLess_StencilFunc
    307         GR_GL_LEQUAL,           // kLEqual_StencilFunc,
    308         GR_GL_EQUAL,            // kEqual_StencilFunc,
    309         GR_GL_NOTEQUAL,         // kNotEqual_StencilFunc,
    310     };
    311     GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kBasicStencilFuncCount);
    312     GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
    313     GR_STATIC_ASSERT(1 == kNever_StencilFunc);
    314     GR_STATIC_ASSERT(2 == kGreater_StencilFunc);
    315     GR_STATIC_ASSERT(3 == kGEqual_StencilFunc);
    316     GR_STATIC_ASSERT(4 == kLess_StencilFunc);
    317     GR_STATIC_ASSERT(5 == kLEqual_StencilFunc);
    318     GR_STATIC_ASSERT(6 == kEqual_StencilFunc);
    319     GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc);
    320     SkASSERT((unsigned) basicFunc < kBasicStencilFuncCount);
    321 
    322     return gTable[basicFunc];
    323 }
    324