/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "GrGLUtil.h" #include "SkMatrix.h" #include <stdio.h> void GrGLClearErr(const GrGLInterface* gl) { while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {} } namespace { const char *get_error_string(uint32_t err) { switch (err) { case GR_GL_NO_ERROR: return ""; case GR_GL_INVALID_ENUM: return "Invalid Enum"; case GR_GL_INVALID_VALUE: return "Invalid Value"; case GR_GL_INVALID_OPERATION: return "Invalid Operation"; case GR_GL_OUT_OF_MEMORY: return "Out of Memory"; case GR_GL_CONTEXT_LOST: return "Context Lost"; } return "Unknown"; } } void GrGLCheckErr(const GrGLInterface* gl, const char* location, const char* call) { uint32_t err = GR_GL_GET_ERROR(gl); if (GR_GL_NO_ERROR != err) { GrPrintf("---- glGetError 0x%x(%s)", err, get_error_string(err)); if (NULL != location) { GrPrintf(" at\n\t%s", location); } if (NULL != call) { GrPrintf("\n\t\t%s", call); } GrPrintf("\n"); } } namespace { // Mesa uses a non-standard version string of format: 1.4 Mesa <mesa_major>.<mesa_minor>. // The mapping of from mesa version to GL version came from here: http://www.mesa3d.org/intro.html bool get_gl_version_for_mesa(int mesaMajorVersion, int* major, int* minor) { switch (mesaMajorVersion) { case 2: case 3: case 4: case 5: case 6: *major = 1; *minor = mesaMajorVersion - 1; return true; case 7: *major = 2; *minor = 1; return true; case 8: *major = 3; *minor = 0; return true; case 9: *major = 3; *minor = 1; return true; case 10: *major = 3; *minor = 3; return true; default: return false; } } } /////////////////////////////////////////////////////////////////////////////// #if GR_GL_LOG_CALLS bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START); #endif #if GR_GL_CHECK_ERROR bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START); #endif /////////////////////////////////////////////////////////////////////////////// GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) { if (NULL == versionString) { SkDebugf("NULL GL version string."); return kNone_GrGLStandard; } int major, minor; // check for desktop int n = sscanf(versionString, "%d.%d", &major, &minor); if (2 == n) { return kGL_GrGLStandard; } // check for ES 1 char profile[2]; n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor); if (4 == n) { // we no longer support ES1. return kNone_GrGLStandard; } // check for ES2 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor); if (2 == n) { return kGLES_GrGLStandard; } return kNone_GrGLStandard; } bool GrGLIsMesaFromVersionString(const char* versionString) { int major, minor, mesaMajor, mesaMinor; int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor); return 4 == n; } bool GrGLIsChromiumFromRendererString(const char* rendererString) { return 0 == strcmp(rendererString, "Chromium"); } GrGLVersion GrGLGetVersionFromString(const char* versionString) { if (NULL == versionString) { SkDebugf("NULL GL version string."); return GR_GL_INVALID_VER; } int major, minor; // check for mesa int mesaMajor, mesaMinor; int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor); if (4 == n) { if (get_gl_version_for_mesa(mesaMajor, &major, &minor)) { return GR_GL_VER(major, minor); } else { return GR_GL_INVALID_VER; } } n = sscanf(versionString, "%d.%d", &major, &minor); if (2 == n) { return GR_GL_VER(major, minor); } char profile[2]; n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor); if (4 == n) { return GR_GL_VER(major, minor); } n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor); if (2 == n) { return GR_GL_VER(major, minor); } return GR_GL_INVALID_VER; } GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) { if (NULL == versionString) { SkDebugf("NULL GLSL version string."); return GR_GLSL_INVALID_VER; } int major, minor; int n = sscanf(versionString, "%d.%d", &major, &minor); if (2 == n) { return GR_GLSL_VER(major, minor); } n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor); if (2 == n) { return GR_GLSL_VER(major, minor); } #ifdef SK_BUILD_FOR_ANDROID // android hack until the gpu vender updates their drivers n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor); if (2 == n) { return GR_GLSL_VER(major, minor); } #endif return GR_GLSL_INVALID_VER; } GrGLVendor GrGLGetVendorFromString(const char* vendorString) { if (NULL != vendorString) { if (0 == strcmp(vendorString, "ARM")) { return kARM_GrGLVendor; } if (0 == strcmp(vendorString, "Imagination Technologies")) { return kImagination_GrGLVendor; } if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) { return kIntel_GrGLVendor; } if (0 == strcmp(vendorString, "Qualcomm")) { return kQualcomm_GrGLVendor; } } return kOther_GrGLVendor; } GrGLRenderer GrGLGetRendererFromString(const char* rendererString) { if (NULL != rendererString) { if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) { return kTegra3_GrGLRenderer; } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) { return kTegra2_GrGLRenderer; } } return kOther_GrGLRenderer; } GrGLVersion GrGLGetVersion(const GrGLInterface* gl) { const GrGLubyte* v; GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION)); return GrGLGetVersionFromString((const char*) v); } GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) { const GrGLubyte* v; GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); return GrGLGetGLSLVersionFromString((const char*) v); } GrGLVendor GrGLGetVendor(const GrGLInterface* gl) { const GrGLubyte* v; GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR)); return GrGLGetVendorFromString((const char*) v); } GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) { const GrGLubyte* v; GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER)); return GrGLGetRendererFromString((const char*) v); } template<> void GrGLGetMatrix<3>(GrGLfloat* dest, const SkMatrix& src) { // Col 0 dest[0] = SkScalarToFloat(src[SkMatrix::kMScaleX]); dest[1] = SkScalarToFloat(src[SkMatrix::kMSkewY]); dest[2] = SkScalarToFloat(src[SkMatrix::kMPersp0]); // Col 1 dest[3] = SkScalarToFloat(src[SkMatrix::kMSkewX]); dest[4] = SkScalarToFloat(src[SkMatrix::kMScaleY]); dest[5] = SkScalarToFloat(src[SkMatrix::kMPersp1]); // Col 2 dest[6] = SkScalarToFloat(src[SkMatrix::kMTransX]); dest[7] = SkScalarToFloat(src[SkMatrix::kMTransY]); dest[8] = SkScalarToFloat(src[SkMatrix::kMPersp2]); } template<> void GrGLGetMatrix<4>(GrGLfloat* dest, const SkMatrix& src) { // Col 0 dest[0] = SkScalarToFloat(src[SkMatrix::kMScaleX]); dest[1] = SkScalarToFloat(src[SkMatrix::kMSkewY]); dest[2] = 0; dest[3] = SkScalarToFloat(src[SkMatrix::kMPersp0]); // Col 1 dest[4] = SkScalarToFloat(src[SkMatrix::kMSkewX]); dest[5] = SkScalarToFloat(src[SkMatrix::kMScaleY]); dest[6] = 0; dest[7] = SkScalarToFloat(src[SkMatrix::kMPersp1]); // Col 2 dest[8] = 0; dest[9] = 0; dest[10] = 1; dest[11] = 0; // Col 3 dest[12] = SkScalarToFloat(src[SkMatrix::kMTransX]); dest[13] = SkScalarToFloat(src[SkMatrix::kMTransY]); dest[14] = 0; dest[15] = SkScalarToFloat(src[SkMatrix::kMPersp2]); }