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         GrPrintf("---- glGetError 0x%x(%s)", err, get_error_string(err));
     43         if (NULL != location) {
     44             GrPrintf(" at\n\t%s", location);
     45         }
     46         if (NULL != call) {
     47             GrPrintf("\n\t\t%s", call);
     48         }
     49         GrPrintf("\n");
     50     }
     51 }
     52 
     53 namespace {
     54 // Mesa uses a non-standard version string of format: 1.4 Mesa <mesa_major>.<mesa_minor>.
     55 // The mapping of from mesa version to GL version came from here: http://www.mesa3d.org/intro.html
     56 bool get_gl_version_for_mesa(int mesaMajorVersion, int* major, int* minor) {
     57     switch (mesaMajorVersion) {
     58         case 2:
     59         case 3:
     60         case 4:
     61         case 5:
     62         case 6:
     63             *major = 1;
     64             *minor = mesaMajorVersion - 1;
     65             return true;
     66         case 7:
     67             *major = 2;
     68             *minor = 1;
     69             return true;
     70         case 8:
     71             *major = 3;
     72             *minor = 0;
     73             return true;
     74         case 9:
     75             *major = 3;
     76             *minor = 1;
     77             return true;
     78         case 10:
     79             *major = 3;
     80             *minor = 3;
     81             return true;
     82         default:
     83             return false;
     84     }
     85 }
     86 }
     87 
     88 ///////////////////////////////////////////////////////////////////////////////
     89 
     90 #if GR_GL_LOG_CALLS
     91     bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
     92 #endif
     93 
     94 #if GR_GL_CHECK_ERROR
     95     bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
     96 #endif
     97 
     98 ///////////////////////////////////////////////////////////////////////////////
     99 
    100 GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
    101     if (NULL == versionString) {
    102         SkDebugf("NULL GL version string.");
    103         return kNone_GrGLStandard;
    104     }
    105 
    106     int major, minor;
    107 
    108     // check for desktop
    109     int n = sscanf(versionString, "%d.%d", &major, &minor);
    110     if (2 == n) {
    111         return kGL_GrGLStandard;
    112     }
    113 
    114     // check for ES 1
    115     char profile[2];
    116     n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
    117     if (4 == n) {
    118         // we no longer support ES1.
    119         return kNone_GrGLStandard;
    120     }
    121 
    122     // check for ES2
    123     n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    124     if (2 == n) {
    125         return kGLES_GrGLStandard;
    126     }
    127     return kNone_GrGLStandard;
    128 }
    129 
    130 bool GrGLIsMesaFromVersionString(const char* versionString) {
    131     int major, minor, mesaMajor, mesaMinor;
    132     int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    133     return 4 == n;
    134 }
    135 
    136 bool GrGLIsChromiumFromRendererString(const char* rendererString) {
    137     return 0 == strcmp(rendererString, "Chromium");
    138 }
    139 
    140 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
    141     if (NULL == versionString) {
    142         SkDebugf("NULL GL version string.");
    143         return GR_GL_INVALID_VER;
    144     }
    145 
    146     int major, minor;
    147 
    148     // check for mesa
    149     int mesaMajor, mesaMinor;
    150     int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    151     if (4 == n) {
    152         if (get_gl_version_for_mesa(mesaMajor, &major, &minor)) {
    153             return GR_GL_VER(major, minor);
    154         } else {
    155             return GR_GL_INVALID_VER;
    156         }
    157     }
    158 
    159     n = sscanf(versionString, "%d.%d", &major, &minor);
    160     if (2 == n) {
    161         return GR_GL_VER(major, minor);
    162     }
    163 
    164     char profile[2];
    165     n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
    166                &major, &minor);
    167     if (4 == n) {
    168         return GR_GL_VER(major, minor);
    169     }
    170 
    171     n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    172     if (2 == n) {
    173         return GR_GL_VER(major, minor);
    174     }
    175 
    176     return GR_GL_INVALID_VER;
    177 }
    178 
    179 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
    180     if (NULL == versionString) {
    181         SkDebugf("NULL GLSL version string.");
    182         return GR_GLSL_INVALID_VER;
    183     }
    184 
    185     int major, minor;
    186 
    187     int n = sscanf(versionString, "%d.%d", &major, &minor);
    188     if (2 == n) {
    189         return GR_GLSL_VER(major, minor);
    190     }
    191 
    192     n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
    193     if (2 == n) {
    194         return GR_GLSL_VER(major, minor);
    195     }
    196 
    197 #ifdef SK_BUILD_FOR_ANDROID
    198     // android hack until the gpu vender updates their drivers
    199     n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
    200     if (2 == n) {
    201         return GR_GLSL_VER(major, minor);
    202     }
    203 #endif
    204 
    205     return GR_GLSL_INVALID_VER;
    206 }
    207 
    208 GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
    209     if (NULL != vendorString) {
    210         if (0 == strcmp(vendorString, "ARM")) {
    211             return kARM_GrGLVendor;
    212         }
    213         if (0 == strcmp(vendorString, "Imagination Technologies")) {
    214             return kImagination_GrGLVendor;
    215         }
    216         if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
    217             return kIntel_GrGLVendor;
    218         }
    219         if (0 == strcmp(vendorString, "Qualcomm")) {
    220             return kQualcomm_GrGLVendor;
    221         }
    222     }
    223     return kOther_GrGLVendor;
    224 }
    225 
    226 GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
    227     if (NULL != rendererString) {
    228         if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
    229             return kTegra3_GrGLRenderer;
    230         } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
    231             return kTegra2_GrGLRenderer;
    232         }
    233     }
    234     return kOther_GrGLRenderer;
    235 }
    236 
    237 GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
    238     const GrGLubyte* v;
    239     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
    240     return GrGLGetVersionFromString((const char*) v);
    241 }
    242 
    243 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
    244     const GrGLubyte* v;
    245     GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
    246     return GrGLGetGLSLVersionFromString((const char*) v);
    247 }
    248 
    249 GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
    250     const GrGLubyte* v;
    251     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
    252     return GrGLGetVendorFromString((const char*) v);
    253 }
    254 
    255 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
    256     const GrGLubyte* v;
    257     GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
    258     return GrGLGetRendererFromString((const char*) v);
    259 }
    260 
    261 template<> void GrGLGetMatrix<3>(GrGLfloat* dest, const SkMatrix& src) {
    262     // Col 0
    263     dest[0] = SkScalarToFloat(src[SkMatrix::kMScaleX]);
    264     dest[1] = SkScalarToFloat(src[SkMatrix::kMSkewY]);
    265     dest[2] = SkScalarToFloat(src[SkMatrix::kMPersp0]);
    266 
    267     // Col 1
    268     dest[3] = SkScalarToFloat(src[SkMatrix::kMSkewX]);
    269     dest[4] = SkScalarToFloat(src[SkMatrix::kMScaleY]);
    270     dest[5] = SkScalarToFloat(src[SkMatrix::kMPersp1]);
    271 
    272     // Col 2
    273     dest[6] = SkScalarToFloat(src[SkMatrix::kMTransX]);
    274     dest[7] = SkScalarToFloat(src[SkMatrix::kMTransY]);
    275     dest[8] = SkScalarToFloat(src[SkMatrix::kMPersp2]);
    276 }
    277 
    278 template<> void GrGLGetMatrix<4>(GrGLfloat* dest, const SkMatrix& src) {
    279     // Col 0
    280     dest[0]  = SkScalarToFloat(src[SkMatrix::kMScaleX]);
    281     dest[1]  = SkScalarToFloat(src[SkMatrix::kMSkewY]);
    282     dest[2]  = 0;
    283     dest[3]  = SkScalarToFloat(src[SkMatrix::kMPersp0]);
    284 
    285     // Col 1
    286     dest[4]  = SkScalarToFloat(src[SkMatrix::kMSkewX]);
    287     dest[5]  = SkScalarToFloat(src[SkMatrix::kMScaleY]);
    288     dest[6]  = 0;
    289     dest[7]  = SkScalarToFloat(src[SkMatrix::kMPersp1]);
    290 
    291     // Col 2
    292     dest[8]  = 0;
    293     dest[9]  = 0;
    294     dest[10] = 1;
    295     dest[11] = 0;
    296 
    297     // Col 3
    298     dest[12] = SkScalarToFloat(src[SkMatrix::kMTransX]);
    299     dest[13] = SkScalarToFloat(src[SkMatrix::kMTransY]);
    300     dest[14] = 0;
    301     dest[15] = SkScalarToFloat(src[SkMatrix::kMPersp2]);
    302 }
    303