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->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         default:
     79             return false;
     80     }
     81 }
     82 }
     83 
     84 ///////////////////////////////////////////////////////////////////////////////
     85 
     86 #if GR_GL_LOG_CALLS
     87     bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
     88 #endif
     89 
     90 #if GR_GL_CHECK_ERROR
     91     bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
     92 #endif
     93 
     94 ///////////////////////////////////////////////////////////////////////////////
     95 
     96 GrGLBinding GrGLGetBindingInUseFromString(const char* versionString) {
     97     if (NULL == versionString) {
     98         SkDEBUGFAIL("NULL GL version string.");
     99         return kNone_GrGLBinding;
    100     }
    101 
    102     int major, minor;
    103 
    104     // check for desktop
    105     int n = sscanf(versionString, "%d.%d", &major, &minor);
    106     if (2 == n) {
    107         return kDesktop_GrGLBinding;
    108     }
    109 
    110     // check for ES 1
    111     char profile[2];
    112     n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
    113     if (4 == n) {
    114         // we no longer support ES1.
    115         return kNone_GrGLBinding;
    116     }
    117 
    118     // check for ES2
    119     n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    120     if (2 == n) {
    121         return kES_GrGLBinding;
    122     }
    123     return kNone_GrGLBinding;
    124 }
    125 
    126 bool GrGLIsMesaFromVersionString(const char* versionString) {
    127     int major, minor, mesaMajor, mesaMinor;
    128     int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    129     return 4 == n;
    130 }
    131 
    132 bool GrGLIsChromiumFromRendererString(const char* rendererString) {
    133     return 0 == strcmp(rendererString, "Chromium");
    134 }
    135 
    136 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
    137     if (NULL == versionString) {
    138         SkDEBUGFAIL("NULL GL version string.");
    139         return 0;
    140     }
    141 
    142     int major, minor;
    143 
    144     // check for mesa
    145     int mesaMajor, mesaMinor;
    146     int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    147     if (4 == n) {
    148         if (get_gl_version_for_mesa(mesaMajor, &major, &minor)) {
    149             return GR_GL_VER(major, minor);
    150         } else {
    151             return 0;
    152         }
    153     }
    154 
    155     n = sscanf(versionString, "%d.%d", &major, &minor);
    156     if (2 == n) {
    157         return GR_GL_VER(major, minor);
    158     }
    159 
    160     char profile[2];
    161     n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
    162                &major, &minor);
    163     if (4 == n) {
    164         return GR_GL_VER(major, minor);
    165     }
    166 
    167     n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    168     if (2 == n) {
    169         return GR_GL_VER(major, minor);
    170     }
    171 
    172     return 0;
    173 }
    174 
    175 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
    176     if (NULL == versionString) {
    177         SkDEBUGFAIL("NULL GLSL version string.");
    178         return 0;
    179     }
    180 
    181     int major, minor;
    182 
    183     int n = sscanf(versionString, "%d.%d", &major, &minor);
    184     if (2 == n) {
    185         return GR_GLSL_VER(major, minor);
    186     }
    187 
    188     n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
    189     if (2 == n) {
    190         return GR_GLSL_VER(major, minor);
    191     }
    192 
    193 #ifdef SK_BUILD_FOR_ANDROID
    194     // android hack until the gpu vender updates their drivers
    195     n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
    196     if (2 == n) {
    197         return GR_GLSL_VER(major, minor);
    198     }
    199 #endif
    200 
    201     return 0;
    202 }
    203 
    204 GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
    205     if (NULL != vendorString) {
    206         if (0 == strcmp(vendorString, "ARM")) {
    207             return kARM_GrGLVendor;
    208         }
    209         if (0 == strcmp(vendorString, "Imagination Technologies")) {
    210             return kImagination_GrGLVendor;
    211         }
    212         if (0 == strcmp(vendorString, "Intel")) {
    213             return kIntel_GrGLVendor;
    214         }
    215         if (0 == strcmp(vendorString, "Qualcomm")) {
    216             return kQualcomm_GrGLVendor;
    217         }
    218     }
    219     return kOther_GrGLVendor;
    220 }
    221 
    222 GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
    223     if (NULL != rendererString) {
    224         if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
    225             return kTegra3_GrGLRenderer;
    226         }
    227     }
    228     return kOther_GrGLRenderer;
    229 }
    230 
    231 GrGLBinding GrGLGetBindingInUse(const GrGLInterface* gl) {
    232     const GrGLubyte* v;
    233     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
    234     return GrGLGetBindingInUseFromString((const char*) v);
    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