tizen 2.4 release
[sdk/emulator-yagl.git] / GLESv2 / yagl_gles2_context.c
1 /*
2  * YaGL
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact :
7  * Stanislav Vorobiov <s.vorobiov@samsung.com>
8  * Jinhyung Jo <jinhyung.jo@samsung.com>
9  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  * copies of the Software, and to permit persons to whom the Software is
16  * furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27  * THE SOFTWARE.
28  *
29  * Contributors:
30  * - S-Core Co., Ltd
31  *
32  */
33
34 #include "GLES2/gl2.h"
35 #include "GLES2/gl2ext.h"
36 #include "yagl_gles2_context.h"
37 #include "yagl_gles2_program.h"
38 #include "yagl_gles2_utils.h"
39 #include "yagl_gles_array.h"
40 #include "yagl_gles_buffer.h"
41 #include "yagl_gles_texture.h"
42 #include "yagl_gles_texture_unit.h"
43 #include "yagl_gles_vertex_array.h"
44 #include "yagl_gles_utils.h"
45 #include "yagl_log.h"
46 #include "yagl_malloc.h"
47 #include "yagl_state.h"
48 #include "yagl_egl_fence.h"
49 #include "yagl_texcompress.h"
50 #include "yagl_host_gles_calls.h"
51 #include <string.h>
52 #include <stdlib.h>
53 #include <assert.h>
54
55 #define YAGL_SET_ERR(err) \
56     yagl_gles_context_set_error(&ctx->base, err); \
57     YAGL_LOG_ERROR("error = 0x%X", err)
58
59 /*
60  * We can't include GL/glext.h here
61  */
62 #define GL_POINT_SPRITE                    0x8861
63 #define GL_VERTEX_PROGRAM_POINT_SIZE       0x8642
64 #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
65 #define GL_MAX_VERTEX_UNIFORM_COMPONENTS   0x8B4A
66 #define GL_MAX_VARYING_FLOATS              0x8B4B
67 #define GL_VERTEX_ATTRIB_ARRAY_INTEGER     0x88FD
68
69 static const GLchar *egl_image_ext = "GL_OES_EGL_image";
70 static const GLchar *depth24_ext = "GL_OES_depth24";
71 static const GLchar *depth32_ext = "GL_OES_depth32";
72 static const GLchar *texture_float_ext = "GL_OES_texture_float";
73 static const GLchar *texture_float_linear_ext = "GL_OES_texture_float_linear";
74 static const GLchar *texture_format_bgra8888_ext = "GL_EXT_texture_format_BGRA8888";
75 static const GLchar *depth_texture_ext = "GL_OES_depth_texture";
76 static const GLchar *framebuffer_blit_ext = "GL_ANGLE_framebuffer_blit";
77 static const GLchar *draw_buffers_ext = "GL_EXT_draw_buffers";
78 static const GLchar *mapbuffer_ext = "GL_OES_mapbuffer";
79 static const GLchar *map_buffer_range_ext = "GL_EXT_map_buffer_range";
80 static const GLchar *element_index_uint_ext = "GL_OES_element_index_uint";
81 static const GLchar *texture_3d_ext = "GL_OES_texture_3D";
82 static const GLchar *blend_minmax_ext = "GL_EXT_blend_minmax";
83 static const GLchar *pbo_ext = "GL_NV_pixel_buffer_object";
84 static const GLchar *read_buffer_ext = "GL_NV_read_buffer";
85 static const GLchar *compressed_etc1_rgb8_texture_ext = "GL_OES_compressed_ETC1_RGB8_texture";
86 static const GLchar *pack_subimage_ext = "GL_NV_pack_subimage";
87 static const GLchar *unpack_subimage_ext = "GL_EXT_unpack_subimage";
88 static const GLchar *surfaceless_context_ext = "GL_OES_surfaceless_context";
89 static const GLchar *egl_sync_ext = "GL_OES_EGL_sync";
90 static const GLchar *packed_depth_stencil_ext = "GL_OES_packed_depth_stencil";
91 static const GLchar *texture_npot_ext = "GL_OES_texture_npot";
92 static const GLchar *texture_filter_anisotropic_ext = "GL_EXT_texture_filter_anisotropic";
93 static const GLchar *vertex_array_object_ext = "GL_OES_vertex_array_object";
94 static const GLchar *texture_half_float_ext = "GL_OES_texture_half_float";
95 static const GLchar *texture_half_float_linear_ext = "GL_OES_texture_half_float_linear";
96 static const GLchar *vertex_half_float_ext = "GL_OES_vertex_half_float";
97 static const GLchar *standard_derivatives_ext = "GL_OES_standard_derivatives";
98 static const GLchar *instanced_arrays_ext = "GL_EXT_instanced_arrays";
99
100 static void yagl_gles2_context_prepare_internal(struct yagl_client_context *ctx)
101 {
102     struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
103     const GLchar **extensions;
104     int num_extensions;
105
106     yagl_gles2_context_prepare(gles2_ctx);
107
108     extensions = yagl_gles2_context_get_extensions(gles2_ctx, &num_extensions);
109
110     yagl_gles_context_prepare_end(&gles2_ctx->base, extensions, num_extensions);
111 }
112
113 static void yagl_gles2_context_destroy(struct yagl_client_context *ctx)
114 {
115     struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
116
117     YAGL_LOG_FUNC_ENTER(yagl_gles2_context_destroy, "%p", ctx);
118
119     yagl_gles2_context_cleanup(gles2_ctx);
120
121     yagl_free(gles2_ctx);
122
123     YAGL_LOG_FUNC_EXIT(NULL);
124 }
125
126 static void yagl_gles2_array_apply(struct yagl_gles_array *array,
127                                    uint32_t first,
128                                    uint32_t count,
129                                    const GLvoid *ptr,
130                                    void *user_data)
131 {
132     if (array->integer) {
133         if (array->vbo) {
134             yagl_host_glVertexAttribIPointerOffset(array->index,
135                                                    array->size,
136                                                    array->actual_type,
137                                                    array->actual_stride,
138                                                    array->actual_offset);
139         } else {
140             yagl_host_glVertexAttribIPointerData(array->index,
141                                                  array->size,
142                                                  array->actual_type,
143                                                  array->actual_stride,
144                                                  first,
145                                                  ptr + (first * array->actual_stride),
146                                                  count * array->actual_stride);
147         }
148
149         return;
150     }
151
152     if (array->vbo) {
153         yagl_host_glVertexAttribPointerOffset(array->index,
154                                               array->size,
155                                               array->actual_type,
156                                               array->normalized,
157                                               array->actual_stride,
158                                               array->actual_offset);
159     } else {
160         yagl_host_glVertexAttribPointerData(array->index,
161                                             array->size,
162                                             array->actual_type,
163                                             array->normalized,
164                                             array->actual_stride,
165                                             first,
166                                             ptr + (first * array->actual_stride),
167                                             count * array->actual_stride);
168     }
169 }
170
171 static const GLchar
172     *yagl_gles2_context_get_string(struct yagl_gles_context *ctx,
173                                    GLenum name)
174 {
175     const char *str = NULL;
176
177     switch (name) {
178     case GL_VERSION:
179         str = "OpenGL ES 2.0";
180         break;
181     case GL_RENDERER:
182         str = "YaGL GLESv2";
183         break;
184     case GL_SHADING_LANGUAGE_VERSION:
185         str = "OpenGL ES GLSL ES 1.4";
186         break;
187     default:
188         str = "";
189     }
190
191     return str;
192 }
193
194 static int yagl_gles2_context_enable(struct yagl_gles_context *ctx,
195                                      GLenum cap,
196                                      GLboolean enable)
197 {
198     return 0;
199 }
200
201 static int yagl_gles2_context_is_enabled(struct yagl_gles_context *ctx,
202                                          GLenum cap,
203                                          GLboolean *enabled)
204 {
205     return 0;
206 }
207
208 static int yagl_gles2_context_bind_buffer(struct yagl_gles_context *ctx,
209                                           GLenum target,
210                                           struct yagl_gles_buffer *buffer)
211 {
212     return 0;
213 }
214
215 static void yagl_gles2_context_unbind_buffer(struct yagl_gles_context *ctx,
216                                              yagl_object_name buffer_local_name)
217 {
218 }
219
220 static int yagl_gles2_context_acquire_binded_buffer(struct yagl_gles_context *ctx,
221                                                     GLenum target,
222                                                     struct yagl_gles_buffer **buffer)
223 {
224     return 0;
225 }
226
227 static int yagl_gles2_context_pre_use_program(struct yagl_gles2_context *ctx,
228                                               struct yagl_gles2_program *program)
229 {
230     return 1;
231 }
232
233 static int yagl_gles2_context_pre_link_program(struct yagl_gles2_context *ctx,
234                                                struct yagl_gles2_program *program)
235 {
236     return 1;
237 }
238
239 void yagl_gles2_context_init(struct yagl_gles2_context *ctx,
240                              yagl_client_api client_api,
241                              struct yagl_sharegroup *sg)
242 {
243     yagl_gles_context_init(&ctx->base, client_api, sg);
244
245     ctx->sg = sg;
246 }
247
248 void yagl_gles2_context_cleanup(struct yagl_gles2_context *ctx)
249 {
250     yagl_gles2_program_release(ctx->program);
251
252     yagl_gles_buffer_release(ctx->vertex_attrib0.vbo);
253
254     yagl_gles_context_cleanup(&ctx->base);
255 }
256
257 void yagl_gles2_context_prepare(struct yagl_gles2_context *ctx)
258 {
259     GLint num_texture_units = 0;
260     int32_t size = 0;
261     char *extensions, *nonconformant;
262     int num_arrays = 1;
263
264     YAGL_LOG_FUNC_ENTER(yagl_gles2_context_prepare, "%p", ctx);
265
266     yagl_host_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &num_arrays, 1, NULL);
267
268     yagl_host_glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
269                             &num_texture_units, 1, NULL);
270
271     /*
272      * We limit this by 32 for conformance.
273      */
274     if (num_texture_units > 32) {
275         num_texture_units = 32;
276     }
277
278     yagl_gles_context_prepare(&ctx->base,
279                               num_texture_units,
280                               num_arrays);
281
282     ctx->vertex_attrib0.value.f[0] = 0.0f;
283     ctx->vertex_attrib0.value.f[1] = 0.0f;
284     ctx->vertex_attrib0.value.f[2] = 0.0f;
285     ctx->vertex_attrib0.value.f[3] = 1.0f;
286     ctx->vertex_attrib0.type = GL_FLOAT;
287     ctx->vertex_attrib0.vbo = yagl_gles_buffer_create();
288
289     nonconformant = getenv("YAGL_NONCONFORMANT");
290
291     /*
292      * Generating variable locations on target is faster, but
293      * it's not conformant (will not pass some khronos tests)
294      * since we can't know if variable with a given name exists or not,
295      * so we just assume it exists.
296      *
297      * We used to set 'gen_locations' to 1 by default, but that's bad,
298      * since app may do something like this:
299      * if (glGetUniformLocation(p, "my_uniform") == -1) {
300      *     // do logic when 'my_uniform' is not in the shader
301      * } else {
302      *     // do logic when 'my_uniform' is in the shader
303      * }
304      * i.e. 'gen_locations == 1' will break this logic, thus, we
305      * now set gen_locations to 0 by default.
306      */
307
308     if (nonconformant && atoi(nonconformant)) {
309         ctx->gen_locations = 1;
310     } else {
311         ctx->gen_locations = 0;
312     }
313
314     yagl_host_glGetString(GL_EXTENSIONS, NULL, 0, &size);
315     extensions = yagl_malloc0(size);
316     yagl_host_glGetString(GL_EXTENSIONS, extensions, size, NULL);
317
318     if (yagl_get_host_gl_version() > yagl_gl_2) {
319         ctx->texture_half_float = 1;
320         ctx->vertex_half_float = 1;
321     } else {
322         ctx->texture_half_float = (strstr(extensions, "GL_ARB_half_float_pixel ") != NULL) ||
323                                   (strstr(extensions, "GL_NV_half_float ") != NULL);
324
325         ctx->vertex_half_float = (strstr(extensions, "GL_ARB_half_float_vertex ") != NULL);
326     }
327
328     ctx->standard_derivatives = 1;
329
330     yagl_free(extensions);
331
332     ctx->instanced_arrays = (yagl_get_host_gl_version() > yagl_gl_2);
333
334     YAGL_LOG_FUNC_EXIT(NULL);
335 }
336
337 const GLchar **yagl_gles2_context_get_extensions(struct yagl_gles2_context *ctx,
338                                                  int *num_extensions)
339 {
340     const GLchar **extensions;
341     int i = 0;
342
343     extensions = yagl_malloc(100 * sizeof(*extensions));
344
345     extensions[i++] = egl_image_ext;
346     extensions[i++] = depth24_ext;
347     extensions[i++] = depth32_ext;
348     extensions[i++] = texture_float_ext;
349     extensions[i++] = texture_float_linear_ext;
350     extensions[i++] = texture_format_bgra8888_ext;
351     extensions[i++] = depth_texture_ext;
352     extensions[i++] = framebuffer_blit_ext;
353     extensions[i++] = draw_buffers_ext;
354     extensions[i++] = mapbuffer_ext;
355     extensions[i++] = map_buffer_range_ext;
356     extensions[i++] = element_index_uint_ext;
357     extensions[i++] = texture_3d_ext;
358     extensions[i++] = blend_minmax_ext;
359     extensions[i++] = pbo_ext;
360     extensions[i++] = read_buffer_ext;
361     extensions[i++] = compressed_etc1_rgb8_texture_ext;
362     extensions[i++] = pack_subimage_ext;
363     extensions[i++] = unpack_subimage_ext;
364     extensions[i++] = surfaceless_context_ext;
365
366     if (yagl_egl_fence_supported()) {
367         extensions[i++] = egl_sync_ext;
368     }
369
370     if (ctx->base.packed_depth_stencil) {
371         extensions[i++] = packed_depth_stencil_ext;
372     }
373
374     if (ctx->base.texture_npot) {
375         extensions[i++] = texture_npot_ext;
376     }
377
378     if (ctx->base.texture_filter_anisotropic) {
379         extensions[i++] = texture_filter_anisotropic_ext;
380     }
381
382     if (ctx->base.vertex_arrays_supported) {
383         extensions[i++] = vertex_array_object_ext;
384     }
385
386     if (ctx->texture_half_float) {
387         extensions[i++] = texture_half_float_ext;
388         extensions[i++] = texture_half_float_linear_ext;
389     }
390
391     if (ctx->vertex_half_float) {
392         extensions[i++] = vertex_half_float_ext;
393     }
394
395     if (ctx->standard_derivatives) {
396         extensions[i++] = standard_derivatives_ext;
397     }
398
399     if (ctx->instanced_arrays) {
400         extensions[i++] = instanced_arrays_ext;
401     }
402
403     *num_extensions = i;
404
405     return extensions;
406 }
407
408 struct yagl_gles_array
409     *yagl_gles2_context_create_arrays(struct yagl_gles_context *ctx)
410 {
411     GLint i;
412     struct yagl_gles_array *arrays;
413
414     arrays = yagl_malloc(ctx->num_arrays * sizeof(*arrays));
415
416     for (i = 0; i < ctx->num_arrays; ++i) {
417         yagl_gles_array_init(&arrays[i],
418                              i,
419                              &yagl_gles2_array_apply,
420                              ctx);
421     }
422
423     return arrays;
424 }
425
426 void yagl_gles2_context_pre_draw(struct yagl_gles2_context *ctx,
427                                  GLenum mode,
428                                  GLint count)
429 {
430     YAGL_LOG_FUNC_SET(yagl_gles2_context_pre_draw);
431
432     /*
433      * 'count' can be <= 0 in case of integer overflows, this is
434      * typically user problem, just don't simulate vertex attribute array 0
435      * in this case.
436      */
437
438     if (!ctx->base.vao->arrays[0].enabled && (count > 0)) {
439         /*
440          * vertex attribute array 0 not enabled, simulate
441          * vertex attribute array 0.
442          */
443
444         GLint size = count * sizeof(ctx->vertex_attrib0.value);
445         void *tmp, *it;
446
447         if (!ctx->vertex_attrib0.warned) {
448             YAGL_LOG_WARN("vertex attribute array 0 not enabled, simulating");
449
450             ctx->vertex_attrib0.warned = 1;
451         }
452
453         if (ctx->vertex_attrib0.vbo->size < size) {
454             /*
455              * Required buffer size is greater than allocated so far,
456              * we're forced to reallocate. This is slow path, we basically
457              * need to update everything.
458              */
459
460             tmp = it = yagl_get_tmp_buffer2(size);
461
462             while (it < (tmp + size)) {
463                 memcpy(it, &ctx->vertex_attrib0.value, sizeof(ctx->vertex_attrib0.value));
464                 it += sizeof(ctx->vertex_attrib0.value);
465             }
466
467             yagl_gles_buffer_set_data(ctx->vertex_attrib0.vbo,
468                                       size,
469                                       tmp,
470                                       GL_STREAM_DRAW);
471
472             ctx->vertex_attrib0.count = count;
473         } else {
474             /*
475              * We can fit it in existing buffer.
476              */
477
478             GLint offset = 0;
479
480             tmp = ctx->vertex_attrib0.vbo->data;
481
482             if (memcmp(tmp,
483                        &ctx->vertex_attrib0.value,
484                        sizeof(ctx->vertex_attrib0.value)) == 0) {
485                 if (ctx->vertex_attrib0.count < count) {
486                     /*
487                      * vertex attribute 0 didn't change, but we need more than
488                      * 'vertex_attrib0.count' elements, thus, update only part
489                      * of the buffer. This is semi-fast path. We also update
490                      * 'vertex_attrib0.count' here to specify that we now
491                      * have more valid elements in the buffer.
492                      */
493                     offset = sizeof(ctx->vertex_attrib0.value) * ctx->vertex_attrib0.count;
494                     size = sizeof(ctx->vertex_attrib0.value) * (count - ctx->vertex_attrib0.count);
495                     ctx->vertex_attrib0.count = count;
496                 } else {
497                     /*
498                      * vertex attribute 0 didn't change and we need less than
499                      * 'vertex_attrib0.count' elements, this is fast-path,
500                      * don't transfer anything. Also, don't update
501                      * 'vertex_attrib0.count' here since elements pass 'count'
502                      * are still equal to vertex attribute 0, thus, they can
503                      * be reused later.
504                      */
505                     size = 0;
506                 }
507             } else {
508                 /*
509                  * vertex attribute 0 changed, we'll update the buffer
510                  * starting from element 0 and up to 'count' elements.
511                  * Also, we set 'vertex_attrib0.count' to specify that we have
512                  * 'vertex_attrib0.count' elements valid. Note that the buffer
513                  * may still contain elements with outdated vertex attribute 0
514                  * values.
515                  */
516
517                 ctx->vertex_attrib0.count = count;
518             }
519
520             tmp = it = yagl_get_tmp_buffer2(size);
521
522             while (it < (tmp + size)) {
523                 memcpy(it, &ctx->vertex_attrib0.value, sizeof(ctx->vertex_attrib0.value));
524                 it += sizeof(ctx->vertex_attrib0.value);
525             }
526
527             yagl_gles_buffer_update_data(ctx->vertex_attrib0.vbo,
528                                          offset,
529                                          size,
530                                          tmp);
531         }
532
533         yagl_host_glEnableVertexAttribArray(0);
534
535         if (ctx->base.vao->arrays[0].divisor != 0) {
536             yagl_host_glVertexAttribDivisor(0, 0);
537         }
538
539         yagl_gles_buffer_bind(ctx->vertex_attrib0.vbo,
540                               0,
541                               0,
542                               GL_ARRAY_BUFFER);
543         yagl_gles_buffer_transfer(ctx->vertex_attrib0.vbo,
544                                   0,
545                                   GL_ARRAY_BUFFER,
546                                   0);
547         switch (ctx->vertex_attrib0.type) {
548         case GL_INT:
549         case GL_UNSIGNED_INT:
550             yagl_host_glVertexAttribIPointerOffset(0,
551                                                    4,
552                                                    ctx->vertex_attrib0.type,
553                                                    0,
554                                                    0);
555             break;
556         default:
557             assert(0);
558         case GL_FLOAT:
559             yagl_host_glVertexAttribPointerOffset(0,
560                                                   4,
561                                                   ctx->vertex_attrib0.type,
562                                                   GL_FALSE,
563                                                   0,
564                                                   0);
565             break;
566         }
567         yagl_host_glBindBuffer(GL_ARRAY_BUFFER, 0);
568     }
569
570     /*
571      * Enable texture generation for GL_POINTS and gl_PointSize shader variable.
572      * GLESv2 assumes this is enabled by default, we need to set this
573      * state for GL.
574      */
575
576     if (mode == GL_POINTS) {
577         if (yagl_get_host_gl_version() <= yagl_gl_3_2) {
578             yagl_host_glEnable(GL_POINT_SPRITE);
579         }
580         yagl_host_glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
581     }
582 }
583
584 void yagl_gles2_context_post_draw(struct yagl_gles2_context *ctx,
585                                   GLenum mode,
586                                   GLint count)
587 {
588     if (mode == GL_POINTS) {
589         yagl_host_glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
590         if (yagl_get_host_gl_version() <= yagl_gl_3_2) {
591             yagl_host_glDisable(GL_POINT_SPRITE);
592         }
593     }
594
595     if (!ctx->base.vao->arrays[0].enabled && (count > 0)) {
596         /*
597          * Restore vertex attribute array 0 pointer.
598          */
599         yagl_gles_array_apply(&ctx->base.vao->arrays[0]);
600
601         if (ctx->base.vao->arrays[0].divisor != 0) {
602             /*
603              * Restore vertex attribute array 0 divisor.
604              */
605             yagl_host_glVertexAttribDivisor(0, ctx->base.vao->arrays[0].divisor);
606         }
607
608         /*
609          * Restore vertex attribute array 0 state.
610          */
611         yagl_host_glDisableVertexAttribArray(0);
612     }
613 }
614
615 void yagl_gles2_context_compressed_tex_image_2d(struct yagl_gles_context *gles_ctx,
616                                                 GLenum target,
617                                                 struct yagl_gles_texture *texture,
618                                                 GLint level,
619                                                 GLenum internalformat,
620                                                 GLsizei width,
621                                                 GLsizei height,
622                                                 GLint border,
623                                                 GLsizei imageSize,
624                                                 const GLvoid *data)
625 {
626     struct yagl_gles2_context *ctx = (struct yagl_gles2_context*)gles_ctx;
627     struct yagl_texcompress_format *tc_format;
628     GLsizei src_stride;
629     GLsizei dst_stride;
630     GLsizei dst_size;
631     uint8_t *buff;
632
633     YAGL_LOG_FUNC_SET(glCompressedTexImage2D);
634
635     tc_format = yagl_texcompress_get_format(internalformat);
636
637     if (!tc_format) {
638         YAGL_SET_ERR(GL_INVALID_ENUM);
639         return;
640     }
641
642     if (!yagl_texcompress_get_info(tc_format,
643                                    width,
644                                    height,
645                                    imageSize,
646                                    &src_stride,
647                                    &dst_stride,
648                                    &dst_size)) {
649         YAGL_SET_ERR(GL_INVALID_VALUE);
650         return;
651     }
652
653     if (!data) {
654         yagl_host_glTexImage2DData(target,
655                                    level,
656                                    tc_format->dst_internalformat,
657                                    width,
658                                    height,
659                                    border,
660                                    tc_format->dst_format,
661                                    tc_format->dst_type,
662                                    NULL,
663                                    dst_size);
664
665         yagl_gles_texture_set_internalformat(texture,
666                                              tc_format->dst_internalformat,
667                                              tc_format->dst_type,
668                                              yagl_gles_context_convert_textures(gles_ctx));
669
670         return;
671     }
672
673     buff = yagl_get_tmp_buffer(dst_size);
674
675     tc_format->unpack(tc_format,
676                       data,
677                       width,
678                       height,
679                       src_stride,
680                       buff,
681                       dst_stride);
682
683     yagl_gles_reset_unpack(&gles_ctx->unpack);
684
685     yagl_host_glTexImage2DData(target,
686                                level,
687                                tc_format->dst_internalformat,
688                                width,
689                                height,
690                                border,
691                                tc_format->dst_format,
692                                tc_format->dst_type,
693                                buff,
694                                dst_size);
695
696     yagl_gles_set_unpack(&gles_ctx->unpack);
697
698     yagl_gles_texture_set_internalformat(texture,
699                                          tc_format->dst_internalformat,
700                                          tc_format->dst_type,
701                                          yagl_gles_context_convert_textures(gles_ctx));
702 }
703
704 void yagl_gles2_context_compressed_tex_sub_image_2d(struct yagl_gles_context *gles_ctx,
705                                                     GLenum target,
706                                                     GLint level,
707                                                     GLint xoffset,
708                                                     GLint yoffset,
709                                                     GLsizei width,
710                                                     GLsizei height,
711                                                     GLenum format,
712                                                     GLsizei imageSize,
713                                                     const GLvoid *data)
714 {
715     struct yagl_gles2_context *ctx = (struct yagl_gles2_context*)gles_ctx;
716     struct yagl_texcompress_format *tc_format;
717     GLsizei src_stride;
718     GLsizei dst_stride;
719     GLsizei dst_size;
720     uint8_t *buff;
721
722     YAGL_LOG_FUNC_SET(glCompressedTexSubImage2D);
723
724     if (format == GL_ETC1_RGB8_OES) {
725         /*
726          * "INVALID_OPERATION is generated by CompressedTexSubImage2D,
727          * TexSubImage2D, or CopyTexSubImage2D if the texture image <level>
728          * bound to <target> has internal format ETC1_RGB8_OES."
729          */
730         YAGL_SET_ERR(GL_INVALID_OPERATION);
731         return;
732     }
733
734     tc_format = yagl_texcompress_get_format(format);
735
736     if (!tc_format) {
737         YAGL_SET_ERR(GL_INVALID_ENUM);
738         return;
739     }
740
741     if (!yagl_texcompress_get_info(tc_format,
742                                    width,
743                                    height,
744                                    imageSize,
745                                    &src_stride,
746                                    &dst_stride,
747                                    &dst_size)) {
748         YAGL_SET_ERR(GL_INVALID_VALUE);
749         return;
750     }
751
752     if (!data) {
753         yagl_host_glTexSubImage2DData(target,
754                                       level,
755                                       xoffset,
756                                       yoffset,
757                                       width,
758                                       height,
759                                       tc_format->dst_format,
760                                       tc_format->dst_type,
761                                       NULL,
762                                       dst_size);
763
764         return;
765     }
766
767     buff = yagl_get_tmp_buffer(dst_size);
768
769     tc_format->unpack(tc_format,
770                       data,
771                       width,
772                       height,
773                       src_stride,
774                       buff,
775                       dst_stride);
776
777     yagl_gles_reset_unpack(&gles_ctx->unpack);
778
779     yagl_host_glTexSubImage2DData(target,
780                                   level,
781                                   xoffset,
782                                   yoffset,
783                                   width,
784                                   height,
785                                   tc_format->dst_format,
786                                   tc_format->dst_type,
787                                   buff,
788                                   dst_size);
789
790     yagl_gles_set_unpack(&gles_ctx->unpack);
791 }
792
793 void yagl_gles2_context_compressed_tex_image_3d(struct yagl_gles2_context *ctx,
794                                                 GLenum target,
795                                                 struct yagl_gles_texture *texture,
796                                                 GLint level,
797                                                 GLenum internalformat,
798                                                 GLsizei width,
799                                                 GLsizei height,
800                                                 GLsizei depth,
801                                                 GLint border,
802                                                 GLsizei imageSize,
803                                                 const GLvoid *data)
804 {
805     GLsizei singleImageSize = 0;
806     struct yagl_texcompress_format *tc_format;
807     GLsizei src_stride;
808     GLsizei dst_stride;
809     GLsizei dst_size;
810     uint8_t *buff, *tmp;
811     GLsizei i;
812
813     YAGL_LOG_FUNC_SET(glCompressedTexImage3D);
814
815     tc_format = yagl_texcompress_get_format(internalformat);
816
817     if (!tc_format) {
818         YAGL_SET_ERR(GL_INVALID_ENUM);
819         return;
820     }
821
822     if (depth > 0) {
823         singleImageSize = imageSize / depth;
824     }
825
826     if (!yagl_texcompress_get_info(tc_format,
827                                    width,
828                                    height,
829                                    singleImageSize,
830                                    &src_stride,
831                                    &dst_stride,
832                                    &dst_size)) {
833         YAGL_SET_ERR(GL_INVALID_VALUE);
834         return;
835     }
836
837     if (!data) {
838         yagl_host_glTexImage3DData(target,
839                                    level,
840                                    tc_format->dst_internalformat,
841                                    width,
842                                    height,
843                                    depth,
844                                    border,
845                                    tc_format->dst_format,
846                                    tc_format->dst_type,
847                                    NULL,
848                                    dst_size * depth);
849
850         yagl_gles_texture_set_internalformat(texture,
851                                              tc_format->dst_internalformat,
852                                              tc_format->dst_type,
853                                              yagl_gles_context_convert_textures(&ctx->base));
854
855         return;
856     }
857
858     buff = tmp = yagl_get_tmp_buffer(dst_size * depth);
859
860     for (i = 0; i < depth; ++i) {
861         tc_format->unpack(tc_format,
862                           data,
863                           width,
864                           height,
865                           src_stride,
866                           tmp,
867                           dst_stride);
868         data += singleImageSize;
869         tmp += dst_size;
870     }
871
872     yagl_gles_reset_unpack(&ctx->base.unpack);
873
874     yagl_host_glTexImage3DData(target,
875                                level,
876                                tc_format->dst_internalformat,
877                                width,
878                                height,
879                                depth,
880                                border,
881                                tc_format->dst_format,
882                                tc_format->dst_type,
883                                buff,
884                                dst_size * depth);
885
886     yagl_gles_set_unpack(&ctx->base.unpack);
887
888     yagl_gles_texture_set_internalformat(texture,
889                                          tc_format->dst_internalformat,
890                                          tc_format->dst_type,
891                                          yagl_gles_context_convert_textures(&ctx->base));
892 }
893
894 void yagl_gles2_context_compressed_tex_sub_image_3d(struct yagl_gles2_context *ctx,
895                                                     GLenum target,
896                                                     GLint level,
897                                                     GLint xoffset,
898                                                     GLint yoffset,
899                                                     GLint zoffset,
900                                                     GLsizei width,
901                                                     GLsizei height,
902                                                     GLsizei depth,
903                                                     GLenum format,
904                                                     GLsizei imageSize,
905                                                     const GLvoid *data)
906 {
907     GLsizei singleImageSize = 0;
908     struct yagl_texcompress_format *tc_format;
909     GLsizei src_stride;
910     GLsizei dst_stride;
911     GLsizei dst_size;
912     uint8_t *buff, *tmp;
913     GLsizei i;
914
915     YAGL_LOG_FUNC_SET(glCompressedTexSubImage3D);
916
917     if (format == GL_ETC1_RGB8_OES) {
918         /*
919          * "INVALID_OPERATION is generated by CompressedTexSubImage2D,
920          * TexSubImage2D, or CopyTexSubImage2D if the texture image <level>
921          * bound to <target> has internal format ETC1_RGB8_OES."
922          */
923         YAGL_SET_ERR(GL_INVALID_OPERATION);
924         return;
925     }
926
927     tc_format = yagl_texcompress_get_format(format);
928
929     if (!tc_format) {
930         YAGL_SET_ERR(GL_INVALID_ENUM);
931         return;
932     }
933
934     if (depth > 0) {
935         singleImageSize = imageSize / depth;
936     }
937
938     if (!yagl_texcompress_get_info(tc_format,
939                                    width,
940                                    height,
941                                    singleImageSize,
942                                    &src_stride,
943                                    &dst_stride,
944                                    &dst_size)) {
945         YAGL_SET_ERR(GL_INVALID_VALUE);
946         return;
947     }
948
949     if (!data) {
950         yagl_host_glTexSubImage3DData(target,
951                                       level,
952                                       xoffset,
953                                       yoffset,
954                                       zoffset,
955                                       width,
956                                       height,
957                                       depth,
958                                       tc_format->dst_format,
959                                       tc_format->dst_type,
960                                       NULL,
961                                       dst_size * depth);
962
963         return;
964     }
965
966     buff = tmp = yagl_get_tmp_buffer(dst_size * depth);
967
968     for (i = 0; i < depth; ++i) {
969         tc_format->unpack(tc_format,
970                           data,
971                           width,
972                           height,
973                           src_stride,
974                           tmp,
975                           dst_stride);
976         data += singleImageSize;
977         tmp += dst_size;
978     }
979
980     yagl_gles_reset_unpack(&ctx->base.unpack);
981
982     yagl_host_glTexSubImage3DData(target,
983                                   level,
984                                   xoffset,
985                                   yoffset,
986                                   zoffset,
987                                   width,
988                                   height,
989                                   depth,
990                                   tc_format->dst_format,
991                                   tc_format->dst_type,
992                                   buff,
993                                   dst_size * depth);
994
995     yagl_gles_set_unpack(&ctx->base.unpack);
996 }
997
998 int yagl_gles2_context_get_integerv(struct yagl_gles_context *ctx,
999                                     GLenum pname,
1000                                     GLint *params,
1001                                     uint32_t *num_params)
1002 {
1003     int processed = 1;
1004     struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
1005     struct yagl_gles_texture_target_state *tts;
1006
1007     switch (pname) {
1008     case GL_NUM_SHADER_BINARY_FORMATS:
1009         *params = 0;
1010         *num_params = 1;
1011         break;
1012     case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1013         *params = yagl_texcompress_get_format_names(NULL);
1014         *num_params = 1;
1015         break;
1016     case GL_TEXTURE_BINDING_CUBE_MAP:
1017         tts = yagl_gles_context_get_active_texture_target_state(ctx,
1018             yagl_gles_texture_target_cubemap);
1019         *params = tts->texture->base.local_name;
1020         *num_params = 1;
1021         break;
1022     case GL_TEXTURE_BINDING_3D_OES:
1023         tts = yagl_gles_context_get_active_texture_target_state(ctx,
1024             yagl_gles_texture_target_3d);
1025         *params = tts->texture->base.local_name;
1026         *num_params = 1;
1027         break;
1028     case GL_CURRENT_PROGRAM:
1029         *params = gles2_ctx->program ? gles2_ctx->program->base.local_name : 0;
1030         *num_params = 1;
1031         break;
1032     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1033         *params = ctx->num_texture_units;
1034         *num_params = 1;
1035         break;
1036     case GL_MAX_VERTEX_ATTRIBS:
1037         *params = ctx->num_arrays;
1038         *num_params = 1;
1039         break;
1040     case GL_COMPRESSED_TEXTURE_FORMATS:
1041         *num_params = yagl_texcompress_get_format_names((GLenum*)params);
1042         break;
1043     case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1044         *num_params = 1;
1045         if (gles2_ctx->have_max_fragment_uniform_components) {
1046             *params = gles2_ctx->max_fragment_uniform_components;
1047         } else {
1048             yagl_host_glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, params, *num_params, NULL);
1049             gles2_ctx->max_fragment_uniform_components = *params;
1050             gles2_ctx->have_max_fragment_uniform_components = 1;
1051         }
1052         *params /= 4;
1053         break;
1054     case GL_MAX_VARYING_VECTORS:
1055         *num_params = 1;
1056         if (yagl_get_host_gl_version() >= yagl_gl_3_2) {
1057             /*
1058              * GL_MAX_VARYING_COMPONENTS is an alias for GL_MAX_VARYING_FLOATS
1059              * and it should be used in OpenGL 3.1, but it's deprecated in
1060              * OpenGL 3.2, thus, we use a constant.
1061              */
1062             *params = 64;
1063         } else if (gles2_ctx->have_max_varying_floats) {
1064             *params = gles2_ctx->max_varying_floats;
1065         } else {
1066             yagl_host_glGetIntegerv(GL_MAX_VARYING_FLOATS, params, *num_params, NULL);
1067             gles2_ctx->max_varying_floats = *params;
1068             gles2_ctx->have_max_varying_floats = 1;
1069         }
1070         *params /= 4;
1071         break;
1072     case GL_MAX_VERTEX_UNIFORM_VECTORS:
1073         *num_params = 1;
1074         if (gles2_ctx->have_max_vertex_uniform_components) {
1075             *params = gles2_ctx->max_vertex_uniform_components;
1076         } else {
1077             yagl_host_glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, params, *num_params, NULL);
1078             gles2_ctx->max_vertex_uniform_components = *params;
1079             gles2_ctx->have_max_vertex_uniform_components = 1;
1080         }
1081         *params /= 4;
1082         break;
1083     case GL_SHADER_COMPILER:
1084         *params = GL_TRUE;
1085         *num_params = 1;
1086         break;
1087     case GL_STENCIL_BACK_FAIL:
1088         *params = ctx->stencil_back.fail;
1089         *num_params = 1;
1090         break;
1091     case GL_STENCIL_BACK_FUNC:
1092         *params = ctx->stencil_back.func;
1093         *num_params = 1;
1094         break;
1095     case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1096         *params = ctx->stencil_back.zfail;
1097         *num_params = 1;
1098         break;
1099     case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1100         *params = ctx->stencil_back.zpass;
1101         *num_params = 1;
1102         break;
1103     case GL_STENCIL_BACK_REF:
1104         *params = ctx->stencil_back.ref;
1105         *num_params = 1;
1106         break;
1107     case GL_STENCIL_BACK_VALUE_MASK:
1108         *params = ctx->stencil_back.mask;
1109         *num_params = 1;
1110         break;
1111     case GL_STENCIL_BACK_WRITEMASK:
1112         *params = ctx->stencil_back.writemask;
1113         *num_params = 1;
1114         break;
1115     case GL_DITHER:
1116         *params = ctx->dither_enabled;
1117         *num_params = 1;
1118         break;
1119     case GL_MAX_TEXTURE_SIZE:
1120         if (gles2_ctx->have_max_texture_size) {
1121             *params = gles2_ctx->max_texture_size;
1122             *num_params = 1;
1123         } else {
1124             processed = 0;
1125         }
1126         break;
1127     case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1128         if (gles2_ctx->have_max_cubemap_texture_size) {
1129             *params = gles2_ctx->max_cubemap_texture_size;
1130             *num_params = 1;
1131         } else {
1132             processed = 0;
1133         }
1134         break;
1135     case GL_MAX_SAMPLES_IMG:
1136         if (gles2_ctx->have_max_samples_img) {
1137             *params = gles2_ctx->max_samples_img;
1138             *num_params = 1;
1139         } else {
1140             processed = 0;
1141         }
1142         break;
1143     case GL_MAX_TEXTURE_IMAGE_UNITS:
1144         if (gles2_ctx->have_max_texture_image_units) {
1145             *params = gles2_ctx->max_texture_image_units;
1146             *num_params = 1;
1147         } else {
1148             processed = 0;
1149         }
1150         break;
1151     case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1152         if (gles2_ctx->have_max_texture_max_anisotropy) {
1153             *params = gles2_ctx->max_texture_max_anisotropy;
1154             *num_params = 1;
1155         } else {
1156             processed = 0;
1157         }
1158         break;
1159     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1160         if (gles2_ctx->have_max_vertex_texture_image_units) {
1161             *params = gles2_ctx->max_vertex_texture_image_units;
1162             *num_params = 1;
1163         } else {
1164             processed = 0;
1165         }
1166         break;
1167     case GL_MAX_3D_TEXTURE_SIZE_OES:
1168         if (gles2_ctx->have_max_3d_texture_size) {
1169             *params = gles2_ctx->max_3d_texture_size;
1170             *num_params = 1;
1171         } else {
1172             processed = 0;
1173         }
1174         break;
1175     default:
1176         processed = 0;
1177         break;
1178     }
1179
1180     if (processed) {
1181         return 1;
1182     }
1183
1184     switch (pname) {
1185     case GL_MAX_TEXTURE_SIZE:
1186         *num_params = 1;
1187         yagl_host_glGetIntegerv(pname, params, *num_params, NULL);
1188         gles2_ctx->max_texture_size = *params;
1189         gles2_ctx->have_max_texture_size = 1;
1190         break;
1191     case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1192         *num_params = 1;
1193         yagl_host_glGetIntegerv(pname, params, *num_params, NULL);
1194         gles2_ctx->max_cubemap_texture_size = *params;
1195         gles2_ctx->have_max_cubemap_texture_size = 1;
1196         break;
1197     case GL_MAX_SAMPLES_IMG:
1198         *num_params = 1;
1199         yagl_host_glGetIntegerv(pname, params, *num_params, NULL);
1200         gles2_ctx->max_samples_img = *params;
1201         gles2_ctx->have_max_samples_img = 1;
1202         break;
1203     case GL_MAX_TEXTURE_IMAGE_UNITS:
1204         *num_params = 1;
1205         yagl_host_glGetIntegerv(pname, params, *num_params, NULL);
1206         gles2_ctx->max_texture_image_units = *params;
1207         gles2_ctx->have_max_texture_image_units = 1;
1208         break;
1209     case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1210         *num_params = 1;
1211         yagl_host_glGetIntegerv(pname, params, *num_params, NULL);
1212         gles2_ctx->max_texture_max_anisotropy = *params;
1213         gles2_ctx->have_max_texture_max_anisotropy = 1;
1214         break;
1215     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1216         *num_params = 1;
1217         yagl_host_glGetIntegerv(pname, params, *num_params, NULL);
1218         gles2_ctx->max_vertex_texture_image_units = *params;
1219         gles2_ctx->have_max_vertex_texture_image_units = 1;
1220         break;
1221     case GL_SHADER_BINARY_FORMATS:
1222         *num_params = 0;
1223         break;
1224     case GL_MAX_3D_TEXTURE_SIZE_OES:
1225         *num_params = 1;
1226         yagl_host_glGetIntegerv(pname, params, *num_params, NULL);
1227         gles2_ctx->max_3d_texture_size = *params;
1228         gles2_ctx->have_max_3d_texture_size = 1;
1229         break;
1230     default:
1231         return 0;
1232     }
1233
1234     return 1;
1235 }
1236
1237 int yagl_gles2_context_get_floatv(struct yagl_gles_context *ctx,
1238                                   GLenum pname,
1239                                   GLfloat *params,
1240                                   uint32_t *num_params,
1241                                   int *needs_map)
1242 {
1243     struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
1244
1245     switch (pname) {
1246     case GL_BLEND_COLOR:
1247         params[0] = gles2_ctx->blend_color[0];
1248         params[1] = gles2_ctx->blend_color[1];
1249         params[2] = gles2_ctx->blend_color[2];
1250         params[3] = gles2_ctx->blend_color[3];
1251         *num_params = 4;
1252         *needs_map = 1;
1253         break;
1254     default:
1255         return 0;
1256     }
1257
1258     return 1;
1259 }
1260
1261 void yagl_gles2_context_draw_arrays(struct yagl_gles_context *ctx,
1262                                     GLenum mode,
1263                                     GLint first,
1264                                     GLsizei count,
1265                                     GLsizei primcount)
1266 {
1267     struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
1268
1269     yagl_gles2_context_pre_draw(gles2_ctx, mode, first + count);
1270
1271     if (primcount < 0) {
1272         yagl_host_glDrawArrays(mode, first, count);
1273     } else {
1274         yagl_host_glDrawArraysInstanced(mode, first, count, primcount);
1275     }
1276
1277     yagl_gles2_context_post_draw(gles2_ctx, mode, first + count);
1278 }
1279
1280 void yagl_gles2_context_draw_elements(struct yagl_gles_context *ctx,
1281                                       GLenum mode,
1282                                       GLsizei count,
1283                                       GLenum type,
1284                                       const GLvoid *indices,
1285                                       int32_t indices_count,
1286                                       GLsizei primcount,
1287                                       uint32_t max_idx)
1288 {
1289     struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
1290
1291     yagl_gles2_context_pre_draw(gles2_ctx, mode, max_idx + 1);
1292
1293     if (primcount < 0) {
1294         yagl_host_glDrawElements(mode, count, type, indices, indices_count);
1295     } else {
1296         yagl_host_glDrawElementsInstanced(mode, count, type, indices, indices_count, primcount);
1297     }
1298
1299     yagl_gles2_context_post_draw(gles2_ctx, mode, max_idx + 1);
1300 }
1301
1302 int yagl_gles2_context_validate_texture_target(struct yagl_gles_context *ctx,
1303                                                GLenum target,
1304                                                yagl_gles_texture_target *texture_target)
1305 {
1306     switch (target) {
1307     case GL_TEXTURE_3D_OES:
1308         *texture_target = yagl_gles_texture_target_3d;
1309         break;
1310     case GL_TEXTURE_CUBE_MAP:
1311         *texture_target = yagl_gles_texture_target_cubemap;
1312         break;
1313     default:
1314         return 0;
1315     }
1316
1317     return 1;
1318 }
1319
1320 struct yagl_pixel_format
1321     *yagl_gles2_context_validate_teximage_format(struct yagl_gles_context *ctx,
1322                                                  GLenum internalformat,
1323                                                  GLenum format,
1324                                                  GLenum type)
1325 {
1326     return NULL;
1327 }
1328
1329 struct yagl_pixel_format
1330     *yagl_gles2_context_validate_getteximage_format(struct yagl_gles_context *ctx,
1331                                                     GLenum readbuffer_internalformat,
1332                                                     GLenum format,
1333                                                     GLenum type)
1334 {
1335     return NULL;
1336 }
1337
1338 int yagl_gles2_context_validate_copyteximage_format(struct yagl_gles_context *ctx,
1339                                                     GLenum readbuffer_internalformat,
1340                                                     GLenum *internalformat)
1341 {
1342     return 0;
1343 }
1344
1345 int yagl_gles2_context_validate_texstorage_format(struct yagl_gles_context *ctx,
1346                                                   GLenum *internalformat,
1347                                                   GLenum *base_internalformat,
1348                                                   GLenum *any_format,
1349                                                   GLenum *any_type)
1350 {
1351     struct yagl_texcompress_format *tc_format;
1352
1353     if (*internalformat == GL_ETC1_RGB8_OES) {
1354         /*
1355          * This is not allowed for TexStorage.
1356          */
1357         return 0;
1358     }
1359
1360     tc_format = yagl_texcompress_get_format(*internalformat);
1361
1362     if (!tc_format) {
1363         return 0;
1364     }
1365
1366     *internalformat = tc_format->dst_internalformat;
1367     *base_internalformat = tc_format->dst_internalformat;
1368     *any_format = tc_format->dst_format;
1369     *any_type = tc_format->dst_type;
1370
1371     return 1;
1372 }
1373
1374 int yagl_gles2_context_validate_renderbuffer_format(struct yagl_gles_context *ctx,
1375                                                     GLenum *internalformat)
1376 {
1377     return 0;
1378 }
1379
1380 void yagl_gles2_context_hint(struct yagl_gles_context *ctx,
1381                              GLenum target,
1382                              GLenum mode)
1383 {
1384 }
1385
1386 int yagl_gles2_context_get_programiv(struct yagl_gles2_context *ctx,
1387                                      struct yagl_gles2_program *program,
1388                                      GLenum pname,
1389                                      GLint *params)
1390 {
1391     switch (pname) {
1392     case GL_ATTACHED_SHADERS:
1393         *params = (program->fragment_shader != NULL) ? 1 : 0;
1394         *params += (program->vertex_shader != NULL) ? 1 : 0;
1395         break;
1396     case GL_INFO_LOG_LENGTH:
1397         *params = program->info_log_length;
1398         break;
1399     case GL_ACTIVE_ATTRIBUTES:
1400         *params = program->num_active_attribs;
1401         break;
1402     case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1403         *params = program->max_active_attrib_bufsize;
1404         break;
1405     case GL_ACTIVE_UNIFORMS:
1406         *params = program->num_active_uniforms;
1407         break;
1408     case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1409         *params = program->max_active_uniform_bufsize;
1410         break;
1411     case GL_DELETE_STATUS:
1412         *params = GL_FALSE;
1413         break;
1414     case GL_LINK_STATUS:
1415         *params = program->link_status;
1416         break;
1417     default:
1418         return 0;
1419     }
1420
1421     return 1;
1422 }
1423
1424 struct yagl_client_context *yagl_gles2_context_create(struct yagl_sharegroup *sg)
1425 {
1426     struct yagl_gles2_context *gles2_ctx;
1427
1428     YAGL_LOG_FUNC_ENTER(yagl_gles2_context_create, NULL);
1429
1430     gles2_ctx = yagl_malloc0(sizeof(*gles2_ctx));
1431
1432     yagl_gles2_context_init(gles2_ctx, yagl_client_api_gles2, sg);
1433
1434     gles2_ctx->base.base.prepare = &yagl_gles2_context_prepare_internal;
1435     gles2_ctx->base.base.destroy = &yagl_gles2_context_destroy;
1436     gles2_ctx->base.create_arrays = &yagl_gles2_context_create_arrays;
1437     gles2_ctx->base.get_string = &yagl_gles2_context_get_string;
1438     gles2_ctx->base.compressed_tex_image_2d = &yagl_gles2_context_compressed_tex_image_2d;
1439     gles2_ctx->base.compressed_tex_sub_image_2d = &yagl_gles2_context_compressed_tex_sub_image_2d;
1440     gles2_ctx->base.enable = &yagl_gles2_context_enable;
1441     gles2_ctx->base.is_enabled = &yagl_gles2_context_is_enabled;
1442     gles2_ctx->base.get_integerv = &yagl_gles2_context_get_integerv;
1443     gles2_ctx->base.get_floatv = &yagl_gles2_context_get_floatv;
1444     gles2_ctx->base.draw_arrays = &yagl_gles2_context_draw_arrays;
1445     gles2_ctx->base.draw_elements = &yagl_gles2_context_draw_elements;
1446     gles2_ctx->base.bind_buffer = &yagl_gles2_context_bind_buffer;
1447     gles2_ctx->base.unbind_buffer = &yagl_gles2_context_unbind_buffer;
1448     gles2_ctx->base.acquire_binded_buffer = &yagl_gles2_context_acquire_binded_buffer;
1449     gles2_ctx->base.validate_texture_target = &yagl_gles2_context_validate_texture_target;
1450     gles2_ctx->base.validate_teximage_format = &yagl_gles2_context_validate_teximage_format;
1451     gles2_ctx->base.validate_getteximage_format = &yagl_gles2_context_validate_getteximage_format;
1452     gles2_ctx->base.validate_copyteximage_format = &yagl_gles2_context_validate_copyteximage_format;
1453     gles2_ctx->base.validate_texstorage_format = &yagl_gles2_context_validate_texstorage_format;
1454     gles2_ctx->base.validate_renderbuffer_format = &yagl_gles2_context_validate_renderbuffer_format;
1455     gles2_ctx->base.hint = &yagl_gles2_context_hint;
1456     gles2_ctx->get_programiv = &yagl_gles2_context_get_programiv;
1457     gles2_ctx->pre_use_program = &yagl_gles2_context_pre_use_program;
1458     gles2_ctx->pre_link_program = &yagl_gles2_context_pre_link_program;
1459
1460     YAGL_LOG_FUNC_EXIT("%p", gles2_ctx);
1461
1462     return &gles2_ctx->base.base;
1463 }
1464
1465 void yagl_gles2_context_use_program(struct yagl_gles2_context *ctx,
1466                                     struct yagl_gles2_program *program)
1467 {
1468     yagl_gles2_program_acquire(program);
1469     yagl_gles2_program_release(ctx->program);
1470     ctx->program = program;
1471
1472     yagl_host_glUseProgram((program ? program->global_name : 0));
1473 }
1474
1475 void yagl_gles2_context_unuse_program(struct yagl_gles2_context *ctx,
1476                                       struct yagl_gles2_program *program)
1477 {
1478     if (ctx->program == program) {
1479         yagl_gles2_program_release(ctx->program);
1480         ctx->program = NULL;
1481     }
1482 }
1483
1484 int yagl_gles2_context_get_array_param(struct yagl_gles2_context *ctx,
1485                                        GLuint index,
1486                                        GLenum pname,
1487                                        GLint *param)
1488 {
1489     struct yagl_gles_array *array;
1490
1491     YAGL_LOG_FUNC_SET(yagl_gles2_context_get_array_param);
1492
1493     if (index >= ctx->base.num_arrays) {
1494         YAGL_SET_ERR(GL_INVALID_VALUE);
1495         return 1;
1496     }
1497
1498     array = &ctx->base.vao->arrays[index];
1499
1500     switch (pname) {
1501     case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
1502         *param = array->vbo ? array->vbo->base.local_name : 0;
1503         break;
1504     case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
1505         *param = array->enabled;
1506         break;
1507     case GL_VERTEX_ATTRIB_ARRAY_SIZE:
1508         *param = array->size;
1509         break;
1510     case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
1511         *param = array->stride;
1512         break;
1513     case GL_VERTEX_ATTRIB_ARRAY_TYPE:
1514         *param = array->type;
1515         break;
1516     case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
1517         *param = array->normalized;
1518         break;
1519     case GL_CURRENT_VERTEX_ATTRIB:
1520         return 0;
1521     case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT:
1522         if (ctx->instanced_arrays) {
1523             *param = array->divisor;
1524         } else {
1525             YAGL_SET_ERR(GL_INVALID_ENUM);
1526         }
1527         break;
1528     case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
1529         if (ctx->base.base.client_api == yagl_client_api_gles3) {
1530             *param = array->integer;
1531         } else {
1532             YAGL_SET_ERR(GL_INVALID_ENUM);
1533         }
1534         break;
1535     default:
1536         YAGL_SET_ERR(GL_INVALID_ENUM);
1537         break;
1538     }
1539
1540     return 1;
1541 }