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     // These null checks are for test GL contexts that return nullptr in their
    106     // glGetString implementation.
    107     if (!rendererString) {
    108         rendererString = "";
    109     }
    110     if (!versionString) {
    111         versionString = "";
    112     }
    113 
    114     static const char kChromium[] = "Chromium";
    115     char suffix[SK_ARRAY_COUNT(kChromium)];
    116     if (0 == strcmp(rendererString, kChromium) ||
    117         (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) &&
    118          0 == strcmp(kChromium, suffix))) {
    119         *outDriver = kChromium_GrGLDriver;
    120         return;
    121     }
    122 
    123     if (standard == kGL_GrGLStandard) {
    124         if (kNVIDIA_GrGLVendor == vendor) {
    125             *outDriver = kNVIDIA_GrGLDriver;
    126             int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
    127                            &major, &minor, &rev, &driverMajor, &driverMinor);
    128             // Some older NVIDIA drivers don't report the driver version.
    129             if (5 == n) {
    130                 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
    131             }
    132             return;
    133         }
    134         int n = sscanf(versionString, "%d.%d Mesa %d.%d",
    135                        &major, &minor, &driverMajor, &driverMinor);
    136         if (4 == n) {
    137             *outDriver = kMesa_GrGLDriver;
    138             *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
    139             return;
    140         }
    141     }
    142     else {
    143         if (kNVIDIA_GrGLVendor == vendor) {
    144             *outDriver = kNVIDIA_GrGLDriver;
    145             int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
    146                            &major, &minor, &driverMajor, &driverMinor);
    147             // Some older NVIDIA drivers don't report the driver version.
    148             if (4 == n) {
    149                 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
    150             }
    151             return;
    152         }
    153 
    154         int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
    155                        &major, &minor, &driverMajor, &driverMinor);
    156         if (4 == n) {
    157             *outDriver = kMesa_GrGLDriver;
    158             *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
    159             return;
    160         }
    161         if (0 == strncmp("ANGLE", rendererString, 5)) {
    162             *outDriver = kANGLE_GrGLDriver;
    163             n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
    164                                                                       &driverMinor);
    165             if (4 == n) {
    166                 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
    167             }
    168             return;
    169         }
    170     }
    171 
    172     if (kIntel_GrGLVendor == vendor) {
    173         // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
    174         *outDriver = kIntel_GrGLDriver;
    175     }
    176 
    177     if (kQualcomm_GrGLVendor == vendor) {
    178         *outDriver = kQualcomm_GrGLDriver;
    179         int n = sscanf(versionString, "OpenGL ES %d.%d V@%d.%d", &major, &minor, &driverMajor,
    180                        &driverMinor);
    181         if (4 == n) {
    182             *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
    183         }
    184         return;
    185     }
    186 }
    187 
    188 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
    189     if (nullptr == versionString) {
    190         SkDebugf("nullptr GL version string.");
    191         return GR_GL_INVALID_VER;
    192     }
    193 
    194     int major, minor;
    195 
    196     // check for mesa
    197     int mesaMajor, mesaMinor;
    198     int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    199     if (4 == n) {
    200         return GR_GL_VER(major, minor);
    201     }
    202 
    203     n = sscanf(versionString, "%d.%d", &major, &minor);
    204     if (2 == n) {
    205         return GR_GL_VER(major, minor);
    206     }
    207 
    208     char profile[2];
    209     n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
    210                &major, &minor);
    211     if (4 == n) {
    212         return GR_GL_VER(major, minor);
    213     }
    214 
    215     n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    216     if (2 == n) {
    217         return GR_GL_VER(major, minor);
    218     }
    219 
    220     return GR_GL_INVALID_VER;
    221 }
    222 
    223 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
    224     if (nullptr == versionString) {
    225         SkDebugf("nullptr GLSL version string.");
    226         return GR_GLSL_INVALID_VER;
    227     }
    228 
    229     int major, minor;
    230 
    231     int n = sscanf(versionString, "%d.%d", &major, &minor);
    232     if (2 == n) {
    233         return GR_GLSL_VER(major, minor);
    234     }
    235 
    236     n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
    237     if (2 == n) {
    238         return GR_GLSL_VER(major, minor);
    239     }
    240 
    241 #ifdef SK_BUILD_FOR_ANDROID
    242     // android hack until the gpu vender updates their drivers
    243     n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
    244     if (2 == n) {
    245         return GR_GLSL_VER(major, minor);
    246     }
    247 #endif
    248 
    249     return GR_GLSL_INVALID_VER;
    250 }
    251 
    252 GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
    253     if (vendorString) {
    254         if (0 == strcmp(vendorString, "ARM")) {
    255             return kARM_GrGLVendor;
    256         }
    257         if (0 == strcmp(vendorString, "Imagination Technologies")) {
    258             return kImagination_GrGLVendor;
    259         }
    260         if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
    261             return kIntel_GrGLVendor;
    262         }
    263         if (0 == strcmp(vendorString, "Qualcomm")) {
    264             return kQualcomm_GrGLVendor;
    265         }
    266         if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
    267             return kNVIDIA_GrGLVendor;
    268         }
    269         if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
    270             return kATI_GrGLVendor;
    271         }
    272     }
    273     return kOther_GrGLVendor;
    274 }
    275 
    276 GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
    277     if (rendererString) {
    278         if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
    279             return kTegra3_GrGLRenderer;
    280         } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
    281             return kTegra2_GrGLRenderer;
    282         }
    283         int lastDigit;
    284         int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
    285         if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
    286             return kPowerVR54x_GrGLRenderer;
    287         }
    288         // certain iOS devices also use PowerVR54x GPUs
    289         static const char kAppleA4Str[] = "Apple A4";
    290         static const char kAppleA5Str[] = "Apple A5";
    291         static const char kAppleA6Str[] = "Apple A6";
    292         if (0 == strncmp(rendererString, kAppleA4Str,
    293                          SK_ARRAY_COUNT(kAppleA4Str)-1) ||
    294             0 == strncmp(rendererString, kAppleA5Str,
    295                          SK_ARRAY_COUNT(kAppleA5Str)-1) ||
    296             0 == strncmp(rendererString, kAppleA6Str,
    297                          SK_ARRAY_COUNT(kAppleA6Str)-1)) {
    298             return kPowerVR54x_GrGLRenderer;
    299         }
    300         static const char kPowerVRRogueStr[] = "PowerVR Rogue";
    301         static const char kAppleA7Str[] = "Apple A7";
    302         static const char kAppleA8Str[] = "Apple A8";
    303         if (0 == strncmp(rendererString, kPowerVRRogueStr,
    304                          SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
    305             0 == strncmp(rendererString, kAppleA7Str,
    306                          SK_ARRAY_COUNT(kAppleA7Str)-1) ||
    307             0 == strncmp(rendererString, kAppleA8Str,
    308                          SK_ARRAY_COUNT(kAppleA8Str)-1)) {
    309             return kPowerVRRogue_GrGLRenderer;
    310         }
    311         int adrenoNumber;
    312         n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
    313         if (1 == n) {
    314             if (adrenoNumber >= 300) {
    315                 if (adrenoNumber < 400) {
    316                     return kAdreno3xx_GrGLRenderer;
    317                 }
    318                 if (adrenoNumber < 500) {
    319                     return kAdreno4xx_GrGLRenderer;
    320                 }
    321                 if (adrenoNumber < 600) {
    322                     return kAdreno5xx_GrGLRenderer;
    323                 }
    324             }
    325         }
    326         int intelNumber;
    327         n = sscanf(rendererString, "Intel(R) Iris(TM) Graphics %d", &intelNumber);
    328         if (1 != n) {
    329             n = sscanf(rendererString, "Intel(R) HD Graphics %d", &intelNumber);
    330         }
    331         if (1 == n) {
    332             if (intelNumber >= 6000 && intelNumber < 7000) {
    333                 return kIntel6xxx_GrGLRenderer;
    334             }
    335         }
    336         if (0 == strcmp("Mesa Offscreen", rendererString)) {
    337             return kOSMesa_GrGLRenderer;
    338         }
    339         static const char kMaliTStr[] = "Mali-T";
    340         if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
    341             return kMaliT_GrGLRenderer;
    342         }
    343         static const char kANGLEStr[] = "ANGLE";
    344         if (0 == strncmp(rendererString, kANGLEStr, SK_ARRAY_COUNT(kANGLEStr) - 1)) {
    345             return kANGLE_GrGLRenderer;
    346         }
    347     }
    348     return kOther_GrGLRenderer;
    349 }
    350 
    351 GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
    352     const GrGLubyte* v;
    353     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
    354     return GrGLGetVersionFromString((const char*) v);
    355 }
    356 
    357 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
    358     const GrGLubyte* v;
    359     GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
    360     return GrGLGetGLSLVersionFromString((const char*) v);
    361 }
    362 
    363 GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
    364     const GrGLubyte* v;
    365     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
    366     return GrGLGetVendorFromString((const char*) v);
    367 }
    368 
    369 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
    370     const GrGLubyte* v;
    371     GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
    372     return GrGLGetRendererFromString((const char*) v);
    373 }
    374 
    375 GrGLenum GrToGLStencilFunc(GrStencilTest test) {
    376     static const GrGLenum gTable[kGrStencilTestCount] = {
    377         GR_GL_ALWAYS,           // kAlways
    378         GR_GL_NEVER,            // kNever
    379         GR_GL_GREATER,          // kGreater
    380         GR_GL_GEQUAL,           // kGEqual
    381         GR_GL_LESS,             // kLess
    382         GR_GL_LEQUAL,           // kLEqual
    383         GR_GL_EQUAL,            // kEqual
    384         GR_GL_NOTEQUAL,         // kNotEqual
    385     };
    386     GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways);
    387     GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever);
    388     GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater);
    389     GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual);
    390     GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess);
    391     GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual);
    392     GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual);
    393     GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual);
    394     SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
    395 
    396     return gTable[(int)test];
    397 }
    398