1 /*
2 * Cogl
3 *
4 * A Low Level GPU Graphics and Utilities API
5 *
6 * Copyright (C) 2007,2008,2009 Intel Corporation.
7 *
8 * Permission is hereby granted, free of charge, to any person
9 * obtaining a copy of this software and associated documentation
10 * files (the "Software"), to deal in the Software without
11 * restriction, including without limitation the rights to use, copy,
12 * modify, merge, publish, distribute, sublicense, and/or sell copies
13 * of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be
17 * included in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 *
28 *
29 */
30
31 #include "cogl-config.h"
32
33 #include <string.h>
34
35 #include "cogl-context-private.h"
36 #include "cogl-feature-private.h"
37 #include "cogl-renderer-private.h"
38 #include "cogl-private.h"
39 #include "driver/gl/cogl-util-gl-private.h"
40 #include "driver/gl/cogl-framebuffer-gl-private.h"
41 #include "driver/gl/cogl-texture-2d-gl-private.h"
42 #include "driver/gl/cogl-attribute-gl-private.h"
43 #include "driver/gl/cogl-clip-stack-gl-private.h"
44 #include "driver/gl/cogl-buffer-gl-private.h"
45 #include "driver/gl/cogl-pipeline-opengl-private.h"
46
47 #ifndef GL_UNSIGNED_INT_24_8
48 #define GL_UNSIGNED_INT_24_8 0x84FA
49 #endif
50 #ifndef GL_DEPTH_STENCIL
51 #define GL_DEPTH_STENCIL 0x84F9
52 #endif
53 #ifndef GL_RG
54 #define GL_RG 0x8227
55 #endif
56 #ifndef GL_RG8
57 #define GL_RG8 0x822B
58 #endif
59 #ifndef GL_UNSIGNED_INT_2_10_10_10_REV_EXT
60 #define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
61 #endif
62 #ifndef GL_HALF_FLOAT_OES
63 #define GL_HALF_FLOAT_OES 0x8D61
64 #endif
65
66 static gboolean
_cogl_driver_pixel_format_from_gl_internal(CoglContext * context,GLenum gl_int_format,CoglPixelFormat * out_format)67 _cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
68 GLenum gl_int_format,
69 CoglPixelFormat *out_format)
70 {
71 return TRUE;
72 }
73
74 static CoglPixelFormat
_cogl_driver_pixel_format_to_gl(CoglContext * context,CoglPixelFormat format,GLenum * out_glintformat,GLenum * out_glformat,GLenum * out_gltype)75 _cogl_driver_pixel_format_to_gl (CoglContext *context,
76 CoglPixelFormat format,
77 GLenum *out_glintformat,
78 GLenum *out_glformat,
79 GLenum *out_gltype)
80 {
81 CoglPixelFormat required_format;
82 GLenum glintformat;
83 GLenum glformat = 0;
84 GLenum gltype;
85
86 required_format = format;
87
88 /* Find GL equivalents */
89 switch (format)
90 {
91 case COGL_PIXEL_FORMAT_A_8:
92 glintformat = GL_ALPHA;
93 glformat = GL_ALPHA;
94 gltype = GL_UNSIGNED_BYTE;
95 break;
96 case COGL_PIXEL_FORMAT_G_8:
97 glintformat = GL_LUMINANCE;
98 glformat = GL_LUMINANCE;
99 gltype = GL_UNSIGNED_BYTE;
100 break;
101
102 case COGL_PIXEL_FORMAT_RG_88:
103 if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RG))
104 {
105 glintformat = GL_RG8;
106 glformat = GL_RG;
107 }
108 else
109 {
110 /* If red-green textures aren't supported then we'll use RGB
111 * as an internal format. Note this should only end up
112 * mattering for downloading the data because Cogl will
113 * refuse to allocate a texture with RG components if RG
114 * textures aren't supported */
115 glintformat = GL_RGB;
116 glformat = GL_RGB;
117 required_format = COGL_PIXEL_FORMAT_RGB_888;
118 }
119 gltype = GL_UNSIGNED_BYTE;
120 break;
121
122 case COGL_PIXEL_FORMAT_BGRA_8888:
123 case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
124 /* There is an extension to support this format */
125 if (_cogl_has_private_feature
126 (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888))
127 {
128 /* For some reason the extension says you have to specify
129 BGRA for the internal format too */
130 glintformat = GL_BGRA_EXT;
131 glformat = GL_BGRA_EXT;
132 gltype = GL_UNSIGNED_BYTE;
133 required_format = format;
134 break;
135 }
136 /* flow through */
137
138 /* Just one 24-bit ordering supported */
139 case COGL_PIXEL_FORMAT_RGB_888:
140 case COGL_PIXEL_FORMAT_BGR_888:
141 glintformat = GL_RGB;
142 glformat = GL_RGB;
143 gltype = GL_UNSIGNED_BYTE;
144 required_format = COGL_PIXEL_FORMAT_RGB_888;
145 break;
146
147 case COGL_PIXEL_FORMAT_RGBA_1010102:
148 case COGL_PIXEL_FORMAT_RGBA_1010102_PRE:
149 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
150 if (_cogl_has_private_feature
151 (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102))
152 {
153 glintformat = GL_RGBA;
154 glformat = GL_RGBA;
155 gltype = GL_UNSIGNED_INT_2_10_10_10_REV_EXT;
156 break;
157 }
158 #endif
159 case COGL_PIXEL_FORMAT_BGRA_1010102:
160 case COGL_PIXEL_FORMAT_BGRA_1010102_PRE:
161 case COGL_PIXEL_FORMAT_XBGR_2101010:
162 case COGL_PIXEL_FORMAT_ABGR_2101010:
163 case COGL_PIXEL_FORMAT_ABGR_2101010_PRE:
164 case COGL_PIXEL_FORMAT_XRGB_2101010:
165 case COGL_PIXEL_FORMAT_ARGB_2101010:
166 case COGL_PIXEL_FORMAT_ARGB_2101010_PRE:
167 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
168 if (_cogl_has_private_feature
169 (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102))
170 {
171 glintformat = GL_RGBA;
172 glformat = GL_RGBA;
173 gltype = GL_UNSIGNED_INT_2_10_10_10_REV_EXT;
174 required_format = COGL_PIXEL_FORMAT_RGBA_1010102;
175 required_format |= (format & COGL_PREMULT_BIT);
176 break;
177 }
178 #endif
179
180 G_GNUC_FALLTHROUGH;
181 case COGL_PIXEL_FORMAT_RGBA_8888:
182 case COGL_PIXEL_FORMAT_RGBA_8888_PRE:
183 case COGL_PIXEL_FORMAT_ARGB_8888:
184 case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
185 case COGL_PIXEL_FORMAT_ABGR_8888:
186 case COGL_PIXEL_FORMAT_ABGR_8888_PRE:
187 glintformat = GL_RGBA;
188 glformat = GL_RGBA;
189 gltype = GL_UNSIGNED_BYTE;
190 required_format = COGL_PIXEL_FORMAT_RGBA_8888;
191 required_format |= (format & COGL_PREMULT_BIT);
192 break;
193
194 /* The following three types of channel ordering
195 * are always defined using system word byte
196 * ordering (even according to GLES spec) */
197 case COGL_PIXEL_FORMAT_RGB_565:
198 glintformat = GL_RGB;
199 glformat = GL_RGB;
200 gltype = GL_UNSIGNED_SHORT_5_6_5;
201 break;
202 case COGL_PIXEL_FORMAT_RGBA_4444:
203 case COGL_PIXEL_FORMAT_RGBA_4444_PRE:
204 glintformat = GL_RGBA;
205 glformat = GL_RGBA;
206 gltype = GL_UNSIGNED_SHORT_4_4_4_4;
207 break;
208 case COGL_PIXEL_FORMAT_RGBA_5551:
209 case COGL_PIXEL_FORMAT_RGBA_5551_PRE:
210 glintformat = GL_RGBA;
211 glformat = GL_RGBA;
212 gltype = GL_UNSIGNED_SHORT_5_5_5_1;
213 break;
214
215 case COGL_PIXEL_FORMAT_BGRA_FP_16161616:
216 case COGL_PIXEL_FORMAT_XRGB_FP_16161616:
217 case COGL_PIXEL_FORMAT_ARGB_FP_16161616:
218 case COGL_PIXEL_FORMAT_XBGR_FP_16161616:
219 case COGL_PIXEL_FORMAT_ABGR_FP_16161616:
220 case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE:
221 case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE:
222 case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE:
223 g_warning ("Unhandled 16 bpc pixel format used");
224
225 G_GNUC_FALLTHROUGH;
226 case COGL_PIXEL_FORMAT_RGBA_FP_16161616:
227 case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE:
228 if (!_cogl_has_private_feature
229 (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT))
230 g_warning ("Missing 16 bpc half float extension");
231
232 glintformat = GL_RGBA;
233 glformat = GL_RGBA;
234 gltype = GL_HALF_FLOAT_OES;
235 break;
236
237 case COGL_PIXEL_FORMAT_DEPTH_16:
238 glintformat = GL_DEPTH_COMPONENT;
239 glformat = GL_DEPTH_COMPONENT;
240 gltype = GL_UNSIGNED_SHORT;
241 break;
242 case COGL_PIXEL_FORMAT_DEPTH_32:
243 glintformat = GL_DEPTH_COMPONENT;
244 glformat = GL_DEPTH_COMPONENT;
245 gltype = GL_UNSIGNED_INT;
246 break;
247
248 case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
249 glintformat = GL_DEPTH_STENCIL;
250 glformat = GL_DEPTH_STENCIL;
251 gltype = GL_UNSIGNED_INT_24_8;
252 break;
253
254 case COGL_PIXEL_FORMAT_ANY:
255 case COGL_PIXEL_FORMAT_YUV:
256 g_assert_not_reached ();
257 break;
258 }
259
260 /* All of the pixel formats are handled above so if this hits then
261 we've been given an invalid pixel format */
262 g_assert (glformat != 0);
263
264 if (out_glintformat != NULL)
265 *out_glintformat = glintformat;
266 if (out_glformat != NULL)
267 *out_glformat = glformat;
268 if (out_gltype != NULL)
269 *out_gltype = gltype;
270
271 return required_format;
272 }
273
274 static gboolean
_cogl_get_gl_version(CoglContext * ctx,int * major_out,int * minor_out)275 _cogl_get_gl_version (CoglContext *ctx,
276 int *major_out,
277 int *minor_out)
278 {
279 const char *version_string;
280
281 /* Get the OpenGL version number */
282 if ((version_string = _cogl_context_get_gl_version (ctx)) == NULL)
283 return FALSE;
284
285 if (!g_str_has_prefix (version_string, "OpenGL ES "))
286 return FALSE;
287
288 return _cogl_gl_util_parse_gl_version (version_string + 10,
289 major_out,
290 minor_out);
291 }
292
293 static gboolean
_cogl_driver_update_features(CoglContext * context,GError ** error)294 _cogl_driver_update_features (CoglContext *context,
295 GError **error)
296 {
297 unsigned long private_features
298 [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)] = { 0 };
299 char **gl_extensions;
300 int gl_major, gl_minor;
301 int i;
302
303 /* We have to special case getting the pointer to the glGetString
304 function because we need to use it to determine what functions we
305 can expect */
306 context->glGetString =
307 (void *) _cogl_renderer_get_proc_address (context->display->renderer,
308 "glGetString",
309 TRUE);
310 context->glGetStringi =
311 (void *) _cogl_renderer_get_proc_address (context->display->renderer,
312 "glGetStringi",
313 TRUE);
314
315 gl_extensions = _cogl_context_get_gl_extensions (context);
316
317 if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WINSYS)))
318 {
319 char *all_extensions = g_strjoinv (" ", gl_extensions);
320
321 COGL_NOTE (WINSYS,
322 "Checking features\n"
323 " GL_VENDOR: %s\n"
324 " GL_RENDERER: %s\n"
325 " GL_VERSION: %s\n"
326 " GL_EXTENSIONS: %s",
327 context->glGetString (GL_VENDOR),
328 context->glGetString (GL_RENDERER),
329 _cogl_context_get_gl_version (context),
330 all_extensions);
331
332 g_free (all_extensions);
333 }
334
335 context->glsl_major = 1;
336 context->glsl_minor = 0;
337 context->glsl_version_to_use = 100;
338
339 if (!_cogl_get_gl_version (context, &gl_major, &gl_minor))
340 {
341 gl_major = 1;
342 gl_minor = 1;
343 }
344
345 if (!COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0))
346 {
347 g_set_error (error,
348 COGL_DRIVER_ERROR,
349 COGL_DRIVER_ERROR_INVALID_VERSION,
350 "OpenGL ES 2.0 or better is required");
351 return FALSE;
352 }
353
354 _cogl_feature_check_ext_functions (context,
355 gl_major,
356 gl_minor,
357 gl_extensions);
358
359 if (_cogl_check_extension ("GL_ANGLE_pack_reverse_row_order", gl_extensions))
360 COGL_FLAGS_SET (private_features,
361 COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, TRUE);
362
363 /* Note GLES 2 core doesn't support mipmaps for npot textures or
364 * repeat modes other than CLAMP_TO_EDGE. */
365
366 COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ANY_GL, TRUE);
367 COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, TRUE);
368
369 if (context->glGenSamplers)
370 COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, TRUE);
371
372 if (context->glBlitFramebuffer)
373 COGL_FLAGS_SET (context->features,
374 COGL_FEATURE_ID_BLIT_FRAMEBUFFER, TRUE);
375
376 if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions))
377 {
378 COGL_FLAGS_SET (context->features,
379 COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);
380 }
381
382 if (context->glMapBuffer)
383 {
384 /* The GL_OES_mapbuffer extension doesn't support mapping for
385 read */
386 COGL_FLAGS_SET (context->features,
387 COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE);
388 }
389
390 if (context->glMapBufferRange)
391 {
392 /* MapBufferRange in ES3+ does support mapping for read */
393 COGL_FLAGS_SET(context->features,
394 COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE);
395 COGL_FLAGS_SET(context->features,
396 COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, TRUE);
397 }
398
399 if (context->glEGLImageTargetTexture2D)
400 COGL_FLAGS_SET (private_features,
401 COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE, TRUE);
402
403 if (_cogl_check_extension ("GL_OES_packed_depth_stencil", gl_extensions))
404 COGL_FLAGS_SET (private_features,
405 COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL, TRUE);
406
407 if (_cogl_check_extension ("GL_EXT_texture_format_BGRA8888", gl_extensions))
408 COGL_FLAGS_SET (private_features,
409 COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888, TRUE);
410
411 if (_cogl_check_extension ("GL_EXT_texture_type_2_10_10_10_REV", gl_extensions))
412 COGL_FLAGS_SET (private_features,
413 COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102, TRUE);
414
415 if (_cogl_check_extension ("GL_OES_texture_half_float", gl_extensions))
416 COGL_FLAGS_SET (private_features,
417 COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT, TRUE);
418
419 if (_cogl_check_extension ("GL_EXT_unpack_subimage", gl_extensions))
420 COGL_FLAGS_SET (private_features,
421 COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE, TRUE);
422
423 /* A nameless vendor implemented the extension, but got the case wrong
424 * per the spec. */
425 if (_cogl_check_extension ("GL_OES_EGL_sync", gl_extensions) ||
426 _cogl_check_extension ("GL_OES_egl_sync", gl_extensions))
427 COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_OES_EGL_SYNC, TRUE);
428
429 #ifdef GL_ARB_sync
430 if (context->glFenceSync)
431 COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_FENCE, TRUE);
432 #endif
433
434 if (_cogl_check_extension ("GL_EXT_texture_rg", gl_extensions))
435 COGL_FLAGS_SET (context->features,
436 COGL_FEATURE_ID_TEXTURE_RG,
437 TRUE);
438
439 if (context->glGenQueries && context->glQueryCounter)
440 COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_TIMESTAMP_QUERY, TRUE);
441
442 if (context->glGetInteger64v)
443 COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_GET_GPU_TIME, TRUE);
444
445 /* Cache features */
446 for (i = 0; i < G_N_ELEMENTS (private_features); i++)
447 context->private_features[i] |= private_features[i];
448
449 g_strfreev (gl_extensions);
450
451 return TRUE;
452 }
453
454 static gboolean
_cogl_driver_texture_2d_is_get_data_supported(CoglTexture2D * tex_2d)455 _cogl_driver_texture_2d_is_get_data_supported (CoglTexture2D *tex_2d)
456 {
457 return FALSE;
458 }
459
460 const CoglDriverVtable
461 _cogl_driver_gles =
462 {
463 _cogl_driver_gl_context_init,
464 _cogl_driver_gl_context_deinit,
465 _cogl_driver_gl_is_hardware_accelerated,
466 _cogl_gl_get_graphics_reset_status,
467 _cogl_driver_pixel_format_from_gl_internal,
468 _cogl_driver_pixel_format_to_gl,
469 _cogl_driver_update_features,
470 _cogl_driver_gl_create_framebuffer_driver,
471 _cogl_driver_gl_flush_framebuffer_state,
472 _cogl_texture_2d_gl_free,
473 _cogl_texture_2d_gl_can_create,
474 _cogl_texture_2d_gl_init,
475 _cogl_texture_2d_gl_allocate,
476 _cogl_texture_2d_gl_copy_from_framebuffer,
477 _cogl_texture_2d_gl_get_gl_handle,
478 _cogl_texture_2d_gl_generate_mipmap,
479 _cogl_texture_2d_gl_copy_from_bitmap,
480 _cogl_driver_texture_2d_is_get_data_supported,
481 NULL, /* texture_2d_get_data */
482 _cogl_gl_flush_attributes_state,
483 _cogl_clip_stack_gl_flush,
484 _cogl_buffer_gl_create,
485 _cogl_buffer_gl_destroy,
486 _cogl_buffer_gl_map_range,
487 _cogl_buffer_gl_unmap,
488 _cogl_buffer_gl_set_data,
489 _cogl_sampler_gl_init,
490 _cogl_sampler_gl_free,
491 _cogl_gl_set_uniform,
492 cogl_gl_create_timestamp_query,
493 cogl_gl_free_timestamp_query,
494 cogl_gl_timestamp_query_get_time_ns,
495 cogl_gl_get_gpu_time_ns,
496 };
497