• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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