1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the copyright holder nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27#define VCOS_LOG_CATEGORY (&gl_client_log)
28#include "interface/khronos/common/khrn_client_mangle.h"
29
30#include "interface/khronos/common/khrn_int_common.h"
31#include "interface/khronos/common/khrn_options.h"
32
33#include "interface/khronos/glxx/glxx_client.h"
34#include "interface/khronos/glxx/gl11_int_config.h"
35#include "interface/khronos/include/GLES/glext.h"
36#include "interface/khronos/include/GLES2/gl2ext.h"
37
38#ifdef RPC_DIRECT
39#include "interface/khronos/glxx/gl11_int_impl.h"
40#include "interface/khronos/glxx/gl20_int_impl.h"
41#include "interface/khronos/glxx/glxx_int_impl.h"
42#if defined(V3D_LEAN)
43#include "interface/khronos/common/khrn_int_misc_impl.h"
44#endif
45#endif
46
47#include "interface/khronos/common/khrn_client_rpc.h"
48#include "interface/khronos/common/khrn_int_util.h"
49//#include "../khronos.h"
50
51#ifdef RPC_DIRECT
52#ifdef RPC_DELAYED_USE_OF_POINTERS
53#include "middleware/khronos/common/khrn_hw.h"
54#endif
55#endif
56
57#include <string.h>
58#include <stdlib.h>
59#include <math.h>
60
61VCOS_LOG_CAT_T gl_client_log = VCOS_LOG_INIT("gl_client", VCOS_LOG_WARN);
62
63#ifdef __HIGHC__
64#pragma warning( disable : 4100 4127 4204) // unreferenced formal parameter, constant conditional expression, non-constant initializer
65#endif
66
67#ifdef GL11_CLIENT_SINGLE
68GLXX_CLIENT_STATE_T gl11_client_state;
69#endif
70
71#ifdef GL20_CLIENT_SINGLE
72GLXX_CLIENT_STATE_T gl20_client_state;
73#endif
74
75#define SET_SERIALIZED_ATTRIB(target, b, x, k) { (target)[0] = RPC_INT((x).size); \
76 (target)[1] = RPC_ENUM((x).type); \
77 (target)[2] = RPC_BOOLEAN((x).normalized), \
78 (target)[3] = RPC_SIZEI((x).stride); \
79 (target)[4] = RPC_UINT((b ? (uint32_t)(k + offsetof(CACHE_ENTRY_T, data)) : (uint32_t)(uintptr_t)(x).pointer)); \
80 (target)[5] = RPC_UINT((x).buffer); }
81
82#define SERIALIZE_ATTRIB(b, x, k) RPC_INT((x).size), \
83 RPC_ENUM((x).type), \
84 RPC_BOOLEAN((x).normalized), \
85 RPC_SIZEI((x).stride), \
86 RPC_UINT((b ? (uint32_t)(k + offsetof(CACHE_ENTRY_T, data)) : (uint32_t)(uintptr_t)(x).pointer)), \
87 RPC_UINT((x).buffer)
88
89#define SET_SERIALIZED_ATTRIB_VALUE(target, x) { target[0] = RPC_FLOAT((x).value[0]); \
90 target[1] = RPC_FLOAT((x).value[1]); \
91 target[2] = RPC_FLOAT((x).value[2]); \
92 target[3] = RPC_FLOAT((x).value[3]); }
93
94#define SERIALIZE_ATTRIB_VALUE(x) RPC_FLOAT((x).value[0]), \
95 RPC_FLOAT((x).value[1]), \
96 RPC_FLOAT((x).value[2]), \
97 RPC_FLOAT((x).value[3])
98
99#ifdef DISABLE_OPTION_PARSING
100static void set_error(GLXX_CLIENT_STATE_T *state, GLenum error)
101{
102 if (state->error == GL_NO_ERROR)
103 state->error = error;
104}
105#else
106static void set_error_ex(GLXX_CLIENT_STATE_T *state, GLenum error, const char *func)
107{
108 khrn_error_assist(error, func);
109
110 if (state->error == GL_NO_ERROR)
111 state->error = error;
112}
113#define set_error(a, b) set_error_ex(a, b, __func__)
114#endif
115
116void glxx_set_error(GLXX_CLIENT_STATE_T *state, GLenum error)
117{
118 set_error(state,error);
119}
120
121void glxx_set_error_api(uint32_t api, GLenum error)
122{
123 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
124 if (IS_OPENGLES_API(thread, api))
125 {
126 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
127 glxx_set_error(state, error);
128 }
129}
130
131#ifndef RPC_DIRECT
132static void read_out_bulk(CLIENT_THREAD_STATE_T *thread, void *out)
133{
134 rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_BULK | RPC_RECV_FLAG_LEN));
135}
136#endif
137
138static GLuint get_bound_buffer(GLXX_CLIENT_STATE_T *state, GLenum target)
139{
140 GLuint buffer = 0;
141
142 switch (target) {
143 case GL_ARRAY_BUFFER:
144 buffer = state->bound_buffer.array;
145 break;
146 case GL_ELEMENT_ARRAY_BUFFER:
147 buffer = state->bound_buffer.element_array;
148 break;
149 default:
150 break;
151 }
152 return buffer;
153}
154
155void glxx_buffer_info_set(GLXX_CLIENT_STATE_T *state, GLenum target, GLXX_BUFFER_INFO_T* buffer_info)
156{
157 GLuint buffer = get_bound_buffer(state, target);
158
159 if(buffer != 0)
160 {
161 GLXX_BUFFER_INFO_T *stored = khrn_pointer_map_lookup(&state->buffers, buffer);
162 if(!stored)
163 {
164 stored = khrn_platform_malloc(sizeof(GLXX_BUFFER_INFO_T), "GLXX_BUFFER_INFO_T");
165 khrn_pointer_map_insert(&state->buffers, buffer, stored);
166 }
167 buffer_info->id = buffer;
168 //copy into stored
169 *stored = *buffer_info;
170 }
171}
172
173void glxx_buffer_info_get(GLXX_CLIENT_STATE_T *state, GLenum target, GLXX_BUFFER_INFO_T* buffer_info)
174{
175 GLuint buffer = get_bound_buffer(state, target);
176
177 memset(buffer_info,0,sizeof(GLXX_BUFFER_INFO_T));
178
179 buffer_info->id = 0;
180
181 if(buffer != 0)
182 {
183 GLXX_BUFFER_INFO_T *stored = khrn_pointer_map_lookup(&state->buffers, buffer);
184 if(stored)
185 *buffer_info = *stored;
186 }
187}
188
189static void buffer_info_delete(GLXX_CLIENT_STATE_T *state, GLuint buffer)
190{
191 GLXX_BUFFER_INFO_T *stored = khrn_pointer_map_lookup(&state->buffers, buffer);
192 if(stored)
193 {
194 khrn_platform_free(stored);
195 khrn_pointer_map_delete(&state->buffers,buffer);
196 }
197}
198
199GL_API void GL_APIENTRY glActiveTexture (GLenum texture)
200{
201 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
202 if (IS_OPENGLES_11(thread)) {
203 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
204
205 if (texture >= GL_TEXTURE0 && texture < GL_TEXTURE0 + GL11_CONFIG_MAX_TEXTURE_UNITS)
206 state->active_texture.server = texture;
207
208 RPC_CALL1(glActiveTexture_impl,
209 thread,
210 GLACTIVETEXTURE_ID,
211 RPC_ENUM(texture));
212 }
213
214 if (IS_OPENGLES_20(thread)) {
215 RPC_CALL1(glActiveTexture_impl,
216 thread,
217 GLACTIVETEXTURE_ID,
218 RPC_ENUM(texture));
219 }
220}
221
222GL_API void GL_APIENTRY glAlphaFunc (GLenum func, GLclampf ref)
223{
224 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
225 if (IS_OPENGLES_11(thread)) {
226 RPC_CALL2(glAlphaFunc_impl_11,
227 thread,
228 GLALPHAFUNC_ID_11,
229 RPC_ENUM(func),
230 RPC_FLOAT(ref));
231 }
232}
233
234GL_API void GL_APIENTRY glAlphaFuncx (GLenum func, GLclampx ref)
235{
236 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
237 if (IS_OPENGLES_11(thread)) {
238 RPC_CALL2(glAlphaFuncx_impl_11,
239 thread,
240 GLALPHAFUNCX_ID_11,
241 RPC_ENUM(func),
242 RPC_FIXED(ref));
243 }
244}
245
246GL_API void GL_APIENTRY glAttachShader (GLuint program, GLuint shader)
247{
248 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
249 if (IS_OPENGLES_20(thread)) {
250 RPC_CALL2(glAttachShader_impl_20,
251 thread,
252 GLATTACHSHADER_ID_20,
253 RPC_UINT(program),
254 RPC_UINT(shader));
255 }
256}
257
258GL_API void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const char *name)
259{
260 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
261 if (IS_OPENGLES_20(thread)) {
262 RPC_CALL3_IN_BULK(glBindAttribLocation_impl_20,
263 thread,
264 GLBINDATTRIBLOCATION_ID_20,
265 RPC_UINT(program),
266 RPC_UINT(index),
267 name,
268 strlen(name) + 1);
269 }
270}
271
272GL_API void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer)
273{
274 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
275
276 if(IS_OPENGLES_11_OR_20(thread)) {
277 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
278 vcos_assert(state != NULL);
279
280 switch (target) {
281 case GL_ARRAY_BUFFER:
282 state->bound_buffer.array = buffer;
283 break;
284 case GL_ELEMENT_ARRAY_BUFFER:
285 state->bound_buffer.element_array = buffer;
286 break;
287 default:
288 // do nothing, server will signal error
289 break;
290 }
291
292 RPC_CALL2(glBindBuffer_impl,
293 thread,
294 GLBINDBUFFER_ID,
295 RPC_ENUM(target),
296 RPC_UINT(buffer));
297 }
298
299}
300
301GL_API void GL_APIENTRY glBindTexture (GLenum target, GLuint texture)
302{
303 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
304 if (IS_OPENGLES_11_OR_20(thread)) {
305 vcos_log_trace("[%s] target 0x%x texture %d", __FUNCTION__, target, texture);
306 RPC_CALL2(glBindTexture_impl,
307 thread,
308 GLBINDTEXTURE_ID,
309 RPC_ENUM(target),
310 RPC_UINT(texture));
311 }
312}
313
314GL_API void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) // S
315{
316 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
317 if (IS_OPENGLES_20(thread)) {
318 RPC_CALL4(glBlendColor_impl_20,
319 thread,
320 GLBLENDCOLOR_ID_20,
321 RPC_FLOAT(red),
322 RPC_FLOAT(green),
323 RPC_FLOAT(blue),
324 RPC_FLOAT(alpha));
325 }
326}
327
328GL_API void GL_APIENTRY glBlendEquation( GLenum mode ) // S
329{
330 glBlendEquationSeparate(mode, mode);
331}
332
333GL_API void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) // S
334{
335 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
336 if (IS_OPENGLES_20(thread)) {
337 RPC_CALL2(glBlendEquationSeparate_impl_20,
338 thread,
339 GLBLENDEQUATIONSEPARATE_ID_20,
340 RPC_ENUM(modeRGB),
341 RPC_ENUM(modeAlpha));
342 }
343}
344
345static void set_blend_func (CLIENT_THREAD_STATE_T *thread, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
346 RPC_CALL4(glBlendFuncSeparate_impl,
347 thread,
348 GLBLENDFUNCSEPARATE_ID,
349 RPC_ENUM(srcRGB),
350 RPC_ENUM(dstRGB),
351 RPC_ENUM(srcAlpha),
352 RPC_ENUM(dstAlpha));
353}
354
355GL_API void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor)
356{
357 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
358 if (IS_OPENGLES_11_OR_20(thread)) set_blend_func(thread, sfactor, dfactor, sfactor, dfactor);
359}
360
361GL_API void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) // S
362{
363 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
364 if (IS_OPENGLES_20(thread)) set_blend_func(thread, srcRGB, dstRGB, srcAlpha, dstAlpha);
365}
366
367GL_API void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
368{
369 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
370 if (IS_OPENGLES_11_OR_20(thread)) {
371
372 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
373
374 GLXX_BUFFER_INFO_T buffer;
375 glxx_buffer_info_get(state, target, &buffer);
376 if(buffer.id != ~0 && buffer.mapped_pointer != 0)
377 {
378 /* buffer is mapped */
379 set_error(state, GL_INVALID_OPERATION);
380 }
381 else
382 {
383 if( ((target == GL_ARRAY_BUFFER && state->bound_buffer.array != 0) ||
384 (target == GL_ELEMENT_ARRAY_BUFFER && state->bound_buffer.element_array != 0)) &&
385 (usage == GL_STATIC_DRAW || usage == GL_DYNAMIC_DRAW || (IS_OPENGLES_20(thread) && usage == GL_STREAM_DRAW)) &&
386 size >=0
387 )
388 {
389
390 /* server call should succeed in setting buffer size unless out of memory */
391 /* cache size so we can use it in mapBuffer without a round trip */
392 buffer.cached_size = size;
393 glxx_buffer_info_set(state, target, &buffer);
394 }
395 else
396 {
397 buffer.cached_size = 0;
398 glxx_buffer_info_set(state, target, &buffer);
399 }
400
401 RPC_CALL4_IN_BULK(glBufferData_impl,
402 thread,
403 GLBUFFERDATA_ID,
404 RPC_ENUM(target),
405 RPC_SIZEIPTR(size),
406 RPC_ENUM(usage),
407 NULL,
408 0);
409
410 if (data) {
411 int offset = 0;
412
413 while (size > 0) {
414 int32_t batch = _min(KHDISPATCH_WORKSPACE_SIZE, (int32_t) size);
415
416 RPC_CALL4_IN_BULK(glBufferSubData_impl,
417 thread,
418 GLBUFFERSUBDATA_ID,
419 RPC_ENUM(target),
420 RPC_INTPTR(offset),
421 RPC_SIZEIPTR(batch),
422 (char *)data + offset,
423 (size_t) batch);
424
425 offset += batch;
426 size -= batch;
427 }
428 }
429 }
430 }
431}
432
433GL_API void GL_APIENTRY glBufferSubData (GLenum target, GLintptr base, GLsizeiptr size, const GLvoid *data)
434{
435 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
436 if (IS_OPENGLES_11_OR_20(thread)) {
437 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
438
439 GLXX_BUFFER_INFO_T buffer;
440 glxx_buffer_info_get(state, target, &buffer);
441 if(buffer.id != ~0 && buffer.mapped_pointer != 0)
442 {
443 /* buffer is mapped */
444 set_error(state, GL_INVALID_OPERATION);
445 }
446 else
447 {
448 if (data) {
449 int offset = 0;
450
451 while (size > 0) {
452 int32_t batch = _min(KHDISPATCH_WORKSPACE_SIZE, (int32_t)size);
453
454 RPC_CALL4_IN_BULK(glBufferSubData_impl,
455 thread,
456 GLBUFFERSUBDATA_ID,
457 RPC_ENUM(target),
458 RPC_INTPTR(base+offset),
459 RPC_SIZEIPTR(batch),
460 (char *)data + offset,
461 (size_t) batch);
462
463 offset += batch;
464 size -= batch;
465 }
466 }
467 }
468 }
469}
470
471GL_API void GL_APIENTRY glClear (GLbitfield mask)
472{
473 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
474 if (IS_OPENGLES_11_OR_20(thread)) {
475 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
476
477 //TODO: pixmap behaviour can be better optimized to handle clears
478 if (state->render_callback)
479 state->render_callback();
480
481 RPC_CALL1(glClear_impl,
482 thread,
483 GLCLEAR_ID,
484 RPC_BITFIELD(mask));
485 }
486}
487
488GL_API void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
489{
490 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
491 if (IS_OPENGLES_11_OR_20(thread)) {
492 RPC_CALL4(glClearColor_impl,
493 thread,
494 GLCLEARCOLOR_ID,
495 RPC_FLOAT(red),
496 RPC_FLOAT(green),
497 RPC_FLOAT(blue),
498 RPC_FLOAT(alpha));
499 }
500}
501
502GL_API void GL_APIENTRY glClearColorx (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
503{
504 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
505 if (IS_OPENGLES_11(thread)) {
506 RPC_CALL4(glClearColorx_impl_11,
507 thread,
508 GLCLEARCOLORX_ID_11,
509 RPC_FIXED(red),
510 RPC_FIXED(green),
511 RPC_FIXED(blue),
512 RPC_FIXED(alpha));
513 }
514}
515
516GL_API void GL_APIENTRY glClearDepthf (GLclampf depth)
517{
518 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
519 if (IS_OPENGLES_11_OR_20(thread)) {
520 RPC_CALL1(glClearDepthf_impl,
521 thread,
522 GLCLEARDEPTHF_ID,
523 RPC_FLOAT(depth));
524 }
525}
526
527GL_API void GL_APIENTRY glClearDepthx (GLclampx depth)
528{
529 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
530 if (IS_OPENGLES_11(thread)) {
531 RPC_CALL1(glClearDepthx_impl_11,
532 thread,
533 GLCLEARDEPTHX_ID_11,
534 RPC_FIXED(depth));
535 }
536}
537
538GL_API void GL_APIENTRY glClearStencil (GLint s)
539{
540 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
541 if (IS_OPENGLES_11_OR_20(thread)) {
542 RPC_CALL1(glClearStencil_impl,
543 thread,
544 GLCLEARSTENCIL_ID,
545 RPC_INT(s));
546 }
547}
548
549GL_API void GL_APIENTRY glClientActiveTexture (GLenum texture)
550{
551 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
552 if (IS_OPENGLES_11(thread)) {
553 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
554
555 vcos_assert(state != NULL);
556
557 if (texture >= GL_TEXTURE0 && texture < GL_TEXTURE0 + GL11_CONFIG_MAX_TEXTURE_UNITS)
558 {
559 state->active_texture.client = texture;
560 RPC_CALL1(glClientActiveTexture_impl_11,
561 thread,
562 GLCLIENTACTIVETEXTURE_ID_11,
563 RPC_ENUM(texture));
564 }
565 else
566 set_error(state, GL_INVALID_ENUM);
567 }
568}
569
570GL_API void GL_APIENTRY glClipPlanef (GLenum plane, const GLfloat *equation)
571{
572 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
573 if (IS_OPENGLES_11(thread)) {
574 RPC_CALL2_IN_CTRL(glClipPlanef_impl_11,
575 thread,
576 GLCLIPPLANEF_ID_11,
577 RPC_ENUM(plane),
578 equation,
579 4 * sizeof(GLfloat));
580 }
581}
582
583GL_API void GL_APIENTRY glClipPlanex (GLenum plane, const GLfixed *equation)
584{
585 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
586 if (IS_OPENGLES_11(thread)) {
587 RPC_CALL2_IN_CTRL(glClipPlanex_impl_11,
588 thread,
589 GLCLIPPLANEX_ID_11,
590 RPC_ENUM(plane),
591 equation,
592 4 * sizeof(GLfixed));
593 }
594}
595
596GL_API void GL_APIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
597{
598 glintColor(
599 clampf(red, 0.0f, 1.0f),
600 clampf(green, 0.0f, 1.0f),
601 clampf(blue, 0.0f, 1.0f),
602 clampf(alpha, 0.0f, 1.0f));
603}
604
605GL_API void GL_APIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
606{
607 glintColor(
608 (float)red / 255.0f,
609 (float)green / 255.0f,
610 (float)blue / 255.0f,
611 (float)alpha / 255.0f);
612}
613
614GL_API void GL_APIENTRY glColor4x (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
615{
616 glintColor(
617 clampf(fixed_to_float(red), 0.0f, 1.0f),
618 clampf(fixed_to_float(green), 0.0f, 1.0f),
619 clampf(fixed_to_float(blue), 0.0f, 1.0f),
620 clampf(fixed_to_float(alpha), 0.0f, 1.0f));
621}
622
623GL_API void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
624{
625 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
626 if (IS_OPENGLES_11_OR_20(thread)) {
627 RPC_CALL4(glColorMask_impl,
628 thread,
629 GLCOLORMASK_ID,
630 RPC_BOOLEAN(red),
631 RPC_BOOLEAN(green),
632 RPC_BOOLEAN(blue),
633 RPC_BOOLEAN(alpha));
634 }
635}
636
637static bool is_color_size(GLint size)
638{
639 return size == 4;
640}
641
642static bool is_color_type(GLenum type)
643{
644 return type == GL_UNSIGNED_BYTE ||
645 type == GL_FIXED ||
646 type == GL_FLOAT;
647}
648
649static bool is_aligned( GLenum type, size_t value)
650{
651 switch (type) {
652 case GL_BYTE:
653 case GL_UNSIGNED_BYTE:
654 return GL_TRUE;
655 case GL_SHORT:
656 case GL_UNSIGNED_SHORT:
657 return (value & 1) == 0;
658 case GL_FIXED:
659 case GL_FLOAT:
660 return (value & 3) == 0;
661 default:
662 UNREACHABLE();
663 return GL_FALSE;
664 }
665}
666
667GL_API void GL_APIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
668{
669 if (is_color_type(type)) {
670 if (is_color_size(size) && is_aligned(type, (size_t)pointer) && is_aligned(type, (size_t)stride) && stride >= 0) {
671 glintAttribPointer(GLXX_API_11, GL11_IX_COLOR, size, type, GL_TRUE, stride, pointer);
672 } else
673 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
674 } else
675 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
676}
677
678static uint32_t get_palette_size(GLenum internalformat)
679{
680 switch (internalformat)
681 {
682 case GL_PALETTE4_RGB8_OES: return 16 * 3;
683 case GL_PALETTE4_RGBA8_OES: return 16 * 4;
684 case GL_PALETTE4_R5_G6_B5_OES: return 16 * 2;
685 case GL_PALETTE4_RGBA4_OES: return 16 * 2;
686 case GL_PALETTE4_RGB5_A1_OES: return 16 * 2;
687 case GL_PALETTE8_RGB8_OES: return 256 * 3;
688 case GL_PALETTE8_RGBA8_OES: return 256 * 4;
689 case GL_PALETTE8_R5_G6_B5_OES: return 256 * 2;
690 case GL_PALETTE8_RGBA4_OES: return 256 * 2;
691 case GL_PALETTE8_RGB5_A1_OES: return 256 * 2;
692 default:
693 UNREACHABLE();
694 return 0;
695 }
696}
697
698GL_API void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
699{
700 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
701 GLboolean res;
702 if (IS_OPENGLES_11_OR_20(thread)) {
703 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
704 switch (internalformat)
705 {
706 case GL_ETC1_RGB8_OES:
707 {
708 uint32_t pitch = 2 * ((width + 3) / 4);
709 uint32_t lines = pitch ? (uint32_t)(KHDISPATCH_WORKSPACE_SIZE / pitch) : (uint32_t)height;
710
711 res = RPC_BOOLEAN_RES(RPC_CALL8_IN_BULK_RES(glCompressedTexImage2D_impl,
712 thread,
713 GLCOMPRESSEDTEXIMAGE2D_ID,
714 RPC_ENUM (target),
715 RPC_INT (level),
716 RPC_ENUM (internalformat),
717 RPC_SIZEI (width),
718 RPC_SIZEI (height),
719 RPC_INT (border),
720 RPC_SIZEI (imageSize),
721 NULL,
722 0));
723
724 if (res && data && lines && width && height) {
725 int offset = 0;
726
727 while (height > 0) {
728 int32_t batch = (_min(lines, (int32_t)height) + 3) & ~3;
729
730 RPC_CALL9_IN_BULK(glCompressedTexSubImage2D_impl,
731 thread,
732 GLCOMPRESSEDTEXSUBIMAGE2D_ID,
733 RPC_ENUM(target),
734 RPC_INT(level),
735 RPC_INT(0),
736 RPC_INT(offset),
737 RPC_SIZEI(width),
738 RPC_SIZEI(batch),
739 RPC_ENUM(internalformat),
740 batch * pitch,
741 (char *)data + offset * pitch,
742 batch * pitch);
743
744 offset += batch;
745 height -= batch;
746 }
747 }
748 break;
749 }
750 case GL_PALETTE4_RGB8_OES:
751 case GL_PALETTE4_RGBA8_OES:
752 case GL_PALETTE4_R5_G6_B5_OES:
753 case GL_PALETTE4_RGBA4_OES:
754 case GL_PALETTE4_RGB5_A1_OES:
755 case GL_PALETTE8_RGB8_OES:
756 case GL_PALETTE8_RGBA8_OES:
757 case GL_PALETTE8_R5_G6_B5_OES:
758 case GL_PALETTE8_RGBA4_OES:
759 case GL_PALETTE8_RGB5_A1_OES:
760 {
761 int palette_size = get_palette_size(internalformat);
762
763 level = -level;
764 res = RPC_BOOLEAN_RES(RPC_CALL8_IN_BULK_RES(glCompressedTexImage2D_impl,
765 thread,
766 GLCOMPRESSEDTEXIMAGE2D_ID,
767 RPC_ENUM (target),
768 RPC_INT (level),
769 RPC_ENUM (internalformat),
770 RPC_SIZEI (width),
771 RPC_SIZEI (height),
772 RPC_INT (border),
773 RPC_SIZEI (imageSize),
774 data,
775 palette_size));
776
777 if (res && data && width && height) {
778 int offset = palette_size;
779 while (offset < imageSize) {
780 int32_t batch = _min(KHDISPATCH_WORKSPACE_SIZE, imageSize - offset);
781
782 RPC_CALL9_IN_BULK(glCompressedTexSubImage2D_impl,
783 thread,
784 GLCOMPRESSEDTEXSUBIMAGE2D_ID,
785 RPC_ENUM(target),
786 RPC_INT(level),
787 RPC_INT(offset - palette_size),
788 RPC_INT(0),
789 RPC_SIZEI(width),
790 RPC_SIZEI(height),
791 RPC_ENUM(internalformat),
792 batch,
793 (char *)data + offset,
794 batch);
795
796 offset += batch;
797 }
798 }
799 break;
800 }
801 default:
802 set_error(state, GL_INVALID_ENUM );
803 break;
804 }
805 }
806}
807
808GL_API void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)
809{
810 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
811 UNUSED(target);
812 UNUSED(level);
813 UNUSED(xoffset);
814 UNUSED(yoffset);
815 UNUSED(width);
816 UNUSED(height);
817 UNUSED(imageSize);
818 UNUSED(data);
819
820 if (IS_OPENGLES_11_OR_20(thread)) {
821 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
822
823 switch (format)
824 {
825 case GL_ETC1_RGB8_OES:
826 // Cannot specify subimages of ETC1 textures
827 set_error(state, GL_INVALID_OPERATION);
828 break;
829 case GL_PALETTE4_RGB8_OES:
830 case GL_PALETTE4_RGBA8_OES:
831 case GL_PALETTE4_R5_G6_B5_OES:
832 case GL_PALETTE4_RGBA4_OES:
833 case GL_PALETTE4_RGB5_A1_OES:
834 case GL_PALETTE8_RGB8_OES:
835 case GL_PALETTE8_RGBA8_OES:
836 case GL_PALETTE8_R5_G6_B5_OES:
837 case GL_PALETTE8_RGBA4_OES:
838 case GL_PALETTE8_RGB5_A1_OES:
839 // Cannot specify subimages of paletted textures
840 set_error(state, GL_INVALID_OPERATION);
841 break;
842 default:
843 // Some format we don't recognise
844 set_error(state, GL_INVALID_VALUE);
845 break;
846 }
847 }
848}
849
850GL_API void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
851{
852 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
853 if (IS_OPENGLES_11_OR_20(thread)) {
854 RPC_CALL8(glCopyTexImage2D_impl,
855 thread,
856 GLCOPYTEXIMAGE2D_ID,
857 RPC_ENUM(target),
858 RPC_INT(level),
859 RPC_ENUM(internalformat),
860 RPC_INT(x),
861 RPC_INT(y),
862 RPC_SIZEI(width),
863 RPC_SIZEI(height),
864 RPC_INT(border));
865 }
866}
867
868GL_API void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
869{
870 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
871 if (IS_OPENGLES_11_OR_20(thread)) {
872 RPC_CALL8(glCopyTexSubImage2D_impl,
873 thread,
874 GLCOPYTEXSUBIMAGE2D_ID,
875 RPC_ENUM(target),
876 RPC_INT(level),
877 RPC_INT(xoffset),
878 RPC_INT(yoffset),
879 RPC_INT(x),
880 RPC_INT(y),
881 RPC_SIZEI(width),
882 RPC_SIZEI(height));
883 }
884}
885
886GL_API GLuint GL_APIENTRY glCreateProgram (void)
887{
888 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
889 if (IS_OPENGLES_20(thread)) {
890 return RPC_UINT_RES(RPC_CALL0_RES(glCreateProgram_impl_20,
891 thread,
892 GLCREATEPROGRAM_ID_20));
893 }
894
895 return 0;
896}
897
898GL_API GLuint GL_APIENTRY glCreateShader (GLenum type)
899{
900 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
901 if (IS_OPENGLES_20(thread)) {
902 return RPC_UINT_RES(RPC_CALL1_RES(glCreateShader_impl_20,
903 thread,
904 GLCREATESHADER_ID_20,
905 RPC_ENUM(type)));
906 }
907
908 return 0;
909}
910
911GL_API void GL_APIENTRY glCullFace (GLenum mode)
912{
913 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
914 if (IS_OPENGLES_11_OR_20(thread)) {
915 RPC_CALL1(glCullFace_impl,
916 thread,
917 GLCULLFACE_ID,
918 RPC_ENUM(mode));
919 }
920}
921
922GL_API void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers)
923{
924 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
925 int offset = 0;
926 if (IS_OPENGLES_11_OR_20(thread)) {
927 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
928
929 int i, j;
930
931 for (i = 0; i < n; i++) {
932 GLuint buffer = buffers[i];
933
934 if (state->bound_buffer.array == buffer)
935 state->bound_buffer.array = 0;
936 if (state->bound_buffer.element_array == buffer)
937 state->bound_buffer.element_array = 0;
938
939 for (j = 0; j < GLXX_CONFIG_MAX_VERTEX_ATTRIBS; j++)
940 if (state->attrib[j].buffer == buffer)
941 state->attrib[j].buffer = 0;
942
943 buffer_info_delete(state, buffer);
944 }
945 }
946
947 if (IS_OPENGLES_11_OR_20(thread)) {
948 do {
949 int32_t items = (int32_t)( KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint) );
950 int32_t batch = _min(items, (int32_t) n);
951
952 RPC_CALL2_IN_BULK(glDeleteBuffers_impl,
953 thread,
954 GLDELETEBUFFERS_ID,
955 RPC_SIZEI(batch),
956 buffers + offset,
957 batch > 0 ? batch * sizeof(GLuint) : 0);
958
959 offset += batch;
960 n -= batch;
961 } while (n > 0);
962 }
963}
964
965GL_API void GL_APIENTRY glDeleteProgram (GLuint program)
966{
967 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
968 if (IS_OPENGLES_20(thread)) {
969 RPC_CALL1(glDeleteProgram_impl_20,
970 thread,
971 GLDELETEPROGRAM_ID_20,
972 RPC_UINT(program));
973 }
974}
975
976GL_API void GL_APIENTRY glDeleteShader (GLuint shader)
977{
978 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
979 if (IS_OPENGLES_20(thread)) {
980 RPC_CALL1(glDeleteShader_impl_20,
981 thread,
982 GLDELETESHADER_ID_20,
983 RPC_UINT(shader));
984 }
985}
986
987GL_API void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures)
988{
989 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
990 int offset = 0;
991
992 if (IS_OPENGLES_11_OR_20(thread)) {
993 do {
994 int32_t items = (int32_t)(KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
995 int32_t batch = _min(items, (int32_t)n);
996
997 RPC_CALL2_IN_BULK(glDeleteTextures_impl,
998 thread,
999 GLDELETETEXTURES_ID,
1000 RPC_SIZEI(batch),
1001 textures + offset,
1002 batch > 0 ? batch * sizeof(GLuint) : 0);
1003
1004 offset += batch;
1005 n -= batch;
1006 } while (n > 0);
1007 }
1008}
1009
1010GL_API void GL_APIENTRY glDepthFunc (GLenum func)
1011{
1012 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1013 if (IS_OPENGLES_11_OR_20(thread)) {
1014 RPC_CALL1(glDepthFunc_impl,
1015 thread,
1016 GLDEPTHFUNC_ID,
1017 RPC_ENUM(func));
1018 }
1019}
1020
1021GL_API void GL_APIENTRY glDepthMask (GLboolean flag)
1022{
1023 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1024 if (IS_OPENGLES_11_OR_20(thread)) {
1025 RPC_CALL1(glDepthMask_impl,
1026 thread,
1027 GLDEPTHMASK_ID,
1028 RPC_BOOLEAN(flag));
1029 }
1030}
1031
1032GL_API void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar)
1033{
1034 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1035 if (IS_OPENGLES_11_OR_20(thread)) {
1036 RPC_CALL2(glDepthRangef_impl,
1037 thread,
1038 GLDEPTHRANGEF_ID,
1039 RPC_FLOAT(zNear),
1040 RPC_FLOAT(zFar));
1041 }
1042}
1043
1044GL_API void GL_APIENTRY glDepthRangex (GLclampx zNear, GLclampx zFar)
1045{
1046 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1047 if (IS_OPENGLES_11(thread)) {
1048 RPC_CALL2(glDepthRangex_impl_11,
1049 thread,
1050 GLDEPTHRANGEX_ID_11,
1051 RPC_FIXED(zNear),
1052 RPC_FIXED(zFar));
1053 }
1054}
1055
1056GL_API void GL_APIENTRY glDetachShader (GLuint program, GLuint shader)
1057{
1058 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1059 if (IS_OPENGLES_20(thread)) {
1060 RPC_CALL2(glDetachShader_impl_20,
1061 thread,
1062 GLDETACHSHADER_ID_20,
1063 RPC_UINT(program),
1064 RPC_UINT(shader));
1065 }
1066}
1067
1068GL_API void GL_APIENTRY glDisable (GLenum cap)
1069{
1070 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1071 if (IS_OPENGLES_11_OR_20(thread)) {
1072 RPC_CALL1(glDisable_impl,
1073 thread,
1074 GLDISABLE_ID,
1075 RPC_ENUM(cap));
1076 }
1077}
1078
1079static void set_enabled_11(GLenum array, GLboolean enabled)
1080{
1081 switch (array) {
1082 case GL_VERTEX_ARRAY:
1083 glintAttribEnable(GLXX_API_11, GL11_IX_VERTEX, enabled);
1084 break;
1085 case GL_NORMAL_ARRAY:
1086 glintAttribEnable(GLXX_API_11, GL11_IX_NORMAL, enabled);
1087 break;
1088 case GL_COLOR_ARRAY:
1089 glintAttribEnable(GLXX_API_11, GL11_IX_COLOR, enabled);
1090 break;
1091 case GL_POINT_SIZE_ARRAY_OES:
1092 glintAttribEnable(GLXX_API_11, GL11_IX_POINT_SIZE, enabled);
1093 break;
1094#if GL_OES_matrix_palette
1095 case GL_MATRIX_INDEX_ARRAY_OES:
1096 glintAttribEnable(GLXX_API_11, GL11_IX_MATRIX_INDEX, enabled);
1097 break;
1098 case GL_WEIGHT_ARRAY_OES:
1099 glintAttribEnable(GLXX_API_11, GL11_IX_MATRIX_WEIGHT, enabled);
1100 break;
1101#endif
1102 case GL_TEXTURE_COORD_ARRAY:
1103 glintAttribEnable(GLXX_API_11, GL11_IX_CLIENT_ACTIVE_TEXTURE, enabled);
1104 break;
1105 default:
1106 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
1107 break;
1108 }
1109}
1110
1111GL_API void GL_APIENTRY glDisableClientState (GLenum array)
1112{
1113 set_enabled_11(array, GL_FALSE);
1114}
1115
1116GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index)
1117{
1118 glintAttribEnable(GLXX_API_20, index, GL_FALSE);
1119}
1120
1121static int align_length(int length)
1122{
1123 return (length + 15) & ~15;
1124}
1125
1126static int calc_length(int max, int size, GLenum type, int stride)
1127{
1128 if (max >= 0) {
1129 int type_size = khrn_get_type_size( (int)type);
1130
1131 return align_length(size * type_size + max * (stride ? stride : size * type_size));
1132 } else
1133 return 0;
1134}
1135
1136static GLboolean is_index_type(GLenum type)
1137{
1138 return type == GL_UNSIGNED_BYTE ||
1139 type == GL_UNSIGNED_SHORT;
1140}
1141
1142typedef struct MERGE_INFO
1143{
1144 bool send;
1145
1146 const char *start;
1147 const char *end;
1148
1149 int next;
1150} MERGE_INFO_T;
1151
1152static void draw_arrays_or_elements(CLIENT_THREAD_STATE_T *thread, GLXX_CLIENT_STATE_T *state, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
1153{
1154 uint32_t indices_offset = 0;
1155 GLuint indices_buffer;
1156 bool send_indices;
1157 int max = 0;
1158 int indices_length = 0;
1159 int indices_key = 0;
1160 int first = 0;
1161 int i, j, k;
1162 MERGE_INFO_T merge[GLXX_CONFIG_MAX_VERTEX_ATTRIBS];
1163 GLXX_CACHE_INFO_T cache_info;
1164
1165 vcos_assert(state != NULL);
1166
1167 if (state->render_callback && (IS_OPENGLES_11(thread) || state->default_framebuffer))
1168 state->render_callback();
1169
1170 if(count<0)
1171 {
1172 glxx_set_error(state, GL_INVALID_VALUE);
1173 return;
1174 }
1175
1176 cache_info.send_any = 0;
1177 for (i = 0; i < GLXX_CONFIG_MAX_VERTEX_ATTRIBS; i++)
1178 {
1179 if (state->attrib[i].enabled && state->attrib[i].buffer == 0)
1180 {
1181 cache_info.send_any = 1;
1182
1183 /* TODO: what should we do if people give us null pointers? */
1184 if (state->attrib[i].pointer == NULL)
1185 return;
1186 }
1187 }
1188
1189 if(type==0)
1190 {
1191 first = (int)indices;
1192 indices_offset = first;
1193 indices_buffer = 0;
1194 send_indices = 0;
1195 indices_key = 0;
1196
1197 max = first + count - 1;
1198 }
1199 else
1200 {
1201 send_indices = count >= 0 && state->bound_buffer.element_array == 0;
1202 indices_buffer = state->bound_buffer.element_array;
1203
1204 indices_length = align_length(count * khrn_get_type_size( (int) type ));
1205 if (send_indices)
1206 {
1207 max = find_max(count, khrn_get_type_size( (int)type ), indices);
1208 indices_key = khrn_cache_lookup(thread, &state->cache, indices, indices_length, 0);
1209 indices_offset = indices_key + offsetof(CACHE_ENTRY_T, data);
1210 }
1211 else
1212 {
1213 indices_key = 0;
1214 indices_offset = (uint32_t)indices;
1215
1216 if (cache_info.send_any)
1217 max = RPC_INT_RES(RPC_CALL3_RES(
1218 glintFindMax_impl,
1219 thread,
1220 GLINTFINDMAX_ID,
1221 RPC_SIZEI(count),
1222 RPC_ENUM(type),
1223 RPC_UINT(indices_offset)));
1224 else
1225 max = -1;
1226 }
1227 }
1228
1229 if (cache_info.send_any)
1230 {
1231 /* Merge overlapping arrays */
1232 for (i = 0; i < GLXX_CONFIG_MAX_VERTEX_ATTRIBS; i++)
1233 {
1234 if (state->attrib[i].enabled && state->attrib[i].buffer == 0)
1235 {
1236 merge[i].send = true;
1237 merge[i].start = state->attrib[i].pointer;
1238 merge[i].end = (const char *)state->attrib[i].pointer + calc_length(max, state->attrib[i].size, state->attrib[i].type, state->attrib[i].stride);
1239 merge[i].next = -1;
1240
1241 for (j = 0; j < i; j++)
1242 {
1243 if (merge[j].send && merge[j].next == -1)
1244 {
1245 const char *start = merge[i].start < merge[j].start ? merge[i].start : merge[j].start;
1246 const char *end = merge[i].end > merge[j].end ? merge[i].end : merge[j].end;
1247
1248 if ((uint32_t)(end - start) < (uint32_t)((merge[i].end - merge[i].start) + (merge[j].end - merge[j].start)))
1249 {
1250 if (merge[i].start < merge[j].start)
1251 {
1252 k = i;
1253 while (merge[k].next != -1)
1254 k = merge[k].next;
1255 merge[k].end = end;
1256 merge[j].next = i;
1257 }
1258 else
1259 {
1260 vcos_assert(merge[j].next == -1);
1261 merge[j].end = end;
1262 merge[i].next = j;
1263 }
1264 }
1265 }
1266 }
1267 }
1268 else
1269 {
1270 merge[i].send = false;
1271 }
1272 }
1273
1274 /* Perform cache lookups */
1275 for (i = 0; i < GLXX_CONFIG_MAX_VERTEX_ATTRIBS; i++)
1276 {
1277 if (merge[i].send && merge[i].next == -1)
1278 {
1279 int key = khrn_cache_lookup(thread, &state->cache, merge[i].start, merge[i].end - merge[i].start, CACHE_SIG_ATTRIB_0 + i);
1280 if (key == -1)
1281 {
1282 glxx_set_error(state, GL_OUT_OF_MEMORY);
1283 return;
1284 }
1285 cache_info.entries[i].cache_offset = key + offsetof(CACHE_ENTRY_T, data);
1286 cache_info.entries[i].has_interlock = 1;
1287 }
1288 else
1289 {
1290 cache_info.entries[i].cache_offset = ~0;
1291 }
1292 }
1293
1294 /* Fill in the rest of cache_info (for the merged attribs which didn't force their own cache lookup) */
1295 for (i = 0; i < GLXX_CONFIG_MAX_VERTEX_ATTRIBS; i++)
1296 {
1297 if (merge[i].send && merge[i].next != -1)
1298 {
1299 k = i;
1300 while (merge[k].next != -1)
1301 k = merge[k].next;
1302
1303 vcos_assert(k != -1);
1304 vcos_assert(cache_info.entries[k].cache_offset != ~0);
1305 cache_info.entries[i].cache_offset = cache_info.entries[k].cache_offset + ((size_t)state->attrib[i].pointer - (size_t)state->attrib[k].pointer);
1306 cache_info.entries[i].has_interlock = 0;
1307 }
1308 }
1309
1310 /* Execute draw call, sending attrib cache information */
1311 RPC_CALL5_IN_CTRL(glintDrawElements_impl,
1312 thread,
1313 GLINTDRAWELEMENTS_ID,
1314 RPC_ENUM(mode),
1315 RPC_SIZEI(count),
1316 RPC_ENUM(type),
1317 RPC_UINT(indices_offset),
1318 &cache_info,
1319 sizeof(cache_info));
1320 }
1321 else
1322 {
1323 /* Execute draw call without sending any attrib cache information (except for send_any==0) */
1324 RPC_CALL5_IN_CTRL(glintDrawElements_impl,
1325 thread,
1326 GLINTDRAWELEMENTS_ID,
1327 RPC_ENUM(mode),
1328 RPC_SIZEI(count),
1329 RPC_ENUM(type),
1330 RPC_UINT(indices_offset),
1331 &cache_info,
1332 4/*sizeof(cache_info.send_any)*/);
1333 }
1334}
1335
1336GL_API void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count)
1337{
1338 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1339 if (IS_OPENGLES_11_OR_20(thread)) {
1340 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1341 draw_arrays_or_elements(thread, state, mode, count, 0, (void *)first);
1342 }
1343}
1344
1345
1346GL_API void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
1347{
1348 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1349 if (IS_OPENGLES_11_OR_20(thread)) {
1350 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1351 if (!is_index_type(type)) {
1352 set_error(state, GL_INVALID_ENUM);
1353 return;
1354 }
1355 if (!is_aligned(type, (size_t)indices)) {
1356 set_error(state, GL_INVALID_VALUE);
1357 return;
1358 }
1359 draw_arrays_or_elements(thread, state, mode, count, type, indices);
1360 }
1361}
1362
1363GL_API void GL_APIENTRY glEnable (GLenum cap)
1364{
1365 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1366 if (IS_OPENGLES_11_OR_20(thread)) {
1367 RPC_CALL1(glEnable_impl,
1368 thread,
1369 GLENABLE_ID,
1370 RPC_ENUM(cap));
1371 }
1372}
1373
1374GL_API void GL_APIENTRY glEnableClientState (GLenum array)
1375{
1376 set_enabled_11(array, GL_TRUE);
1377}
1378
1379GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index)
1380{
1381 glintAttribEnable(GLXX_API_20, index, GL_TRUE);
1382}
1383
1384GL_API void GL_APIENTRY glFinish (void)
1385{
1386 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1387 if (IS_OPENGLES_11_OR_20(thread)) {
1388 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1389 (void) RPC_UINT_RES(RPC_CALL0_RES(glFinish_impl,
1390 thread,
1391 GLFINISH_ID)); // Return ignored - read performed to force blocking
1392
1393 if (state->flush_callback)
1394 state->flush_callback(true);
1395 }
1396}
1397
1398GL_API void GL_APIENTRY glFlush (void)
1399{
1400 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1401 if (IS_OPENGLES_11_OR_20(thread)) {
1402 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1403 RPC_CALL0(glFlush_impl,
1404 thread,
1405 GLFLUSH_ID);
1406
1407 if (state->flush_callback)
1408 state->flush_callback(false);
1409 }
1410
1411 //TODO: where exactly should we put RPC_FLUSH? Are there any other functions
1412 //which need it? (e.g. eglSwapBuffers)
1413 RPC_FLUSH(thread);
1414}
1415
1416GL_API void GL_APIENTRY glFogf (GLenum pname, GLfloat param)
1417{
1418 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1419 if (IS_OPENGLES_11(thread)) {
1420 RPC_CALL2(glFogf_impl_11,
1421 thread,
1422 GLFOGF_ID_11,
1423 RPC_ENUM(pname),
1424 RPC_FLOAT(param));
1425 }
1426}
1427
1428GL_API void GL_APIENTRY glFogfv (GLenum pname, const GLfloat *params)
1429{
1430 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1431 if (IS_OPENGLES_11(thread)) {
1432 /*
1433 the only supported fog params are
1434
1435 FOG_MODE (1)
1436 FOG_DENSITY (1)
1437 FOG_START (1)
1438 FOG_END (1)
1439 FOG_COLOR (4)
1440
1441 so we need to transmit 4 words of parameter data
1442 */
1443
1444 RPC_CALL2_IN_CTRL(glFogfv_impl_11,
1445 thread,
1446 GLFOGFV_ID_11,
1447 RPC_ENUM(pname),
1448 params,
1449 4 * sizeof(GLfloat));
1450 }
1451}
1452
1453GL_API void GL_APIENTRY glFogx (GLenum pname, GLfixed param)
1454{
1455 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1456 if (IS_OPENGLES_11(thread)) {
1457 RPC_CALL2(glFogx_impl_11,
1458 thread,
1459 GLFOGX_ID_11,
1460 RPC_ENUM(pname),
1461 RPC_FIXED(param));
1462 }
1463}
1464
1465GL_API void GL_APIENTRY glFogxv (GLenum pname, const GLfixed *params)
1466{
1467 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1468 if (IS_OPENGLES_11(thread)) {
1469 /*
1470 the only supported fog params are
1471
1472 FOG_MODE (1)
1473 FOG_DENSITY (1)
1474 FOG_START (1)
1475 FOG_END (1)
1476 FOG_COLOR (4)
1477
1478 so we need to transmit 4 words of parameter data
1479 */
1480
1481 RPC_CALL2_IN_CTRL(glFogxv_impl_11,
1482 thread,
1483 GLFOGXV_ID_11,
1484 RPC_ENUM(pname),
1485 params,
1486 4 * sizeof(GLfixed));
1487 }
1488}
1489
1490GL_API void GL_APIENTRY glFrontFace (GLenum mode)
1491{
1492 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1493 if (IS_OPENGLES_11_OR_20(thread)) {
1494 RPC_CALL1(glFrontFace_impl,
1495 thread,
1496 GLFRONTFACE_ID,
1497 RPC_ENUM(mode));
1498 }
1499}
1500
1501GL_API void GL_APIENTRY glFrustumf (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
1502{
1503 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1504 if (IS_OPENGLES_11(thread)) {
1505 RPC_CALL6(glFrustumf_impl_11,
1506 thread,
1507 GLFRUSTUMF_ID_11,
1508 RPC_FLOAT(left),
1509 RPC_FLOAT(right),
1510 RPC_FLOAT(bottom),
1511 RPC_FLOAT(top),
1512 RPC_FLOAT(zNear),
1513 RPC_FLOAT(zFar));
1514 }
1515}
1516
1517GL_API void GL_APIENTRY glFrustumx (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
1518{
1519 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1520 if (IS_OPENGLES_11(thread)) {
1521 RPC_CALL6(glFrustumx_impl_11,
1522 thread,
1523 GLFRUSTUMX_ID_11,
1524 RPC_FIXED(left),
1525 RPC_FIXED(right),
1526 RPC_FIXED(bottom),
1527 RPC_FIXED(top),
1528 RPC_FIXED(zNear),
1529 RPC_FIXED(zFar));
1530 }
1531}
1532
1533GL_API void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers)
1534{
1535 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1536 if (IS_OPENGLES_11_OR_20(thread)) {
1537 int offset = 0;
1538
1539 do {
1540 int32_t items = (int32_t) (KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
1541 int32_t batch = _min(items, (int32_t) n);
1542
1543 RPC_CALL2_OUT_BULK(glGenBuffers_impl,
1544 thread,
1545 GLGENBUFFERS_ID,
1546 RPC_SIZEI(batch),
1547 (GLuint*)(buffers + offset));
1548
1549 offset += batch;
1550 n -= batch;
1551 } while (n > 0);
1552 }
1553}
1554
1555GL_API void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures)
1556{
1557 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1558 if (IS_OPENGLES_11_OR_20(thread)) {
1559 int offset = 0;
1560
1561 do {
1562 int32_t items = (int32_t) (KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
1563 int32_t batch = _min(items, (int32_t)n);
1564
1565 RPC_CALL2_OUT_BULK(glGenTextures_impl,
1566 thread,
1567 GLGENTEXTURES_ID,
1568 RPC_SIZEI(batch),
1569 textures + offset);
1570
1571 offset += batch;
1572 n -= batch;
1573 } while (n > 0);
1574 }
1575}
1576
1577GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name)
1578{
1579 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1580 if (IS_OPENGLES_20(thread)) {
1581#ifdef RPC_DIRECT
1582 RPC_CALL7(glGetActiveAttrib_impl_20, thread, no_id, program, index, bufsize, length, size, type, name);
1583#else
1584 GLuint result[3];
1585
1586 rpc_begin(thread);
1587
1588 RPC_CALL4_OUT_CTRL(no_function,
1589 thread,
1590 GLGETACTIVEATTRIB_ID_20,
1591 RPC_UINT(program),
1592 RPC_UINT(index),
1593 RPC_SIZEI(bufsize),
1594 result);
1595
1596 if (length)
1597 *length = (GLsizei)result[0];
1598 if (size)
1599 *size = (GLint)result[1];
1600 if (type)
1601 *type = (GLenum)result[2];
1602
1603 read_out_bulk(thread, name);
1604
1605 rpc_end(thread);
1606#endif
1607 }
1608}
1609
1610GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name)
1611{
1612 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1613 if (IS_OPENGLES_20(thread)) {
1614#ifdef RPC_DIRECT
1615 RPC_CALL7(glGetActiveUniform_impl_20, thread, no_id, program, index, bufsize, length, size, type, name);
1616#else
1617 GLuint result[3];
1618
1619 rpc_begin(thread);
1620
1621 RPC_CALL4_OUT_CTRL(no_function,
1622 thread,
1623 GLGETACTIVEUNIFORM_ID_20,
1624 RPC_UINT(program),
1625 RPC_UINT(index),
1626 RPC_SIZEI(bufsize),
1627 result);
1628
1629 if (length)
1630 *length = (GLsizei)result[0];
1631 if (size)
1632 *size = (GLint)result[1];
1633 if (type)
1634 *type = (GLenum)result[2];
1635
1636 read_out_bulk(thread, name);
1637
1638 rpc_end(thread);
1639#endif
1640 }
1641}
1642
1643GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
1644{
1645 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1646 if (IS_OPENGLES_20(thread)) {
1647#ifdef RPC_DIRECT
1648 RPC_CALL4(glGetAttachedShaders_impl_20, thread, no_id, program, maxcount, count, shaders);
1649#else
1650 GLuint i;
1651
1652 GLuint result[3];
1653
1654 RPC_CALL3_OUT_CTRL(no_function,
1655 thread,
1656 GLGETATTACHEDSHADERS_ID_20,
1657 RPC_UINT(program),
1658 RPC_SIZEI(maxcount),
1659 result);
1660
1661 if (count)
1662 *count = (GLsizei) result[0];
1663
1664 for (i = 0; i < 2; i++)
1665 if ((GLuint)maxcount > i && result[0] > i)
1666 shaders[i] = result[i + 1];
1667#endif
1668 }
1669}
1670
1671GL_APICALL int GL_APIENTRY glGetAttribLocation (GLuint program, const char *name)
1672{
1673 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1674 if (IS_OPENGLES_20(thread)) {
1675 return RPC_INT_RES(RPC_CALL2_IN_BULK_RES(glGetAttribLocation_impl_20,
1676 thread,
1677 GLGETATTRIBLOCATION_ID_20,
1678 RPC_UINT(program),
1679 name,
1680 strlen(name) + 1));
1681 }
1682
1683 return 0;
1684}
1685
1686/*
1687 native client-side boolean variables
1688
1689 VERTEX ARRAY IsEnabled
1690 NORMAL ARRAY IsEnabled
1691 COLOR ARRAY IsEnabled
1692 TEXTURE COORD ARRAY IsEnabled
1693 POINT SIZE ARRAY OES IsEnabled
1694 MATRIX INDEX ARRAY OES IsEnabled
1695 WEIGHT ARRAY OES IsEnabled
1696*/
1697
1698static int get_boolean_internal_11(CLIENT_THREAD_STATE_T *thread, GLenum pname, GLboolean *params)
1699{
1700 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1701
1702 vcos_assert(state != NULL);
1703
1704 switch (pname) {
1705 case GL_VERTEX_ARRAY:
1706 params[0] = state->attrib[GL11_IX_VERTEX].enabled;
1707 return 1;
1708 case GL_NORMAL_ARRAY:
1709 params[0] = state->attrib[GL11_IX_NORMAL].enabled;
1710 return 1;
1711 case GL_COLOR_ARRAY:
1712 params[0] = state->attrib[GL11_IX_COLOR].enabled;
1713 return 1;
1714 case GL_TEXTURE_COORD_ARRAY:
1715 params[0] = state->attrib[state->active_texture.client - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].enabled;
1716 return 1;
1717 case GL_POINT_SIZE_ARRAY_OES:
1718 params[0] = state->attrib[GL11_IX_POINT_SIZE].enabled;
1719 return 1;
1720 case GL_MATRIX_INDEX_ARRAY_OES:
1721 params[0] = state->attrib[GL11_IX_MATRIX_INDEX].enabled;
1722 return 1;
1723 case GL_WEIGHT_ARRAY_OES:
1724 params[0] = state->attrib[GL11_IX_MATRIX_WEIGHT].enabled;
1725 return 1;
1726 default:
1727 UNREACHABLE();
1728 break;
1729 }
1730
1731 return 0;
1732}
1733
1734/*
1735 native client-side floating-point state variables
1736
1737 CURRENT_COLOR
1738 CURRENT_TEXTURE_COORDS
1739 CURRENT_NORMAL
1740 POINT_SIZE
1741*/
1742
1743static int get_float_internal_11(CLIENT_THREAD_STATE_T *thread, GLenum pname, GLfloat *params)
1744{
1745 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1746
1747 int i;
1748
1749 switch (pname) {
1750 case GL_CURRENT_TEXTURE_COORDS:
1751 {
1752 /*
1753 apparently we need the current texture coordinates for the _server_ active texture unit
1754 */
1755
1756 for (i = 0; i < 4; i++)
1757 params[i] = state->attrib[state->active_texture.server - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].value[i];
1758 return 4;
1759 }
1760 case GL_CURRENT_COLOR:
1761 {
1762 for (i = 0; i < 4; i++)
1763 params[i] = state->attrib[GL11_IX_COLOR].value[i];
1764 return 4;
1765 }
1766 case GL_CURRENT_NORMAL:
1767 {
1768 for (i = 0; i < 3; i++)
1769 params[i] = state->attrib[GL11_IX_NORMAL].value[i];
1770 return 3;
1771 }
1772 case GL_POINT_SIZE:
1773 params[0] = state->attrib[GL11_IX_POINT_SIZE].value[0];
1774 return 1;
1775 default:
1776 UNREACHABLE();
1777 break;
1778 }
1779
1780 return 0;
1781}
1782
1783/*
1784 native client-side integer state variables
1785
1786 CLIENT ACTIVE TEXTURE GetIntegerv
1787 VERTEX ARRAY SIZE GetIntegerv
1788 VERTEX ARRAY TYPE GetIntegerv
1789 VERTEX ARRAY STRIDE GetIntegerv
1790 NORMAL ARRAY TYPE GetIntegerv
1791 NORMAL ARRAY STRIDE GetIntegerv
1792 COLOR ARRAY SIZE GetIntegerv
1793 COLOR ARRAY TYPE GetIntegerv
1794 COLOR ARRAY STRIDE GetIntegerv
1795 TEXTURE COORD ARRAY SIZE GetIntegerv
1796 TEXTURE COORD ARRAY TYPE GetIntegerv
1797 TEXTURE COORD ARRAY STRIDE GetIntegerv
1798 POINT SIZE ARRAY TYPE OES GetIntegerv
1799 POINT SIZE ARRAY STRIDE OES GetIntegerv
1800
1801 MATRIX_INDEX_ARRAY_SIZE_OES GetInegerv
1802 MATRIX_INDEX_ARRAY_TYPE_OES GetInegerv
1803 MATRIX_INDEX_ARRAY_STRIDE_OES GetInegerv
1804 WEIGHT_ARRAY_SIZE_OES GetInegerv
1805 WEIGHT_ARRAY_TYPE_OES GetInegerv
1806 WEIGHT_ARRAY_STRIDE_OES GetInegerv
1807
1808 VERTEX ARRAY BUFFER BINDING GetIntegerv
1809 NORMAL ARRAY BUFFER BINDING GetIntegerv
1810 COLOR ARRAY BUFFER BINDING GetIntegerv
1811 TEXTURE COORD ARRAY BUFFER BINDING GetIntegerv
1812 POINT SIZE ARRAY BUFFER BINDING OES GetIntegerv
1813 MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES GetIntegerv
1814 WEIGHT_ARRAY_BUFFER_BINDING_OES GetIntegerv
1815
1816 UNPACK ALIGNMENT GetIntegerv
1817 PACK ALIGNMENT GetIntegerv
1818*/
1819
1820static int get_integer_internal_11(CLIENT_THREAD_STATE_T *thread, GLenum pname, GLint *params)
1821{
1822 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1823
1824 vcos_assert(state != NULL);
1825
1826 switch (pname) {
1827 case GL_CLIENT_ACTIVE_TEXTURE:
1828 params[0] = (GLint) state->active_texture.client;
1829 return 1;
1830 case GL_VERTEX_ARRAY_SIZE:
1831 params[0] = (GLint) state->attrib[GL11_IX_VERTEX].size;
1832 return 1;
1833 case GL_VERTEX_ARRAY_TYPE:
1834 params[0] = (GLint) state->attrib[GL11_IX_VERTEX].type;
1835 return 1;
1836 case GL_VERTEX_ARRAY_STRIDE:
1837 params[0] = (GLint) state->attrib[GL11_IX_VERTEX].stride;
1838 return 1;
1839 case GL_NORMAL_ARRAY_TYPE:
1840 params[0] = (GLint) state->attrib[GL11_IX_NORMAL].type;
1841 return 1;
1842 case GL_NORMAL_ARRAY_STRIDE:
1843 params[0] = (GLint) state->attrib[GL11_IX_NORMAL].stride;
1844 return 1;
1845 case GL_COLOR_ARRAY_SIZE:
1846 params[0] = (GLint) state->attrib[GL11_IX_COLOR].size;
1847 return 1;
1848 case GL_COLOR_ARRAY_TYPE:
1849 params[0] = (GLint) state->attrib[GL11_IX_COLOR].type;
1850 return 1;
1851 case GL_COLOR_ARRAY_STRIDE:
1852 params[0] = (GLint) state->attrib[GL11_IX_COLOR].stride;
1853 return 1;
1854 case GL_TEXTURE_COORD_ARRAY_SIZE:
1855 params[0] = (GLint) state->attrib[state->active_texture.client - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].size;
1856 return 1;
1857 case GL_TEXTURE_COORD_ARRAY_TYPE:
1858 params[0] = (GLint) state->attrib[state->active_texture.client - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].type;
1859 return 1;
1860 case GL_TEXTURE_COORD_ARRAY_STRIDE:
1861 params[0] = (GLint) state->attrib[state->active_texture.client - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].stride;
1862 return 1;
1863 case GL_POINT_SIZE_ARRAY_TYPE_OES:
1864 params[0] = (GLint) state->attrib[GL11_IX_POINT_SIZE].type;
1865 return 1;
1866 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
1867 params[0] = (GLint) state->attrib[GL11_IX_POINT_SIZE].stride;
1868 return 1;
1869 case GL_MATRIX_INDEX_ARRAY_SIZE_OES:
1870 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_INDEX].size;
1871 return 1;
1872 case GL_MATRIX_INDEX_ARRAY_TYPE_OES:
1873 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_INDEX].type;
1874 return 1;
1875 case GL_MATRIX_INDEX_ARRAY_STRIDE_OES:
1876 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_INDEX].stride;
1877 return 1;
1878 case GL_WEIGHT_ARRAY_SIZE_OES:
1879 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_WEIGHT].size;
1880 return 1;
1881 case GL_WEIGHT_ARRAY_TYPE_OES:
1882 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_WEIGHT].type;
1883 return 1;
1884 case GL_WEIGHT_ARRAY_STRIDE_OES:
1885 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_WEIGHT].stride;
1886 return 1;
1887 case GL_ARRAY_BUFFER_BINDING:
1888 params[0] = (GLint) state->bound_buffer.array;
1889 return 1;
1890 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1891 params[0] = (GLint) state->bound_buffer.element_array;
1892 return 1;
1893 case GL_VERTEX_ARRAY_BUFFER_BINDING:
1894 params[0] = (GLint) state->attrib[GL11_IX_VERTEX].buffer;
1895 return 1;
1896 case GL_NORMAL_ARRAY_BUFFER_BINDING:
1897 params[0] = (GLint) state->attrib[GL11_IX_NORMAL].buffer;
1898 return 1;
1899 case GL_COLOR_ARRAY_BUFFER_BINDING:
1900 params[0] = (GLint) state->attrib[GL11_IX_COLOR].buffer;
1901 return 1;
1902 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
1903 /*
1904 TODO is this right?
1905 Most texture state variables are qualified by the value of ACTIVE TEXTURE
1906to determine which server texture state vector is queried. Client texture
1907state variables such as texture coordinate array pointers are qualified by the
1908value of CLIENT ACTIVE TEXTURE. Tables 6.3, 6.4, 6.7, 6.13, 6.15, and 6.21
1909indicate those state variables which are qualified by ACTIVE TEXTURE or
1910CLIENT ACTIVE TEXTURE during state queries
1911 */
1912 params[0] = (GLint) state->attrib[state->active_texture.client - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].buffer;
1913 return 1;
1914 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
1915 params[0] = (GLint) state->attrib[GL11_IX_POINT_SIZE].buffer;
1916 return 1;
1917 case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES:
1918 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_INDEX].buffer;
1919 return 1;
1920 case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES:
1921 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_WEIGHT].buffer;
1922 return 1;
1923
1924 case GL_UNPACK_ALIGNMENT:
1925 params[0] = (GLint) state->alignment.unpack;
1926 return 1;
1927 case GL_PACK_ALIGNMENT:
1928 params[0] = (GLint) state->alignment.pack;
1929 return 1;
1930
1931 //TODO: these are horrible and don't make any sense
1932 //Is this a sensible thing to return?
1933 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1934 params[0] = (GLint) GL_UNSIGNED_BYTE;
1935 return 1;
1936 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1937 params[0] = (GLint) GL_RGBA;
1938 return 1;
1939 //end TODO
1940
1941 default:
1942 UNREACHABLE();
1943 break;
1944 }
1945
1946 return 0;
1947}
1948
1949static int get_integer_internal_20(CLIENT_THREAD_STATE_T *thread, GLenum pname, GLint *params)
1950{
1951 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1952
1953 vcos_assert(state != NULL);
1954
1955 switch (pname) {
1956 case GL_UNPACK_ALIGNMENT:
1957 params[0] = state->alignment.unpack;
1958 return 1;
1959 case GL_PACK_ALIGNMENT:
1960 params[0] = state->alignment.pack;
1961 return 1;
1962 default:
1963 UNREACHABLE();
1964 break;
1965 }
1966
1967 return 0;
1968}
1969
1970GL_API void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *params)
1971{
1972 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1973 if (IS_OPENGLES_11(thread)) {
1974 switch (pname) {
1975 case GL_VERTEX_ARRAY:
1976 case GL_NORMAL_ARRAY:
1977 case GL_COLOR_ARRAY:
1978 case GL_TEXTURE_COORD_ARRAY:
1979 case GL_POINT_SIZE_ARRAY_OES:
1980 get_boolean_internal_11(thread, pname, params);
1981 break;
1982 case GL_CLIENT_ACTIVE_TEXTURE:
1983 case GL_VERTEX_ARRAY_SIZE:
1984 case GL_VERTEX_ARRAY_TYPE:
1985 case GL_VERTEX_ARRAY_STRIDE:
1986 case GL_NORMAL_ARRAY_TYPE:
1987 case GL_NORMAL_ARRAY_STRIDE:
1988 case GL_COLOR_ARRAY_SIZE:
1989 case GL_COLOR_ARRAY_TYPE:
1990 case GL_COLOR_ARRAY_STRIDE:
1991 case GL_TEXTURE_COORD_ARRAY_SIZE:
1992 case GL_TEXTURE_COORD_ARRAY_TYPE:
1993 case GL_TEXTURE_COORD_ARRAY_STRIDE:
1994 case GL_POINT_SIZE_ARRAY_TYPE_OES:
1995 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
1996 case GL_ARRAY_BUFFER_BINDING:
1997 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1998 case GL_VERTEX_ARRAY_BUFFER_BINDING:
1999 case GL_NORMAL_ARRAY_BUFFER_BINDING:
2000 case GL_COLOR_ARRAY_BUFFER_BINDING:
2001 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2002 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2003 case GL_UNPACK_ALIGNMENT:
2004 case GL_PACK_ALIGNMENT:
2005 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
2006 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
2007 {
2008 GLint temp;
2009
2010 get_integer_internal_11(thread, pname, &temp);
2011
2012 params[0] = temp != 0;
2013 break;
2014 }
2015 case GL_CURRENT_TEXTURE_COORDS:
2016 case GL_CURRENT_COLOR:
2017 case GL_CURRENT_NORMAL:
2018 case GL_POINT_SIZE:
2019 {
2020 GLfloat temp[4];
2021 GLuint count = (GLuint) get_float_internal_11(thread, pname, temp);
2022 GLuint i;
2023
2024 vcos_assert(count <= 4);
2025
2026 for (i = 0; i < count; i++)
2027 params[i] = temp[i] != 0.0f;
2028
2029 break;
2030 }
2031 default:
2032 RPC_CALL2_OUT_CTRL(glGetBooleanv_impl,
2033 thread,
2034 GLGETBOOLEANV_ID,
2035 RPC_ENUM(pname),
2036 params);
2037 break;
2038 }
2039 }
2040
2041 if (IS_OPENGLES_20(thread)) {
2042 switch (pname) {
2043 case GL_UNPACK_ALIGNMENT:
2044 case GL_PACK_ALIGNMENT:
2045 {
2046 GLint temp = 0;
2047
2048 get_integer_internal_20(thread, pname, &temp);
2049
2050 params[0] = temp != 0;
2051 break;
2052 }
2053 default:
2054 RPC_CALL2_OUT_CTRL(glGetBooleanv_impl,
2055 thread,
2056 GLGETBOOLEANV_ID,
2057 RPC_ENUM(pname),
2058 params);
2059 break;
2060 }
2061
2062 }
2063}
2064
2065GL_API void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params)
2066{
2067 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2068 if (IS_OPENGLES_11_OR_20(thread)) {
2069 switch(pname) {
2070 case GL_BUFFER_ACCESS_OES:
2071 {
2072 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2073 if(get_bound_buffer(state, target) != 0)
2074 {
2075 params[0] = GL_WRITE_ONLY_OES;
2076 }
2077 else
2078 {
2079 params[0] = 0;
2080 }
2081 break;
2082 }
2083 case GL_BUFFER_MAPPED_OES:
2084 {
2085 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2086 GLXX_BUFFER_INFO_T buffer;
2087 glxx_buffer_info_get(state, target, &buffer);
2088 if(buffer.id != 0 && buffer.mapped_pointer != 0)
2089 {
2090 params[0] = GL_TRUE;
2091 }
2092 else
2093 {
2094 params[0] = GL_FALSE;
2095 }
2096 break;
2097 }
2098 default:
2099 RPC_CALL3_OUT_CTRL(glGetBufferParameteriv_impl,
2100 thread,
2101 GLGETBUFFERPARAMETERIV_ID,
2102 RPC_ENUM(target),
2103 RPC_ENUM(pname),
2104 params);
2105
2106 if(pname == GL_BUFFER_SIZE)
2107 {
2108 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2109 GLXX_BUFFER_INFO_T buffer;
2110 glxx_buffer_info_get(state, target, &buffer);
2111 buffer.cached_size = params[0];
2112 glxx_buffer_info_set(state, target, &buffer);
2113 }
2114 }
2115 }
2116}
2117
2118GL_API void GL_APIENTRY glGetClipPlanef (GLenum pname, GLfloat eqn[4])
2119{
2120 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2121 if (IS_OPENGLES_11(thread)) {
2122 RPC_CALL2_OUT_CTRL(glGetClipPlanef_impl_11,
2123 thread,
2124 GLGETCLIPPLANEF_ID_11,
2125 RPC_ENUM(pname),
2126 eqn);
2127 }
2128}
2129
2130GL_API void GL_APIENTRY glGetClipPlanex (GLenum pname, GLfixed eqn[4])
2131{
2132 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2133 if (IS_OPENGLES_11(thread)) {
2134 RPC_CALL2_OUT_CTRL(glGetClipPlanex_impl_11,
2135 thread,
2136 GLGETCLIPPLANEX_ID_11,
2137 RPC_ENUM(pname),
2138 eqn);
2139 }
2140}
2141
2142GL_API GLenum GL_APIENTRY glGetError (void)
2143{
2144 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); /* Decrements glgeterror_hack variable for every API call made */
2145 if (IS_OPENGLES_11_OR_20(thread)) {
2146 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2147
2148 GLenum result = state->error;
2149
2150 if ((result == GL_NO_ERROR) && !thread->async_error_notification) {
2151 /* Don't query the server if our previous API call was glGetError() */
2152 if (0 == thread->glgeterror_hack ) {
2153 result = RPC_ENUM_RES(RPC_CALL0_RES(glGetError_impl,
2154 thread,
2155 GLGETERROR_ID));
2156 }
2157
2158 if(result != GL_NO_ERROR) {
2159 vcos_log_warn("glGetError 0x%x", result);
2160 thread->glgeterror_hack = 0;
2161 } else {
2162 thread->glgeterror_hack = 2;
2163 }
2164 }
2165 state->error = GL_NO_ERROR;
2166
2167 return result;
2168 }
2169
2170 return 0;
2171}
2172
2173GL_API void GL_APIENTRY glGetFixedv (GLenum pname, GLfixed *params)
2174{
2175 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2176 if (IS_OPENGLES_11(thread)) {
2177 switch (pname) {
2178 case GL_VERTEX_ARRAY:
2179 case GL_NORMAL_ARRAY:
2180 case GL_COLOR_ARRAY:
2181 case GL_TEXTURE_COORD_ARRAY:
2182 case GL_POINT_SIZE_ARRAY_OES:
2183 {
2184 GLboolean temp[4];
2185
2186 int count = get_boolean_internal_11(thread, pname, temp);
2187 int i;
2188
2189 vcos_assert(count <= 4);
2190
2191 for (i = 0; i < count; i++)
2192 params[i] = temp[i] ? (GLfixed)float_to_fixed(1.0f) : (GLfixed)float_to_fixed(0.0f);
2193
2194 break;
2195 }
2196 case GL_CURRENT_TEXTURE_COORDS:
2197 case GL_CURRENT_COLOR:
2198 case GL_CURRENT_NORMAL:
2199 case GL_POINT_SIZE:
2200 {
2201 GLfloat temp[4];
2202
2203 int count = get_float_internal_11(thread, pname, temp);
2204 int i;
2205
2206 vcos_assert(count <= 4);
2207
2208 for (i = 0; i < count; i++)
2209 params[i] = (GLfixed) float_to_fixed(temp[i]);
2210
2211 break;
2212 }
2213 case GL_CLIENT_ACTIVE_TEXTURE:
2214 case GL_VERTEX_ARRAY_SIZE:
2215 case GL_VERTEX_ARRAY_TYPE:
2216 case GL_VERTEX_ARRAY_STRIDE:
2217 case GL_NORMAL_ARRAY_TYPE:
2218 case GL_NORMAL_ARRAY_STRIDE:
2219 case GL_COLOR_ARRAY_SIZE:
2220 case GL_COLOR_ARRAY_TYPE:
2221 case GL_COLOR_ARRAY_STRIDE:
2222 case GL_TEXTURE_COORD_ARRAY_SIZE:
2223 case GL_TEXTURE_COORD_ARRAY_TYPE:
2224 case GL_TEXTURE_COORD_ARRAY_STRIDE:
2225 case GL_POINT_SIZE_ARRAY_TYPE_OES:
2226 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
2227 case GL_ARRAY_BUFFER_BINDING:
2228 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2229 case GL_VERTEX_ARRAY_BUFFER_BINDING:
2230 case GL_NORMAL_ARRAY_BUFFER_BINDING:
2231 case GL_COLOR_ARRAY_BUFFER_BINDING:
2232 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2233 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2234 case GL_UNPACK_ALIGNMENT:
2235 case GL_PACK_ALIGNMENT:
2236 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
2237 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
2238 {
2239 GLint temp;
2240
2241 get_integer_internal_11(thread, pname, &temp);
2242
2243 params[0] = (GLfixed) float_to_fixed((GLfloat)temp);
2244 break;
2245 }
2246 default:
2247 RPC_CALL2_OUT_CTRL(glGetFixedv_impl_11,
2248 thread,
2249 GLGETFIXEDV_ID_11,
2250 RPC_ENUM(pname),
2251 params);
2252 break;
2253 }
2254 }
2255}
2256
2257GL_API void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *params)
2258{
2259 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2260 if (IS_OPENGLES_11(thread)) {
2261 switch (pname) {
2262 case GL_VERTEX_ARRAY:
2263 case GL_NORMAL_ARRAY:
2264 case GL_COLOR_ARRAY:
2265 case GL_TEXTURE_COORD_ARRAY:
2266 case GL_POINT_SIZE_ARRAY_OES:
2267 {
2268 GLboolean temp[4];
2269 GLuint count = (GLuint) get_boolean_internal_11(thread, pname, temp);
2270 GLuint i;
2271
2272 vcos_assert(count <= 4);
2273
2274 for (i = 0; i < count; i++)
2275 params[i] = temp[i] ? 1.0f : 0.0f;
2276
2277 break;
2278 }
2279 case GL_CURRENT_TEXTURE_COORDS:
2280 case GL_CURRENT_COLOR:
2281 case GL_CURRENT_NORMAL:
2282 case GL_POINT_SIZE:
2283 get_float_internal_11(thread, pname, params);
2284
2285 break;
2286 case GL_CLIENT_ACTIVE_TEXTURE:
2287 case GL_VERTEX_ARRAY_SIZE:
2288 case GL_VERTEX_ARRAY_TYPE:
2289 case GL_VERTEX_ARRAY_STRIDE:
2290 case GL_NORMAL_ARRAY_TYPE:
2291 case GL_NORMAL_ARRAY_STRIDE:
2292 case GL_COLOR_ARRAY_SIZE:
2293 case GL_COLOR_ARRAY_TYPE:
2294 case GL_COLOR_ARRAY_STRIDE:
2295 case GL_TEXTURE_COORD_ARRAY_SIZE:
2296 case GL_TEXTURE_COORD_ARRAY_TYPE:
2297 case GL_TEXTURE_COORD_ARRAY_STRIDE:
2298 case GL_POINT_SIZE_ARRAY_TYPE_OES:
2299 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
2300 case GL_ARRAY_BUFFER_BINDING:
2301 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2302 case GL_VERTEX_ARRAY_BUFFER_BINDING:
2303 case GL_NORMAL_ARRAY_BUFFER_BINDING:
2304 case GL_COLOR_ARRAY_BUFFER_BINDING:
2305 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2306 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2307 case GL_UNPACK_ALIGNMENT:
2308 case GL_PACK_ALIGNMENT:
2309 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
2310 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
2311 {
2312 GLint temp;
2313
2314 get_integer_internal_11(thread, pname, &temp);
2315
2316 params[0] = (GLfloat)temp;
2317 break;
2318 }
2319 default:
2320 RPC_CALL2_OUT_CTRL(glGetFloatv_impl,
2321 thread,
2322 GLGETFLOATV_ID,
2323 RPC_ENUM(pname),
2324 params);
2325 break;
2326 }
2327 }
2328 else if (IS_OPENGLES_20(thread)) {
2329 switch (pname) {
2330 case GL_UNPACK_ALIGNMENT:
2331 case GL_PACK_ALIGNMENT:
2332 {
2333 GLint temp = 0;
2334
2335 get_integer_internal_20(thread, pname, &temp);
2336
2337 params[0] = (GLfloat)temp;
2338 break;
2339 }
2340 default:
2341 RPC_CALL2_OUT_CTRL(glGetFloatv_impl,
2342 thread,
2343 GLGETFLOATV_ID,
2344 RPC_ENUM(pname),
2345 params);
2346 break;
2347 }
2348 }
2349}
2350
2351GL_API void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *params)
2352{
2353 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2354 if (IS_OPENGLES_11(thread)) {
2355 switch (pname) {
2356 case GL_VERTEX_ARRAY:
2357 case GL_NORMAL_ARRAY:
2358 case GL_COLOR_ARRAY:
2359 case GL_TEXTURE_COORD_ARRAY:
2360 case GL_POINT_SIZE_ARRAY_OES:
2361 {
2362 GLboolean temp[4];
2363 GLuint count = (GLuint) get_boolean_internal_11(thread, pname, temp);
2364 GLuint i;
2365
2366 vcos_assert(count <= 4);
2367
2368 for (i = 0; i < count; i++)
2369 params[i] = temp[i] ? 1 : 0;
2370
2371 break;
2372 }
2373 case GL_CURRENT_COLOR:
2374 case GL_CURRENT_NORMAL:
2375 {
2376 GLfloat temp[4];
2377 GLuint count = (GLuint) get_float_internal_11(thread, pname, temp);
2378 GLuint i;
2379
2380 vcos_assert(count <= 4);
2381
2382 for (i = 0; i < count; i++)
2383 params[i] = (GLint)floor((4294967295.0f * temp[i] - 1.0f) / 2.0f + 0.5f);
2384
2385 //TODO: that the above is correct wrt table 2.7 in the GL spec
2386
2387 break;
2388 }
2389 case GL_CURRENT_TEXTURE_COORDS:
2390 case GL_POINT_SIZE:
2391 {
2392 GLfloat temp[4];
2393 GLuint count = (GLuint) get_float_internal_11(thread, pname, temp);
2394 GLuint i;
2395
2396 vcos_assert(count <= 4);
2397
2398 for (i = 0; i < count; i++)
2399 params[i] = (GLint) float_to_int(temp[i]);
2400
2401 break;
2402 }
2403 case GL_CLIENT_ACTIVE_TEXTURE:
2404 case GL_VERTEX_ARRAY_SIZE:
2405 case GL_VERTEX_ARRAY_TYPE:
2406 case GL_VERTEX_ARRAY_STRIDE:
2407 case GL_NORMAL_ARRAY_TYPE:
2408 case GL_NORMAL_ARRAY_STRIDE:
2409 case GL_COLOR_ARRAY_SIZE:
2410 case GL_COLOR_ARRAY_TYPE:
2411 case GL_COLOR_ARRAY_STRIDE:
2412 case GL_TEXTURE_COORD_ARRAY_SIZE:
2413 case GL_TEXTURE_COORD_ARRAY_TYPE:
2414 case GL_TEXTURE_COORD_ARRAY_STRIDE:
2415 case GL_POINT_SIZE_ARRAY_TYPE_OES:
2416 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
2417 case GL_MATRIX_INDEX_ARRAY_SIZE_OES:
2418 case GL_MATRIX_INDEX_ARRAY_TYPE_OES:
2419 case GL_MATRIX_INDEX_ARRAY_STRIDE_OES:
2420 case GL_WEIGHT_ARRAY_SIZE_OES:
2421 case GL_WEIGHT_ARRAY_TYPE_OES:
2422 case GL_WEIGHT_ARRAY_STRIDE_OES:
2423 case GL_ARRAY_BUFFER_BINDING:
2424 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2425 case GL_VERTEX_ARRAY_BUFFER_BINDING:
2426 case GL_NORMAL_ARRAY_BUFFER_BINDING:
2427 case GL_COLOR_ARRAY_BUFFER_BINDING:
2428 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2429 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2430 case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES:
2431 case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES:
2432 case GL_UNPACK_ALIGNMENT:
2433 case GL_PACK_ALIGNMENT:
2434 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
2435 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
2436 get_integer_internal_11(thread, pname, params);
2437 break;
2438 default:
2439 RPC_CALL2_OUT_CTRL(glGetIntegerv_impl,
2440 thread,
2441 GLGETINTEGERV_ID,
2442 RPC_ENUM(pname),
2443 params);
2444 break;
2445 }
2446 }
2447 else if (IS_OPENGLES_20(thread)) {
2448 switch (pname) {
2449 case GL_UNPACK_ALIGNMENT:
2450 case GL_PACK_ALIGNMENT:
2451 get_integer_internal_20(thread, pname, params);
2452 break;
2453 default:
2454 RPC_CALL2_OUT_CTRL(glGetIntegerv_impl,
2455 thread,
2456 GLGETINTEGERV_ID,
2457 RPC_ENUM(pname),
2458 params);
2459 break;
2460 }
2461 }
2462}
2463
2464GL_API void GL_APIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params)
2465{
2466 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2467 if (IS_OPENGLES_11(thread)) {
2468 RPC_CALL3_OUT_CTRL(glGetLightfv_impl_11,
2469 thread,
2470 GLGETLIGHTFV_ID_11,
2471 RPC_ENUM(light),
2472 RPC_ENUM(pname),
2473 params);
2474 }
2475}
2476
2477GL_API void GL_APIENTRY glGetLightxv (GLenum light, GLenum pname, GLfixed *params)
2478{
2479 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2480 if (IS_OPENGLES_11(thread)) {
2481 RPC_CALL3_OUT_CTRL(glGetLightxv_impl_11,
2482 thread,
2483 GLGETLIGHTXV_ID_11,
2484 RPC_ENUM(light),
2485 RPC_ENUM(pname),
2486 params);
2487 }
2488}
2489
2490GL_API void GL_APIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params)
2491{
2492 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2493 if (IS_OPENGLES_11(thread)) {
2494 RPC_CALL3_OUT_CTRL(glGetMaterialfv_impl_11,
2495 thread,
2496 GLGETMATERIALFV_ID_11,
2497 RPC_ENUM(face),
2498 RPC_ENUM(pname),
2499 params);
2500 }
2501}
2502
2503GL_API void GL_APIENTRY glGetMaterialxv (GLenum face, GLenum pname, GLfixed *params)
2504{
2505 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2506 if (IS_OPENGLES_11(thread)) {
2507 RPC_CALL3_OUT_CTRL(glGetMaterialxv_impl_11,
2508 thread,
2509 GLGETMATERIALXV_ID_11,
2510 RPC_ENUM(face),
2511 RPC_ENUM(pname),
2512 params);
2513 }
2514}
2515
2516/*
2517 VERTEX ARRAY POINTER GetPointerv
2518 NORMAL ARRAY POINTER GetPointerv
2519 COLOR ARRAY POINTER GetPointerv
2520 TEXTURE COORD ARRAY POINTER GetPointerv
2521 POINT SIZE ARRAY POINTER OES GetPointerv
2522 MATRIX_INDEX_ARRAY_POINTER_OES GetPointerv
2523 WEIGHT_ARRAY_POINTER_OES GetPointerv
2524*/
2525
2526GL_API void GL_APIENTRY glGetPointerv (GLenum pname, GLvoid **params)
2527{
2528 void *result = NULL;
2529
2530 switch (pname) {
2531 case GL_VERTEX_ARRAY_POINTER:
2532 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_VERTEX);
2533 break;
2534 case GL_NORMAL_ARRAY_POINTER:
2535 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_NORMAL);
2536 break;
2537 case GL_COLOR_ARRAY_POINTER:
2538 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_COLOR);
2539 break;
2540 case GL_TEXTURE_COORD_ARRAY_POINTER:
2541 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_CLIENT_ACTIVE_TEXTURE);
2542 break;
2543 case GL_POINT_SIZE_ARRAY_POINTER_OES:
2544 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_POINT_SIZE);
2545 break;
2546#if GL_OES_matrix_palette
2547 case GL_MATRIX_INDEX_ARRAY_POINTER_OES:
2548 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_MATRIX_INDEX);
2549 break;
2550 case GL_WEIGHT_ARRAY_POINTER_OES:
2551 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_MATRIX_WEIGHT);
2552 break;
2553#endif
2554 default:
2555 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
2556 break;
2557 }
2558
2559 if (result != NULL)
2560 params[0] = result;
2561}
2562
2563GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params)
2564{
2565 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2566 if (IS_OPENGLES_20(thread)) {
2567 RPC_CALL3_OUT_CTRL(glGetProgramiv_impl_20,
2568 thread,
2569 GLGETPROGRAMIV_ID_20,
2570 RPC_UINT(program),
2571 RPC_ENUM(pname),
2572 params);
2573 }
2574}
2575
2576GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei *length, char *infolog)
2577{
2578 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2579 if (IS_OPENGLES_20(thread)) {
2580#ifdef RPC_DIRECT
2581 RPC_CALL4(glGetProgramInfoLog_impl_20, thread, no_id, program, bufsize, length, infolog);
2582#else
2583 GLuint result[1];
2584
2585 rpc_begin(thread);
2586
2587 RPC_CALL3_OUT_CTRL(no_function,
2588 thread,
2589 GLGETPROGRAMINFOLOG_ID_20,
2590 RPC_UINT(program),
2591 RPC_SIZEI(bufsize),
2592 result);
2593
2594 if (length)
2595 *length = (GLsizei)result[0];
2596
2597 read_out_bulk(thread, infolog);
2598
2599 rpc_end(thread);
2600#endif
2601 }
2602}
2603
2604GL_API const GLubyte * GL_APIENTRY glGetString (GLenum name)
2605{
2606 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2607 if (IS_OPENGLES_11(thread)) {
2608 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2609
2610 vcos_assert(state != NULL);
2611
2612 switch (name) {
2613 case GL_VENDOR:
2614#ifndef NDEBUG
2615 return (const GLubyte *)"Broadcom DEBUG";
2616#else
2617 return (const GLubyte *)"Broadcom";
2618#endif
2619 case GL_RENDERER:
2620 return (const GLubyte *)"VideoCore IV HW";
2621 case GL_VERSION:
2622 return (const GLubyte *)"OpenGL ES-CM 1.1";
2623 case GL_EXTENSIONS:
2624 return (const GLubyte *)"GL_OES_compressed_ETC1_RGB8_texture "
2625 "GL_OES_compressed_paletted_texture "
2626 "GL_OES_texture_npot " /*TODO is npot right? I can't find it in glext.h */
2627 "GL_OES_EGL_image "
2628 "GL_OES_EGL_image_external "
2629 "GL_EXT_discard_framebuffer "
2630 "GL_OES_query_matrix "
2631 "GL_OES_framebuffer_object "
2632 "GL_OES_rgb8_rgba8 "
2633 "GL_OES_depth24 "
2634 "GL_OES_depth32 "
2635 "GL_OES_stencil8 "
2636 "GL_OES_draw_texture "
2637 "GL_OES_mapbuffer "
2638#if GL_EXT_texture_format_BGRA8888
2639 "GL_EXT_texture_format_BGRA8888 "
2640#endif
2641#if GL_APPLE_rgb_422
2642 "GL_APPLE_rgb_422 "
2643#endif
2644#if GL_OES_matrix_palette
2645 "GL_OES_matrix_palette "
2646#endif
2647#ifdef GL_EXT_debug_marker
2648 "GL_EXT_debug_marker "
2649#endif
2650 ;
2651 default:
2652 set_error(state, GL_INVALID_ENUM);
2653 return NULL;
2654 }
2655 }
2656 else if (IS_OPENGLES_20(thread)) {
2657 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2658
2659 vcos_assert(state != NULL);
2660
2661 switch (name) {
2662 case GL_VENDOR:
2663#ifndef NDEBUG
2664 return (const GLubyte *)"Broadcom DEBUG";
2665#else
2666 return (const GLubyte *)"Broadcom";
2667#endif
2668 case GL_RENDERER:
2669 return (const GLubyte *)"VideoCore IV HW";
2670 case GL_VERSION:
2671 return (const GLubyte *)"OpenGL ES 2.0";
2672 case GL_SHADING_LANGUAGE_VERSION:
2673 return (const GLubyte *)"OpenGL ES GLSL ES 1.00";
2674 case GL_EXTENSIONS:
2675 return (const GLubyte *)"GL_OES_compressed_ETC1_RGB8_texture "
2676 "GL_OES_compressed_paletted_texture "
2677 "GL_OES_texture_npot "
2678 "GL_OES_depth24 "
2679 "GL_OES_vertex_half_float "
2680 "GL_OES_EGL_image "
2681 "GL_OES_EGL_image_external "
2682 "GL_EXT_discard_framebuffer "
2683 "GL_OES_rgb8_rgba8 "
2684 "GL_OES_depth32 "
2685 "GL_OES_mapbuffer "
2686#if GL_EXT_texture_format_BGRA8888
2687 "GL_EXT_texture_format_BGRA8888 "
2688#endif
2689#if GL_APPLE_rgb_422
2690 "GL_APPLE_rgb_422 "
2691#endif
2692#ifdef GL_EXT_debug_marker
2693 "GL_EXT_debug_marker "
2694#endif
2695 ;
2696 default:
2697 set_error(state, GL_INVALID_ENUM);
2698 return NULL;
2699 }
2700 }
2701
2702 return NULL;
2703}
2704
2705GL_API void GL_APIENTRY glGetTexEnviv (GLenum env, GLenum pname, GLint *params)
2706{
2707 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2708 if (IS_OPENGLES_11(thread)) {
2709 RPC_CALL3_OUT_CTRL(glGetTexEnviv_impl_11,
2710 thread,
2711 GLGETTEXENVIV_ID_11,
2712 RPC_ENUM(env),
2713 RPC_ENUM(pname),
2714 params);
2715 }
2716}
2717
2718GL_API void GL_APIENTRY glGetTexEnvfv (GLenum env, GLenum pname, GLfloat *params)
2719{
2720 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2721 if (IS_OPENGLES_11(thread)) {
2722 RPC_CALL3_OUT_CTRL(glGetTexEnvfv_impl_11,
2723 thread,
2724 GLGETTEXENVFV_ID_11,
2725 RPC_ENUM(env),
2726 RPC_ENUM(pname),
2727 params);
2728 }
2729}
2730
2731GL_API void GL_APIENTRY glGetTexEnvxv (GLenum env, GLenum pname, GLfixed *params)
2732{
2733 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2734 if (IS_OPENGLES_11(thread)) {
2735 RPC_CALL3_OUT_CTRL(glGetTexEnvxv_impl_11,
2736 thread,
2737 GLGETTEXENVXV_ID_11,
2738 RPC_ENUM(env),
2739 RPC_ENUM(pname),
2740 params);
2741 }
2742}
2743
2744GL_API void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params)
2745{
2746 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2747 if (IS_OPENGLES_11_OR_20(thread)) {
2748 RPC_CALL3_OUT_CTRL(glGetTexParameteriv_impl,
2749 thread,
2750 GLGETTEXPARAMETERIV_ID,
2751 RPC_ENUM(target),
2752 RPC_ENUM(pname),
2753 params);
2754 }
2755}
2756
2757GL_API void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params)
2758{
2759 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2760 if (IS_OPENGLES_11_OR_20(thread)) {
2761 RPC_CALL3_OUT_CTRL(glGetTexParameterfv_impl,
2762 thread,
2763 GLGETTEXPARAMETERFV_ID,
2764 RPC_ENUM(target),
2765 RPC_ENUM(pname),
2766 params);
2767 }
2768}
2769
2770GL_API void GL_APIENTRY glGetTexParameterxv (GLenum target, GLenum pname, GLfixed *params)
2771{
2772 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2773 if (IS_OPENGLES_11(thread)) {
2774 RPC_CALL3_OUT_CTRL(glGetTexParameterxv_impl_11,
2775 thread,
2776 GLGETTEXPARAMETERXV_ID_11,
2777 RPC_ENUM(target),
2778 RPC_ENUM(pname),
2779 params);
2780 }
2781}
2782
2783GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params)
2784{
2785 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2786 if (IS_OPENGLES_20(thread)) {
2787 RPC_CALL3_OUT_CTRL(glGetUniformfv_impl_20,
2788 thread,
2789 GLGETUNIFORMFV_ID_20,
2790 RPC_UINT(program),
2791 RPC_INT(location),
2792 params);
2793 }
2794}
2795
2796GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params)
2797{
2798 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2799 if (IS_OPENGLES_20(thread)) {
2800 RPC_CALL3_OUT_CTRL(glGetUniformiv_impl_20,
2801 thread,
2802 GLGETUNIFORMIV_ID_20,
2803 RPC_UINT(program),
2804 RPC_INT(location),
2805 params);
2806 }
2807}
2808
2809GL_APICALL int GL_APIENTRY glGetUniformLocation (GLuint program, const char *name)
2810{
2811 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2812 if (IS_OPENGLES_20(thread)) {
2813 return RPC_INT_RES(RPC_CALL2_IN_BULK_RES(glGetUniformLocation_impl_20,
2814 thread,
2815 GLGETUNIFORMLOCATION_ID_20,
2816 RPC_UINT(program),
2817 name,
2818 strlen(name) + 1));
2819 }
2820
2821 return 0;
2822}
2823
2824/*
2825 GetVertexAttrib
2826
2827 VERTEX ATTRIB ARRAY ENABLED False GetVertexAttrib
2828 VERTEX ATTRIB ARRAY SIZE 4 GetVertexAttrib
2829 VERTEX ATTRIB ARRAY STRIDE 0 GetVertexAttrib
2830 VERTEX ATTRIB ARRAY TYPE FLOAT GetVertexAttrib
2831 VERTEX ATTRIB ARRAY NORMALIZED False GetVertexAttrib
2832 VERTEX ATTRIB ARRAY BUFFER BINDING 0 GetVertexAttrib
2833
2834 CURRENT VERTEX ATTRIB 0,0,0,1 GetVertexAttributes
2835*/
2836
2837GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params)
2838{
2839 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2840 if (IS_OPENGLES_20(thread)) {
2841 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2842
2843 vcos_assert(state != NULL);
2844
2845 if (index < GL20_CONFIG_MAX_VERTEX_ATTRIBS)
2846 switch (pname) {
2847 case GL_CURRENT_VERTEX_ATTRIB:
2848 params[0] = state->attrib[index].value[0];
2849 params[1] = state->attrib[index].value[1];
2850 params[2] = state->attrib[index].value[2];
2851 params[3] = state->attrib[index].value[3];
2852 break;
2853
2854 //TODO: is this the best way to handle conversions? We duplicate
2855 //the entire switch statement.
2856 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2857 params[0] = state->attrib[index].enabled ? 1.0f : 0.0f;
2858 break;
2859 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2860 params[0] = (GLfloat)state->attrib[index].size;
2861 break;
2862 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2863 params[0] = (GLfloat)state->attrib[index].stride;
2864 break;
2865 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2866 params[0] = (GLfloat)state->attrib[index].type;
2867 break;
2868 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2869 params[0] = state->attrib[index].normalized ? 1.0f : 0.0f;
2870 break;
2871 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2872 params[0] = (GLfloat)state->attrib[index].buffer;
2873 break;
2874
2875
2876
2877 default:
2878 set_error(state, GL_INVALID_ENUM);
2879 break;
2880 }
2881 else
2882 set_error(state, GL_INVALID_VALUE);
2883 }
2884}
2885
2886GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params)
2887{
2888 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2889 if (IS_OPENGLES_20(thread)) {
2890 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2891
2892 vcos_assert(state != NULL);
2893
2894 if (index < GL20_CONFIG_MAX_VERTEX_ATTRIBS)
2895 switch (pname) {
2896 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2897 params[0] = (GLint) state->attrib[index].enabled ? GL_TRUE : GL_FALSE;
2898 break;
2899 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2900 params[0] = (GLint) state->attrib[index].size;
2901 break;
2902 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2903 params[0] = (GLint) state->attrib[index].stride;
2904 break;
2905 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2906 params[0] = (GLint) state->attrib[index].type;
2907 break;
2908 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2909 params[0] = (GLint) state->attrib[index].normalized ? GL_TRUE : GL_FALSE;
2910 break;
2911 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2912 params[0] = (GLint) state->attrib[index].buffer;
2913 break;
2914
2915
2916 //TODO: is this the best way to handle conversions? We duplicate
2917 //the entire switch statement.
2918 case GL_CURRENT_VERTEX_ATTRIB:
2919 params[0] = (GLint)state->attrib[index].value[0];
2920 params[1] = (GLint)state->attrib[index].value[1];
2921 params[2] = (GLint)state->attrib[index].value[2];
2922 params[3] = (GLint)state->attrib[index].value[3];
2923 break;
2924
2925 default:
2926 set_error(state, GL_INVALID_ENUM);
2927 break;
2928 }
2929 else
2930 set_error(state, GL_INVALID_VALUE);
2931 }
2932}
2933
2934/*
2935 GetVertexAttribPointer
2936
2937 VERTEX ATTRIB ARRAY POINTER NULL GetVertexAttribPointer
2938*/
2939
2940GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer)
2941{
2942 void *result = NULL;
2943
2944 if (pname == GL_VERTEX_ATTRIB_ARRAY_POINTER)
2945 result = glintAttribGetPointer(GLXX_API_20, index);
2946 else
2947 glxx_set_error_api(GLXX_API_20, GL_INVALID_ENUM);
2948
2949 if (result != NULL)
2950 *pointer = result;
2951}
2952
2953GL_API void GL_APIENTRY glHint (GLenum target, GLenum mode)
2954{
2955 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2956 if (IS_OPENGLES_11_OR_20(thread)) {
2957 RPC_CALL2(glHint_impl,
2958 thread,
2959 GLHINT_ID,
2960 RPC_ENUM(target),
2961 RPC_ENUM(mode));
2962 }
2963}
2964
2965GL_API GLboolean GL_APIENTRY glIsBuffer (GLuint buffer)
2966{
2967 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2968 if (IS_OPENGLES_11_OR_20(thread)) {
2969 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsBuffer_impl,
2970 thread,
2971 GLISBUFFER_ID,
2972 RPC_UINT(buffer)));
2973 }
2974
2975 return 0;
2976}
2977
2978GL_API GLboolean GL_APIENTRY glIsEnabled (GLenum cap)
2979{
2980 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2981 if (IS_OPENGLES_11(thread)) {
2982 switch (cap) {
2983 case GL_VERTEX_ARRAY:
2984 case GL_NORMAL_ARRAY:
2985 case GL_COLOR_ARRAY:
2986 case GL_POINT_SIZE_ARRAY_OES:
2987 case GL_TEXTURE_COORD_ARRAY:
2988 case GL_MATRIX_INDEX_ARRAY_OES:
2989 case GL_WEIGHT_ARRAY_OES:
2990 {
2991 GLboolean temp = 0;
2992 GLuint count = (GLuint) get_boolean_internal_11(thread, cap, &temp);
2993 UNUSED_NDEBUG(count);
2994 vcos_assert(count == 1);
2995
2996 return temp;
2997 }
2998 default:
2999 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsEnabled_impl,
3000 thread,
3001 GLISENABLED_ID,
3002 RPC_ENUM(cap)));
3003 }
3004 }
3005 else if (IS_OPENGLES_20(thread)) {
3006 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsEnabled_impl,
3007 thread,
3008 GLISENABLED_ID,
3009 RPC_ENUM(cap)));
3010 }
3011
3012 return 0;
3013}
3014
3015GL_API GLboolean GL_APIENTRY glIsProgram (GLuint program)
3016{
3017 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3018 if (IS_OPENGLES_20(thread)) {
3019 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsProgram_impl_20,
3020 thread,
3021 GLISPROGRAM_ID_20,
3022 RPC_UINT(program)));
3023 }
3024
3025 return 0;
3026}
3027
3028GL_API GLboolean GL_APIENTRY glIsShader (GLuint shader)
3029{
3030 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3031 if (IS_OPENGLES_20(thread)) {
3032 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsShader_impl_20,
3033 thread,
3034 GLISSHADER_ID_20,
3035 RPC_UINT(shader)));
3036 }
3037
3038 return 0;
3039}
3040
3041GL_API GLboolean GL_APIENTRY glIsTexture (GLuint texture)
3042{
3043 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3044 if (IS_OPENGLES_11_OR_20(thread)) {
3045 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsTexture_impl,
3046 thread,
3047 GLISTEXTURE_ID,
3048 RPC_UINT(texture)));
3049 }
3050 return 0;
3051}
3052
3053GL_API void GL_APIENTRY glLightModelf (GLenum pname, GLfloat param)
3054{
3055 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3056 if (IS_OPENGLES_11(thread)) {
3057 RPC_CALL2(glLightModelf_impl_11,
3058 thread,
3059 GLLIGHTMODELF_ID_11,
3060 RPC_ENUM(pname),
3061 RPC_FLOAT(param));
3062 }
3063}
3064
3065GL_API void GL_APIENTRY glLightModelfv (GLenum pname, const GLfloat *params)
3066{
3067 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3068 if (IS_OPENGLES_11(thread)) {
3069 /*
3070 the only supported lighting model params are
3071
3072 LIGHT_MODEL_AMBIENT (4)
3073 LIGHT_MODEL_TWO_SIDE (1)
3074
3075 so we need to transmit 4 words of parameter data
3076 */
3077
3078 RPC_CALL2_IN_CTRL(glLightModelfv_impl_11,
3079 thread,
3080 GLLIGHTMODELFV_ID_11,
3081 RPC_ENUM(pname),
3082 params,
3083 4 * sizeof(GLfloat));
3084 }
3085}
3086
3087GL_API void GL_APIENTRY glLightModelx (GLenum pname, GLfixed param)
3088{
3089 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3090 if (IS_OPENGLES_11(thread)) {
3091 RPC_CALL2(glLightModelx_impl_11,
3092 thread,
3093 GLLIGHTMODELX_ID_11,
3094 RPC_ENUM(pname),
3095 RPC_FIXED(param));
3096 }
3097}
3098
3099GL_API void GL_APIENTRY glLightModelxv (GLenum pname, const GLfixed *params)
3100{
3101 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3102 if (IS_OPENGLES_11(thread)) {
3103 /*
3104 the only supported lighting model params are
3105
3106 LIGHT_MODEL_AMBIENT (4)
3107 LIGHT_MODEL_TWO_SIDE (1)
3108
3109 so we need to transmit 4 words of parameter data
3110 */
3111
3112 RPC_CALL2_IN_CTRL(glLightModelxv_impl_11,
3113 thread,
3114 GLLIGHTMODELXV_ID_11,
3115 RPC_ENUM(pname),
3116 params,
3117 4 * sizeof(GLfixed));
3118 }
3119}
3120
3121GL_API void GL_APIENTRY glLightf (GLenum light, GLenum pname, GLfloat param)
3122{
3123 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3124 if (IS_OPENGLES_11(thread)) {
3125 RPC_CALL3(glLightf_impl_11,
3126 thread,
3127 GLLIGHTF_ID_11,
3128 RPC_ENUM(light),
3129 RPC_ENUM(pname),
3130 RPC_FLOAT(param));
3131 }
3132}
3133
3134GL_API void GL_APIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params)
3135{
3136 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3137 if (IS_OPENGLES_11(thread)) {
3138 /*
3139 the only supported light params are
3140
3141 AMBIENT (4)
3142 DIFFUSE (4)
3143 SPECULAR (4)
3144 POSITION (4)
3145 SPOT_DIRECTION (3)
3146 SPOT_EXPONENT (1)
3147 SPOT_CUTOFF (1)
3148 CONSTANT_ATTENUATION (1)
3149 LINEAR_ATTENUATION (1)
3150 QUADRATIC_ATTENUATION (1)
3151
3152 so we need to transmit 4 words of parameter data
3153 */
3154
3155 RPC_CALL3_IN_CTRL(glLightfv_impl_11,
3156 thread,
3157 GLLIGHTFV_ID_11,
3158 RPC_ENUM(light),
3159 RPC_ENUM(pname),
3160 params,
3161 4 * sizeof(GLfloat));
3162 }
3163}
3164
3165GL_API void GL_APIENTRY glLightx (GLenum light, GLenum pname, GLfixed param)
3166{
3167 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3168 if (IS_OPENGLES_11(thread)) {
3169 RPC_CALL3(glLightx_impl_11,
3170 thread,
3171 GLLIGHTX_ID_11,
3172 RPC_ENUM(light),
3173 RPC_ENUM(pname),
3174 RPC_FIXED(param));
3175 }
3176}
3177
3178GL_API void GL_APIENTRY glLightxv (GLenum light, GLenum pname, const GLfixed *params)
3179{
3180 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3181 if (IS_OPENGLES_11(thread)) {
3182 /*
3183 the only supported light params are
3184
3185 AMBIENT (4)
3186 DIFFUSE (4)
3187 SPECULAR (4)
3188 POSITION (4)
3189 SPOT_DIRECTION (3)
3190 SPOT_EXPONENT (1)
3191 SPOT_CUTOFF (1)
3192 CONSTANT_ATTENUATION (1)
3193 LINEAR_ATTENUATION (1)
3194 QUADRATIC_ATTENUATION (1)
3195
3196 so we need to transmit 4 words of parameter data
3197 */
3198
3199 RPC_CALL3_IN_CTRL(glLightxv_impl_11,
3200 thread,
3201 GLLIGHTXV_ID_11,
3202 RPC_ENUM(light),
3203 RPC_ENUM(pname),
3204 params,
3205 4 * sizeof(GLfixed));
3206 }
3207}
3208
3209GL_API void GL_APIENTRY glLineWidth (GLfloat width)
3210{
3211 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3212 if (IS_OPENGLES_11_OR_20(thread)) {
3213 RPC_CALL1(glLineWidth_impl,
3214 thread,
3215 GLLINEWIDTH_ID,
3216 RPC_FLOAT(width));
3217 }
3218}
3219
3220GL_API void GL_APIENTRY glLineWidthx (GLfixed width)
3221{
3222 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3223 if (IS_OPENGLES_11(thread)) {
3224 RPC_CALL1(glLineWidthx_impl_11,
3225 thread,
3226 GLLINEWIDTHX_ID_11,
3227 RPC_FIXED(width));
3228 }
3229}
3230
3231GL_API void GL_APIENTRY glLinkProgram (GLuint program)
3232{
3233 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3234 if (IS_OPENGLES_20(thread)) {
3235 RPC_CALL1(glLinkProgram_impl_20,
3236 thread,
3237 GLLINKPROGRAM_ID_20,
3238 RPC_UINT(program));
3239 }
3240}
3241
3242GL_API void GL_APIENTRY glLoadIdentity (void)
3243{
3244 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3245 if (IS_OPENGLES_11(thread)) {
3246 RPC_CALL0(glLoadIdentity_impl_11,
3247 thread,
3248 GLLOADIDENTITY_ID_11);
3249 }
3250}
3251
3252GL_API void GL_APIENTRY glLoadMatrixf (const GLfloat *m)
3253{
3254 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3255 if (IS_OPENGLES_11(thread)) {
3256 RPC_CALL1_IN_CTRL(glLoadMatrixf_impl_11,
3257 thread,
3258 GLLOADMATRIXF_ID_11,
3259 m,
3260 16 * sizeof(GLfloat));
3261 }
3262}
3263
3264GL_API void GL_APIENTRY glLoadMatrixx (const GLfixed *m)
3265{
3266 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3267 if (IS_OPENGLES_11(thread)) {
3268 RPC_CALL1_IN_CTRL(glLoadMatrixx_impl_11,
3269 thread,
3270 GLLOADMATRIXX_ID_11,
3271 m,
3272 16 * sizeof(GLfixed));
3273 }
3274}
3275
3276GL_API void GL_APIENTRY glLogicOp (GLenum opcode)
3277{
3278 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3279 if (IS_OPENGLES_11(thread)) {
3280 RPC_CALL1(glLogicOp_impl_11,
3281 thread,
3282 GLLOGICOP_ID_11,
3283 RPC_ENUM(opcode));
3284 }
3285}
3286
3287GL_API void GL_APIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param)
3288{
3289 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3290 if (IS_OPENGLES_11(thread)) {
3291 RPC_CALL3(glMaterialf_impl_11,
3292 thread,
3293 GLMATERIALF_ID_11,
3294 RPC_ENUM(face),
3295 RPC_ENUM(pname),
3296 RPC_FLOAT(param));
3297 }
3298}
3299
3300GL_API void GL_APIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params)
3301{
3302 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3303 if (IS_OPENGLES_11(thread)) {
3304 /*
3305 the only supported material params are
3306
3307 AMBIENT (4)
3308 DIFFUSE (4)
3309 SPECULAR (4)
3310 EMISSION (4)
3311 SHININESS (1)
3312
3313 so we need to transmit 4 words of parameter data
3314 */
3315
3316 RPC_CALL3_IN_CTRL(glMaterialfv_impl_11,
3317 thread,
3318 GLMATERIALFV_ID_11,
3319 RPC_ENUM(face),
3320 RPC_ENUM(pname),
3321 params,
3322 4 * sizeof(GLfloat));
3323 }
3324}
3325
3326GL_API void GL_APIENTRY glMaterialx (GLenum face, GLenum pname, GLfixed param)
3327{
3328 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3329 if (IS_OPENGLES_11(thread)) {
3330 RPC_CALL3(glMaterialx_impl_11,
3331 thread,
3332 GLMATERIALX_ID_11,
3333 RPC_ENUM(face),
3334 RPC_ENUM(pname),
3335 RPC_FIXED(param));
3336 }
3337}
3338
3339GL_API void GL_APIENTRY glMaterialxv (GLenum face, GLenum pname, const GLfixed *params)
3340{
3341 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3342 if (IS_OPENGLES_11(thread)) {
3343 /*
3344 the only supported material params are
3345
3346 AMBIENT (4)
3347 DIFFUSE (4)
3348 SPECULAR (4)
3349 EMISSION (4)
3350 SHININESS (1)
3351
3352 so we need to transmit 4 words of parameter data
3353 */
3354
3355 RPC_CALL3_IN_CTRL(glMaterialxv_impl_11,
3356 thread,
3357 GLMATERIALXV_ID_11,
3358 RPC_ENUM(face),
3359 RPC_ENUM(pname),
3360 params,
3361 4 * sizeof(GLfixed));
3362 }
3363}
3364
3365GL_API void GL_APIENTRY glMatrixMode (GLenum mode)
3366{
3367 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3368 if (IS_OPENGLES_11(thread)) {
3369 RPC_CALL1(glMatrixMode_impl_11,
3370 thread,
3371 GLMATRIXMODE_ID_11,
3372 RPC_ENUM(mode));
3373 }
3374}
3375
3376GL_API void GL_APIENTRY glMultMatrixf (const GLfloat *m)
3377{
3378 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3379 if (IS_OPENGLES_11(thread)) {
3380 RPC_CALL1_IN_CTRL(glMultMatrixf_impl_11,
3381 thread,
3382 GLMULTMATRIXF_ID_11,
3383 m,
3384 16 * sizeof(GLfloat));
3385 }
3386}
3387
3388GL_API void GL_APIENTRY glMultMatrixx (const GLfixed *m)
3389{
3390 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3391 if (IS_OPENGLES_11(thread)) {
3392 RPC_CALL1_IN_CTRL(glMultMatrixx_impl_11,
3393 thread,
3394 GLMULTMATRIXX_ID_11,
3395 m,
3396 16 * sizeof(GLfixed));
3397 }
3398}
3399
3400GL_API void GL_APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
3401{
3402 if (target >= GL_TEXTURE0 && target < GL_TEXTURE0 + GL11_CONFIG_MAX_TEXTURE_UNITS) {
3403 uint32_t indx = GL11_IX_TEXTURE_COORD + target - GL_TEXTURE0;
3404 glintAttrib(GLXX_API_11, indx, s, t, r, q);
3405 } else
3406 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
3407}
3408
3409GL_API void GL_APIENTRY glMultiTexCoord4x (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
3410{
3411 if (target >= GL_TEXTURE0 && target < GL_TEXTURE0 + GL11_CONFIG_MAX_TEXTURE_UNITS) {
3412 uint32_t indx = GL11_IX_TEXTURE_COORD + target - GL_TEXTURE0;
3413 glintAttrib(GLXX_API_11, indx, fixed_to_float(s), fixed_to_float(t), fixed_to_float(r), fixed_to_float(q));
3414 } else
3415 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
3416}
3417
3418GL_API void GL_APIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz)
3419{
3420 glintAttrib(GLXX_API_11, GL11_IX_NORMAL, nx, ny, nz, 0.0f);
3421}
3422
3423GL_API void GL_APIENTRY glNormal3x (GLfixed nx, GLfixed ny, GLfixed nz)
3424{
3425 glintAttrib(GLXX_API_11, GL11_IX_NORMAL, fixed_to_float(nx), fixed_to_float(ny), fixed_to_float(nz), 0.0f);
3426}
3427
3428static bool is_normal_type(GLenum type)
3429{
3430 return type == GL_BYTE ||
3431 type == GL_SHORT ||
3432 type == GL_FIXED ||
3433 type == GL_FLOAT;
3434}
3435
3436GL_API void GL_APIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer)
3437{
3438 if (is_normal_type(type)) {
3439 if (is_aligned(type, (size_t)pointer) && is_aligned(type, (size_t)stride) && stride >= 0) {
3440 glintAttribPointer(GLXX_API_11, GL11_IX_NORMAL, 3, type, GL_TRUE, stride, pointer);
3441 } else
3442 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
3443 } else
3444 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
3445}
3446
3447GL_API void GL_APIENTRY glOrthof (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
3448{
3449 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3450 if (IS_OPENGLES_11(thread)) {
3451 RPC_CALL6(glOrthof_impl_11,
3452 thread,
3453 GLORTHOF_ID_11,
3454 RPC_FLOAT(left),
3455 RPC_FLOAT(right),
3456 RPC_FLOAT(bottom),
3457 RPC_FLOAT(top),
3458 RPC_FLOAT(zNear),
3459 RPC_FLOAT(zFar));
3460 }
3461}
3462
3463GL_API void GL_APIENTRY glOrthox (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
3464{
3465 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3466 if (IS_OPENGLES_11(thread)) {
3467 RPC_CALL6(glOrthox_impl_11,
3468 thread,
3469 GLORTHOX_ID_11,
3470 RPC_FIXED(left),
3471 RPC_FIXED(right),
3472 RPC_FIXED(bottom),
3473 RPC_FIXED(top),
3474 RPC_FIXED(zNear),
3475 RPC_FIXED(zFar));
3476 }
3477}
3478
3479static GLboolean is_alignment(GLint param)
3480{
3481 return param == 1 ||
3482 param == 2 ||
3483 param == 4 ||
3484 param == 8;
3485}
3486
3487GL_API void GL_APIENTRY glPixelStorei (GLenum pname, GLint param)
3488{
3489 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3490 if (IS_OPENGLES_11_OR_20(thread)) {
3491 if (is_alignment(param)) {
3492 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
3493
3494 vcos_assert(state != NULL);
3495
3496 switch (pname) {
3497 case GL_PACK_ALIGNMENT:
3498 state->alignment.pack = param;
3499 break;
3500 case GL_UNPACK_ALIGNMENT:
3501 state->alignment.unpack = param;
3502 break;
3503 }
3504 }
3505 }
3506}
3507
3508GL_API void GL_APIENTRY glPointParameterf (GLenum pname, GLfloat param)
3509{
3510 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3511 if (IS_OPENGLES_11(thread)) {
3512 RPC_CALL2(glPointParameterf_impl_11,
3513 thread,
3514 GLPOINTPARAMETERF_ID_11,
3515 RPC_ENUM(pname),
3516 RPC_FLOAT(param));
3517 }
3518}
3519
3520GL_API void GL_APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params)
3521{
3522 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3523 if (IS_OPENGLES_11(thread)) {
3524 /*
3525 the only supported material params are
3526
3527 POINT_SIZE_MIN (1)
3528 POINT_SIZE_MAX (1)
3529 POINT_FADE_THRESHOLD_SIZE (1)
3530 POINT_DISTANCE_ATTENUATION (3)
3531
3532 so we need to transmit 3 words of parameter data
3533 */
3534
3535 RPC_CALL2_IN_CTRL(glPointParameterfv_impl_11,
3536 thread,
3537 GLPOINTPARAMETERFV_ID_11,
3538 RPC_ENUM(pname),
3539 params,
3540 3 * sizeof(GLfloat));
3541 }
3542}
3543
3544GL_API void GL_APIENTRY glPointParameterx (GLenum pname, GLfixed param)
3545{
3546 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3547 if (IS_OPENGLES_11(thread)) {
3548 RPC_CALL2(glPointParameterx_impl_11,
3549 thread,
3550 GLPOINTPARAMETERX_ID_11,
3551 RPC_ENUM(pname),
3552 RPC_FIXED(param));
3553 }
3554}
3555
3556GL_API void GL_APIENTRY glPointParameterxv (GLenum pname, const GLfixed *params)
3557{
3558 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3559 if (IS_OPENGLES_11(thread)) {
3560 /*
3561 the only supported material params are
3562
3563 POINT_SIZE_MIN (1)
3564 POINT_SIZE_MAX (1)
3565 POINT_FADE_THRESHOLD_SIZE (1)
3566 POINT_DISTANCE_ATTENUATION (3)
3567
3568 so we need to transmit 3 words of parameter data
3569 */
3570
3571 RPC_CALL2_IN_CTRL(glPointParameterxv_impl_11,
3572 thread,
3573 GLPOINTPARAMETERXV_ID_11,
3574 RPC_ENUM(pname),
3575 params,
3576 3 * sizeof(GLfixed));
3577 }
3578}
3579
3580GL_API void GL_APIENTRY glPointSize (GLfloat size)
3581{
3582 size = clean_float(size);
3583
3584 if (size > 0.0f)
3585 glintAttrib(GLXX_API_11, GL11_IX_POINT_SIZE, size, 0.0f, 0.0f, 0.0f);
3586 else
3587 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
3588}
3589
3590GL_API void GL_APIENTRY glPointSizex (GLfixed size)
3591{
3592 if (size > 0)
3593 glintAttrib(GLXX_API_11, GL11_IX_POINT_SIZE, fixed_to_float(size), 0.0f, 0.0f, 0.0f);
3594 else
3595 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
3596}
3597
3598GL_API void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units)
3599{
3600 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3601 if (IS_OPENGLES_11_OR_20(thread)) {
3602 RPC_CALL2(glPolygonOffset_impl,
3603 thread,
3604 GLPOLYGONOFFSET_ID,
3605 RPC_FLOAT(factor),
3606 RPC_FLOAT(units));
3607 }
3608}
3609
3610GL_API void GL_APIENTRY glPolygonOffsetx (GLfixed factor, GLfixed units)
3611{
3612 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3613 if (IS_OPENGLES_11(thread)) {
3614 RPC_CALL2(glPolygonOffsetx_impl_11,
3615 thread,
3616 GLPOLYGONOFFSETX_ID_11,
3617 RPC_FIXED(factor),
3618 RPC_FIXED(units));
3619 }
3620}
3621
3622GL_API void GL_APIENTRY glPopMatrix (void)
3623{
3624 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3625 if (IS_OPENGLES_11(thread)) {
3626 RPC_CALL0(glPopMatrix_impl_11,
3627 thread,
3628 GLPOPMATRIX_ID_11);
3629 }
3630}
3631
3632GL_API void GL_APIENTRY glPushMatrix (void)
3633{
3634 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3635 if (IS_OPENGLES_11(thread)) {
3636 RPC_CALL0(glPushMatrix_impl_11,
3637 thread,
3638 GLPUSHMATRIX_ID_11);
3639 }
3640}
3641
3642/*
3643 we need to calculate on the client side how much data to transfer to the
3644 server on a call to glTexImage2D()
3645
3646 from section 3.6 of the OpenGL ES 1.1 spec
3647
3648 the first element of the Nth row is indicated by
3649
3650 p + Nk
3651
3652 where N is the row number (counting from zero) and k is defined as
3653
3654 k = nl if s >= a
3655 = a/s * ceil(snl/a) otherwise
3656
3657 where n is the number of elements in a group, l is the number of groups in
3658 the row, a is the value of UNPACK ALIGNMENT, and s is the size, in units of GL
3659 ubytes, of an element.
3660
3661 this code is
3662*/
3663
3664static uint32_t get_pitch(uint32_t w, GLenum format, GLenum type, uint32_t a)
3665{
3666 uint32_t n = 0;
3667 uint32_t s = 0;
3668 uint32_t k = 0;
3669
3670 switch (format) {
3671 case GL_RGBA:
3672#if GL_EXT_texture_format_BGRA8888
3673 case GL_BGRA_EXT:
3674#endif
3675#if GL_texture_format_RGBX8888_BRCM
3676 case GL_RGBX_BRCM:
3677#endif
3678 switch (type) {
3679 case GL_UNSIGNED_BYTE:
3680 n = 4;
3681 s = 1;
3682 break;
3683 case GL_UNSIGNED_SHORT_4_4_4_4:
3684 case GL_UNSIGNED_SHORT_5_5_5_1:
3685 n = 1;
3686 s = 2;
3687 break;
3688 }
3689 break;
3690 case GL_RGB:
3691 switch (type) {
3692 case GL_UNSIGNED_BYTE:
3693 n = 3;
3694 s = 1;
3695 break;
3696 case GL_UNSIGNED_SHORT_5_6_5:
3697 n = 1;
3698 s = 2;
3699 break;
3700 }
3701 break;
3702 case GL_LUMINANCE_ALPHA:
3703 n = 2;
3704 s = 1;
3705 break;
3706 case GL_LUMINANCE:
3707 case GL_ALPHA:
3708 n = 1;
3709 s = 1;
3710 break;
3711#if GL_APPLE_rgb_422
3712 case GL_RGB_422_APPLE:
3713 n = 1;
3714 s = 2;
3715 break;
3716#endif
3717 }
3718
3719 if (s != 0) { /* Avoid division by zero errors on invalid formats */
3720 if (s < a)
3721 k = (a / s) * ((s * n * w + a - 1) / a);
3722 else
3723 k = n * w;
3724 }
3725
3726 switch (format) {
3727 case GL_RGBA:
3728#if GL_EXT_texture_format_BGRA8888
3729 case GL_BGRA_EXT:
3730#endif
3731#if GL_texture_format_RGBX8888_BRCM
3732 case GL_RGBX_BRCM:
3733#endif
3734 switch (type) {
3735 case GL_UNSIGNED_BYTE:
3736 return k;
3737 case GL_UNSIGNED_SHORT_4_4_4_4:
3738 case GL_UNSIGNED_SHORT_5_5_5_1:
3739 return k * 2;
3740 }
3741 break;
3742 case GL_RGB:
3743 switch (type) {
3744 case GL_UNSIGNED_BYTE:
3745 return k;
3746 case GL_UNSIGNED_SHORT_5_6_5:
3747 return k * 2;
3748 }
3749 break;
3750 case GL_LUMINANCE_ALPHA:
3751 case GL_LUMINANCE:
3752 case GL_ALPHA:
3753 return k;
3754#if GL_APPLE_rgb_422
3755 case GL_RGB_422_APPLE:
3756 return k * 2;
3757#endif
3758 }
3759
3760 return 0; // transfer no data, format will be rejected by server
3761}
3762
3763GL_API void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
3764{
3765 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3766 if (IS_OPENGLES_11_OR_20(thread)) {
3767 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
3768
3769 uint32_t pitch = get_pitch( (uint32_t)width, format, type, (uint32_t) state->alignment.pack);
3770 uint32_t lines = pitch ? (uint32_t) (KHDISPATCH_WORKSPACE_SIZE / pitch) : (uint32_t)height;
3771
3772 if (pixels && lines) {
3773 int offset = 0;
3774
3775 while (height > 0) {
3776 int32_t batch = _min(lines, (int32_t) height);
3777
3778 RPC_CALL8_OUT_BULK(glReadPixels_impl,
3779 thread,
3780 GLREADPIXELS_ID,
3781 RPC_INT(x),
3782 RPC_INT(y + offset),
3783 RPC_SIZEI(width),
3784 RPC_SIZEI(batch),
3785 RPC_ENUM(format),
3786 RPC_ENUM(type),
3787 RPC_INT(state->alignment.pack),
3788 (char *)pixels + offset * pitch);
3789
3790 offset += batch;
3791 height -= batch;
3792 }
3793 }
3794
3795 // We do not call flush_callback as the spec does not imply a full flush
3796 // at this point (I think).
3797 }
3798}
3799
3800GL_API void GL_APIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3801{
3802 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3803 if (IS_OPENGLES_11(thread)) {
3804 RPC_CALL4(glRotatef_impl_11,
3805 thread,
3806 GLROTATEF_ID_11,
3807 RPC_FLOAT(angle),
3808 RPC_FLOAT(x),
3809 RPC_FLOAT(y),
3810 RPC_FLOAT(z));
3811 }
3812}
3813
3814GL_API void GL_APIENTRY glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
3815{
3816 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3817 if (IS_OPENGLES_11(thread)) {
3818 RPC_CALL4(glRotatex_impl_11,
3819 thread,
3820 GLROTATEX_ID_11,
3821 RPC_FIXED(angle),
3822 RPC_FIXED(x),
3823 RPC_FIXED(y),
3824 RPC_FIXED(z));
3825 }
3826}
3827
3828GL_API void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert)
3829{
3830 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3831 if (IS_OPENGLES_11_OR_20(thread)) {
3832 RPC_CALL2(glSampleCoverage_impl,
3833 thread,
3834 GLSAMPLECOVERAGE_ID,
3835 RPC_FLOAT(value),
3836 RPC_BOOLEAN(invert));
3837 }
3838}
3839
3840GL_API void GL_APIENTRY glSampleCoveragex (GLclampx value, GLboolean invert)
3841{
3842 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3843 if (IS_OPENGLES_11(thread)) {
3844 RPC_CALL2(glSampleCoveragex_impl_11,
3845 thread,
3846 GLSAMPLECOVERAGEX_ID_11,
3847 RPC_FIXED(value),
3848 RPC_BOOLEAN(invert));
3849 }
3850}
3851
3852GL_API void GL_APIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z)
3853{
3854 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3855 if (IS_OPENGLES_11(thread)) {
3856 RPC_CALL3(glScalef_impl_11,
3857 thread,
3858 GLSCALEF_ID_11,
3859 RPC_FLOAT(x),
3860 RPC_FLOAT(y),
3861 RPC_FLOAT(z));
3862 }
3863}
3864
3865GL_API void GL_APIENTRY glScalex (GLfixed x, GLfixed y, GLfixed z)
3866{
3867 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3868 if (IS_OPENGLES_11(thread)) {
3869 RPC_CALL3(glScalex_impl_11,
3870 thread,
3871 GLSCALEX_ID_11,
3872 RPC_FIXED(x),
3873 RPC_FIXED(y),
3874 RPC_FIXED(z));
3875 }
3876}
3877
3878GL_API void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height)
3879{
3880 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3881 if (IS_OPENGLES_11_OR_20(thread)) {
3882 RPC_CALL4(glScissor_impl,
3883 thread,
3884 GLSCISSOR_ID,
3885 RPC_INT(x),
3886 RPC_INT(y),
3887 RPC_SIZEI(width),
3888 RPC_SIZEI(height));
3889 }
3890}
3891
3892GL_API void GL_APIENTRY glShadeModel (GLenum mode)
3893{
3894 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3895 if (IS_OPENGLES_11(thread)) {
3896 RPC_CALL1(glShadeModel_impl_11,
3897 thread,
3898 GLSHADEMODEL_ID_11,
3899 RPC_ENUM(mode));
3900 }
3901}
3902
3903static void set_stencil_func(CLIENT_THREAD_STATE_T *thread, GLenum face, GLenum func, GLint ref, GLuint mask) {
3904 RPC_CALL4(glStencilFuncSeparate_impl,
3905 thread,
3906 GLSTENCILFUNCSEPARATE_ID,
3907 RPC_ENUM(face),
3908 RPC_ENUM(func),
3909 RPC_INT(ref),
3910 RPC_UINT(mask));
3911}
3912
3913GL_API void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask)
3914{
3915 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3916 if (IS_OPENGLES_11_OR_20(thread)) set_stencil_func(thread, GL_FRONT_AND_BACK, func, ref, mask);
3917}
3918
3919GL_API void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask) // S
3920{
3921 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3922 if (IS_OPENGLES_20(thread)) set_stencil_func(thread, face, func, ref, mask);
3923}
3924
3925static void set_stencil_mask(CLIENT_THREAD_STATE_T *thread, GLenum face, GLuint mask) {
3926 RPC_CALL2(glStencilMaskSeparate_impl,
3927 thread,
3928 GLSTENCILMASKSEPARATE_ID,
3929 RPC_ENUM(face),
3930 RPC_UINT(mask));
3931}
3932
3933GL_API void GL_APIENTRY glStencilMask (GLuint mask)
3934{
3935 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3936 if (IS_OPENGLES_11_OR_20(thread)) set_stencil_mask(thread, GL_FRONT_AND_BACK, mask);
3937}
3938
3939GL_API void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask) // S
3940{
3941 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3942 if (IS_OPENGLES_20(thread)) set_stencil_mask(thread, face, mask);
3943}
3944
3945static void set_stencil_op(CLIENT_THREAD_STATE_T *thread, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
3946 RPC_CALL4(glStencilOpSeparate_impl,
3947 thread,
3948 GLSTENCILOPSEPARATE_ID,
3949 RPC_ENUM(face),
3950 RPC_ENUM(fail),
3951 RPC_ENUM(zfail),
3952 RPC_ENUM(zpass));
3953}
3954
3955GL_API void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass)
3956{
3957 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3958 if (IS_OPENGLES_11_OR_20(thread)) set_stencil_op(thread, GL_FRONT_AND_BACK, fail, zfail, zpass);
3959}
3960
3961GL_API void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass) // S
3962{
3963 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3964 if (IS_OPENGLES_20(thread)) set_stencil_op(thread, face, fail, zfail, zpass);
3965}
3966
3967static bool is_texture_coord_size(GLint size)
3968{
3969 return size == 2 ||
3970 size == 3 ||
3971 size == 4;
3972}
3973
3974static bool is_texture_coord_type(GLenum type)
3975{
3976 return type == GL_BYTE ||
3977 type == GL_SHORT ||
3978 type == GL_FIXED ||
3979 type == GL_FLOAT;
3980}
3981
3982GL_API void GL_APIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
3983{
3984 if (is_texture_coord_type(type)) {
3985 if (is_texture_coord_size(size) && is_aligned(type, (size_t)pointer) && is_aligned(type, (size_t)stride) && stride >= 0) {
3986 glintAttribPointer(GLXX_API_11, GL11_IX_CLIENT_ACTIVE_TEXTURE, size, type, GL_FALSE, stride, pointer);
3987 } else
3988 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
3989 } else
3990 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
3991}
3992
3993GL_API void GL_APIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param)
3994{
3995 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3996 if (IS_OPENGLES_11(thread)) {
3997 RPC_CALL3(glTexEnvi_impl_11,
3998 thread,
3999 GLTEXENVI_ID_11,
4000 RPC_ENUM(target),
4001 RPC_ENUM(pname),
4002 RPC_INT(param));
4003 }
4004}
4005
4006GL_API void GL_APIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params)
4007{
4008 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4009 if (IS_OPENGLES_11(thread)) {
4010 /*
4011 the only supported texture environment params are
4012
4013 COORD_REPLACE_OES (1)
4014 TEXTURE_ENV_MODE (1)
4015 TEXTURE_ENV_COLOR (4)
4016 COMBINE_RGB (1)
4017 RGB_SCALE (1)
4018 SRC0_RGB (1)
4019 SRC1_RGB (1)
4020 SRC2_RGB (1)
4021 OPERAND0_RGB (1)
4022 OPERAND1_RGB (1)
4023 OPERAND2_RGB (1)
4024 COMBINE_ALPHA (1)
4025 ALPHA_SCALE (1)
4026 SRC0_ALPHA (1)
4027 SRC1_ALPHA (1)
4028 SRC2_ALPHA (1)
4029 OPERAND0_ALPHA (1)
4030 OPERAND1_ALPHA (1)
4031 OPERAND2_ALPHA (1)
4032
4033 so we need to transmit 4 words of parameter data
4034 */
4035
4036 RPC_CALL3_IN_CTRL(glTexEnviv_impl_11,
4037 thread,
4038 GLTEXENVIV_ID_11,
4039 RPC_ENUM(target),
4040 RPC_ENUM(pname),
4041 params,
4042 4 * sizeof(GLint));
4043 }
4044}
4045
4046GL_API void GL_APIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param)
4047{
4048 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4049 if (IS_OPENGLES_11(thread)) {
4050 RPC_CALL3(glTexEnvf_impl_11,
4051 thread,
4052 GLTEXENVF_ID_11,
4053 RPC_ENUM(target),
4054 RPC_ENUM(pname),
4055 RPC_FLOAT(param));
4056 }
4057}
4058
4059GL_API void GL_APIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params)
4060{
4061 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4062 if (IS_OPENGLES_11(thread)) {
4063 /*
4064 the only supported texture environment params are
4065
4066 COORD_REPLACE_OES (1)
4067 TEXTURE_ENV_MODE (1)
4068 TEXTURE_ENV_COLOR (4)
4069 COMBINE_RGB (1)
4070 RGB_SCALE (1)
4071 SRC0_RGB (1)
4072 SRC1_RGB (1)
4073 SRC2_RGB (1)
4074 OPERAND0_RGB (1)
4075 OPERAND1_RGB (1)
4076 OPERAND2_RGB (1)
4077 COMBINE_ALPHA (1)
4078 ALPHA_SCALE (1)
4079 SRC0_ALPHA (1)
4080 SRC1_ALPHA (1)
4081 SRC2_ALPHA (1)
4082 OPERAND0_ALPHA (1)
4083 OPERAND1_ALPHA (1)
4084 OPERAND2_ALPHA (1)
4085
4086 so we need to transmit 4 words of parameter data
4087 */
4088
4089 RPC_CALL3_IN_CTRL(glTexEnvfv_impl_11,
4090 thread,
4091 GLTEXENVFV_ID_11,
4092 RPC_ENUM(target),
4093 RPC_ENUM(pname),
4094 params,
4095 4 * sizeof(GLfloat));
4096 }
4097}
4098
4099GL_API void GL_APIENTRY glTexEnvx (GLenum target, GLenum pname, GLfixed param)
4100{
4101 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4102 if (IS_OPENGLES_11(thread)) {
4103 RPC_CALL3(glTexEnvx_impl_11,
4104 thread,
4105 GLTEXENVX_ID_11,
4106 RPC_ENUM(target),
4107 RPC_ENUM(pname),
4108 RPC_FIXED(param));
4109 }
4110}
4111
4112GL_API void GL_APIENTRY glTexEnvxv (GLenum target, GLenum pname, const GLfixed *params)
4113{
4114 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4115 if (IS_OPENGLES_11(thread)) {
4116 /*
4117 the only supported texture environment params are
4118
4119 COORD_REPLACE_OES (1)
4120 TEXTURE_ENV_MODE (1)
4121 TEXTURE_ENV_COLOR (4)
4122 COMBINE_RGB (1)
4123 RGB_SCALE (1)
4124 SRC0_RGB (1)
4125 SRC1_RGB (1)
4126 SRC2_RGB (1)
4127 OPERAND0_RGB (1)
4128 OPERAND1_RGB (1)
4129 OPERAND2_RGB (1)
4130 COMBINE_ALPHA (1)
4131 ALPHA_SCALE (1)
4132 SRC0_ALPHA (1)
4133 SRC1_ALPHA (1)
4134 SRC2_ALPHA (1)
4135 OPERAND0_ALPHA (1)
4136 OPERAND1_ALPHA (1)
4137 OPERAND2_ALPHA (1)
4138
4139 so we need to transmit 4 words of parameter data
4140 */
4141
4142 RPC_CALL3_IN_CTRL(glTexEnvxv_impl_11,
4143 thread,
4144 GLTEXENVXV_ID_11,
4145 RPC_ENUM(target),
4146 RPC_ENUM(pname),
4147 params,
4148 4 * sizeof(GLfixed));
4149 }
4150}
4151
4152GL_API void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
4153{
4154 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4155 GLboolean res;
4156 if (IS_OPENGLES_11_OR_20(thread)) {
4157 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
4158
4159 uint32_t pitch = get_pitch( (uint32_t)width, format, type, (uint32_t)state->alignment.unpack);
4160 uint32_t lines = pitch ? (uint32_t)(KHDISPATCH_WORKSPACE_SIZE / pitch) : (uint32_t)height;
4161
4162 res = RPC_BOOLEAN_RES(RPC_CALL10_IN_BULK_RES(glTexImage2D_impl,
4163 thread,
4164 GLTEXIMAGE2D_ID,
4165 RPC_ENUM(target),
4166 RPC_INT(level),
4167 RPC_ENUM(internalformat),
4168 RPC_SIZEI(width),
4169 RPC_SIZEI(height),
4170 RPC_INT(border),
4171 RPC_ENUM(format),
4172 RPC_ENUM(type),
4173 RPC_INT(state->alignment.unpack),
4174 NULL,
4175 0));
4176
4177 if (res && pixels && lines) {
4178 int offset = 0;
4179
4180 while (height > 0) {
4181 int32_t batch = _min(lines, (int32_t)height);
4182
4183 RPC_CALL10_IN_BULK(glTexSubImage2D_impl,
4184 thread,
4185 GLTEXSUBIMAGE2D_ID,
4186 RPC_ENUM(target),
4187 RPC_INT(level),
4188 RPC_INT(0),
4189 RPC_INT(offset),
4190 RPC_SIZEI(width),
4191 RPC_SIZEI(batch),
4192 RPC_ENUM(format),
4193 RPC_ENUM(type),
4194 RPC_INT(state->alignment.unpack),
4195 (char *)pixels + offset * pitch,
4196 batch * pitch);
4197
4198 offset += batch;
4199 height -= batch;
4200 }
4201 }
4202 }
4203}
4204
4205GL_API void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param)
4206{
4207 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4208 if (IS_OPENGLES_11_OR_20(thread)) {
4209 RPC_CALL3(glTexParameteri_impl,
4210 thread,
4211 GLTEXPARAMETERI_ID,
4212 RPC_ENUM(target),
4213 RPC_ENUM(pname),
4214 RPC_INT(param));
4215 }
4216}
4217
4218GL_API void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param)
4219{
4220 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4221 if (IS_OPENGLES_11_OR_20(thread)) {
4222 RPC_CALL3(glTexParameterf_impl,
4223 thread,
4224 GLTEXPARAMETERF_ID,
4225 RPC_ENUM(target),
4226 RPC_ENUM(pname),
4227 RPC_FLOAT(param));
4228 }
4229}
4230
4231GL_API void GL_APIENTRY glTexParameterx (GLenum target, GLenum pname, GLfixed param)
4232{
4233 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4234 if (IS_OPENGLES_11(thread)) {
4235 RPC_CALL3(glTexParameterx_impl_11,
4236 thread,
4237 GLTEXPARAMETERX_ID_11,
4238 RPC_ENUM(target),
4239 RPC_ENUM(pname),
4240 RPC_FIXED(param));
4241 }
4242}
4243
4244GL_API void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params)
4245{
4246 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4247 /*
4248 the only supported texture params are
4249
4250 TEXTURE_MIN_FILTER
4251 TEXTURE_MAG_FILTER
4252 TEXTURE_WRAP_S
4253 TEXTURE_WRAP_T
4254
4255 each of which takes a single argument
4256
4257 and for 1.1
4258 TEXTURE_CROP_RECT_OES
4259 which takes 4 ints
4260 */
4261
4262 if (IS_OPENGLES_11(thread)) {
4263 if(pname != GL_TEXTURE_CROP_RECT_OES) {
4264 glTexParameteri(target, pname, params[0]);
4265 }
4266 else {
4267 RPC_CALL3_IN_CTRL(glTexParameteriv_impl,
4268 thread,
4269 GLTEXPARAMETERIV_ID,
4270 RPC_ENUM(target),
4271 RPC_ENUM(pname),
4272 params,
4273 4 * sizeof(GLint));
4274 }
4275 }
4276 else if(IS_OPENGLES_20(thread))
4277 glTexParameteri(target, pname, params[0]);
4278}
4279
4280GL_API void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params)
4281{
4282 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4283 /*
4284 the only supported texture params are
4285
4286 TEXTURE_MIN_FILTER
4287 TEXTURE_MAG_FILTER
4288 TEXTURE_WRAP_S
4289 TEXTURE_WRAP_T
4290
4291 each of which takes a single argument
4292
4293 and for 1.1
4294 TEXTURE_CROP_RECT_OES
4295 which takes 4 ints
4296 */
4297
4298 if (IS_OPENGLES_11(thread)) {
4299 if(pname != GL_TEXTURE_CROP_RECT_OES) {
4300 glTexParameterf(target, pname, params[0]);
4301 }
4302 else {
4303 RPC_CALL3_IN_CTRL(glTexParameterfv_impl,
4304 thread,
4305 GLTEXPARAMETERFV_ID,
4306 RPC_ENUM(target),
4307 RPC_ENUM(pname),
4308 params,
4309 4 * sizeof(GLfloat));
4310 }
4311 }
4312 else if(IS_OPENGLES_20(thread))
4313 glTexParameterf(target, pname, params[0]);
4314}
4315
4316GL_API void GL_APIENTRY glTexParameterxv (GLenum target, GLenum pname, const GLfixed *params)
4317{
4318 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4319 /*
4320 the only supported texture params are
4321
4322 TEXTURE_MIN_FILTER
4323 TEXTURE_MAG_FILTER
4324 TEXTURE_WRAP_S
4325 TEXTURE_WRAP_T
4326
4327 each of which takes a single argument
4328
4329 and for 1.1
4330 TEXTURE_CROP_RECT_OES
4331 which takes 4 ints
4332 */
4333
4334 if (IS_OPENGLES_11(thread)) {
4335 if(pname != GL_TEXTURE_CROP_RECT_OES) {
4336 glTexParameterx(target, pname, params[0]);
4337 }
4338 else {
4339 RPC_CALL3_IN_CTRL(glTexParameterxv_impl_11,
4340 thread,
4341 GLTEXPARAMETERXV_ID_11,
4342 RPC_ENUM(target),
4343 RPC_ENUM(pname),
4344 params,
4345 4 * sizeof(GLfixed));
4346 }
4347 }
4348 else if(IS_OPENGLES_20(thread))
4349 glTexParameterx(target, pname, params[0]);
4350}
4351
4352GL_API void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
4353{
4354 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4355 if (IS_OPENGLES_11_OR_20(thread)) {
4356 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
4357
4358 uint32_t pitch = get_pitch( (uint32_t)width, format, type, (uint32_t)state->alignment.unpack);
4359 uint32_t lines = pitch ? (uint32_t)(KHDISPATCH_WORKSPACE_SIZE / pitch) : (uint32_t)height;
4360
4361 if (pixels && lines) {
4362 int offset = 0;
4363
4364 while (height > 0) {
4365 int32_t batch = _min(lines, (int32_t)height);
4366
4367 RPC_CALL10_IN_BULK(glTexSubImage2D_impl,
4368 thread,
4369 GLTEXSUBIMAGE2D_ID,
4370 RPC_ENUM(target),
4371 RPC_INT(level),
4372 RPC_INT(xoffset),
4373 RPC_INT(yoffset+offset),
4374 RPC_SIZEI(width),
4375 RPC_SIZEI(batch),
4376 RPC_ENUM(format),
4377 RPC_ENUM(type),
4378 RPC_INT(state->alignment.unpack),
4379 (char *)pixels + offset * pitch,
4380 batch * pitch);
4381
4382 offset += batch;
4383 height -= batch;
4384 }
4385 }
4386 }
4387}
4388
4389GL_API void GL_APIENTRY texSubImage2DAsync (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLint hpixels)
4390{
4391 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4392 if (IS_OPENGLES_11_OR_20(thread)) {
4393
4394 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
4395 RPC_CALL10(texSubImage2DAsync_impl,
4396 thread,
4397 TEXSUBIMAGE2DASYNC_ID,
4398 RPC_ENUM(target),
4399 RPC_INT(level),
4400 RPC_INT(xoffset),
4401 RPC_INT(yoffset),
4402 RPC_SIZEI(width),
4403 RPC_SIZEI(height),
4404 RPC_ENUM(format),
4405 RPC_ENUM(type),
4406 RPC_INT(state->alignment.unpack),
4407 RPC_INT(hpixels));
4408 }
4409}
4410
4411GL_API void GL_APIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z)
4412{
4413 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4414 if (IS_OPENGLES_11(thread)) {
4415 RPC_CALL3(glTranslatef_impl_11,
4416 thread,
4417 GLTRANSLATEF_ID_11,
4418 RPC_FLOAT(x),
4419 RPC_FLOAT(y),
4420 RPC_FLOAT(z));
4421 }
4422}
4423
4424GL_API void GL_APIENTRY glTranslatex (GLfixed x, GLfixed y, GLfixed z)
4425{
4426 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4427 if (IS_OPENGLES_11(thread)) {
4428 RPC_CALL3(glTranslatex_impl_11,
4429 thread,
4430 GLTRANSLATEX_ID_11,
4431 RPC_FIXED(x),
4432 RPC_FIXED(y),
4433 RPC_FIXED(z));
4434 }
4435}
4436
4437GL_API void GL_APIENTRY glUniform1i (GLint location, GLint x)
4438{
4439 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4440 if (IS_OPENGLES_20(thread)) {
4441 RPC_CALL2(glUniform1i_impl_20,
4442 thread,
4443 GLUNIFORM1I_ID_20,
4444 RPC_INT(location),
4445 RPC_INT(x));
4446 }
4447}
4448
4449GL_API void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y)
4450{
4451 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4452 if (IS_OPENGLES_20(thread)) {
4453 RPC_CALL3(glUniform2i_impl_20,
4454 thread,
4455 GLUNIFORM2I_ID_20,
4456 RPC_INT(location),
4457 RPC_INT(x),
4458 RPC_INT(y));
4459 }
4460}
4461
4462GL_API void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z)
4463{
4464 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4465 if (IS_OPENGLES_20(thread)) {
4466 RPC_CALL4(glUniform3i_impl_20,
4467 thread,
4468 GLUNIFORM3I_ID_20,
4469 RPC_INT(location),
4470 RPC_INT(x),
4471 RPC_INT(y),
4472 RPC_INT(z));
4473 }
4474}
4475
4476GL_API void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w)
4477{
4478 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4479 if (IS_OPENGLES_20(thread)) {
4480 RPC_CALL5(glUniform4i_impl_20,
4481 thread,
4482 GLUNIFORM4I_ID_20,
4483 RPC_INT(location),
4484 RPC_INT(x),
4485 RPC_INT(y),
4486 RPC_INT(z),
4487 RPC_INT(w));
4488 }
4489}
4490
4491GL_API void GL_APIENTRY glUniform1f (GLint location, GLfloat x)
4492{
4493 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4494 if (IS_OPENGLES_20(thread)) {
4495 RPC_CALL2(glUniform1f_impl_20,
4496 thread,
4497 GLUNIFORM1F_ID_20,
4498 RPC_INT(location),
4499 RPC_FLOAT(x));
4500 }
4501}
4502
4503GL_API void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y)
4504{
4505 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4506 if (IS_OPENGLES_20(thread)) {
4507 RPC_CALL3(glUniform2f_impl_20,
4508 thread,
4509 GLUNIFORM2F_ID_20,
4510 RPC_INT(location),
4511 RPC_FLOAT(x),
4512 RPC_FLOAT(y));
4513 }
4514}
4515
4516GL_API void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z)
4517{
4518 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4519 if (IS_OPENGLES_20(thread)) {
4520 RPC_CALL4(glUniform3f_impl_20,
4521 thread,
4522 GLUNIFORM3F_ID_20,
4523 RPC_INT(location),
4524 RPC_FLOAT(x),
4525 RPC_FLOAT(y),
4526 RPC_FLOAT(z));
4527 }
4528}
4529
4530GL_API void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4531{
4532 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4533 if (IS_OPENGLES_20(thread)) {
4534 RPC_CALL5(glUniform4f_impl_20,
4535 thread,
4536 GLUNIFORM4F_ID_20,
4537 RPC_INT(location),
4538 RPC_FLOAT(x),
4539 RPC_FLOAT(y),
4540 RPC_FLOAT(z),
4541 RPC_FLOAT(w));
4542 }
4543}
4544
4545/*
4546 clamp the size of uniform data to the maximum conceivable value (128 vec4s)
4547*/
4548
4549#define MAX_UNIFORM_SIZE 2048
4550
4551static INLINE int clamp_uniform_size(int size)
4552{
4553 return (int) _min( (int32_t)size, MAX_UNIFORM_SIZE);
4554}
4555
4556GL_API void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *v)
4557{
4558 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4559 if (IS_OPENGLES_20(thread)) {
4560 int size = clamp_uniform_size( (int)(count * 1 * sizeof(GLint)));
4561
4562 RPC_CALL4_IN_CTRL(glUniform1iv_impl_20,
4563 thread,
4564 GLUNIFORM1IV_ID_20,
4565 RPC_INT(location),
4566 RPC_SIZEI(count),
4567 RPC_INT(size),
4568 v,
4569 (size_t)size);
4570 }
4571}
4572
4573GL_API void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *v)
4574{
4575 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4576 if (IS_OPENGLES_20(thread)) {
4577 int size = clamp_uniform_size( (int)(count * 2 * sizeof(GLint)));
4578
4579 RPC_CALL4_IN_CTRL(glUniform2iv_impl_20,
4580 thread,
4581 GLUNIFORM2IV_ID_20,
4582 RPC_INT(location),
4583 RPC_SIZEI(count),
4584 RPC_INT(size),
4585 v,
4586 (size_t)size);
4587 }
4588}
4589
4590GL_API void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *v)
4591{
4592 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4593 if (IS_OPENGLES_20(thread)) {
4594 int size = clamp_uniform_size( (int)(count * 3 * sizeof(GLint)));
4595
4596 RPC_CALL4_IN_CTRL(glUniform3iv_impl_20,
4597 thread,
4598 GLUNIFORM3IV_ID_20,
4599 RPC_INT(location),
4600 RPC_SIZEI(count),
4601 RPC_INT(size),
4602 v,
4603 (size_t)size);
4604 }
4605}
4606
4607GL_API void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *v)
4608{
4609 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4610 if (IS_OPENGLES_20(thread)) {
4611 int size = clamp_uniform_size( (int)(count * 4 * sizeof(GLint)));
4612
4613 RPC_CALL4_IN_CTRL(glUniform4iv_impl_20,
4614 thread,
4615 GLUNIFORM4IV_ID_20,
4616 RPC_INT(location),
4617 RPC_SIZEI(count),
4618 RPC_INT(size),
4619 v,
4620 (size_t)size);
4621 }
4622}
4623
4624GL_API void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *v)
4625{
4626 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4627 if (IS_OPENGLES_20(thread)) {
4628 int size = clamp_uniform_size( (int)(count * 1 * sizeof(GLfloat)));
4629
4630 RPC_CALL4_IN_CTRL(glUniform1fv_impl_20,
4631 thread,
4632 GLUNIFORM1FV_ID_20,
4633 RPC_INT(location),
4634 RPC_SIZEI(count),
4635 RPC_INT(size),
4636 v,
4637 (size_t)size);
4638 }
4639}
4640
4641GL_API void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *v)
4642{
4643 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4644 if (IS_OPENGLES_20(thread)) {
4645 int size = clamp_uniform_size( (int)(count * 2 * sizeof(GLfloat)));
4646
4647 RPC_CALL4_IN_CTRL(glUniform2fv_impl_20,
4648 thread,
4649 GLUNIFORM2FV_ID_20,
4650 RPC_INT(location),
4651 RPC_SIZEI(count),
4652 RPC_INT(size),
4653 v,
4654 (size_t)size);
4655 }
4656}
4657
4658GL_API void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *v)
4659{
4660 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4661 if (IS_OPENGLES_20(thread)) {
4662 int size = clamp_uniform_size( (int)(count * 3 * sizeof(GLfloat)));
4663
4664 RPC_CALL4_IN_CTRL(glUniform3fv_impl_20,
4665 thread,
4666 GLUNIFORM3FV_ID_20,
4667 RPC_INT(location),
4668 RPC_SIZEI(count),
4669 RPC_INT(size),
4670 v,
4671 (size_t)size);
4672 }
4673}
4674
4675GL_API void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *v)
4676{
4677 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4678 if (IS_OPENGLES_20(thread)) {
4679 int size = clamp_uniform_size( (int)(count * 4 * sizeof(GLfloat)));
4680
4681 RPC_CALL4_IN_CTRL(glUniform4fv_impl_20,
4682 thread,
4683 GLUNIFORM4FV_ID_20,
4684 RPC_INT(location),
4685 RPC_SIZEI(count),
4686 RPC_INT(size),
4687 v,
4688 (size_t)size);
4689 }
4690}
4691
4692/*
4693 If transpose is GL_FALSE, each matrix is assumed to be supplied in column major order.
4694 If transpose is GL_TRUE, each matrix is assumed to be supplied in row major order.
4695*/
4696
4697GL_API void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4698{
4699 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4700 if (IS_OPENGLES_20(thread)) {
4701 int size = clamp_uniform_size( (int)(count * 2 * 2 * sizeof(GLfloat)));
4702
4703 RPC_CALL5_IN_CTRL(glUniformMatrix2fv_impl_20,
4704 thread,
4705 GLUNIFORMMATRIX2FV_ID_20,
4706 RPC_INT(location),
4707 RPC_SIZEI(count),
4708 RPC_BOOLEAN(transpose),
4709 RPC_INT(size),
4710 value,
4711 (size_t)size);
4712 }
4713}
4714
4715GL_API void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4716{
4717 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4718 if (IS_OPENGLES_20(thread)) {
4719 int size = clamp_uniform_size( (int)(count * 3 * 3 * sizeof(GLfloat)));
4720
4721 RPC_CALL5_IN_CTRL(glUniformMatrix3fv_impl_20,
4722 thread,
4723 GLUNIFORMMATRIX3FV_ID_20,
4724 RPC_INT(location),
4725 RPC_SIZEI(count),
4726 RPC_BOOLEAN(transpose),
4727 RPC_INT(size),
4728 value,
4729 (size_t)size);
4730 }
4731}
4732
4733GL_API void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4734{
4735 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4736 if (IS_OPENGLES_20(thread)) {
4737 int size = clamp_uniform_size( (int)(count * 4 * 4 * sizeof(GLfloat)));
4738
4739 RPC_CALL5_IN_CTRL(glUniformMatrix4fv_impl_20,
4740 thread,
4741 GLUNIFORMMATRIX4FV_ID_20,
4742 RPC_INT(location),
4743 RPC_SIZEI(count),
4744 RPC_BOOLEAN(transpose),
4745 RPC_INT(size),
4746 value,
4747 (size_t)size);
4748 }
4749}
4750
4751GL_API void GL_APIENTRY glUseProgram (GLuint program) // S
4752{
4753 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4754 if (IS_OPENGLES_20(thread)) {
4755 RPC_CALL1(glUseProgram_impl_20,
4756 thread,
4757 GLUSEPROGRAM_ID_20,
4758 RPC_UINT(program));
4759 }
4760}
4761
4762GL_API void GL_APIENTRY glValidateProgram (GLuint program)
4763{
4764 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4765 if (IS_OPENGLES_20(thread)) {
4766 RPC_CALL1(glValidateProgram_impl_20,
4767 thread,
4768 GLVALIDATEPROGRAM_ID_20,
4769 RPC_UINT(program));
4770 }
4771}
4772
4773GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x)
4774{
4775 glintAttrib(GLXX_API_20, indx, x, 0.0f, 0.0f, 1.0f);
4776}
4777
4778GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y)
4779{
4780 glintAttrib(GLXX_API_20, indx, x, y, 0.0f, 1.0f);
4781}
4782
4783GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z)
4784{
4785 glintAttrib(GLXX_API_20, indx, x, y, z, 1.0f);
4786}
4787
4788GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4789{
4790 glintAttrib(GLXX_API_20, indx, x, y, z, w);
4791}
4792
4793GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat *values)
4794{
4795 glintAttrib(GLXX_API_20, indx, values[0], 0.0f, 0.0f, 1.0f);
4796}
4797
4798GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat *values)
4799{
4800 glintAttrib(GLXX_API_20, indx, values[0], values[1], 0.0f, 1.0f);
4801}
4802
4803GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat *values)
4804{
4805 glintAttrib(GLXX_API_20, indx, values[0], values[1], values[2], 1.0f);
4806}
4807
4808GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat *values)
4809{
4810 glintAttrib(GLXX_API_20, indx, values[0], values[1], values[2], values[3]);
4811}
4812
4813static bool is_vertex_attrib_size(GLint size)
4814{
4815 return size >= 1 && size <= 4;
4816}
4817
4818static bool is_vertex_attrib_type(GLenum type)
4819{
4820 return type == GL_BYTE ||
4821 type == GL_UNSIGNED_BYTE ||
4822 type == GL_SHORT ||
4823 type == GL_UNSIGNED_SHORT ||
4824 type == GL_FLOAT ||
4825 type == GL_FIXED ||
4826 type == GL_HALF_FLOAT_OES;
4827}
4828
4829GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr)
4830{
4831 if (is_vertex_attrib_size(size) && stride >= 0) {
4832 if (is_vertex_attrib_type(type) || type == GL_HALF_FLOAT_OES) {
4833 glintAttribPointer(GLXX_API_20, indx, size, type, normalized, stride, ptr);
4834 } else
4835 glxx_set_error_api(GLXX_API_20, GL_INVALID_ENUM);
4836 } else
4837 glxx_set_error_api(GLXX_API_20, GL_INVALID_VALUE);
4838}
4839
4840static bool is_vertex_size(GLint size)
4841{
4842 return size == 2 ||
4843 size == 3 ||
4844 size == 4;
4845}
4846
4847static bool is_vertex_type(GLenum type)
4848{
4849 return type == GL_BYTE ||
4850 type == GL_SHORT ||
4851 type == GL_FIXED ||
4852 type == GL_FLOAT;
4853}
4854
4855GL_API void GL_APIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
4856{
4857 if (is_vertex_type(type)) {
4858 if (is_vertex_size(size) && is_aligned(type, (size_t)pointer) && is_aligned(type, (size_t)stride) && stride >= 0) {
4859 glintAttribPointer(GLXX_API_11, GL11_IX_VERTEX, size, type, GL_FALSE, stride, pointer);
4860 } else
4861 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
4862 } else
4863 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
4864}
4865
4866GL_API void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height)
4867{
4868 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4869 if (IS_OPENGLES_11_OR_20(thread)) {
4870 RPC_CALL4(glViewport_impl,
4871 thread,
4872 GLVIEWPORT_ID,
4873 RPC_INT(x),
4874 RPC_INT(y),
4875 RPC_SIZEI(width),
4876 RPC_SIZEI(height));
4877 }
4878}
4879/*****************************************************************************************/
4880/* OES extension functions */
4881/*****************************************************************************************/
4882
4883static bool is_point_size_type(GLenum type)
4884{
4885 return type == GL_FIXED ||
4886 type == GL_FLOAT;
4887}
4888
4889GL_API void GL_APIENTRY glPointSizePointerOES (GLenum type, GLsizei stride, const GLvoid *pointer)
4890{
4891 if (is_point_size_type(type)) {
4892 if (is_aligned(type, (size_t)pointer) && is_aligned(type, (size_t)stride) && stride >= 0) {
4893 glintAttribPointer(GLXX_API_11, GL11_IX_POINT_SIZE, 1, type, GL_FALSE, stride, pointer);
4894 } else
4895 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
4896 } else
4897 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
4898}
4899
4900/* OES_shader_source */
4901GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader)
4902{
4903 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4904 if (IS_OPENGLES_20(thread)) {
4905 RPC_CALL1(glCompileShader_impl_20,
4906 thread,
4907 GLCOMPILESHADER_ID_20,
4908 RPC_UINT(shader));
4909 }
4910}
4911
4912GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params)
4913{
4914 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4915 if (IS_OPENGLES_20(thread)) {
4916 RPC_CALL3_OUT_CTRL(glGetShaderiv_impl_20,
4917 thread,
4918 GLGETSHADERIV_ID_20,
4919 RPC_ENUM(shader),
4920 RPC_ENUM(pname),
4921 params);
4922 }
4923}
4924
4925GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei *length, char *infolog)
4926{
4927 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4928 if (IS_OPENGLES_20(thread)) {
4929#ifdef RPC_DIRECT
4930 RPC_CALL4(glGetShaderInfoLog_impl_20, thread, no_id, shader, bufsize, length, infolog);
4931#else
4932 GLuint result[1];
4933
4934 rpc_begin(thread);
4935
4936 RPC_CALL3_OUT_CTRL(no_function,
4937 thread,
4938 GLGETSHADERINFOLOG_ID_20,
4939 RPC_UINT(shader),
4940 RPC_SIZEI(bufsize),
4941 result);
4942
4943 if (length)
4944 *length = (GLsizei)result[0];
4945
4946 read_out_bulk(thread, infolog);
4947
4948 rpc_end(thread);
4949#endif
4950 }
4951}
4952
4953GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei *length, char *source)
4954{
4955 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4956 if (IS_OPENGLES_20(thread)) {
4957#ifdef RPC_DIRECT
4958 RPC_CALL4(glGetShaderSource_impl_20, thread, no_id, shader, bufsize, length, source);
4959#else
4960 GLuint result[1];
4961
4962 rpc_begin(thread);
4963
4964 RPC_CALL3_OUT_CTRL(no_function,
4965 thread,
4966 GLGETSHADERSOURCE_ID_20,
4967 RPC_UINT(shader),
4968 RPC_SIZEI(bufsize),
4969 result);
4970
4971 if (length)
4972 *length = (GLsizei)result[0];
4973
4974 read_out_bulk(thread, source);
4975
4976 rpc_end(thread);
4977#endif
4978 }
4979}
4980
4981GL_APICALL void GL_APIENTRY glReleaseShaderCompiler(void)
4982{
4983 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4984 if (IS_OPENGLES_20(thread)) {
4985 }
4986}
4987
4988GL_APICALL void GL_APIENTRY glShaderBinary (GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
4989{
4990 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4991 UNUSED(n);
4992 UNUSED(shaders);
4993 UNUSED(binaryformat);
4994 UNUSED(binary);
4995 UNUSED(length);
4996
4997 if (IS_OPENGLES_20(thread)) {
4998 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
4999 set_error(state, GL_INVALID_ENUM);
5000 }
5001}
5002
5003GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const char **string, const GLint *length)
5004{
5005 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5006 if (IS_OPENGLES_20(thread)) {
5007#ifdef RPC_DIRECT
5008 RPC_CALL4(glShaderSource_impl_20, thread, no_id, shader,
5009 count,
5010 string,
5011 length);
5012#else
5013 /*
5014 calculate total workspace required for string, length and source
5015 */
5016#ifdef __SYMBIAN32__
5017
5018 int total = (int)(rpc_pad_bulk(count * 4) + rpc_pad_bulk(count * 4));
5019 int i;
5020
5021 for (i = 0; i < count; i++) {
5022 if (!length || length[i] < 0)
5023 total += rpc_pad_bulk(string[i] ? (int)strlen(string[i]) + 1 : 1);
5024 else
5025 total += rpc_pad_bulk(length[i]);
5026 }
5027
5028 rpc_begin(thread);
5029
5030 // Assume worst-case (need to compute and send all lengths) - include
5031 // the 5 words we're sending in the RPC_CALL4() (do we need to do this?)
5032 //
5033 rpc_send_ctrl_begin(thread, (count + 5) * sizeof(GLint) );
5034
5035 RPC_CALL4(no_function,
5036 thread,
5037 GLSHADERSOURCE_ID_20,
5038 RPC_UINT(shader),
5039 RPC_SIZEI(count),
5040 RPC_INT(total),
5041 RPC_BOOLEAN(length ? 1 : 0));
5042
5043 if (length)
5044 rpc_send_bulk(thread, length, count * sizeof(GLint));
5045
5046//Send all lengths before the first bulk transfer of a line of source code
5047//NB this is a temporary fix until issues, with our bulk transfers and the
5048//rpc assumptions, have been resolved
5049//NB assumes that the line count numbers all fit in the merge buffer
5050//which is why a more permanent fix is needed
5051 for (i = 0; i < count; i++) {
5052 GLint len;
5053
5054 if (!length || length[i] < 0) {
5055 len = string[i] ? (GLint) strlen(string[i]) + 1 : 1;
5056
5057// rpc_send_bulk(&len, sizeof(GLint)); /* todo: this now violates the semantics of rpc_send_bulk. todo: check for other violations in GL */
5058
5059 rpc_send_ctrl_write(thread, (uint32_t *)&len, sizeof(GLint));
5060 }
5061 }
5062
5063 rpc_send_ctrl_end(thread); //no more ctrl data to send
5064
5065 for (i = 0; i < count; i++) {
5066 GLint len;
5067
5068 if (!length || length[i] < 0) {
5069 len = string[i] ? strlen(string[i]) + 1 : 1;
5070 } else
5071 len = length[i];
5072
5073 /* TODO: we currently treat null strings as empty strings
5074 * But we shouldn't need to deal with them (VND-116)
5075 */
5076 rpc_send_bulk(thread, string[i] ? string[i] : "", (uint32_t)len);
5077 }
5078 rpc_end(thread);
5079#else
5080 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5081 int total = (int)(rpc_pad_bulk(count * 4) + rpc_pad_bulk(count * 4) + rpc_pad_bulk(sizeof(GLint)));
5082 int i;
5083
5084 for (i = 0; i < count; i++)
5085 if (!length || length[i] < 0)
5086 total += rpc_pad_bulk(string[i] ? (int)strlen(string[i]) + 1 : 1);
5087 else
5088 total += rpc_pad_bulk(length[i]);
5089
5090 rpc_begin(thread);
5091
5092 RPC_CALL4(no_function,
5093 thread,
5094 GLSHADERSOURCE_ID_20,
5095 RPC_UINT(shader),
5096 RPC_SIZEI(count),
5097 RPC_INT(total),
5098 RPC_BOOLEAN(length ? 1 : 0));
5099
5100 if (length)
5101 rpc_send_bulk(thread, length, count * sizeof(GLint));
5102
5103 for (i = 0; i < count; i++) {
5104 GLint len;
5105
5106 if (!length || length[i] < 0) {
5107 len = string[i] ? (GLint) strlen(string[i]) + 1 : 1;
5108
5109 rpc_send_bulk(thread, &len, sizeof(GLint)); /* todo: this now violates the semantics of rpc_send_bulk. todo: check for other violations in GL */
5110 } else
5111 len = length[i];
5112
5113 /* TODO: we currently treat null strings as empty strings
5114 * But we shouldn't need to deal with them (VND-116)
5115 */
5116 rpc_send_bulk(thread, string[i] ? string[i] : "", (uint32_t)len);
5117 }
5118
5119 rpc_end(thread);
5120#endif
5121#endif
5122 }
5123}
5124
5125/* OES_framebuffer_object */
5126
5127GLboolean glxx_client_IsRenderbuffer(GLuint renderbuffer)
5128{
5129 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5130 if (IS_OPENGLES_11_OR_20(thread)) {
5131 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsRenderbuffer_impl,
5132 thread,
5133 GLISRENDERBUFFER_ID,
5134 RPC_UINT(renderbuffer)));
5135 }
5136
5137 return 0;
5138}
5139
5140
5141GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
5142{
5143 return glxx_client_IsRenderbuffer(renderbuffer);
5144}
5145
5146void glxx_client_BindRenderbuffer(GLenum target, GLuint renderbuffer)
5147{
5148 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5149 if (IS_OPENGLES_11_OR_20(thread)) {
5150 RPC_CALL2(glBindRenderbuffer_impl,
5151 thread,
5152 GLBINDRENDERBUFFER_ID,
5153 RPC_ENUM(target),
5154 RPC_UINT(renderbuffer));
5155 }
5156}
5157
5158GL_APICALL void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
5159{
5160 glxx_client_BindRenderbuffer(target, renderbuffer);
5161}
5162
5163
5164void glxx_client_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
5165{
5166 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5167 int offset = 0;
5168
5169 do {
5170 int32_t items = (int32_t) (KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
5171 int32_t batch = _min(items, (int32_t)n);
5172
5173 if (IS_OPENGLES_11_OR_20(thread)) {
5174 RPC_CALL2_IN_BULK(glDeleteRenderbuffers_impl,
5175 thread,
5176 GLDELETERENDERBUFFERS_ID,
5177 RPC_SIZEI(batch),
5178 renderbuffers + offset,
5179 batch > 0 ? batch * sizeof(GLuint) : 0);
5180 }
5181
5182 offset += batch;
5183 n -= batch;
5184 } while (n > 0);
5185}
5186
5187GL_APICALL void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
5188{
5189 glxx_client_DeleteRenderbuffers(n, renderbuffers);
5190}
5191
5192void glxx_client_GenRenderbuffers(GLsizei n, GLuint *renderbuffers)
5193{
5194 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5195 int offset = 0;
5196
5197 do {
5198 int32_t items = (int32_t)(KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
5199 int32_t batch = _min(items, (int32_t)n);
5200
5201 if (IS_OPENGLES_11_OR_20(thread)) {
5202 RPC_CALL2_OUT_BULK(glGenRenderbuffers_impl,
5203 thread,
5204 GLGENRENDERBUFFERS_ID,
5205 RPC_SIZEI(batch),
5206 renderbuffers + offset);
5207 }
5208
5209 offset += batch;
5210 n -= batch;
5211 } while (n > 0);
5212}
5213
5214GL_APICALL void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint *renderbuffers)
5215{
5216 glxx_client_GenRenderbuffers(n, renderbuffers);
5217}
5218
5219void glxx_client_RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
5220{
5221 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5222 if (IS_OPENGLES_11_OR_20(thread)) {
5223 RPC_CALL4(glRenderbufferStorage_impl,
5224 thread,
5225 GLRENDERBUFFERSTORAGE_ID,
5226 RPC_ENUM(target),
5227 RPC_ENUM(internalformat),
5228 RPC_SIZEI(width),
5229 RPC_SIZEI(height));
5230 }
5231}
5232
5233GL_APICALL void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
5234{
5235 glxx_client_RenderbufferStorage(target, internalformat, width, height);
5236}
5237
5238void glxx_client_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
5239{
5240 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5241 if (IS_OPENGLES_11_OR_20(thread)) {
5242 RPC_CALL3_OUT_CTRL(glGetRenderbufferParameteriv_impl,
5243 thread,
5244 GLGETRENDERBUFFERPARAMETERIV_ID,
5245 RPC_ENUM(target),
5246 RPC_ENUM(pname),
5247 params);
5248 }
5249}
5250
5251GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
5252{
5253 glxx_client_GetRenderbufferParameteriv(target, pname, params);
5254}
5255
5256GLboolean glxx_client_IsFramebuffer(GLuint framebuffer)
5257{
5258 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5259 if (IS_OPENGLES_11_OR_20(thread)) {
5260 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsFramebuffer_impl,
5261 thread,
5262 GLISFRAMEBUFFER_ID,
5263 RPC_UINT(framebuffer)));
5264 }
5265
5266 return 0;
5267}
5268
5269GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
5270{
5271 return glxx_client_IsFramebuffer(framebuffer);
5272}
5273
5274/*
5275 Spec deviation:
5276 eglMakeCurrent(gles2.0 context, pixmap surface)
5277 glBindFramebuffer(invalid framebuffer id)
5278 glDrawSomeStuff()
5279 glFinish()
5280 Pixmap will not have been updated, as client assumes that rendering is
5281 taking place outside of the default framebuffer
5282*/
5283
5284void glxx_client_BindFramebuffer(GLenum target, GLuint framebuffer)
5285{
5286 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5287 if (IS_OPENGLES_11_OR_20(thread)) {
5288 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5289 RPC_CALL2(glBindFramebuffer_impl,
5290 thread,
5291 GLBINDFRAMEBUFFER_ID,
5292 RPC_ENUM(target),
5293 RPC_UINT(framebuffer));
5294
5295 //TODO: this may be set incorrectly if there's an error
5296 state->default_framebuffer = (framebuffer == 0);
5297 }
5298}
5299
5300GL_APICALL void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
5301{
5302 glxx_client_BindFramebuffer(target, framebuffer);
5303}
5304
5305void glxx_client_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
5306{
5307 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5308 int offset = 0;
5309
5310 do {
5311 int32_t items = (int32_t)(KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
5312 int32_t batch = _min(items, (int32_t)n);
5313
5314 if (IS_OPENGLES_11_OR_20(thread)) {
5315 RPC_CALL2_IN_BULK(glDeleteFramebuffers_impl,
5316 thread,
5317 GLDELETEFRAMEBUFFERS_ID,
5318 RPC_SIZEI(batch),
5319 framebuffers + offset,
5320 batch > 0 ? batch * sizeof(GLuint) : 0);
5321 }
5322
5323 offset += batch;
5324 n -= batch;
5325 } while (n > 0);
5326}
5327
5328GL_APICALL void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
5329{
5330 glxx_client_DeleteFramebuffers(n, framebuffers);
5331}
5332
5333void glxx_client_GenFramebuffers(GLsizei n, GLuint *framebuffers)
5334{
5335 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5336 int offset = 0;
5337
5338 do {
5339 int32_t items = (int32_t)(KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
5340 int32_t batch = _min(items, (int32_t)n);
5341
5342 if (IS_OPENGLES_11_OR_20(thread)) {
5343 RPC_CALL2_OUT_BULK(glGenFramebuffers_impl,
5344 thread,
5345 GLGENFRAMEBUFFERS_ID,
5346 RPC_SIZEI(batch),
5347 framebuffers + offset);
5348 }
5349
5350 offset += batch;
5351 n -= batch;
5352 } while (n > 0);
5353}
5354
5355GL_APICALL void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers)
5356{
5357 glxx_client_GenFramebuffers(n, framebuffers);
5358}
5359
5360GLenum glxx_client_CheckFramebufferStatus(GLenum target)
5361{
5362 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5363 if (IS_OPENGLES_11_OR_20(thread)) {
5364 return RPC_ENUM_RES(RPC_CALL1_RES(glCheckFramebufferStatus_impl,
5365 thread,
5366 GLCHECKFRAMEBUFFERSTATUS_ID,
5367 RPC_ENUM(target)));
5368 }
5369
5370 return GL_NONE;
5371}
5372
5373GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
5374{
5375 return glxx_client_CheckFramebufferStatus(target);
5376}
5377
5378void glxx_client_FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
5379{
5380 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5381 if (IS_OPENGLES_11_OR_20(thread)) {
5382 RPC_CALL5(glFramebufferTexture2D_impl,
5383 thread,
5384 GLFRAMEBUFFERTEXTURE2D_ID,
5385 RPC_ENUM(target),
5386 RPC_ENUM(attachment),
5387 RPC_ENUM(textarget),
5388 RPC_UINT(texture),
5389 RPC_INT(level));
5390 }
5391}
5392
5393GL_APICALL void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
5394{
5395 glxx_client_FramebufferTexture2D(target, attachment, textarget, texture, level);
5396}
5397
5398void glxx_client_FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
5399{
5400 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5401 if (IS_OPENGLES_11_OR_20(thread)) {
5402 RPC_CALL4(glFramebufferRenderbuffer_impl,
5403 thread,
5404 GLFRAMEBUFFERRENDERBUFFER_ID,
5405 RPC_ENUM(target),
5406 RPC_ENUM(attachment),
5407 RPC_ENUM(renderbuffertarget),
5408 RPC_UINT(renderbuffer));
5409 }
5410}
5411
5412GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
5413{
5414 glxx_client_FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
5415}
5416
5417void glxx_client_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params)
5418{
5419 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5420 if (IS_OPENGLES_11_OR_20(thread)) {
5421 RPC_CALL4_OUT_CTRL(glGetFramebufferAttachmentParameteriv_impl,
5422 thread,
5423 GLGETFRAMEBUFFERATTACHMENTPARAMETERIV_ID,
5424 RPC_ENUM(target),
5425 RPC_ENUM(attachment),
5426 RPC_ENUM(pname),
5427 params);
5428 }
5429}
5430
5431GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params)
5432{
5433 glxx_client_GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
5434}
5435
5436void glxx_client_GenerateMipmap(GLenum target)
5437{
5438 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5439 if (IS_OPENGLES_11_OR_20(thread)) {
5440 RPC_CALL1(glGenerateMipmap_impl,
5441 thread,
5442 GLGENERATEMIPMAP_ID,
5443 RPC_ENUM(target));
5444 }
5445}
5446
5447GL_APICALL void GL_APIENTRY glGenerateMipmap(GLenum target)
5448{
5449 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5450 if (IS_OPENGLES_20(thread)) {
5451 glxx_client_GenerateMipmap(target);
5452 }
5453}
5454
5455/* OES_shader_source + OES_shader_binary */
5456GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision)
5457{
5458 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5459 if (IS_OPENGLES_20(thread)) {
5460 GLint result[3];
5461
5462 RPC_CALL3_OUT_CTRL(glGetShaderPrecisionFormat_impl_20,
5463 thread,
5464 GLGETSHADERPRECISIONFORMAT_ID_20,
5465 RPC_ENUM(shadertype),
5466 RPC_ENUM(precisiontype),
5467 result);
5468
5469 if (range) {
5470 range[0] = result[0];
5471 range[1] = result[1];
5472 }
5473 if (precision)
5474 *precision = result[2];
5475 }
5476}
5477
5478GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments)
5479{
5480 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5481 if (IS_OPENGLES_11_OR_20(thread))
5482 {
5483 RPC_CALL3_IN_CTRL(glDiscardFramebufferEXT_impl,
5484 thread,
5485 GLDISCARDFRAMEBUFFEREXT_ID,
5486 RPC_ENUM(target),
5487 RPC_SIZEI(numAttachments),
5488 attachments,
5489 numAttachments * sizeof(GLenum));
5490 }
5491}
5492
5493static void glxx_client_state_init(GLXX_CLIENT_STATE_T *state)
5494{
5495 int i;
5496
5497 state->error = GL_NO_ERROR;
5498
5499 state->alignment.pack = 4;
5500 state->alignment.unpack = 4;
5501
5502 state->bound_buffer.array = 0;
5503 state->bound_buffer.element_array = 0;
5504
5505 for (i = 0; i < GLXX_CONFIG_MAX_VERTEX_ATTRIBS; i++) {
5506 state->attrib[i].enabled = GL_FALSE;
5507 state->attrib[i].size = 4;
5508 state->attrib[i].type = GL_FLOAT;
5509 state->attrib[i].normalized = GL_FALSE;
5510 state->attrib[i].stride = 0;
5511 state->attrib[i].pointer = NULL;
5512 state->attrib[i].buffer = 0;
5513 state->attrib[i].value[0] = 0.0f;
5514 state->attrib[i].value[1] = 0.0f;
5515 state->attrib[i].value[2] = 0.0f;
5516 state->attrib[i].value[3] = 1.0f;
5517 }
5518
5519 state->render_callback = NULL;
5520 state->flush_callback = NULL;
5521
5522 //buffer info
5523 khrn_pointer_map_init(&state->buffers,8);
5524
5525}
5526
5527int gl11_client_state_init(GLXX_CLIENT_STATE_T *state)
5528{
5529 state->type = OPENGL_ES_11;
5530
5531 //perform common initialisation
5532 glxx_client_state_init(state);
5533 //gl2.0 specific
5534
5535 state->active_texture.client = GL_TEXTURE0;
5536 state->active_texture.server = GL_TEXTURE0;
5537
5538 gl11_attrib_init(state->attrib);
5539
5540#ifdef GLXX_NO_VERTEX_CACHE
5541 return 1;
5542#else
5543 return khrn_cache_init(&state->cache);
5544#endif
5545}
5546
5547int gl20_client_state_init(GLXX_CLIENT_STATE_T *state)
5548{
5549 state->type = OPENGL_ES_20;
5550
5551 //perform common initialisation
5552 glxx_client_state_init(state);
5553 //gl2.0 specific
5554
5555 state->default_framebuffer = true;
5556
5557 gl20_attrib_init(state->attrib);
5558
5559#ifdef GLXX_NO_VERTEX_CACHE
5560 return 1;
5561#else
5562 return khrn_cache_init(&state->cache);
5563#endif
5564}
5565
5566static void callback_delete_buffer_info(KHRN_POINTER_MAP_T *map, uint32_t key, void *value, void *data)
5567{
5568 UNUSED(map);
5569 UNUSED(data);
5570 UNUSED(key);
5571 khrn_platform_free(value);
5572}
5573
5574void glxx_client_state_free(GLXX_CLIENT_STATE_T *state)
5575{
5576 khrn_pointer_map_iterate(&state->buffers, callback_delete_buffer_info, NULL);
5577 khrn_pointer_map_term(&state->buffers);
5578#ifndef GLXX_NO_VERTEX_CACHE
5579 khrn_cache_term(&state->cache);
5580#endif
5581 khrn_platform_free(state);
5582}
5583
5584static bool attrib_translate(GLXX_CLIENT_STATE_T *state, uint32_t *indx)
5585{
5586 if (state->type == OPENGL_ES_11)
5587 {
5588 if (*indx == GL11_IX_CLIENT_ACTIVE_TEXTURE)
5589 {
5590 *indx = GL11_IX_TEXTURE_COORD + state->active_texture.client - GL_TEXTURE0;
5591 }
5592 vcos_assert(*indx < GL11_IX_MAX_ATTRIBS);
5593 return true;
5594 }
5595 else
5596 {
5597 vcos_assert(state->type == OPENGL_ES_20);
5598 if (*indx < GL20_CONFIG_MAX_VERTEX_ATTRIBS)
5599 {
5600 return true;
5601 }
5602 else
5603 {
5604 glxx_set_error(state, GL_INVALID_VALUE);
5605 return false;
5606 }
5607 }
5608}
5609
5610void glintAttribPointer (uint32_t api, uint32_t indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr)
5611{
5612 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5613 if (IS_OPENGLES_API(thread, api))
5614 {
5615 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5616 if (attrib_translate(state, &indx))
5617 {
5618 state->attrib[indx].size = size;
5619 state->attrib[indx].type = type;
5620 state->attrib[indx].normalized = normalized;
5621 state->attrib[indx].stride = stride;
5622 state->attrib[indx].pointer = ptr;
5623 state->attrib[indx].buffer = state->bound_buffer.array;
5624
5625 RPC_CALL7(glintAttribPointer_impl,
5626 thread,
5627 GLINTATTRIBPOINTER_ID,
5628 RPC_UINT(api),
5629 RPC_UINT(indx),
5630 RPC_INT(size),
5631 RPC_ENUM(type),
5632 RPC_BOOLEAN(normalized),
5633 RPC_SIZEI(stride),
5634 RPC_INTPTR((GLintptr)ptr));
5635 }
5636 }
5637}
5638
5639void glintAttrib (uint32_t api, uint32_t indx, float x, float y, float z, float w)
5640{
5641 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5642 if (IS_OPENGLES_API(thread, api))
5643 {
5644 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5645 if (attrib_translate(state, &indx))
5646 {
5647 vcos_assert(indx < GLXX_CONFIG_MAX_VERTEX_ATTRIBS);
5648 state->attrib[indx].value[0] = x;
5649 state->attrib[indx].value[1] = y;
5650 state->attrib[indx].value[2] = z;
5651 state->attrib[indx].value[3] = w;
5652
5653 RPC_CALL6(glintAttrib_impl,
5654 thread,
5655 GLINTATTRIB_ID,
5656 RPC_UINT(api),
5657 RPC_UINT(indx),
5658 RPC_FLOAT(x),
5659 RPC_FLOAT(y),
5660 RPC_FLOAT(z),
5661 RPC_FLOAT(w));
5662 }
5663 }
5664}
5665
5666/*
5667Separate path for glColor because it needs to update the material
5668*/
5669
5670void glintColor (float x, float y, float z, float w)
5671{
5672 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5673 if (IS_OPENGLES_11(thread))
5674 {
5675 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5676
5677 state->attrib[GL11_IX_COLOR].value[0] = x;
5678 state->attrib[GL11_IX_COLOR].value[1] = y;
5679 state->attrib[GL11_IX_COLOR].value[2] = z;
5680 state->attrib[GL11_IX_COLOR].value[3] = w;
5681
5682 RPC_CALL4(glintColor_impl_11,
5683 thread,
5684 GLINTCOLOR_ID_11,
5685 RPC_FLOAT(x),
5686 RPC_FLOAT(y),
5687 RPC_FLOAT(z),
5688 RPC_FLOAT(w));
5689 }
5690}
5691
5692void glintAttribEnable(uint32_t api, uint32_t indx, bool enabled)
5693{
5694 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5695 if (IS_OPENGLES_API(thread, api))
5696 {
5697 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5698 if (attrib_translate(state, &indx))
5699 {
5700 state->attrib[indx].enabled = enabled;
5701
5702 RPC_CALL3(glintAttribEnable_impl,
5703 thread,
5704 GLINTATTRIBENABLE_ID,
5705 RPC_UINT(api),
5706 RPC_UINT(indx),
5707 RPC_BOOLEAN(enabled));
5708 }
5709 }
5710}
5711
5712void *glintAttribGetPointer(uint32_t api, uint32_t indx)
5713{
5714 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5715 if (IS_OPENGLES_API(thread, api))
5716 {
5717 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5718 if (attrib_translate(state, &indx))
5719 return (void *)state->attrib[indx].pointer;
5720 }
5721 return NULL;
5722}
5723
5724//TODO we need these to get the conformance test to build
5725#ifdef __cplusplus
5726extern "C" {
5727#endif
5728
5729GL_API void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) { UNUSED(target); UNUSED(level); UNUSED(internalformat); UNUSED(width); UNUSED(height); UNUSED(depth); UNUSED(border); UNUSED(format); UNUSED(type); UNUSED(pixels); }
5730GL_API void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) { UNUSED(target); UNUSED(level); UNUSED(xoffset); UNUSED(yoffset); UNUSED(zoffset); UNUSED(width); UNUSED(height); UNUSED(depth); UNUSED(format); UNUSED(type); UNUSED(pixels); }
5731
5732#ifdef __cplusplus
5733}
5734#endif
5735