|
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 SkDEBUGFAIL("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 SkDEBUGFAIL("NULL GL version string."); |
|
143 return 0; |
|
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 0; |
|
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 0; |
|
177 } |
|
178 |
|
179 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) { |
|
180 if (NULL == versionString) { |
|
181 SkDEBUGFAIL("NULL GLSL version string."); |
|
182 return 0; |
|
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 0; |
|
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 } |