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->fFunctions.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 SkDebugf("---- glGetError 0x%x(%s)", err, get_error_string(err));
43 if (location) {
44 SkDebugf(" at\n\t%s", location);
45 }
46 if (call) {
47 SkDebugf("\n\t\t%s", call);
48 }
49 SkDebugf("\n");
50 }
51 }
52
53 ///////////////////////////////////////////////////////////////////////////////
54
55 #if GR_GL_LOG_CALLS
56 bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
57 #endif
58
59 #if GR_GL_CHECK_ERROR
60 bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
61 #endif
62
63 ///////////////////////////////////////////////////////////////////////////////
64
GrGLGetStandardInUseFromString(const char * versionString)65 GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
66 if (NULL == versionString) {
67 SkDebugf("NULL GL version string.");
68 return kNone_GrGLStandard;
69 }
70
71 int major, minor;
72
73 // check for desktop
74 int n = sscanf(versionString, "%d.%d", &major, &minor);
75 if (2 == n) {
76 return kGL_GrGLStandard;
77 }
78
79 // check for ES 1
80 char profile[2];
81 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
82 if (4 == n) {
83 // we no longer support ES1.
84 return kNone_GrGLStandard;
85 }
86
87 // check for ES2
88 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
89 if (2 == n) {
90 return kGLES_GrGLStandard;
91 }
92 return kNone_GrGLStandard;
93 }
94
GrGLIsMesaFromVersionString(const char * versionString)95 bool GrGLIsMesaFromVersionString(const char* versionString) {
96 int major, minor, mesaMajor, mesaMinor;
97
98 GrGLStandard standard = GrGLGetStandardInUseFromString(versionString);
99
100 if (standard == kGL_GrGLStandard) {
101 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
102 return 4 == n;
103 }
104 else {
105 int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
106 return 4 == n;
107 }
108 return false;
109 }
110
GrGLIsChromiumFromRendererString(const char * rendererString)111 bool GrGLIsChromiumFromRendererString(const char* rendererString) {
112 return 0 == strcmp(rendererString, "Chromium");
113 }
114
GrGLGetVersionFromString(const char * versionString)115 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
116 if (NULL == versionString) {
117 SkDebugf("NULL GL version string.");
118 return GR_GL_INVALID_VER;
119 }
120
121 int major, minor;
122
123 // check for mesa
124 int mesaMajor, mesaMinor;
125 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
126 if (4 == n) {
127 return GR_GL_VER(major, minor);
128 }
129
130 n = sscanf(versionString, "%d.%d", &major, &minor);
131 if (2 == n) {
132 return GR_GL_VER(major, minor);
133 }
134
135 char profile[2];
136 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
137 &major, &minor);
138 if (4 == n) {
139 return GR_GL_VER(major, minor);
140 }
141
142 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
143 if (2 == n) {
144 return GR_GL_VER(major, minor);
145 }
146
147 return GR_GL_INVALID_VER;
148 }
149
GrGLGetGLSLVersionFromString(const char * versionString)150 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
151 if (NULL == versionString) {
152 SkDebugf("NULL GLSL version string.");
153 return GR_GLSL_INVALID_VER;
154 }
155
156 int major, minor;
157
158 int n = sscanf(versionString, "%d.%d", &major, &minor);
159 if (2 == n) {
160 return GR_GLSL_VER(major, minor);
161 }
162
163 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
164 if (2 == n) {
165 return GR_GLSL_VER(major, minor);
166 }
167
168 #ifdef SK_BUILD_FOR_ANDROID
169 // android hack until the gpu vender updates their drivers
170 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
171 if (2 == n) {
172 return GR_GLSL_VER(major, minor);
173 }
174 #endif
175
176 return GR_GLSL_INVALID_VER;
177 }
178
GrGLGetVendorFromString(const char * vendorString)179 GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
180 if (vendorString) {
181 if (0 == strcmp(vendorString, "ARM")) {
182 return kARM_GrGLVendor;
183 }
184 if (0 == strcmp(vendorString, "Imagination Technologies")) {
185 return kImagination_GrGLVendor;
186 }
187 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
188 return kIntel_GrGLVendor;
189 }
190 if (0 == strcmp(vendorString, "Qualcomm")) {
191 return kQualcomm_GrGLVendor;
192 }
193 if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
194 return kNVIDIA_GrGLVendor;
195 }
196 }
197 return kOther_GrGLVendor;
198 }
199
GrGLGetRendererFromString(const char * rendererString)200 GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
201 if (rendererString) {
202 if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
203 return kTegra3_GrGLRenderer;
204 } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
205 return kTegra2_GrGLRenderer;
206 }
207 int lastDigit;
208 int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
209 if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
210 return kPowerVR54x_GrGLRenderer;
211 }
212 static const char kPowerVRRogueStr[] = "PowerVR Rogue";
213 if (0 == strncmp(rendererString, kPowerVRRogueStr,
214 SK_ARRAY_COUNT(kPowerVRRogueStr)-1)) {
215 return kPowerVRRogue_GrGLRenderer;
216 }
217 int adrenoNumber;
218 n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
219 if (1 == n) {
220 if (adrenoNumber >= 300) {
221 if (adrenoNumber < 400) {
222 return kAdreno3xx_GrGLRenderer;
223 }
224 if (adrenoNumber < 500) {
225 return kAdreno4xx_GrGLRenderer;
226 }
227 }
228 }
229 }
230 return kOther_GrGLRenderer;
231 }
232
GrGLGetVersion(const GrGLInterface * gl)233 GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
234 const GrGLubyte* v;
235 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
236 return GrGLGetVersionFromString((const char*) v);
237 }
238
GrGLGetGLSLVersion(const GrGLInterface * gl)239 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
240 const GrGLubyte* v;
241 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
242 return GrGLGetGLSLVersionFromString((const char*) v);
243 }
244
GrGLGetVendor(const GrGLInterface * gl)245 GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
246 const GrGLubyte* v;
247 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
248 return GrGLGetVendorFromString((const char*) v);
249 }
250
GrGLGetRenderer(const GrGLInterface * gl)251 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
252 const GrGLubyte* v;
253 GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
254 return GrGLGetRendererFromString((const char*) v);
255 }
256
GrGLGetMatrix(GrGLfloat * dest,const SkMatrix & src)257 template<> void GrGLGetMatrix<3>(GrGLfloat* dest, const SkMatrix& src) {
258 // Col 0
259 dest[0] = SkScalarToFloat(src[SkMatrix::kMScaleX]);
260 dest[1] = SkScalarToFloat(src[SkMatrix::kMSkewY]);
261 dest[2] = SkScalarToFloat(src[SkMatrix::kMPersp0]);
262
263 // Col 1
264 dest[3] = SkScalarToFloat(src[SkMatrix::kMSkewX]);
265 dest[4] = SkScalarToFloat(src[SkMatrix::kMScaleY]);
266 dest[5] = SkScalarToFloat(src[SkMatrix::kMPersp1]);
267
268 // Col 2
269 dest[6] = SkScalarToFloat(src[SkMatrix::kMTransX]);
270 dest[7] = SkScalarToFloat(src[SkMatrix::kMTransY]);
271 dest[8] = SkScalarToFloat(src[SkMatrix::kMPersp2]);
272 }
273
GrGLGetMatrix(GrGLfloat * dest,const SkMatrix & src)274 template<> void GrGLGetMatrix<4>(GrGLfloat* dest, const SkMatrix& src) {
275 // Col 0
276 dest[0] = SkScalarToFloat(src[SkMatrix::kMScaleX]);
277 dest[1] = SkScalarToFloat(src[SkMatrix::kMSkewY]);
278 dest[2] = 0;
279 dest[3] = SkScalarToFloat(src[SkMatrix::kMPersp0]);
280
281 // Col 1
282 dest[4] = SkScalarToFloat(src[SkMatrix::kMSkewX]);
283 dest[5] = SkScalarToFloat(src[SkMatrix::kMScaleY]);
284 dest[6] = 0;
285 dest[7] = SkScalarToFloat(src[SkMatrix::kMPersp1]);
286
287 // Col 2
288 dest[8] = 0;
289 dest[9] = 0;
290 dest[10] = 1;
291 dest[11] = 0;
292
293 // Col 3
294 dest[12] = SkScalarToFloat(src[SkMatrix::kMTransX]);
295 dest[13] = SkScalarToFloat(src[SkMatrix::kMTransY]);
296 dest[14] = 0;
297 dest[15] = SkScalarToFloat(src[SkMatrix::kMPersp2]);
298 }
299
GrToGLStencilFunc(GrStencilFunc basicFunc)300 GrGLenum GrToGLStencilFunc(GrStencilFunc basicFunc) {
301 static const GrGLenum gTable[] = {
302 GR_GL_ALWAYS, // kAlways_StencilFunc
303 GR_GL_NEVER, // kNever_StencilFunc
304 GR_GL_GREATER, // kGreater_StencilFunc
305 GR_GL_GEQUAL, // kGEqual_StencilFunc
306 GR_GL_LESS, // kLess_StencilFunc
307 GR_GL_LEQUAL, // kLEqual_StencilFunc,
308 GR_GL_EQUAL, // kEqual_StencilFunc,
309 GR_GL_NOTEQUAL, // kNotEqual_StencilFunc,
310 };
311 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kBasicStencilFuncCount);
312 GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
313 GR_STATIC_ASSERT(1 == kNever_StencilFunc);
314 GR_STATIC_ASSERT(2 == kGreater_StencilFunc);
315 GR_STATIC_ASSERT(3 == kGEqual_StencilFunc);
316 GR_STATIC_ASSERT(4 == kLess_StencilFunc);
317 GR_STATIC_ASSERT(5 == kLEqual_StencilFunc);
318 GR_STATIC_ASSERT(6 == kEqual_StencilFunc);
319 GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc);
320 SkASSERT((unsigned) basicFunc < kBasicStencilFuncCount);
321
322 return gTable[basicFunc];
323 }
324