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 (nullptr == versionString) {
     67         SkDebugf("nullptr 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 void GrGLGetDriverInfo(GrGLStandard standard,
     96                        GrGLVendor vendor,
     97                        const char* rendererString,
     98                        const char* versionString,
     99                        GrGLDriver* outDriver,
    100                        GrGLDriverVersion* outVersion) {
    101     int major, minor, rev, driverMajor, driverMinor;
    102 
    103     *outDriver = kUnknown_GrGLDriver;
    104     *outVersion = GR_GL_DRIVER_UNKNOWN_VER;
    105 
    106     if (0 == strcmp(rendererString, "Chromium")) {
    107         *outDriver = kChromium_GrGLDriver;
    108         return;
    109     }
    110 
    111     if (standard == kGL_GrGLStandard) {
    112         if (kNVIDIA_GrGLVendor == vendor) {
    113             *outDriver = kNVIDIA_GrGLDriver;
    114             int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
    115                            &major, &minor, &rev, &driverMajor, &driverMinor);
    116             // Some older NVIDIA drivers don't report the driver version.
    117             if (5 == n) {
    118                 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
    119             }
    120             return;
    121         }
    122 
    123         int n = sscanf(versionString, "%d.%d Mesa %d.%d",
    124                        &major, &minor, &driverMajor, &driverMinor);
    125         if (4 == n) {
    126             *outDriver = kMesa_GrGLDriver;
    127             *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
    128             return;
    129         }
    130     }
    131     else {
    132         if (kNVIDIA_GrGLVendor == vendor) {
    133             *outDriver = kNVIDIA_GrGLDriver;
    134             int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
    135                            &major, &minor, &driverMajor, &driverMinor);
    136             // Some older NVIDIA drivers don't report the driver version.
    137             if (4 == n) {
    138                 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
    139             }
    140             return;
    141         }
    142 
    143         int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
    144                        &major, &minor, &driverMajor, &driverMinor);
    145         if (4 == n) {
    146             *outDriver = kMesa_GrGLDriver;
    147             *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
    148             return;
    149         }
    150         if (0 == strncmp("ANGLE", rendererString, 5)) {
    151             *outDriver = kANGLE_GrGLDriver;
    152             n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
    153                                                                       &driverMinor);
    154             if (4 == n) {
    155                 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
    156             }
    157             return;
    158         }
    159     }
    160 
    161     if (kIntel_GrGLVendor == vendor) {
    162         // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
    163         *outDriver = kIntel_GrGLDriver;
    164     }
    165 }
    166 
    167 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
    168     if (nullptr == versionString) {
    169         SkDebugf("nullptr GL version string.");
    170         return GR_GL_INVALID_VER;
    171     }
    172 
    173     int major, minor;
    174 
    175     // check for mesa
    176     int mesaMajor, mesaMinor;
    177     int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    178     if (4 == n) {
    179         return GR_GL_VER(major, minor);
    180     }
    181 
    182     n = sscanf(versionString, "%d.%d", &major, &minor);
    183     if (2 == n) {
    184         return GR_GL_VER(major, minor);
    185     }
    186 
    187     char profile[2];
    188     n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
    189                &major, &minor);
    190     if (4 == n) {
    191         return GR_GL_VER(major, minor);
    192     }
    193 
    194     n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    195     if (2 == n) {
    196         return GR_GL_VER(major, minor);
    197     }
    198 
    199     return GR_GL_INVALID_VER;
    200 }
    201 
    202 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
    203     if (nullptr == versionString) {
    204         SkDebugf("nullptr GLSL version string.");
    205         return GR_GLSL_INVALID_VER;
    206     }
    207 
    208     int major, minor;
    209 
    210     int n = sscanf(versionString, "%d.%d", &major, &minor);
    211     if (2 == n) {
    212         return GR_GLSL_VER(major, minor);
    213     }
    214 
    215     n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
    216     if (2 == n) {
    217         return GR_GLSL_VER(major, minor);
    218     }
    219 
    220 #ifdef SK_BUILD_FOR_ANDROID
    221     // android hack until the gpu vender updates their drivers
    222     n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
    223     if (2 == n) {
    224         return GR_GLSL_VER(major, minor);
    225     }
    226 #endif
    227 
    228     return GR_GLSL_INVALID_VER;
    229 }
    230 
    231 GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
    232     if (vendorString) {
    233         if (0 == strcmp(vendorString, "ARM")) {
    234             return kARM_GrGLVendor;
    235         }
    236         if (0 == strcmp(vendorString, "Imagination Technologies")) {
    237             return kImagination_GrGLVendor;
    238         }
    239         if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
    240             return kIntel_GrGLVendor;
    241         }
    242         if (0 == strcmp(vendorString, "Qualcomm")) {
    243             return kQualcomm_GrGLVendor;
    244         }
    245         if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
    246             return kNVIDIA_GrGLVendor;
    247         }
    248     }
    249     return kOther_GrGLVendor;
    250 }
    251 
    252 GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
    253     if (rendererString) {
    254         if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
    255             return kTegra3_GrGLRenderer;
    256         } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
    257             return kTegra2_GrGLRenderer;
    258         }
    259         int lastDigit;
    260         int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
    261         if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
    262             return kPowerVR54x_GrGLRenderer;
    263         }
    264         // certain iOS devices also use PowerVR54x GPUs
    265         static const char kAppleA4Str[] = "Apple A4";
    266         static const char kAppleA5Str[] = "Apple A5";
    267         static const char kAppleA6Str[] = "Apple A6";
    268         if (0 == strncmp(rendererString, kAppleA4Str,
    269                          SK_ARRAY_COUNT(kAppleA4Str)-1) ||
    270             0 == strncmp(rendererString, kAppleA5Str,
    271                          SK_ARRAY_COUNT(kAppleA5Str)-1) ||
    272             0 == strncmp(rendererString, kAppleA6Str,
    273                          SK_ARRAY_COUNT(kAppleA6Str)-1)) {
    274             return kPowerVR54x_GrGLRenderer;
    275         }
    276         static const char kPowerVRRogueStr[] = "PowerVR Rogue";
    277         static const char kAppleA7Str[] = "Apple A7";
    278         static const char kAppleA8Str[] = "Apple A8";
    279         if (0 == strncmp(rendererString, kPowerVRRogueStr,
    280                          SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
    281             0 == strncmp(rendererString, kAppleA7Str,
    282                          SK_ARRAY_COUNT(kAppleA7Str)-1) ||
    283             0 == strncmp(rendererString, kAppleA8Str,
    284                          SK_ARRAY_COUNT(kAppleA8Str)-1)) {
    285             return kPowerVRRogue_GrGLRenderer;
    286         }
    287         int adrenoNumber;
    288         n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
    289         if (1 == n) {
    290             if (adrenoNumber >= 300) {
    291                 if (adrenoNumber < 400) {
    292                     return kAdreno3xx_GrGLRenderer;
    293                 }
    294                 if (adrenoNumber < 500) {
    295                     return kAdreno4xx_GrGLRenderer;
    296                 }
    297             }
    298         }
    299     }
    300     return kOther_GrGLRenderer;
    301 }
    302 
    303 GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
    304     const GrGLubyte* v;
    305     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
    306     return GrGLGetVersionFromString((const char*) v);
    307 }
    308 
    309 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
    310     const GrGLubyte* v;
    311     GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
    312     return GrGLGetGLSLVersionFromString((const char*) v);
    313 }
    314 
    315 GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
    316     const GrGLubyte* v;
    317     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
    318     return GrGLGetVendorFromString((const char*) v);
    319 }
    320 
    321 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
    322     const GrGLubyte* v;
    323     GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
    324     return GrGLGetRendererFromString((const char*) v);
    325 }
    326 
    327 GrGLenum GrToGLStencilFunc(GrStencilFunc basicFunc) {
    328     static const GrGLenum gTable[] = {
    329         GR_GL_ALWAYS,           // kAlways_StencilFunc
    330         GR_GL_NEVER,            // kNever_StencilFunc
    331         GR_GL_GREATER,          // kGreater_StencilFunc
    332         GR_GL_GEQUAL,           // kGEqual_StencilFunc
    333         GR_GL_LESS,             // kLess_StencilFunc
    334         GR_GL_LEQUAL,           // kLEqual_StencilFunc,
    335         GR_GL_EQUAL,            // kEqual_StencilFunc,
    336         GR_GL_NOTEQUAL,         // kNotEqual_StencilFunc,
    337     };
    338     GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kBasicStencilFuncCount);
    339     GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
    340     GR_STATIC_ASSERT(1 == kNever_StencilFunc);
    341     GR_STATIC_ASSERT(2 == kGreater_StencilFunc);
    342     GR_STATIC_ASSERT(3 == kGEqual_StencilFunc);
    343     GR_STATIC_ASSERT(4 == kLess_StencilFunc);
    344     GR_STATIC_ASSERT(5 == kLEqual_StencilFunc);
    345     GR_STATIC_ASSERT(6 == kEqual_StencilFunc);
    346     GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc);
    347     SkASSERT((unsigned) basicFunc < kBasicStencilFuncCount);
    348 
    349     return gTable[basicFunc];
    350 }
    351