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