blob: d6f5820781699b3fd8f9c0335b035af90f475e62 [file] [log] [blame]
bsalomon@google.com27847de2011-02-22 20:59:41 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * 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.
bsalomon@google.com27847de2011-02-22 20:59:41 +00006 */
7
epoger@google.comec3ed6a2011-07-28 14:26:00 +00008
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +00009#include "GrGLUtil.h"
commit-bot@chromium.org215a6822013-09-05 18:28:42 +000010#include "SkMatrix.h"
bsalomon@google.comf987d1b2011-04-04 17:13:52 +000011
bsalomon@google.com0b77d682011-08-19 13:28:54 +000012void GrGLClearErr(const GrGLInterface* gl) {
13 while (GR_GL_NO_ERROR != gl->fGetError()) {}
bsalomon@google.comf987d1b2011-04-04 17:13:52 +000014}
bsalomon@google.com27847de2011-02-22 20:59:41 +000015
bsalomon@google.com845eafd2012-06-18 12:27:29 +000016namespace {
17const char *get_error_string(uint32_t err) {
18 switch (err) {
19 case GR_GL_NO_ERROR:
20 return "";
21 case GR_GL_INVALID_ENUM:
22 return "Invalid Enum";
23 case GR_GL_INVALID_VALUE:
24 return "Invalid Value";
25 case GR_GL_INVALID_OPERATION:
26 return "Invalid Operation";
27 case GR_GL_OUT_OF_MEMORY:
28 return "Out of Memory";
29 case GR_GL_CONTEXT_LOST:
30 return "Context Lost";
31 }
32 return "Unknown";
33}
34}
35
bsalomon@google.com0b77d682011-08-19 13:28:54 +000036void GrGLCheckErr(const GrGLInterface* gl,
37 const char* location,
38 const char* call) {
39 uint32_t err = GR_GL_GET_ERROR(gl);
twiz@google.com0f31ca72011-03-18 17:38:11 +000040 if (GR_GL_NO_ERROR != err) {
bsalomon@google.com845eafd2012-06-18 12:27:29 +000041 GrPrintf("---- glGetError 0x%x(%s)", err, get_error_string(err));
bsalomon@google.com27847de2011-02-22 20:59:41 +000042 if (NULL != location) {
43 GrPrintf(" at\n\t%s", location);
44 }
45 if (NULL != call) {
46 GrPrintf("\n\t\t%s", call);
47 }
48 GrPrintf("\n");
49 }
50}
51
bsalomon@google.com960d1142013-05-29 13:11:54 +000052namespace {
53// Mesa uses a non-standard version string of format: 1.4 Mesa <mesa_major>.<mesa_minor>.
54// The mapping of from mesa version to GL version came from here: http://www.mesa3d.org/intro.html
55bool get_gl_version_for_mesa(int mesaMajorVersion, int* major, int* minor) {
56 switch (mesaMajorVersion) {
57 case 2:
58 case 3:
59 case 4:
60 case 5:
61 case 6:
62 *major = 1;
63 *minor = mesaMajorVersion - 1;
64 return true;
65 case 7:
66 *major = 2;
67 *minor = 1;
68 return true;
69 case 8:
70 *major = 3;
71 *minor = 0;
72 return true;
73 case 9:
74 *major = 3;
75 *minor = 1;
76 return true;
77 default:
78 return false;
79 }
80}
81}
82
bsalomon@google.com27847de2011-02-22 20:59:41 +000083///////////////////////////////////////////////////////////////////////////////
84
bsalomon@google.comd5d10492011-04-28 21:16:31 +000085#if GR_GL_LOG_CALLS
86 bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
87#endif
bsalomon@google.com27847de2011-02-22 20:59:41 +000088
bsalomon@google.comd5d10492011-04-28 21:16:31 +000089#if GR_GL_CHECK_ERROR
90 bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
91#endif
92
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000093///////////////////////////////////////////////////////////////////////////////
94
95GrGLBinding GrGLGetBindingInUseFromString(const char* versionString) {
96 if (NULL == versionString) {
mtklein@google.com330313a2013-08-22 15:37:26 +000097 SkDEBUGFAIL("NULL GL version string.");
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000098 return kNone_GrGLBinding;
99 }
100
101 int major, minor;
102
103 // check for desktop
104 int n = sscanf(versionString, "%d.%d", &major, &minor);
105 if (2 == n) {
106 return kDesktop_GrGLBinding;
107 }
108
109 // check for ES 1
110 char profile[2];
bsalomon@google.com960d1142013-05-29 13:11:54 +0000111 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000112 if (4 == n) {
113 // we no longer support ES1.
114 return kNone_GrGLBinding;
115 }
116
117 // check for ES2
118 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
119 if (2 == n) {
bsalomon@google.com791816a2013-08-15 18:54:39 +0000120 return kES_GrGLBinding;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000121 }
122 return kNone_GrGLBinding;
123}
124
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000125bool GrGLIsMesaFromVersionString(const char* versionString) {
126 int major, minor, mesaMajor, mesaMinor;
127 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
128 return 4 == n;
129}
130
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000131GrGLVersion GrGLGetVersionFromString(const char* versionString) {
132 if (NULL == versionString) {
mtklein@google.com330313a2013-08-22 15:37:26 +0000133 SkDEBUGFAIL("NULL GL version string.");
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000134 return 0;
135 }
136
137 int major, minor;
138
bsalomon@google.com960d1142013-05-29 13:11:54 +0000139 // check for mesa
140 int mesaMajor, mesaMinor;
141 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
142 if (4 == n) {
143 if (get_gl_version_for_mesa(mesaMajor, &major, &minor)) {
144 return GR_GL_VER(major, minor);
145 } else {
146 return 0;
147 }
148 }
149
150 n = sscanf(versionString, "%d.%d", &major, &minor);
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000151 if (2 == n) {
152 return GR_GL_VER(major, minor);
153 }
154
155 char profile[2];
156 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
157 &major, &minor);
158 if (4 == n) {
159 return GR_GL_VER(major, minor);
160 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000161
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000162 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
163 if (2 == n) {
164 return GR_GL_VER(major, minor);
165 }
166
167 return 0;
168}
169
170GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
171 if (NULL == versionString) {
mtklein@google.com330313a2013-08-22 15:37:26 +0000172 SkDEBUGFAIL("NULL GLSL version string.");
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000173 return 0;
174 }
175
176 int major, minor;
177
178 int n = sscanf(versionString, "%d.%d", &major, &minor);
179 if (2 == n) {
180 return GR_GLSL_VER(major, minor);
181 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000182
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000183 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
184 if (2 == n) {
185 return GR_GLSL_VER(major, minor);
186 }
187
188#ifdef SK_BUILD_FOR_ANDROID
189 // android hack until the gpu vender updates their drivers
190 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
191 if (2 == n) {
192 return GR_GLSL_VER(major, minor);
193 }
194#endif
195
196 return 0;
197}
198
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000199GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
200 if (NULL != vendorString) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000201 if (0 == strcmp(vendorString, "ARM")) {
202 return kARM_GrGLVendor;
203 }
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000204 if (0 == strcmp(vendorString, "Imagination Technologies")) {
205 return kImagination_GrGLVendor;
206 }
207 if (0 == strcmp(vendorString, "Intel")) {
208 return kIntel_GrGLVendor;
209 }
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000210 if (0 == strcmp(vendorString, "Qualcomm")) {
211 return kQualcomm_GrGLVendor;
212 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000213 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000214 return kOther_GrGLVendor;
215}
216
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000217GrGLBinding GrGLGetBindingInUse(const GrGLInterface* gl) {
218 const GrGLubyte* v;
219 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
220 return GrGLGetBindingInUseFromString((const char*) v);
221}
222
223GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
224 const GrGLubyte* v;
225 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
226 return GrGLGetVersionFromString((const char*) v);
227}
228
229GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
230 const GrGLubyte* v;
231 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
232 return GrGLGetGLSLVersionFromString((const char*) v);
233}
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000234
235GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
236 const GrGLubyte* v;
237 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
238 return GrGLGetVendorFromString((const char*) v);
239}
commit-bot@chromium.org215a6822013-09-05 18:28:42 +0000240
241template<> void GrGLGetMatrix<3>(GrGLfloat* dest, const SkMatrix& src) {
242 // Col 0
243 dest[0] = SkScalarToFloat(src[SkMatrix::kMScaleX]);
244 dest[1] = SkScalarToFloat(src[SkMatrix::kMSkewY]);
245 dest[2] = SkScalarToFloat(src[SkMatrix::kMPersp0]);
246
247 // Col 1
248 dest[3] = SkScalarToFloat(src[SkMatrix::kMSkewX]);
249 dest[4] = SkScalarToFloat(src[SkMatrix::kMScaleY]);
250 dest[5] = SkScalarToFloat(src[SkMatrix::kMPersp1]);
251
252 // Col 2
253 dest[6] = SkScalarToFloat(src[SkMatrix::kMTransX]);
254 dest[7] = SkScalarToFloat(src[SkMatrix::kMTransY]);
255 dest[8] = SkScalarToFloat(src[SkMatrix::kMPersp2]);
256}
257
258template<> void GrGLGetMatrix<4>(GrGLfloat* dest, const SkMatrix& src) {
259 // Col 0
260 dest[0] = SkScalarToFloat(src[SkMatrix::kMScaleX]);
261 dest[1] = SkScalarToFloat(src[SkMatrix::kMSkewY]);
262 dest[2] = 0;
263 dest[3] = SkScalarToFloat(src[SkMatrix::kMPersp0]);
264
265 // Col 1
266 dest[4] = SkScalarToFloat(src[SkMatrix::kMSkewX]);
267 dest[5] = SkScalarToFloat(src[SkMatrix::kMScaleY]);
268 dest[6] = 0;
269 dest[7] = SkScalarToFloat(src[SkMatrix::kMPersp1]);
270
271 // Col 2
272 dest[8] = 0;
273 dest[9] = 0;
274 dest[10] = 1;
275 dest[11] = 0;
276
277 // Col 3
278 dest[12] = SkScalarToFloat(src[SkMatrix::kMTransX]);
279 dest[13] = SkScalarToFloat(src[SkMatrix::kMTransY]);
280 dest[14] = 0;
281 dest[15] = SkScalarToFloat(src[SkMatrix::kMPersp2]);
282}