4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
7 * Stanislav Vorobiov <s.vorobiov@samsung.com>
8 * Jinhyung Jo <jinhyung.jo@samsung.com>
9 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
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:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
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
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"
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"
55 #define YAGL_SET_ERR(err) \
56 yagl_gles_context_set_error(&ctx->base, err); \
57 YAGL_LOG_ERROR("error = 0x%X", err)
60 * We can't include GL/glext.h here
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
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";
100 static void yagl_gles2_context_prepare_internal(struct yagl_client_context *ctx)
102 struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
103 const GLchar **extensions;
106 yagl_gles2_context_prepare(gles2_ctx);
108 extensions = yagl_gles2_context_get_extensions(gles2_ctx, &num_extensions);
110 yagl_gles_context_prepare_end(&gles2_ctx->base, extensions, num_extensions);
113 static void yagl_gles2_context_destroy(struct yagl_client_context *ctx)
115 struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
117 YAGL_LOG_FUNC_ENTER(yagl_gles2_context_destroy, "%p", ctx);
119 yagl_gles2_context_cleanup(gles2_ctx);
121 yagl_free(gles2_ctx);
123 YAGL_LOG_FUNC_EXIT(NULL);
126 static void yagl_gles2_array_apply(struct yagl_gles_array *array,
132 if (array->integer) {
134 yagl_host_glVertexAttribIPointerOffset(array->index,
137 array->actual_stride,
138 array->actual_offset);
140 yagl_host_glVertexAttribIPointerData(array->index,
143 array->actual_stride,
145 ptr + (first * array->actual_stride),
146 count * array->actual_stride);
153 yagl_host_glVertexAttribPointerOffset(array->index,
157 array->actual_stride,
158 array->actual_offset);
160 yagl_host_glVertexAttribPointerData(array->index,
164 array->actual_stride,
166 ptr + (first * array->actual_stride),
167 count * array->actual_stride);
172 *yagl_gles2_context_get_string(struct yagl_gles_context *ctx,
175 const char *str = NULL;
179 str = "OpenGL ES 2.0";
184 case GL_SHADING_LANGUAGE_VERSION:
185 str = "OpenGL ES GLSL ES 1.4";
194 static int yagl_gles2_context_enable(struct yagl_gles_context *ctx,
201 static int yagl_gles2_context_is_enabled(struct yagl_gles_context *ctx,
208 static int yagl_gles2_context_bind_buffer(struct yagl_gles_context *ctx,
210 struct yagl_gles_buffer *buffer)
215 static void yagl_gles2_context_unbind_buffer(struct yagl_gles_context *ctx,
216 yagl_object_name buffer_local_name)
220 static int yagl_gles2_context_acquire_binded_buffer(struct yagl_gles_context *ctx,
222 struct yagl_gles_buffer **buffer)
227 static int yagl_gles2_context_pre_use_program(struct yagl_gles2_context *ctx,
228 struct yagl_gles2_program *program)
233 static int yagl_gles2_context_pre_link_program(struct yagl_gles2_context *ctx,
234 struct yagl_gles2_program *program)
239 void yagl_gles2_context_init(struct yagl_gles2_context *ctx,
240 yagl_client_api client_api,
241 struct yagl_sharegroup *sg)
243 yagl_gles_context_init(&ctx->base, client_api, sg);
248 void yagl_gles2_context_cleanup(struct yagl_gles2_context *ctx)
250 yagl_gles2_program_release(ctx->program);
252 yagl_gles_buffer_release(ctx->vertex_attrib0.vbo);
254 yagl_gles_context_cleanup(&ctx->base);
257 void yagl_gles2_context_prepare(struct yagl_gles2_context *ctx)
259 GLint num_texture_units = 0;
261 char *extensions, *nonconformant;
264 YAGL_LOG_FUNC_ENTER(yagl_gles2_context_prepare, "%p", ctx);
266 yagl_host_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &num_arrays, 1, NULL);
268 yagl_host_glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
269 &num_texture_units, 1, NULL);
272 * We limit this by 32 for conformance.
274 if (num_texture_units > 32) {
275 num_texture_units = 32;
278 yagl_gles_context_prepare(&ctx->base,
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();
289 nonconformant = getenv("YAGL_NONCONFORMANT");
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.
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
302 * // do logic when 'my_uniform' is in the shader
304 * i.e. 'gen_locations == 1' will break this logic, thus, we
305 * now set gen_locations to 0 by default.
308 if (nonconformant && atoi(nonconformant)) {
309 ctx->gen_locations = 1;
311 ctx->gen_locations = 0;
314 yagl_host_glGetString(GL_EXTENSIONS, NULL, 0, &size);
315 extensions = yagl_malloc0(size);
316 yagl_host_glGetString(GL_EXTENSIONS, extensions, size, NULL);
318 if (yagl_get_host_gl_version() > yagl_gl_2) {
319 ctx->texture_half_float = 1;
320 ctx->vertex_half_float = 1;
322 ctx->texture_half_float = (strstr(extensions, "GL_ARB_half_float_pixel ") != NULL) ||
323 (strstr(extensions, "GL_NV_half_float ") != NULL);
325 ctx->vertex_half_float = (strstr(extensions, "GL_ARB_half_float_vertex ") != NULL);
328 ctx->standard_derivatives = 1;
330 yagl_free(extensions);
332 ctx->instanced_arrays = (yagl_get_host_gl_version() > yagl_gl_2);
334 YAGL_LOG_FUNC_EXIT(NULL);
337 const GLchar **yagl_gles2_context_get_extensions(struct yagl_gles2_context *ctx,
340 const GLchar **extensions;
343 extensions = yagl_malloc(100 * sizeof(*extensions));
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;
366 if (yagl_egl_fence_supported()) {
367 extensions[i++] = egl_sync_ext;
370 if (ctx->base.packed_depth_stencil) {
371 extensions[i++] = packed_depth_stencil_ext;
374 if (ctx->base.texture_npot) {
375 extensions[i++] = texture_npot_ext;
378 if (ctx->base.texture_filter_anisotropic) {
379 extensions[i++] = texture_filter_anisotropic_ext;
382 if (ctx->base.vertex_arrays_supported) {
383 extensions[i++] = vertex_array_object_ext;
386 if (ctx->texture_half_float) {
387 extensions[i++] = texture_half_float_ext;
388 extensions[i++] = texture_half_float_linear_ext;
391 if (ctx->vertex_half_float) {
392 extensions[i++] = vertex_half_float_ext;
395 if (ctx->standard_derivatives) {
396 extensions[i++] = standard_derivatives_ext;
399 if (ctx->instanced_arrays) {
400 extensions[i++] = instanced_arrays_ext;
408 struct yagl_gles_array
409 *yagl_gles2_context_create_arrays(struct yagl_gles_context *ctx)
412 struct yagl_gles_array *arrays;
414 arrays = yagl_malloc(ctx->num_arrays * sizeof(*arrays));
416 for (i = 0; i < ctx->num_arrays; ++i) {
417 yagl_gles_array_init(&arrays[i],
419 &yagl_gles2_array_apply,
426 void yagl_gles2_context_pre_draw(struct yagl_gles2_context *ctx,
430 YAGL_LOG_FUNC_SET(yagl_gles2_context_pre_draw);
433 * 'count' can be <= 0 in case of integer overflows, this is
434 * typically user problem, just don't simulate vertex attribute array 0
438 if (!ctx->base.vao->arrays[0].enabled && (count > 0)) {
440 * vertex attribute array 0 not enabled, simulate
441 * vertex attribute array 0.
444 GLint size = count * sizeof(ctx->vertex_attrib0.value);
447 if (!ctx->vertex_attrib0.warned) {
448 YAGL_LOG_WARN("vertex attribute array 0 not enabled, simulating");
450 ctx->vertex_attrib0.warned = 1;
453 if (ctx->vertex_attrib0.vbo->size < size) {
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.
460 tmp = it = yagl_get_tmp_buffer2(size);
462 while (it < (tmp + size)) {
463 memcpy(it, &ctx->vertex_attrib0.value, sizeof(ctx->vertex_attrib0.value));
464 it += sizeof(ctx->vertex_attrib0.value);
467 yagl_gles_buffer_set_data(ctx->vertex_attrib0.vbo,
472 ctx->vertex_attrib0.count = count;
475 * We can fit it in existing buffer.
480 tmp = ctx->vertex_attrib0.vbo->data;
483 &ctx->vertex_attrib0.value,
484 sizeof(ctx->vertex_attrib0.value)) == 0) {
485 if (ctx->vertex_attrib0.count < count) {
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.
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;
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
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
517 ctx->vertex_attrib0.count = count;
520 tmp = it = yagl_get_tmp_buffer2(size);
522 while (it < (tmp + size)) {
523 memcpy(it, &ctx->vertex_attrib0.value, sizeof(ctx->vertex_attrib0.value));
524 it += sizeof(ctx->vertex_attrib0.value);
527 yagl_gles_buffer_update_data(ctx->vertex_attrib0.vbo,
533 yagl_host_glEnableVertexAttribArray(0);
535 if (ctx->base.vao->arrays[0].divisor != 0) {
536 yagl_host_glVertexAttribDivisor(0, 0);
539 yagl_gles_buffer_bind(ctx->vertex_attrib0.vbo,
543 yagl_gles_buffer_transfer(ctx->vertex_attrib0.vbo,
547 switch (ctx->vertex_attrib0.type) {
549 case GL_UNSIGNED_INT:
550 yagl_host_glVertexAttribIPointerOffset(0,
552 ctx->vertex_attrib0.type,
559 yagl_host_glVertexAttribPointerOffset(0,
561 ctx->vertex_attrib0.type,
567 yagl_host_glBindBuffer(GL_ARRAY_BUFFER, 0);
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
576 if (mode == GL_POINTS) {
577 if (yagl_get_host_gl_version() <= yagl_gl_3_2) {
578 yagl_host_glEnable(GL_POINT_SPRITE);
580 yagl_host_glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
584 void yagl_gles2_context_post_draw(struct yagl_gles2_context *ctx,
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);
595 if (!ctx->base.vao->arrays[0].enabled && (count > 0)) {
597 * Restore vertex attribute array 0 pointer.
599 yagl_gles_array_apply(&ctx->base.vao->arrays[0]);
601 if (ctx->base.vao->arrays[0].divisor != 0) {
603 * Restore vertex attribute array 0 divisor.
605 yagl_host_glVertexAttribDivisor(0, ctx->base.vao->arrays[0].divisor);
609 * Restore vertex attribute array 0 state.
611 yagl_host_glDisableVertexAttribArray(0);
615 void yagl_gles2_context_compressed_tex_image_2d(struct yagl_gles_context *gles_ctx,
617 struct yagl_gles_texture *texture,
619 GLenum internalformat,
626 struct yagl_gles2_context *ctx = (struct yagl_gles2_context*)gles_ctx;
627 struct yagl_texcompress_format *tc_format;
633 YAGL_LOG_FUNC_SET(glCompressedTexImage2D);
635 tc_format = yagl_texcompress_get_format(internalformat);
638 YAGL_SET_ERR(GL_INVALID_ENUM);
642 if (!yagl_texcompress_get_info(tc_format,
649 YAGL_SET_ERR(GL_INVALID_VALUE);
654 yagl_host_glTexImage2DData(target,
656 tc_format->dst_internalformat,
660 tc_format->dst_format,
665 yagl_gles_texture_set_internalformat(texture,
666 tc_format->dst_internalformat,
668 yagl_gles_context_convert_textures(gles_ctx));
673 buff = yagl_get_tmp_buffer(dst_size);
675 tc_format->unpack(tc_format,
683 yagl_gles_reset_unpack(&gles_ctx->unpack);
685 yagl_host_glTexImage2DData(target,
687 tc_format->dst_internalformat,
691 tc_format->dst_format,
696 yagl_gles_set_unpack(&gles_ctx->unpack);
698 yagl_gles_texture_set_internalformat(texture,
699 tc_format->dst_internalformat,
701 yagl_gles_context_convert_textures(gles_ctx));
704 void yagl_gles2_context_compressed_tex_sub_image_2d(struct yagl_gles_context *gles_ctx,
715 struct yagl_gles2_context *ctx = (struct yagl_gles2_context*)gles_ctx;
716 struct yagl_texcompress_format *tc_format;
722 YAGL_LOG_FUNC_SET(glCompressedTexSubImage2D);
724 if (format == GL_ETC1_RGB8_OES) {
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."
730 YAGL_SET_ERR(GL_INVALID_OPERATION);
734 tc_format = yagl_texcompress_get_format(format);
737 YAGL_SET_ERR(GL_INVALID_ENUM);
741 if (!yagl_texcompress_get_info(tc_format,
748 YAGL_SET_ERR(GL_INVALID_VALUE);
753 yagl_host_glTexSubImage2DData(target,
759 tc_format->dst_format,
767 buff = yagl_get_tmp_buffer(dst_size);
769 tc_format->unpack(tc_format,
777 yagl_gles_reset_unpack(&gles_ctx->unpack);
779 yagl_host_glTexSubImage2DData(target,
785 tc_format->dst_format,
790 yagl_gles_set_unpack(&gles_ctx->unpack);
793 void yagl_gles2_context_compressed_tex_image_3d(struct yagl_gles2_context *ctx,
795 struct yagl_gles_texture *texture,
797 GLenum internalformat,
805 GLsizei singleImageSize = 0;
806 struct yagl_texcompress_format *tc_format;
813 YAGL_LOG_FUNC_SET(glCompressedTexImage3D);
815 tc_format = yagl_texcompress_get_format(internalformat);
818 YAGL_SET_ERR(GL_INVALID_ENUM);
823 singleImageSize = imageSize / depth;
826 if (!yagl_texcompress_get_info(tc_format,
833 YAGL_SET_ERR(GL_INVALID_VALUE);
838 yagl_host_glTexImage3DData(target,
840 tc_format->dst_internalformat,
845 tc_format->dst_format,
850 yagl_gles_texture_set_internalformat(texture,
851 tc_format->dst_internalformat,
853 yagl_gles_context_convert_textures(&ctx->base));
858 buff = tmp = yagl_get_tmp_buffer(dst_size * depth);
860 for (i = 0; i < depth; ++i) {
861 tc_format->unpack(tc_format,
868 data += singleImageSize;
872 yagl_gles_reset_unpack(&ctx->base.unpack);
874 yagl_host_glTexImage3DData(target,
876 tc_format->dst_internalformat,
881 tc_format->dst_format,
886 yagl_gles_set_unpack(&ctx->base.unpack);
888 yagl_gles_texture_set_internalformat(texture,
889 tc_format->dst_internalformat,
891 yagl_gles_context_convert_textures(&ctx->base));
894 void yagl_gles2_context_compressed_tex_sub_image_3d(struct yagl_gles2_context *ctx,
907 GLsizei singleImageSize = 0;
908 struct yagl_texcompress_format *tc_format;
915 YAGL_LOG_FUNC_SET(glCompressedTexSubImage3D);
917 if (format == GL_ETC1_RGB8_OES) {
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."
923 YAGL_SET_ERR(GL_INVALID_OPERATION);
927 tc_format = yagl_texcompress_get_format(format);
930 YAGL_SET_ERR(GL_INVALID_ENUM);
935 singleImageSize = imageSize / depth;
938 if (!yagl_texcompress_get_info(tc_format,
945 YAGL_SET_ERR(GL_INVALID_VALUE);
950 yagl_host_glTexSubImage3DData(target,
958 tc_format->dst_format,
966 buff = tmp = yagl_get_tmp_buffer(dst_size * depth);
968 for (i = 0; i < depth; ++i) {
969 tc_format->unpack(tc_format,
976 data += singleImageSize;
980 yagl_gles_reset_unpack(&ctx->base.unpack);
982 yagl_host_glTexSubImage3DData(target,
990 tc_format->dst_format,
995 yagl_gles_set_unpack(&ctx->base.unpack);
998 int yagl_gles2_context_get_integerv(struct yagl_gles_context *ctx,
1001 uint32_t *num_params)
1004 struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
1005 struct yagl_gles_texture_target_state *tts;
1008 case GL_NUM_SHADER_BINARY_FORMATS:
1012 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1013 *params = yagl_texcompress_get_format_names(NULL);
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;
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;
1028 case GL_CURRENT_PROGRAM:
1029 *params = gles2_ctx->program ? gles2_ctx->program->base.local_name : 0;
1032 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1033 *params = ctx->num_texture_units;
1036 case GL_MAX_VERTEX_ATTRIBS:
1037 *params = ctx->num_arrays;
1040 case GL_COMPRESSED_TEXTURE_FORMATS:
1041 *num_params = yagl_texcompress_get_format_names((GLenum*)params);
1043 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1045 if (gles2_ctx->have_max_fragment_uniform_components) {
1046 *params = gles2_ctx->max_fragment_uniform_components;
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;
1054 case GL_MAX_VARYING_VECTORS:
1056 if (yagl_get_host_gl_version() >= yagl_gl_3_2) {
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.
1063 } else if (gles2_ctx->have_max_varying_floats) {
1064 *params = gles2_ctx->max_varying_floats;
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;
1072 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1074 if (gles2_ctx->have_max_vertex_uniform_components) {
1075 *params = gles2_ctx->max_vertex_uniform_components;
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;
1083 case GL_SHADER_COMPILER:
1087 case GL_STENCIL_BACK_FAIL:
1088 *params = ctx->stencil_back.fail;
1091 case GL_STENCIL_BACK_FUNC:
1092 *params = ctx->stencil_back.func;
1095 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1096 *params = ctx->stencil_back.zfail;
1099 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1100 *params = ctx->stencil_back.zpass;
1103 case GL_STENCIL_BACK_REF:
1104 *params = ctx->stencil_back.ref;
1107 case GL_STENCIL_BACK_VALUE_MASK:
1108 *params = ctx->stencil_back.mask;
1111 case GL_STENCIL_BACK_WRITEMASK:
1112 *params = ctx->stencil_back.writemask;
1116 *params = ctx->dither_enabled;
1119 case GL_MAX_TEXTURE_SIZE:
1120 if (gles2_ctx->have_max_texture_size) {
1121 *params = gles2_ctx->max_texture_size;
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;
1135 case GL_MAX_SAMPLES_IMG:
1136 if (gles2_ctx->have_max_samples_img) {
1137 *params = gles2_ctx->max_samples_img;
1143 case GL_MAX_TEXTURE_IMAGE_UNITS:
1144 if (gles2_ctx->have_max_texture_image_units) {
1145 *params = gles2_ctx->max_texture_image_units;
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;
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;
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;
1185 case GL_MAX_TEXTURE_SIZE:
1187 yagl_host_glGetIntegerv(pname, params, *num_params, NULL);
1188 gles2_ctx->max_texture_size = *params;
1189 gles2_ctx->have_max_texture_size = 1;
1191 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
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;
1197 case GL_MAX_SAMPLES_IMG:
1199 yagl_host_glGetIntegerv(pname, params, *num_params, NULL);
1200 gles2_ctx->max_samples_img = *params;
1201 gles2_ctx->have_max_samples_img = 1;
1203 case GL_MAX_TEXTURE_IMAGE_UNITS:
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;
1209 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
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;
1215 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
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;
1221 case GL_SHADER_BINARY_FORMATS:
1224 case GL_MAX_3D_TEXTURE_SIZE_OES:
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;
1237 int yagl_gles2_context_get_floatv(struct yagl_gles_context *ctx,
1240 uint32_t *num_params,
1243 struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
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];
1261 void yagl_gles2_context_draw_arrays(struct yagl_gles_context *ctx,
1267 struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
1269 yagl_gles2_context_pre_draw(gles2_ctx, mode, first + count);
1271 if (primcount < 0) {
1272 yagl_host_glDrawArrays(mode, first, count);
1274 yagl_host_glDrawArraysInstanced(mode, first, count, primcount);
1277 yagl_gles2_context_post_draw(gles2_ctx, mode, first + count);
1280 void yagl_gles2_context_draw_elements(struct yagl_gles_context *ctx,
1284 const GLvoid *indices,
1285 int32_t indices_count,
1289 struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
1291 yagl_gles2_context_pre_draw(gles2_ctx, mode, max_idx + 1);
1293 if (primcount < 0) {
1294 yagl_host_glDrawElements(mode, count, type, indices, indices_count);
1296 yagl_host_glDrawElementsInstanced(mode, count, type, indices, indices_count, primcount);
1299 yagl_gles2_context_post_draw(gles2_ctx, mode, max_idx + 1);
1302 int yagl_gles2_context_validate_texture_target(struct yagl_gles_context *ctx,
1304 yagl_gles_texture_target *texture_target)
1307 case GL_TEXTURE_3D_OES:
1308 *texture_target = yagl_gles_texture_target_3d;
1310 case GL_TEXTURE_CUBE_MAP:
1311 *texture_target = yagl_gles_texture_target_cubemap;
1320 struct yagl_pixel_format
1321 *yagl_gles2_context_validate_teximage_format(struct yagl_gles_context *ctx,
1322 GLenum internalformat,
1329 struct yagl_pixel_format
1330 *yagl_gles2_context_validate_getteximage_format(struct yagl_gles_context *ctx,
1331 GLenum readbuffer_internalformat,
1338 int yagl_gles2_context_validate_copyteximage_format(struct yagl_gles_context *ctx,
1339 GLenum readbuffer_internalformat,
1340 GLenum *internalformat)
1345 int yagl_gles2_context_validate_texstorage_format(struct yagl_gles_context *ctx,
1346 GLenum *internalformat,
1347 GLenum *base_internalformat,
1351 struct yagl_texcompress_format *tc_format;
1353 if (*internalformat == GL_ETC1_RGB8_OES) {
1355 * This is not allowed for TexStorage.
1360 tc_format = yagl_texcompress_get_format(*internalformat);
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;
1374 int yagl_gles2_context_validate_renderbuffer_format(struct yagl_gles_context *ctx,
1375 GLenum *internalformat)
1380 void yagl_gles2_context_hint(struct yagl_gles_context *ctx,
1386 int yagl_gles2_context_get_programiv(struct yagl_gles2_context *ctx,
1387 struct yagl_gles2_program *program,
1392 case GL_ATTACHED_SHADERS:
1393 *params = (program->fragment_shader != NULL) ? 1 : 0;
1394 *params += (program->vertex_shader != NULL) ? 1 : 0;
1396 case GL_INFO_LOG_LENGTH:
1397 *params = program->info_log_length;
1399 case GL_ACTIVE_ATTRIBUTES:
1400 *params = program->num_active_attribs;
1402 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1403 *params = program->max_active_attrib_bufsize;
1405 case GL_ACTIVE_UNIFORMS:
1406 *params = program->num_active_uniforms;
1408 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1409 *params = program->max_active_uniform_bufsize;
1411 case GL_DELETE_STATUS:
1414 case GL_LINK_STATUS:
1415 *params = program->link_status;
1424 struct yagl_client_context *yagl_gles2_context_create(struct yagl_sharegroup *sg)
1426 struct yagl_gles2_context *gles2_ctx;
1428 YAGL_LOG_FUNC_ENTER(yagl_gles2_context_create, NULL);
1430 gles2_ctx = yagl_malloc0(sizeof(*gles2_ctx));
1432 yagl_gles2_context_init(gles2_ctx, yagl_client_api_gles2, sg);
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;
1460 YAGL_LOG_FUNC_EXIT("%p", gles2_ctx);
1462 return &gles2_ctx->base.base;
1465 void yagl_gles2_context_use_program(struct yagl_gles2_context *ctx,
1466 struct yagl_gles2_program *program)
1468 yagl_gles2_program_acquire(program);
1469 yagl_gles2_program_release(ctx->program);
1470 ctx->program = program;
1472 yagl_host_glUseProgram((program ? program->global_name : 0));
1475 void yagl_gles2_context_unuse_program(struct yagl_gles2_context *ctx,
1476 struct yagl_gles2_program *program)
1478 if (ctx->program == program) {
1479 yagl_gles2_program_release(ctx->program);
1480 ctx->program = NULL;
1484 int yagl_gles2_context_get_array_param(struct yagl_gles2_context *ctx,
1489 struct yagl_gles_array *array;
1491 YAGL_LOG_FUNC_SET(yagl_gles2_context_get_array_param);
1493 if (index >= ctx->base.num_arrays) {
1494 YAGL_SET_ERR(GL_INVALID_VALUE);
1498 array = &ctx->base.vao->arrays[index];
1501 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
1502 *param = array->vbo ? array->vbo->base.local_name : 0;
1504 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
1505 *param = array->enabled;
1507 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
1508 *param = array->size;
1510 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
1511 *param = array->stride;
1513 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
1514 *param = array->type;
1516 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
1517 *param = array->normalized;
1519 case GL_CURRENT_VERTEX_ATTRIB:
1521 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT:
1522 if (ctx->instanced_arrays) {
1523 *param = array->divisor;
1525 YAGL_SET_ERR(GL_INVALID_ENUM);
1528 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
1529 if (ctx->base.base.client_api == yagl_client_api_gles3) {
1530 *param = array->integer;
1532 YAGL_SET_ERR(GL_INVALID_ENUM);
1536 YAGL_SET_ERR(GL_INVALID_ENUM);