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