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
GrGLClearErr(const GrGLInterface * gl)13 void GrGLClearErr(const GrGLInterface* gl) {
14 while (GR_GL_NO_ERROR != gl->fGetError()) {}
15 }
16
17 namespace {
get_error_string(uint32_t err)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
GrGLCheckErr(const GrGLInterface * gl,const char * location,const char * call)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
get_gl_version_for_mesa(int mesaMajorVersion,int * major,int * minor)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
GrGLGetBindingInUseFromString(const char * versionString)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
GrGLIsMesaFromVersionString(const char * versionString)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
GrGLIsChromiumFromRendererString(const char * rendererString)132 bool GrGLIsChromiumFromRendererString(const char* rendererString) {
133 return 0 == strcmp(rendererString, "Chromium");
134 }
135
GrGLGetVersionFromString(const char * versionString)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
GrGLGetGLSLVersionFromString(const char * versionString)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
GrGLGetVendorFromString(const char * vendorString)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
GrGLGetRendererFromString(const char * rendererString)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
GrGLGetBindingInUse(const GrGLInterface * gl)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
GrGLGetVersion(const GrGLInterface * gl)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
GrGLGetGLSLVersion(const GrGLInterface * gl)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
GrGLGetVendor(const GrGLInterface * gl)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
GrGLGetRenderer(const GrGLInterface * gl)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
GrGLGetMatrix(GrGLfloat * dest,const SkMatrix & src)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
GrGLGetMatrix(GrGLfloat * dest,const SkMatrix & src)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