GrGLUtil.cpp revision 7a434a28685fd045cf848b99b563dfcf978363bc
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
11void GrGLClearErr(const GrGLInterface* gl) {
12    while (GR_GL_NO_ERROR != gl->fGetError()) {}
13}
14
15namespace {
16const char *get_error_string(uint32_t err) {
17    switch (err) {
18    case GR_GL_NO_ERROR:
19        return "";
20    case GR_GL_INVALID_ENUM:
21        return "Invalid Enum";
22    case GR_GL_INVALID_VALUE:
23        return "Invalid Value";
24    case GR_GL_INVALID_OPERATION:
25        return "Invalid Operation";
26    case GR_GL_OUT_OF_MEMORY:
27        return "Out of Memory";
28    case GR_GL_CONTEXT_LOST:
29        return "Context Lost";
30    }
31    return "Unknown";
32}
33}
34
35void GrGLCheckErr(const GrGLInterface* gl,
36                  const char* location,
37                  const char* call) {
38    uint32_t err = GR_GL_GET_ERROR(gl);
39    if (GR_GL_NO_ERROR != err) {
40        GrPrintf("---- glGetError 0x%x(%s)", err, get_error_string(err));
41        if (NULL != location) {
42            GrPrintf(" at\n\t%s", location);
43        }
44        if (NULL != call) {
45            GrPrintf("\n\t\t%s", call);
46        }
47        GrPrintf("\n");
48    }
49}
50
51namespace {
52// Mesa uses a non-standard version string of format: 1.4 Mesa <mesa_major>.<mesa_minor>.
53// The mapping of from mesa version to GL version came from here: http://www.mesa3d.org/intro.html
54bool get_gl_version_for_mesa(int mesaMajorVersion, int* major, int* minor) {
55    switch (mesaMajorVersion) {
56        case 2:
57        case 3:
58        case 4:
59        case 5:
60        case 6:
61            *major = 1;
62            *minor = mesaMajorVersion - 1;
63            return true;
64        case 7:
65            *major = 2;
66            *minor = 1;
67            return true;
68        case 8:
69            *major = 3;
70            *minor = 0;
71            return true;
72        case 9:
73            *major = 3;
74            *minor = 1;
75            return true;
76        default:
77            return false;
78    }
79}
80}
81
82///////////////////////////////////////////////////////////////////////////////
83
84#if GR_GL_LOG_CALLS
85    bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
86#endif
87
88#if GR_GL_CHECK_ERROR
89    bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
90#endif
91
92///////////////////////////////////////////////////////////////////////////////
93
94GrGLBinding GrGLGetBindingInUseFromString(const char* versionString) {
95    if (NULL == versionString) {
96        SkASSERT(!"NULL GL version string.");
97        return kNone_GrGLBinding;
98    }
99
100    int major, minor;
101
102    // check for desktop
103    int n = sscanf(versionString, "%d.%d", &major, &minor);
104    if (2 == n) {
105        return kDesktop_GrGLBinding;
106    }
107
108    // check for ES 1
109    char profile[2];
110    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
111    if (4 == n) {
112        // we no longer support ES1.
113        return kNone_GrGLBinding;
114    }
115
116    // check for ES2
117    n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
118    if (2 == n) {
119        return kES_GrGLBinding;
120    }
121    return kNone_GrGLBinding;
122}
123
124bool GrGLIsMesaFromVersionString(const char* versionString) {
125    int major, minor, mesaMajor, mesaMinor;
126    int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
127    return 4 == n;
128}
129
130GrGLVersion GrGLGetVersionFromString(const char* versionString) {
131    if (NULL == versionString) {
132        SkASSERT(!"NULL GL version string.");
133        return 0;
134    }
135
136    int major, minor;
137
138    // check for mesa
139    int mesaMajor, mesaMinor;
140    int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
141    if (4 == n) {
142        if (get_gl_version_for_mesa(mesaMajor, &major, &minor)) {
143            return GR_GL_VER(major, minor);
144        } else {
145            return 0;
146        }
147    }
148
149    n = sscanf(versionString, "%d.%d", &major, &minor);
150    if (2 == n) {
151        return GR_GL_VER(major, minor);
152    }
153
154    char profile[2];
155    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
156               &major, &minor);
157    if (4 == n) {
158        return GR_GL_VER(major, minor);
159    }
160
161    n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
162    if (2 == n) {
163        return GR_GL_VER(major, minor);
164    }
165
166    return 0;
167}
168
169GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
170    if (NULL == versionString) {
171        SkASSERT(!"NULL GLSL version string.");
172        return 0;
173    }
174
175    int major, minor;
176
177    int n = sscanf(versionString, "%d.%d", &major, &minor);
178    if (2 == n) {
179        return GR_GLSL_VER(major, minor);
180    }
181
182    n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
183    if (2 == n) {
184        return GR_GLSL_VER(major, minor);
185    }
186
187#ifdef SK_BUILD_FOR_ANDROID
188    // android hack until the gpu vender updates their drivers
189    n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
190    if (2 == n) {
191        return GR_GLSL_VER(major, minor);
192    }
193#endif
194
195    return 0;
196}
197
198GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
199    if (NULL != vendorString) {
200        if (0 == strcmp(vendorString, "ARM")) {
201            return kARM_GrGLVendor;
202        }
203        if (0 == strcmp(vendorString, "Imagination Technologies")) {
204            return kImagination_GrGLVendor;
205        }
206        if (0 == strcmp(vendorString, "Intel")) {
207            return kIntel_GrGLVendor;
208        }
209        if (0 == strcmp(vendorString, "Qualcomm")) {
210            return kQualcomm_GrGLVendor;
211        }
212    }
213    return kOther_GrGLVendor;
214}
215
216GrGLBinding GrGLGetBindingInUse(const GrGLInterface* gl) {
217    const GrGLubyte* v;
218    GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
219    return GrGLGetBindingInUseFromString((const char*) v);
220}
221
222GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
223    const GrGLubyte* v;
224    GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
225    return GrGLGetVersionFromString((const char*) v);
226}
227
228GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
229    const GrGLubyte* v;
230    GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
231    return GrGLGetGLSLVersionFromString((const char*) v);
232}
233
234GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
235    const GrGLubyte* v;
236    GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
237    return GrGLGetVendorFromString((const char*) v);
238}
239