1 /*
2 Copyright (c) 2012, Broadcom Europe Ltd
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, 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
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON 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
25 SOFTWARE, 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
61 VCOS_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
68 GLXX_CLIENT_STATE_T gl11_client_state;
69 #endif
70
71 #ifdef GL20_CLIENT_SINGLE
72 GLXX_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
set_error(GLXX_CLIENT_STATE_T * state,GLenum error)100 static 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
set_error_ex(GLXX_CLIENT_STATE_T * state,GLenum error,const char * func)106 static 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
glxx_set_error(GLXX_CLIENT_STATE_T * state,GLenum error)116 void glxx_set_error(GLXX_CLIENT_STATE_T *state, GLenum error)
117 {
118 set_error(state,error);
119 }
120
glxx_set_error_api(uint32_t api,GLenum error)121 void 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
read_out_bulk(CLIENT_THREAD_STATE_T * thread,void * out)132 static 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
get_bound_buffer(GLXX_CLIENT_STATE_T * state,GLenum target)138 static 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
glxx_buffer_info_set(GLXX_CLIENT_STATE_T * state,GLenum target,GLXX_BUFFER_INFO_T * buffer_info)155 void 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
glxx_buffer_info_get(GLXX_CLIENT_STATE_T * state,GLenum target,GLXX_BUFFER_INFO_T * buffer_info)173 void 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
buffer_info_delete(GLXX_CLIENT_STATE_T * state,GLuint buffer)189 static 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
glActiveTexture(GLenum texture)199 GL_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
glAlphaFunc(GLenum func,GLclampf ref)222 GL_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
glAlphaFuncx(GLenum func,GLclampx ref)234 GL_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
glAttachShader(GLuint program,GLuint shader)246 GL_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
glBindAttribLocation(GLuint program,GLuint index,const char * name)258 GL_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
glBindBuffer(GLenum target,GLuint buffer)272 GL_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
glBindTexture(GLenum target,GLuint texture)301 GL_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
glBlendColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)314 GL_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
glBlendEquation(GLenum mode)328 GL_API void GL_APIENTRY glBlendEquation( GLenum mode ) // S
329 {
330 glBlendEquationSeparate(mode, mode);
331 }
332
glBlendEquationSeparate(GLenum modeRGB,GLenum modeAlpha)333 GL_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
set_blend_func(CLIENT_THREAD_STATE_T * thread,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)345 static 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
glBlendFunc(GLenum sfactor,GLenum dfactor)355 GL_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
glBlendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)361 GL_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
glBufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)367 GL_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
glBufferSubData(GLenum target,GLintptr base,GLsizeiptr size,const GLvoid * data)433 GL_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
glClear(GLbitfield mask)471 GL_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
glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)488 GL_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
glClearColorx(GLclampx red,GLclampx green,GLclampx blue,GLclampx alpha)502 GL_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
glClearDepthf(GLclampf depth)516 GL_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
glClearDepthx(GLclampx depth)527 GL_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
glClearStencil(GLint s)538 GL_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
glClientActiveTexture(GLenum texture)549 GL_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
glClipPlanef(GLenum plane,const GLfloat * equation)570 GL_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
glClipPlanex(GLenum plane,const GLfixed * equation)583 GL_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
glColor4f(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)596 GL_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
glColor4ub(GLubyte red,GLubyte green,GLubyte blue,GLubyte alpha)605 GL_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
glColor4x(GLfixed red,GLfixed green,GLfixed blue,GLfixed alpha)614 GL_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
glColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)623 GL_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
is_color_size(GLint size)637 static bool is_color_size(GLint size)
638 {
639 return size == 4;
640 }
641
is_color_type(GLenum type)642 static bool is_color_type(GLenum type)
643 {
644 return type == GL_UNSIGNED_BYTE ||
645 type == GL_FIXED ||
646 type == GL_FLOAT;
647 }
648
is_aligned(GLenum type,size_t value)649 static 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
glColorPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)667 GL_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
get_palette_size(GLenum internalformat)678 static 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
glCompressedTexImage2D(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)698 GL_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
glCompressedTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)808 GL_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
glCopyTexImage2D(GLenum target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)850 GL_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
glCopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)868 GL_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
glCreateProgram(void)886 GL_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
glCreateShader(GLenum type)898 GL_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
glCullFace(GLenum mode)911 GL_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
glDeleteBuffers(GLsizei n,const GLuint * buffers)922 GL_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
glDeleteProgram(GLuint program)965 GL_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
glDeleteShader(GLuint shader)976 GL_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
glDeleteTextures(GLsizei n,const GLuint * textures)987 GL_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
glDepthFunc(GLenum func)1010 GL_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
glDepthMask(GLboolean flag)1021 GL_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
glDepthRangef(GLclampf zNear,GLclampf zFar)1032 GL_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
glDepthRangex(GLclampx zNear,GLclampx zFar)1044 GL_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
glDetachShader(GLuint program,GLuint shader)1056 GL_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
glDisable(GLenum cap)1068 GL_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
set_enabled_11(GLenum array,GLboolean enabled)1079 static 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
glDisableClientState(GLenum array)1111 GL_API void GL_APIENTRY glDisableClientState (GLenum array)
1112 {
1113 set_enabled_11(array, GL_FALSE);
1114 }
1115
glDisableVertexAttribArray(GLuint index)1116 GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index)
1117 {
1118 glintAttribEnable(GLXX_API_20, index, GL_FALSE);
1119 }
1120
align_length(int length)1121 static int align_length(int length)
1122 {
1123 return (length + 15) & ~15;
1124 }
1125
calc_length(int max,int size,GLenum type,int stride)1126 static 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
is_index_type(GLenum type)1136 static GLboolean is_index_type(GLenum type)
1137 {
1138 return type == GL_UNSIGNED_BYTE ||
1139 type == GL_UNSIGNED_SHORT;
1140 }
1141
1142 typedef 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
draw_arrays_or_elements(CLIENT_THREAD_STATE_T * thread,GLXX_CLIENT_STATE_T * state,GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1152 static 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
glDrawArrays(GLenum mode,GLint first,GLsizei count)1336 GL_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
glDrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1345 GL_API void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
1346 {
1347 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1348 if (IS_OPENGLES_11_OR_20(thread)) {
1349 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1350 if (!is_index_type(type)) {
1351 set_error(state, GL_INVALID_ENUM);
1352 return;
1353 }
1354 if (!is_aligned(type, (size_t)indices)) {
1355 set_error(state, GL_INVALID_VALUE);
1356 return;
1357 }
1358 draw_arrays_or_elements(thread, state, mode, count, type, indices);
1359 }
1360 }
1361
glEnable(GLenum cap)1362 GL_API void GL_APIENTRY glEnable (GLenum cap)
1363 {
1364 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1365 if (IS_OPENGLES_11_OR_20(thread)) {
1366 RPC_CALL1(glEnable_impl,
1367 thread,
1368 GLENABLE_ID,
1369 RPC_ENUM(cap));
1370 }
1371 }
1372
glEnableClientState(GLenum array)1373 GL_API void GL_APIENTRY glEnableClientState (GLenum array)
1374 {
1375 set_enabled_11(array, GL_TRUE);
1376 }
1377
glEnableVertexAttribArray(GLuint index)1378 GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index)
1379 {
1380 glintAttribEnable(GLXX_API_20, index, GL_TRUE);
1381 }
1382
glFinish(void)1383 GL_API void GL_APIENTRY glFinish (void)
1384 {
1385 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1386 if (IS_OPENGLES_11_OR_20(thread)) {
1387 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1388 (void) RPC_UINT_RES(RPC_CALL0_RES(glFinish_impl,
1389 thread,
1390 GLFINISH_ID)); // Return ignored - read performed to force blocking
1391
1392 if (state->flush_callback)
1393 state->flush_callback(true);
1394 }
1395 }
1396
glFlush(void)1397 GL_API void GL_APIENTRY glFlush (void)
1398 {
1399 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1400 if (IS_OPENGLES_11_OR_20(thread)) {
1401 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1402 RPC_CALL0(glFlush_impl,
1403 thread,
1404 GLFLUSH_ID);
1405
1406 if (state->flush_callback)
1407 state->flush_callback(false);
1408 }
1409
1410 //TODO: where exactly should we put RPC_FLUSH? Are there any other functions
1411 //which need it? (e.g. eglSwapBuffers)
1412 RPC_FLUSH(thread);
1413 }
1414
glFogf(GLenum pname,GLfloat param)1415 GL_API void GL_APIENTRY glFogf (GLenum pname, GLfloat param)
1416 {
1417 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1418 if (IS_OPENGLES_11(thread)) {
1419 RPC_CALL2(glFogf_impl_11,
1420 thread,
1421 GLFOGF_ID_11,
1422 RPC_ENUM(pname),
1423 RPC_FLOAT(param));
1424 }
1425 }
1426
glFogfv(GLenum pname,const GLfloat * params)1427 GL_API void GL_APIENTRY glFogfv (GLenum pname, const GLfloat *params)
1428 {
1429 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1430 if (IS_OPENGLES_11(thread)) {
1431 /*
1432 the only supported fog params are
1433
1434 FOG_MODE (1)
1435 FOG_DENSITY (1)
1436 FOG_START (1)
1437 FOG_END (1)
1438 FOG_COLOR (4)
1439
1440 so we need to transmit 4 words of parameter data
1441 */
1442
1443 RPC_CALL2_IN_CTRL(glFogfv_impl_11,
1444 thread,
1445 GLFOGFV_ID_11,
1446 RPC_ENUM(pname),
1447 params,
1448 4 * sizeof(GLfloat));
1449 }
1450 }
1451
glFogx(GLenum pname,GLfixed param)1452 GL_API void GL_APIENTRY glFogx (GLenum pname, GLfixed param)
1453 {
1454 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1455 if (IS_OPENGLES_11(thread)) {
1456 RPC_CALL2(glFogx_impl_11,
1457 thread,
1458 GLFOGX_ID_11,
1459 RPC_ENUM(pname),
1460 RPC_FIXED(param));
1461 }
1462 }
1463
glFogxv(GLenum pname,const GLfixed * params)1464 GL_API void GL_APIENTRY glFogxv (GLenum pname, const GLfixed *params)
1465 {
1466 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1467 if (IS_OPENGLES_11(thread)) {
1468 /*
1469 the only supported fog params are
1470
1471 FOG_MODE (1)
1472 FOG_DENSITY (1)
1473 FOG_START (1)
1474 FOG_END (1)
1475 FOG_COLOR (4)
1476
1477 so we need to transmit 4 words of parameter data
1478 */
1479
1480 RPC_CALL2_IN_CTRL(glFogxv_impl_11,
1481 thread,
1482 GLFOGXV_ID_11,
1483 RPC_ENUM(pname),
1484 params,
1485 4 * sizeof(GLfixed));
1486 }
1487 }
1488
glFrontFace(GLenum mode)1489 GL_API void GL_APIENTRY glFrontFace (GLenum mode)
1490 {
1491 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1492 if (IS_OPENGLES_11_OR_20(thread)) {
1493 RPC_CALL1(glFrontFace_impl,
1494 thread,
1495 GLFRONTFACE_ID,
1496 RPC_ENUM(mode));
1497 }
1498 }
1499
glFrustumf(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)1500 GL_API void GL_APIENTRY glFrustumf (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
1501 {
1502 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1503 if (IS_OPENGLES_11(thread)) {
1504 RPC_CALL6(glFrustumf_impl_11,
1505 thread,
1506 GLFRUSTUMF_ID_11,
1507 RPC_FLOAT(left),
1508 RPC_FLOAT(right),
1509 RPC_FLOAT(bottom),
1510 RPC_FLOAT(top),
1511 RPC_FLOAT(zNear),
1512 RPC_FLOAT(zFar));
1513 }
1514 }
1515
glFrustumx(GLfixed left,GLfixed right,GLfixed bottom,GLfixed top,GLfixed zNear,GLfixed zFar)1516 GL_API void GL_APIENTRY glFrustumx (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
1517 {
1518 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1519 if (IS_OPENGLES_11(thread)) {
1520 RPC_CALL6(glFrustumx_impl_11,
1521 thread,
1522 GLFRUSTUMX_ID_11,
1523 RPC_FIXED(left),
1524 RPC_FIXED(right),
1525 RPC_FIXED(bottom),
1526 RPC_FIXED(top),
1527 RPC_FIXED(zNear),
1528 RPC_FIXED(zFar));
1529 }
1530 }
1531
glGenBuffers(GLsizei n,GLuint * buffers)1532 GL_API void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers)
1533 {
1534 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1535 if (IS_OPENGLES_11_OR_20(thread)) {
1536 int offset = 0;
1537
1538 do {
1539 int32_t items = (int32_t) (KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
1540 int32_t batch = _min(items, (int32_t) n);
1541
1542 RPC_CALL2_OUT_BULK(glGenBuffers_impl,
1543 thread,
1544 GLGENBUFFERS_ID,
1545 RPC_SIZEI(batch),
1546 (GLuint*)(buffers + offset));
1547
1548 offset += batch;
1549 n -= batch;
1550 } while (n > 0);
1551 }
1552 }
1553
glGenTextures(GLsizei n,GLuint * textures)1554 GL_API void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures)
1555 {
1556 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1557 if (IS_OPENGLES_11_OR_20(thread)) {
1558 int offset = 0;
1559
1560 do {
1561 int32_t items = (int32_t) (KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
1562 int32_t batch = _min(items, (int32_t)n);
1563
1564 RPC_CALL2_OUT_BULK(glGenTextures_impl,
1565 thread,
1566 GLGENTEXTURES_ID,
1567 RPC_SIZEI(batch),
1568 textures + offset);
1569
1570 offset += batch;
1571 n -= batch;
1572 } while (n > 0);
1573 }
1574 }
1575
glGetActiveAttrib(GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,char * name)1576 GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name)
1577 {
1578 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1579 if (IS_OPENGLES_20(thread)) {
1580 #ifdef RPC_DIRECT
1581 RPC_CALL7(glGetActiveAttrib_impl_20, thread, no_id, program, index, bufsize, length, size, type, name);
1582 #else
1583 GLuint result[3];
1584
1585 rpc_begin(thread);
1586
1587 RPC_CALL4_OUT_CTRL(no_function,
1588 thread,
1589 GLGETACTIVEATTRIB_ID_20,
1590 RPC_UINT(program),
1591 RPC_UINT(index),
1592 RPC_SIZEI(bufsize),
1593 result);
1594
1595 if (length)
1596 *length = (GLsizei)result[0];
1597 if (size)
1598 *size = (GLint)result[1];
1599 if (type)
1600 *type = (GLenum)result[2];
1601
1602 read_out_bulk(thread, name);
1603
1604 rpc_end(thread);
1605 #endif
1606 }
1607 }
1608
glGetActiveUniform(GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,char * name)1609 GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name)
1610 {
1611 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1612 if (IS_OPENGLES_20(thread)) {
1613 #ifdef RPC_DIRECT
1614 RPC_CALL7(glGetActiveUniform_impl_20, thread, no_id, program, index, bufsize, length, size, type, name);
1615 #else
1616 GLuint result[3];
1617
1618 rpc_begin(thread);
1619
1620 RPC_CALL4_OUT_CTRL(no_function,
1621 thread,
1622 GLGETACTIVEUNIFORM_ID_20,
1623 RPC_UINT(program),
1624 RPC_UINT(index),
1625 RPC_SIZEI(bufsize),
1626 result);
1627
1628 if (length)
1629 *length = (GLsizei)result[0];
1630 if (size)
1631 *size = (GLint)result[1];
1632 if (type)
1633 *type = (GLenum)result[2];
1634
1635 read_out_bulk(thread, name);
1636
1637 rpc_end(thread);
1638 #endif
1639 }
1640 }
1641
glGetAttachedShaders(GLuint program,GLsizei maxcount,GLsizei * count,GLuint * shaders)1642 GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
1643 {
1644 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1645 if (IS_OPENGLES_20(thread)) {
1646 #ifdef RPC_DIRECT
1647 RPC_CALL4(glGetAttachedShaders_impl_20, thread, no_id, program, maxcount, count, shaders);
1648 #else
1649 GLuint i;
1650
1651 GLuint result[3];
1652
1653 RPC_CALL3_OUT_CTRL(no_function,
1654 thread,
1655 GLGETATTACHEDSHADERS_ID_20,
1656 RPC_UINT(program),
1657 RPC_SIZEI(maxcount),
1658 result);
1659
1660 if (count)
1661 *count = (GLsizei) result[0];
1662
1663 for (i = 0; i < 2; i++)
1664 if ((GLuint)maxcount > i && result[0] > i)
1665 shaders[i] = result[i + 1];
1666 #endif
1667 }
1668 }
1669
glGetAttribLocation(GLuint program,const char * name)1670 GL_APICALL int GL_APIENTRY glGetAttribLocation (GLuint program, const char *name)
1671 {
1672 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1673 if (IS_OPENGLES_20(thread)) {
1674 return RPC_INT_RES(RPC_CALL2_IN_BULK_RES(glGetAttribLocation_impl_20,
1675 thread,
1676 GLGETATTRIBLOCATION_ID_20,
1677 RPC_UINT(program),
1678 name,
1679 strlen(name) + 1));
1680 }
1681
1682 return 0;
1683 }
1684
1685 /*
1686 native client-side boolean variables
1687
1688 VERTEX ARRAY IsEnabled
1689 NORMAL ARRAY IsEnabled
1690 COLOR ARRAY IsEnabled
1691 TEXTURE COORD ARRAY IsEnabled
1692 POINT SIZE ARRAY OES IsEnabled
1693 MATRIX INDEX ARRAY OES IsEnabled
1694 WEIGHT ARRAY OES IsEnabled
1695 */
1696
get_boolean_internal_11(CLIENT_THREAD_STATE_T * thread,GLenum pname,GLboolean * params)1697 static int get_boolean_internal_11(CLIENT_THREAD_STATE_T *thread, GLenum pname, GLboolean *params)
1698 {
1699 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1700
1701 vcos_assert(state != NULL);
1702
1703 switch (pname) {
1704 case GL_VERTEX_ARRAY:
1705 params[0] = state->attrib[GL11_IX_VERTEX].enabled;
1706 return 1;
1707 case GL_NORMAL_ARRAY:
1708 params[0] = state->attrib[GL11_IX_NORMAL].enabled;
1709 return 1;
1710 case GL_COLOR_ARRAY:
1711 params[0] = state->attrib[GL11_IX_COLOR].enabled;
1712 return 1;
1713 case GL_TEXTURE_COORD_ARRAY:
1714 params[0] = state->attrib[state->active_texture.client - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].enabled;
1715 return 1;
1716 case GL_POINT_SIZE_ARRAY_OES:
1717 params[0] = state->attrib[GL11_IX_POINT_SIZE].enabled;
1718 return 1;
1719 case GL_MATRIX_INDEX_ARRAY_OES:
1720 params[0] = state->attrib[GL11_IX_MATRIX_INDEX].enabled;
1721 return 1;
1722 case GL_WEIGHT_ARRAY_OES:
1723 params[0] = state->attrib[GL11_IX_MATRIX_WEIGHT].enabled;
1724 return 1;
1725 default:
1726 UNREACHABLE();
1727 break;
1728 }
1729
1730 return 0;
1731 }
1732
1733 /*
1734 native client-side floating-point state variables
1735
1736 CURRENT_COLOR
1737 CURRENT_TEXTURE_COORDS
1738 CURRENT_NORMAL
1739 POINT_SIZE
1740 */
1741
get_float_internal_11(CLIENT_THREAD_STATE_T * thread,GLenum pname,GLfloat * params)1742 static int get_float_internal_11(CLIENT_THREAD_STATE_T *thread, GLenum pname, GLfloat *params)
1743 {
1744 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1745
1746 int i;
1747
1748 switch (pname) {
1749 case GL_CURRENT_TEXTURE_COORDS:
1750 {
1751 /*
1752 apparently we need the current texture coordinates for the _server_ active texture unit
1753 */
1754
1755 for (i = 0; i < 4; i++)
1756 params[i] = state->attrib[state->active_texture.server - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].value[i];
1757 return 4;
1758 }
1759 case GL_CURRENT_COLOR:
1760 {
1761 for (i = 0; i < 4; i++)
1762 params[i] = state->attrib[GL11_IX_COLOR].value[i];
1763 return 4;
1764 }
1765 case GL_CURRENT_NORMAL:
1766 {
1767 for (i = 0; i < 3; i++)
1768 params[i] = state->attrib[GL11_IX_NORMAL].value[i];
1769 return 3;
1770 }
1771 case GL_POINT_SIZE:
1772 params[0] = state->attrib[GL11_IX_POINT_SIZE].value[0];
1773 return 1;
1774 default:
1775 UNREACHABLE();
1776 break;
1777 }
1778
1779 return 0;
1780 }
1781
1782 /*
1783 native client-side integer state variables
1784
1785 CLIENT ACTIVE TEXTURE GetIntegerv
1786 VERTEX ARRAY SIZE GetIntegerv
1787 VERTEX ARRAY TYPE GetIntegerv
1788 VERTEX ARRAY STRIDE GetIntegerv
1789 NORMAL ARRAY TYPE GetIntegerv
1790 NORMAL ARRAY STRIDE GetIntegerv
1791 COLOR ARRAY SIZE GetIntegerv
1792 COLOR ARRAY TYPE GetIntegerv
1793 COLOR ARRAY STRIDE GetIntegerv
1794 TEXTURE COORD ARRAY SIZE GetIntegerv
1795 TEXTURE COORD ARRAY TYPE GetIntegerv
1796 TEXTURE COORD ARRAY STRIDE GetIntegerv
1797 POINT SIZE ARRAY TYPE OES GetIntegerv
1798 POINT SIZE ARRAY STRIDE OES GetIntegerv
1799
1800 MATRIX_INDEX_ARRAY_SIZE_OES GetInegerv
1801 MATRIX_INDEX_ARRAY_TYPE_OES GetInegerv
1802 MATRIX_INDEX_ARRAY_STRIDE_OES GetInegerv
1803 WEIGHT_ARRAY_SIZE_OES GetInegerv
1804 WEIGHT_ARRAY_TYPE_OES GetInegerv
1805 WEIGHT_ARRAY_STRIDE_OES GetInegerv
1806
1807 VERTEX ARRAY BUFFER BINDING GetIntegerv
1808 NORMAL ARRAY BUFFER BINDING GetIntegerv
1809 COLOR ARRAY BUFFER BINDING GetIntegerv
1810 TEXTURE COORD ARRAY BUFFER BINDING GetIntegerv
1811 POINT SIZE ARRAY BUFFER BINDING OES GetIntegerv
1812 MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES GetIntegerv
1813 WEIGHT_ARRAY_BUFFER_BINDING_OES GetIntegerv
1814
1815 UNPACK ALIGNMENT GetIntegerv
1816 PACK ALIGNMENT GetIntegerv
1817 */
1818
get_integer_internal_11(CLIENT_THREAD_STATE_T * thread,GLenum pname,GLint * params)1819 static int get_integer_internal_11(CLIENT_THREAD_STATE_T *thread, GLenum pname, GLint *params)
1820 {
1821 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1822
1823 vcos_assert(state != NULL);
1824
1825 switch (pname) {
1826 case GL_CLIENT_ACTIVE_TEXTURE:
1827 params[0] = (GLint) state->active_texture.client;
1828 return 1;
1829 case GL_VERTEX_ARRAY_SIZE:
1830 params[0] = (GLint) state->attrib[GL11_IX_VERTEX].size;
1831 return 1;
1832 case GL_VERTEX_ARRAY_TYPE:
1833 params[0] = (GLint) state->attrib[GL11_IX_VERTEX].type;
1834 return 1;
1835 case GL_VERTEX_ARRAY_STRIDE:
1836 params[0] = (GLint) state->attrib[GL11_IX_VERTEX].stride;
1837 return 1;
1838 case GL_NORMAL_ARRAY_TYPE:
1839 params[0] = (GLint) state->attrib[GL11_IX_NORMAL].type;
1840 return 1;
1841 case GL_NORMAL_ARRAY_STRIDE:
1842 params[0] = (GLint) state->attrib[GL11_IX_NORMAL].stride;
1843 return 1;
1844 case GL_COLOR_ARRAY_SIZE:
1845 params[0] = (GLint) state->attrib[GL11_IX_COLOR].size;
1846 return 1;
1847 case GL_COLOR_ARRAY_TYPE:
1848 params[0] = (GLint) state->attrib[GL11_IX_COLOR].type;
1849 return 1;
1850 case GL_COLOR_ARRAY_STRIDE:
1851 params[0] = (GLint) state->attrib[GL11_IX_COLOR].stride;
1852 return 1;
1853 case GL_TEXTURE_COORD_ARRAY_SIZE:
1854 params[0] = (GLint) state->attrib[state->active_texture.client - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].size;
1855 return 1;
1856 case GL_TEXTURE_COORD_ARRAY_TYPE:
1857 params[0] = (GLint) state->attrib[state->active_texture.client - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].type;
1858 return 1;
1859 case GL_TEXTURE_COORD_ARRAY_STRIDE:
1860 params[0] = (GLint) state->attrib[state->active_texture.client - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].stride;
1861 return 1;
1862 case GL_POINT_SIZE_ARRAY_TYPE_OES:
1863 params[0] = (GLint) state->attrib[GL11_IX_POINT_SIZE].type;
1864 return 1;
1865 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
1866 params[0] = (GLint) state->attrib[GL11_IX_POINT_SIZE].stride;
1867 return 1;
1868 case GL_MATRIX_INDEX_ARRAY_SIZE_OES:
1869 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_INDEX].size;
1870 return 1;
1871 case GL_MATRIX_INDEX_ARRAY_TYPE_OES:
1872 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_INDEX].type;
1873 return 1;
1874 case GL_MATRIX_INDEX_ARRAY_STRIDE_OES:
1875 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_INDEX].stride;
1876 return 1;
1877 case GL_WEIGHT_ARRAY_SIZE_OES:
1878 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_WEIGHT].size;
1879 return 1;
1880 case GL_WEIGHT_ARRAY_TYPE_OES:
1881 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_WEIGHT].type;
1882 return 1;
1883 case GL_WEIGHT_ARRAY_STRIDE_OES:
1884 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_WEIGHT].stride;
1885 return 1;
1886 case GL_ARRAY_BUFFER_BINDING:
1887 params[0] = (GLint) state->bound_buffer.array;
1888 return 1;
1889 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1890 params[0] = (GLint) state->bound_buffer.element_array;
1891 return 1;
1892 case GL_VERTEX_ARRAY_BUFFER_BINDING:
1893 params[0] = (GLint) state->attrib[GL11_IX_VERTEX].buffer;
1894 return 1;
1895 case GL_NORMAL_ARRAY_BUFFER_BINDING:
1896 params[0] = (GLint) state->attrib[GL11_IX_NORMAL].buffer;
1897 return 1;
1898 case GL_COLOR_ARRAY_BUFFER_BINDING:
1899 params[0] = (GLint) state->attrib[GL11_IX_COLOR].buffer;
1900 return 1;
1901 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
1902 /*
1903 TODO is this right?
1904 Most texture state variables are qualified by the value of ACTIVE TEXTURE
1905 to determine which server texture state vector is queried. Client texture
1906 state variables such as texture coordinate array pointers are qualified by the
1907 value of CLIENT ACTIVE TEXTURE. Tables 6.3, 6.4, 6.7, 6.13, 6.15, and 6.21
1908 indicate those state variables which are qualified by ACTIVE TEXTURE or
1909 CLIENT ACTIVE TEXTURE during state queries
1910 */
1911 params[0] = (GLint) state->attrib[state->active_texture.client - GL_TEXTURE0 + GL11_IX_TEXTURE_COORD].buffer;
1912 return 1;
1913 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
1914 params[0] = (GLint) state->attrib[GL11_IX_POINT_SIZE].buffer;
1915 return 1;
1916 case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES:
1917 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_INDEX].buffer;
1918 return 1;
1919 case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES:
1920 params[0] = (GLint) state->attrib[GL11_IX_MATRIX_WEIGHT].buffer;
1921 return 1;
1922
1923 case GL_UNPACK_ALIGNMENT:
1924 params[0] = (GLint) state->alignment.unpack;
1925 return 1;
1926 case GL_PACK_ALIGNMENT:
1927 params[0] = (GLint) state->alignment.pack;
1928 return 1;
1929
1930 //TODO: these are horrible and don't make any sense
1931 //Is this a sensible thing to return?
1932 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1933 params[0] = (GLint) GL_UNSIGNED_BYTE;
1934 return 1;
1935 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1936 params[0] = (GLint) GL_RGBA;
1937 return 1;
1938 //end TODO
1939
1940 default:
1941 UNREACHABLE();
1942 break;
1943 }
1944
1945 return 0;
1946 }
1947
get_integer_internal_20(CLIENT_THREAD_STATE_T * thread,GLenum pname,GLint * params)1948 static int get_integer_internal_20(CLIENT_THREAD_STATE_T *thread, GLenum pname, GLint *params)
1949 {
1950 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
1951
1952 vcos_assert(state != NULL);
1953
1954 switch (pname) {
1955 case GL_UNPACK_ALIGNMENT:
1956 params[0] = state->alignment.unpack;
1957 return 1;
1958 case GL_PACK_ALIGNMENT:
1959 params[0] = state->alignment.pack;
1960 return 1;
1961 default:
1962 UNREACHABLE();
1963 break;
1964 }
1965
1966 return 0;
1967 }
1968
glGetBooleanv(GLenum pname,GLboolean * params)1969 GL_API void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *params)
1970 {
1971 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
1972 if (IS_OPENGLES_11(thread)) {
1973 switch (pname) {
1974 case GL_VERTEX_ARRAY:
1975 case GL_NORMAL_ARRAY:
1976 case GL_COLOR_ARRAY:
1977 case GL_TEXTURE_COORD_ARRAY:
1978 case GL_POINT_SIZE_ARRAY_OES:
1979 get_boolean_internal_11(thread, pname, params);
1980 break;
1981 case GL_CLIENT_ACTIVE_TEXTURE:
1982 case GL_VERTEX_ARRAY_SIZE:
1983 case GL_VERTEX_ARRAY_TYPE:
1984 case GL_VERTEX_ARRAY_STRIDE:
1985 case GL_NORMAL_ARRAY_TYPE:
1986 case GL_NORMAL_ARRAY_STRIDE:
1987 case GL_COLOR_ARRAY_SIZE:
1988 case GL_COLOR_ARRAY_TYPE:
1989 case GL_COLOR_ARRAY_STRIDE:
1990 case GL_TEXTURE_COORD_ARRAY_SIZE:
1991 case GL_TEXTURE_COORD_ARRAY_TYPE:
1992 case GL_TEXTURE_COORD_ARRAY_STRIDE:
1993 case GL_POINT_SIZE_ARRAY_TYPE_OES:
1994 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
1995 case GL_ARRAY_BUFFER_BINDING:
1996 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1997 case GL_VERTEX_ARRAY_BUFFER_BINDING:
1998 case GL_NORMAL_ARRAY_BUFFER_BINDING:
1999 case GL_COLOR_ARRAY_BUFFER_BINDING:
2000 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2001 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2002 case GL_UNPACK_ALIGNMENT:
2003 case GL_PACK_ALIGNMENT:
2004 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
2005 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
2006 {
2007 GLint temp;
2008
2009 get_integer_internal_11(thread, pname, &temp);
2010
2011 params[0] = temp != 0;
2012 break;
2013 }
2014 case GL_CURRENT_TEXTURE_COORDS:
2015 case GL_CURRENT_COLOR:
2016 case GL_CURRENT_NORMAL:
2017 case GL_POINT_SIZE:
2018 {
2019 GLfloat temp[4];
2020 GLuint count = (GLuint) get_float_internal_11(thread, pname, temp);
2021 GLuint i;
2022
2023 vcos_assert(count <= 4);
2024
2025 for (i = 0; i < count; i++)
2026 params[i] = temp[i] != 0.0f;
2027
2028 break;
2029 }
2030 default:
2031 RPC_CALL2_OUT_CTRL(glGetBooleanv_impl,
2032 thread,
2033 GLGETBOOLEANV_ID,
2034 RPC_ENUM(pname),
2035 params);
2036 break;
2037 }
2038 }
2039
2040 if (IS_OPENGLES_20(thread)) {
2041 switch (pname) {
2042 case GL_UNPACK_ALIGNMENT:
2043 case GL_PACK_ALIGNMENT:
2044 {
2045 GLint temp = 0;
2046
2047 get_integer_internal_20(thread, pname, &temp);
2048
2049 params[0] = temp != 0;
2050 break;
2051 }
2052 default:
2053 RPC_CALL2_OUT_CTRL(glGetBooleanv_impl,
2054 thread,
2055 GLGETBOOLEANV_ID,
2056 RPC_ENUM(pname),
2057 params);
2058 break;
2059 }
2060
2061 }
2062 }
2063
glGetBufferParameteriv(GLenum target,GLenum pname,GLint * params)2064 GL_API void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params)
2065 {
2066 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2067 if (IS_OPENGLES_11_OR_20(thread)) {
2068 switch(pname) {
2069 case GL_BUFFER_ACCESS_OES:
2070 {
2071 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2072 if(get_bound_buffer(state, target) != 0)
2073 {
2074 params[0] = GL_WRITE_ONLY_OES;
2075 }
2076 else
2077 {
2078 params[0] = 0;
2079 }
2080 break;
2081 }
2082 case GL_BUFFER_MAPPED_OES:
2083 {
2084 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2085 GLXX_BUFFER_INFO_T buffer;
2086 glxx_buffer_info_get(state, target, &buffer);
2087 if(buffer.id != 0 && buffer.mapped_pointer != 0)
2088 {
2089 params[0] = GL_TRUE;
2090 }
2091 else
2092 {
2093 params[0] = GL_FALSE;
2094 }
2095 break;
2096 }
2097 default:
2098 RPC_CALL3_OUT_CTRL(glGetBufferParameteriv_impl,
2099 thread,
2100 GLGETBUFFERPARAMETERIV_ID,
2101 RPC_ENUM(target),
2102 RPC_ENUM(pname),
2103 params);
2104
2105 if(pname == GL_BUFFER_SIZE)
2106 {
2107 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2108 GLXX_BUFFER_INFO_T buffer;
2109 glxx_buffer_info_get(state, target, &buffer);
2110 buffer.cached_size = params[0];
2111 glxx_buffer_info_set(state, target, &buffer);
2112 }
2113 }
2114 }
2115 }
2116
glGetClipPlanef(GLenum pname,GLfloat eqn[4])2117 GL_API void GL_APIENTRY glGetClipPlanef (GLenum pname, GLfloat eqn[4])
2118 {
2119 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2120 if (IS_OPENGLES_11(thread)) {
2121 RPC_CALL2_OUT_CTRL(glGetClipPlanef_impl_11,
2122 thread,
2123 GLGETCLIPPLANEF_ID_11,
2124 RPC_ENUM(pname),
2125 eqn);
2126 }
2127 }
2128
glGetClipPlanex(GLenum pname,GLfixed eqn[4])2129 GL_API void GL_APIENTRY glGetClipPlanex (GLenum pname, GLfixed eqn[4])
2130 {
2131 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2132 if (IS_OPENGLES_11(thread)) {
2133 RPC_CALL2_OUT_CTRL(glGetClipPlanex_impl_11,
2134 thread,
2135 GLGETCLIPPLANEX_ID_11,
2136 RPC_ENUM(pname),
2137 eqn);
2138 }
2139 }
2140
glGetError(void)2141 GL_API GLenum GL_APIENTRY glGetError (void)
2142 {
2143 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); /* Decrements glgeterror_hack variable for every API call made */
2144 if (IS_OPENGLES_11_OR_20(thread)) {
2145 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2146
2147 GLenum result = state->error;
2148
2149 if ((result == GL_NO_ERROR) && !thread->async_error_notification) {
2150 /* Don't query the server if our previous API call was glGetError() */
2151 if (0 == thread->glgeterror_hack ) {
2152 result = RPC_ENUM_RES(RPC_CALL0_RES(glGetError_impl,
2153 thread,
2154 GLGETERROR_ID));
2155 }
2156
2157 if(result != GL_NO_ERROR) {
2158 vcos_log_warn("glGetError 0x%x", result);
2159 thread->glgeterror_hack = 0;
2160 } else {
2161 thread->glgeterror_hack = 2;
2162 }
2163 }
2164 state->error = GL_NO_ERROR;
2165
2166 return result;
2167 }
2168
2169 return 0;
2170 }
2171
glGetFixedv(GLenum pname,GLfixed * params)2172 GL_API void GL_APIENTRY glGetFixedv (GLenum pname, GLfixed *params)
2173 {
2174 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2175 if (IS_OPENGLES_11(thread)) {
2176 switch (pname) {
2177 case GL_VERTEX_ARRAY:
2178 case GL_NORMAL_ARRAY:
2179 case GL_COLOR_ARRAY:
2180 case GL_TEXTURE_COORD_ARRAY:
2181 case GL_POINT_SIZE_ARRAY_OES:
2182 {
2183 GLboolean temp[4];
2184
2185 int count = get_boolean_internal_11(thread, pname, temp);
2186 int i;
2187
2188 vcos_assert(count <= 4);
2189
2190 for (i = 0; i < count; i++)
2191 params[i] = temp[i] ? (GLfixed)float_to_fixed(1.0f) : (GLfixed)float_to_fixed(0.0f);
2192
2193 break;
2194 }
2195 case GL_CURRENT_TEXTURE_COORDS:
2196 case GL_CURRENT_COLOR:
2197 case GL_CURRENT_NORMAL:
2198 case GL_POINT_SIZE:
2199 {
2200 GLfloat temp[4];
2201
2202 int count = get_float_internal_11(thread, pname, temp);
2203 int i;
2204
2205 vcos_assert(count <= 4);
2206
2207 for (i = 0; i < count; i++)
2208 params[i] = (GLfixed) float_to_fixed(temp[i]);
2209
2210 break;
2211 }
2212 case GL_CLIENT_ACTIVE_TEXTURE:
2213 case GL_VERTEX_ARRAY_SIZE:
2214 case GL_VERTEX_ARRAY_TYPE:
2215 case GL_VERTEX_ARRAY_STRIDE:
2216 case GL_NORMAL_ARRAY_TYPE:
2217 case GL_NORMAL_ARRAY_STRIDE:
2218 case GL_COLOR_ARRAY_SIZE:
2219 case GL_COLOR_ARRAY_TYPE:
2220 case GL_COLOR_ARRAY_STRIDE:
2221 case GL_TEXTURE_COORD_ARRAY_SIZE:
2222 case GL_TEXTURE_COORD_ARRAY_TYPE:
2223 case GL_TEXTURE_COORD_ARRAY_STRIDE:
2224 case GL_POINT_SIZE_ARRAY_TYPE_OES:
2225 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
2226 case GL_ARRAY_BUFFER_BINDING:
2227 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2228 case GL_VERTEX_ARRAY_BUFFER_BINDING:
2229 case GL_NORMAL_ARRAY_BUFFER_BINDING:
2230 case GL_COLOR_ARRAY_BUFFER_BINDING:
2231 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2232 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2233 case GL_UNPACK_ALIGNMENT:
2234 case GL_PACK_ALIGNMENT:
2235 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
2236 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
2237 {
2238 GLint temp;
2239
2240 get_integer_internal_11(thread, pname, &temp);
2241
2242 params[0] = (GLfixed) float_to_fixed((GLfloat)temp);
2243 break;
2244 }
2245 default:
2246 RPC_CALL2_OUT_CTRL(glGetFixedv_impl_11,
2247 thread,
2248 GLGETFIXEDV_ID_11,
2249 RPC_ENUM(pname),
2250 params);
2251 break;
2252 }
2253 }
2254 }
2255
glGetFloatv(GLenum pname,GLfloat * params)2256 GL_API void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *params)
2257 {
2258 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2259 if (IS_OPENGLES_11(thread)) {
2260 switch (pname) {
2261 case GL_VERTEX_ARRAY:
2262 case GL_NORMAL_ARRAY:
2263 case GL_COLOR_ARRAY:
2264 case GL_TEXTURE_COORD_ARRAY:
2265 case GL_POINT_SIZE_ARRAY_OES:
2266 {
2267 GLboolean temp[4];
2268 GLuint count = (GLuint) get_boolean_internal_11(thread, pname, temp);
2269 GLuint i;
2270
2271 vcos_assert(count <= 4);
2272
2273 for (i = 0; i < count; i++)
2274 params[i] = temp[i] ? 1.0f : 0.0f;
2275
2276 break;
2277 }
2278 case GL_CURRENT_TEXTURE_COORDS:
2279 case GL_CURRENT_COLOR:
2280 case GL_CURRENT_NORMAL:
2281 case GL_POINT_SIZE:
2282 get_float_internal_11(thread, pname, params);
2283
2284 break;
2285 case GL_CLIENT_ACTIVE_TEXTURE:
2286 case GL_VERTEX_ARRAY_SIZE:
2287 case GL_VERTEX_ARRAY_TYPE:
2288 case GL_VERTEX_ARRAY_STRIDE:
2289 case GL_NORMAL_ARRAY_TYPE:
2290 case GL_NORMAL_ARRAY_STRIDE:
2291 case GL_COLOR_ARRAY_SIZE:
2292 case GL_COLOR_ARRAY_TYPE:
2293 case GL_COLOR_ARRAY_STRIDE:
2294 case GL_TEXTURE_COORD_ARRAY_SIZE:
2295 case GL_TEXTURE_COORD_ARRAY_TYPE:
2296 case GL_TEXTURE_COORD_ARRAY_STRIDE:
2297 case GL_POINT_SIZE_ARRAY_TYPE_OES:
2298 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
2299 case GL_ARRAY_BUFFER_BINDING:
2300 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2301 case GL_VERTEX_ARRAY_BUFFER_BINDING:
2302 case GL_NORMAL_ARRAY_BUFFER_BINDING:
2303 case GL_COLOR_ARRAY_BUFFER_BINDING:
2304 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2305 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2306 case GL_UNPACK_ALIGNMENT:
2307 case GL_PACK_ALIGNMENT:
2308 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
2309 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
2310 {
2311 GLint temp;
2312
2313 get_integer_internal_11(thread, pname, &temp);
2314
2315 params[0] = (GLfloat)temp;
2316 break;
2317 }
2318 default:
2319 RPC_CALL2_OUT_CTRL(glGetFloatv_impl,
2320 thread,
2321 GLGETFLOATV_ID,
2322 RPC_ENUM(pname),
2323 params);
2324 break;
2325 }
2326 }
2327 else if (IS_OPENGLES_20(thread)) {
2328 switch (pname) {
2329 case GL_UNPACK_ALIGNMENT:
2330 case GL_PACK_ALIGNMENT:
2331 {
2332 GLint temp = 0;
2333
2334 get_integer_internal_20(thread, pname, &temp);
2335
2336 params[0] = (GLfloat)temp;
2337 break;
2338 }
2339 default:
2340 RPC_CALL2_OUT_CTRL(glGetFloatv_impl,
2341 thread,
2342 GLGETFLOATV_ID,
2343 RPC_ENUM(pname),
2344 params);
2345 break;
2346 }
2347 }
2348 }
2349
glGetIntegerv(GLenum pname,GLint * params)2350 GL_API void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *params)
2351 {
2352 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2353 if (IS_OPENGLES_11(thread)) {
2354 switch (pname) {
2355 case GL_VERTEX_ARRAY:
2356 case GL_NORMAL_ARRAY:
2357 case GL_COLOR_ARRAY:
2358 case GL_TEXTURE_COORD_ARRAY:
2359 case GL_POINT_SIZE_ARRAY_OES:
2360 {
2361 GLboolean temp[4];
2362 GLuint count = (GLuint) get_boolean_internal_11(thread, pname, temp);
2363 GLuint i;
2364
2365 vcos_assert(count <= 4);
2366
2367 for (i = 0; i < count; i++)
2368 params[i] = temp[i] ? 1 : 0;
2369
2370 break;
2371 }
2372 case GL_CURRENT_COLOR:
2373 case GL_CURRENT_NORMAL:
2374 {
2375 GLfloat temp[4];
2376 GLuint count = (GLuint) get_float_internal_11(thread, pname, temp);
2377 GLuint i;
2378
2379 vcos_assert(count <= 4);
2380
2381 for (i = 0; i < count; i++)
2382 params[i] = (GLint)floor((4294967295.0f * temp[i] - 1.0f) / 2.0f + 0.5f);
2383
2384 //TODO: that the above is correct wrt table 2.7 in the GL spec
2385
2386 break;
2387 }
2388 case GL_CURRENT_TEXTURE_COORDS:
2389 case GL_POINT_SIZE:
2390 {
2391 GLfloat temp[4];
2392 GLuint count = (GLuint) get_float_internal_11(thread, pname, temp);
2393 GLuint i;
2394
2395 vcos_assert(count <= 4);
2396
2397 for (i = 0; i < count; i++)
2398 params[i] = (GLint) float_to_int(temp[i]);
2399
2400 break;
2401 }
2402 case GL_CLIENT_ACTIVE_TEXTURE:
2403 case GL_VERTEX_ARRAY_SIZE:
2404 case GL_VERTEX_ARRAY_TYPE:
2405 case GL_VERTEX_ARRAY_STRIDE:
2406 case GL_NORMAL_ARRAY_TYPE:
2407 case GL_NORMAL_ARRAY_STRIDE:
2408 case GL_COLOR_ARRAY_SIZE:
2409 case GL_COLOR_ARRAY_TYPE:
2410 case GL_COLOR_ARRAY_STRIDE:
2411 case GL_TEXTURE_COORD_ARRAY_SIZE:
2412 case GL_TEXTURE_COORD_ARRAY_TYPE:
2413 case GL_TEXTURE_COORD_ARRAY_STRIDE:
2414 case GL_POINT_SIZE_ARRAY_TYPE_OES:
2415 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
2416 case GL_MATRIX_INDEX_ARRAY_SIZE_OES:
2417 case GL_MATRIX_INDEX_ARRAY_TYPE_OES:
2418 case GL_MATRIX_INDEX_ARRAY_STRIDE_OES:
2419 case GL_WEIGHT_ARRAY_SIZE_OES:
2420 case GL_WEIGHT_ARRAY_TYPE_OES:
2421 case GL_WEIGHT_ARRAY_STRIDE_OES:
2422 case GL_ARRAY_BUFFER_BINDING:
2423 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2424 case GL_VERTEX_ARRAY_BUFFER_BINDING:
2425 case GL_NORMAL_ARRAY_BUFFER_BINDING:
2426 case GL_COLOR_ARRAY_BUFFER_BINDING:
2427 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2428 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2429 case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES:
2430 case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES:
2431 case GL_UNPACK_ALIGNMENT:
2432 case GL_PACK_ALIGNMENT:
2433 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
2434 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
2435 get_integer_internal_11(thread, pname, params);
2436 break;
2437 default:
2438 RPC_CALL2_OUT_CTRL(glGetIntegerv_impl,
2439 thread,
2440 GLGETINTEGERV_ID,
2441 RPC_ENUM(pname),
2442 params);
2443 break;
2444 }
2445 }
2446 else if (IS_OPENGLES_20(thread)) {
2447 switch (pname) {
2448 case GL_UNPACK_ALIGNMENT:
2449 case GL_PACK_ALIGNMENT:
2450 get_integer_internal_20(thread, pname, params);
2451 break;
2452 default:
2453 RPC_CALL2_OUT_CTRL(glGetIntegerv_impl,
2454 thread,
2455 GLGETINTEGERV_ID,
2456 RPC_ENUM(pname),
2457 params);
2458 break;
2459 }
2460 }
2461 }
2462
glGetLightfv(GLenum light,GLenum pname,GLfloat * params)2463 GL_API void GL_APIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params)
2464 {
2465 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2466 if (IS_OPENGLES_11(thread)) {
2467 RPC_CALL3_OUT_CTRL(glGetLightfv_impl_11,
2468 thread,
2469 GLGETLIGHTFV_ID_11,
2470 RPC_ENUM(light),
2471 RPC_ENUM(pname),
2472 params);
2473 }
2474 }
2475
glGetLightxv(GLenum light,GLenum pname,GLfixed * params)2476 GL_API void GL_APIENTRY glGetLightxv (GLenum light, GLenum pname, GLfixed *params)
2477 {
2478 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2479 if (IS_OPENGLES_11(thread)) {
2480 RPC_CALL3_OUT_CTRL(glGetLightxv_impl_11,
2481 thread,
2482 GLGETLIGHTXV_ID_11,
2483 RPC_ENUM(light),
2484 RPC_ENUM(pname),
2485 params);
2486 }
2487 }
2488
glGetMaterialfv(GLenum face,GLenum pname,GLfloat * params)2489 GL_API void GL_APIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params)
2490 {
2491 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2492 if (IS_OPENGLES_11(thread)) {
2493 RPC_CALL3_OUT_CTRL(glGetMaterialfv_impl_11,
2494 thread,
2495 GLGETMATERIALFV_ID_11,
2496 RPC_ENUM(face),
2497 RPC_ENUM(pname),
2498 params);
2499 }
2500 }
2501
glGetMaterialxv(GLenum face,GLenum pname,GLfixed * params)2502 GL_API void GL_APIENTRY glGetMaterialxv (GLenum face, GLenum pname, GLfixed *params)
2503 {
2504 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2505 if (IS_OPENGLES_11(thread)) {
2506 RPC_CALL3_OUT_CTRL(glGetMaterialxv_impl_11,
2507 thread,
2508 GLGETMATERIALXV_ID_11,
2509 RPC_ENUM(face),
2510 RPC_ENUM(pname),
2511 params);
2512 }
2513 }
2514
2515 /*
2516 VERTEX ARRAY POINTER GetPointerv
2517 NORMAL ARRAY POINTER GetPointerv
2518 COLOR ARRAY POINTER GetPointerv
2519 TEXTURE COORD ARRAY POINTER GetPointerv
2520 POINT SIZE ARRAY POINTER OES GetPointerv
2521 MATRIX_INDEX_ARRAY_POINTER_OES GetPointerv
2522 WEIGHT_ARRAY_POINTER_OES GetPointerv
2523 */
2524
glGetPointerv(GLenum pname,GLvoid ** params)2525 GL_API void GL_APIENTRY glGetPointerv (GLenum pname, GLvoid **params)
2526 {
2527 void *result = NULL;
2528
2529 switch (pname) {
2530 case GL_VERTEX_ARRAY_POINTER:
2531 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_VERTEX);
2532 break;
2533 case GL_NORMAL_ARRAY_POINTER:
2534 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_NORMAL);
2535 break;
2536 case GL_COLOR_ARRAY_POINTER:
2537 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_COLOR);
2538 break;
2539 case GL_TEXTURE_COORD_ARRAY_POINTER:
2540 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_CLIENT_ACTIVE_TEXTURE);
2541 break;
2542 case GL_POINT_SIZE_ARRAY_POINTER_OES:
2543 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_POINT_SIZE);
2544 break;
2545 #if GL_OES_matrix_palette
2546 case GL_MATRIX_INDEX_ARRAY_POINTER_OES:
2547 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_MATRIX_INDEX);
2548 break;
2549 case GL_WEIGHT_ARRAY_POINTER_OES:
2550 result = glintAttribGetPointer(GLXX_API_11, GL11_IX_MATRIX_WEIGHT);
2551 break;
2552 #endif
2553 default:
2554 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
2555 break;
2556 }
2557
2558 if (result != NULL)
2559 params[0] = result;
2560 }
2561
glGetProgramiv(GLuint program,GLenum pname,GLint * params)2562 GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params)
2563 {
2564 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2565 if (IS_OPENGLES_20(thread)) {
2566 RPC_CALL3_OUT_CTRL(glGetProgramiv_impl_20,
2567 thread,
2568 GLGETPROGRAMIV_ID_20,
2569 RPC_UINT(program),
2570 RPC_ENUM(pname),
2571 params);
2572 }
2573 }
2574
glGetProgramInfoLog(GLuint program,GLsizei bufsize,GLsizei * length,char * infolog)2575 GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei *length, char *infolog)
2576 {
2577 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2578 if (IS_OPENGLES_20(thread)) {
2579 #ifdef RPC_DIRECT
2580 RPC_CALL4(glGetProgramInfoLog_impl_20, thread, no_id, program, bufsize, length, infolog);
2581 #else
2582 GLuint result[1];
2583
2584 rpc_begin(thread);
2585
2586 RPC_CALL3_OUT_CTRL(no_function,
2587 thread,
2588 GLGETPROGRAMINFOLOG_ID_20,
2589 RPC_UINT(program),
2590 RPC_SIZEI(bufsize),
2591 result);
2592
2593 if (length)
2594 *length = (GLsizei)result[0];
2595
2596 read_out_bulk(thread, infolog);
2597
2598 rpc_end(thread);
2599 #endif
2600 }
2601 }
2602
glGetString(GLenum name)2603 GL_API const GLubyte * GL_APIENTRY glGetString (GLenum name)
2604 {
2605 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2606 if (IS_OPENGLES_11(thread)) {
2607 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2608
2609 vcos_assert(state != NULL);
2610
2611 switch (name) {
2612 case GL_VENDOR:
2613 #ifndef NDEBUG
2614 return (const GLubyte *)"Broadcom DEBUG";
2615 #else
2616 return (const GLubyte *)"Broadcom";
2617 #endif
2618 case GL_RENDERER:
2619 return (const GLubyte *)"VideoCore IV HW";
2620 case GL_VERSION:
2621 return (const GLubyte *)"OpenGL ES-CM 1.1";
2622 case GL_EXTENSIONS:
2623 return (const GLubyte *)"GL_OES_compressed_ETC1_RGB8_texture "
2624 "GL_OES_compressed_paletted_texture "
2625 "GL_OES_texture_npot " /*TODO is npot right? I can't find it in glext.h */
2626 "GL_OES_EGL_image "
2627 "GL_OES_EGL_image_external "
2628 "GL_EXT_discard_framebuffer "
2629 "GL_OES_query_matrix "
2630 "GL_OES_framebuffer_object "
2631 "GL_OES_rgb8_rgba8 "
2632 "GL_OES_depth24 "
2633 "GL_OES_depth32 "
2634 "GL_OES_stencil8 "
2635 "GL_OES_draw_texture "
2636 "GL_OES_mapbuffer "
2637 #if GL_EXT_texture_format_BGRA8888
2638 "GL_EXT_texture_format_BGRA8888 "
2639 #endif
2640 #if GL_APPLE_rgb_422
2641 "GL_APPLE_rgb_422 "
2642 #endif
2643 #if GL_OES_matrix_palette
2644 "GL_OES_matrix_palette "
2645 #endif
2646 #ifdef GL_EXT_debug_marker
2647 "GL_EXT_debug_marker "
2648 #endif
2649 ;
2650 default:
2651 set_error(state, GL_INVALID_ENUM);
2652 return NULL;
2653 }
2654 }
2655 else if (IS_OPENGLES_20(thread)) {
2656 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2657
2658 vcos_assert(state != NULL);
2659
2660 switch (name) {
2661 case GL_VENDOR:
2662 #ifndef NDEBUG
2663 return (const GLubyte *)"Broadcom DEBUG";
2664 #else
2665 return (const GLubyte *)"Broadcom";
2666 #endif
2667 case GL_RENDERER:
2668 return (const GLubyte *)"VideoCore IV HW";
2669 case GL_VERSION:
2670 return (const GLubyte *)"OpenGL ES 2.0";
2671 case GL_SHADING_LANGUAGE_VERSION:
2672 return (const GLubyte *)"OpenGL ES GLSL ES 1.00";
2673 case GL_EXTENSIONS:
2674 return (const GLubyte *)"GL_OES_compressed_ETC1_RGB8_texture "
2675 "GL_OES_compressed_paletted_texture "
2676 "GL_OES_texture_npot "
2677 "GL_OES_depth24 "
2678 "GL_OES_vertex_half_float "
2679 "GL_OES_EGL_image "
2680 "GL_OES_EGL_image_external "
2681 "GL_EXT_discard_framebuffer "
2682 "GL_OES_rgb8_rgba8 "
2683 "GL_OES_depth32 "
2684 "GL_OES_mapbuffer "
2685 #if GL_EXT_texture_format_BGRA8888
2686 "GL_EXT_texture_format_BGRA8888 "
2687 #endif
2688 #if GL_APPLE_rgb_422
2689 "GL_APPLE_rgb_422 "
2690 #endif
2691 #ifdef GL_EXT_debug_marker
2692 "GL_EXT_debug_marker "
2693 #endif
2694 ;
2695 default:
2696 set_error(state, GL_INVALID_ENUM);
2697 return NULL;
2698 }
2699 }
2700
2701 return NULL;
2702 }
2703
glGetTexEnviv(GLenum env,GLenum pname,GLint * params)2704 GL_API void GL_APIENTRY glGetTexEnviv (GLenum env, GLenum pname, GLint *params)
2705 {
2706 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2707 if (IS_OPENGLES_11(thread)) {
2708 RPC_CALL3_OUT_CTRL(glGetTexEnviv_impl_11,
2709 thread,
2710 GLGETTEXENVIV_ID_11,
2711 RPC_ENUM(env),
2712 RPC_ENUM(pname),
2713 params);
2714 }
2715 }
2716
glGetTexEnvfv(GLenum env,GLenum pname,GLfloat * params)2717 GL_API void GL_APIENTRY glGetTexEnvfv (GLenum env, GLenum pname, GLfloat *params)
2718 {
2719 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2720 if (IS_OPENGLES_11(thread)) {
2721 RPC_CALL3_OUT_CTRL(glGetTexEnvfv_impl_11,
2722 thread,
2723 GLGETTEXENVFV_ID_11,
2724 RPC_ENUM(env),
2725 RPC_ENUM(pname),
2726 params);
2727 }
2728 }
2729
glGetTexEnvxv(GLenum env,GLenum pname,GLfixed * params)2730 GL_API void GL_APIENTRY glGetTexEnvxv (GLenum env, GLenum pname, GLfixed *params)
2731 {
2732 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2733 if (IS_OPENGLES_11(thread)) {
2734 RPC_CALL3_OUT_CTRL(glGetTexEnvxv_impl_11,
2735 thread,
2736 GLGETTEXENVXV_ID_11,
2737 RPC_ENUM(env),
2738 RPC_ENUM(pname),
2739 params);
2740 }
2741 }
2742
glGetTexParameteriv(GLenum target,GLenum pname,GLint * params)2743 GL_API void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params)
2744 {
2745 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2746 if (IS_OPENGLES_11_OR_20(thread)) {
2747 RPC_CALL3_OUT_CTRL(glGetTexParameteriv_impl,
2748 thread,
2749 GLGETTEXPARAMETERIV_ID,
2750 RPC_ENUM(target),
2751 RPC_ENUM(pname),
2752 params);
2753 }
2754 }
2755
glGetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)2756 GL_API void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params)
2757 {
2758 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2759 if (IS_OPENGLES_11_OR_20(thread)) {
2760 RPC_CALL3_OUT_CTRL(glGetTexParameterfv_impl,
2761 thread,
2762 GLGETTEXPARAMETERFV_ID,
2763 RPC_ENUM(target),
2764 RPC_ENUM(pname),
2765 params);
2766 }
2767 }
2768
glGetTexParameterxv(GLenum target,GLenum pname,GLfixed * params)2769 GL_API void GL_APIENTRY glGetTexParameterxv (GLenum target, GLenum pname, GLfixed *params)
2770 {
2771 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2772 if (IS_OPENGLES_11(thread)) {
2773 RPC_CALL3_OUT_CTRL(glGetTexParameterxv_impl_11,
2774 thread,
2775 GLGETTEXPARAMETERXV_ID_11,
2776 RPC_ENUM(target),
2777 RPC_ENUM(pname),
2778 params);
2779 }
2780 }
2781
glGetUniformfv(GLuint program,GLint location,GLfloat * params)2782 GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params)
2783 {
2784 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2785 if (IS_OPENGLES_20(thread)) {
2786 RPC_CALL3_OUT_CTRL(glGetUniformfv_impl_20,
2787 thread,
2788 GLGETUNIFORMFV_ID_20,
2789 RPC_UINT(program),
2790 RPC_INT(location),
2791 params);
2792 }
2793 }
2794
glGetUniformiv(GLuint program,GLint location,GLint * params)2795 GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params)
2796 {
2797 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2798 if (IS_OPENGLES_20(thread)) {
2799 RPC_CALL3_OUT_CTRL(glGetUniformiv_impl_20,
2800 thread,
2801 GLGETUNIFORMIV_ID_20,
2802 RPC_UINT(program),
2803 RPC_INT(location),
2804 params);
2805 }
2806 }
2807
glGetUniformLocation(GLuint program,const char * name)2808 GL_APICALL int GL_APIENTRY glGetUniformLocation (GLuint program, const char *name)
2809 {
2810 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2811 if (IS_OPENGLES_20(thread)) {
2812 return RPC_INT_RES(RPC_CALL2_IN_BULK_RES(glGetUniformLocation_impl_20,
2813 thread,
2814 GLGETUNIFORMLOCATION_ID_20,
2815 RPC_UINT(program),
2816 name,
2817 strlen(name) + 1));
2818 }
2819
2820 return 0;
2821 }
2822
2823 /*
2824 GetVertexAttrib
2825
2826 VERTEX ATTRIB ARRAY ENABLED False GetVertexAttrib
2827 VERTEX ATTRIB ARRAY SIZE 4 GetVertexAttrib
2828 VERTEX ATTRIB ARRAY STRIDE 0 GetVertexAttrib
2829 VERTEX ATTRIB ARRAY TYPE FLOAT GetVertexAttrib
2830 VERTEX ATTRIB ARRAY NORMALIZED False GetVertexAttrib
2831 VERTEX ATTRIB ARRAY BUFFER BINDING 0 GetVertexAttrib
2832
2833 CURRENT VERTEX ATTRIB 0,0,0,1 GetVertexAttributes
2834 */
2835
glGetVertexAttribfv(GLuint index,GLenum pname,GLfloat * params)2836 GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params)
2837 {
2838 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2839 if (IS_OPENGLES_20(thread)) {
2840 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2841
2842 vcos_assert(state != NULL);
2843
2844 if (index < GL20_CONFIG_MAX_VERTEX_ATTRIBS)
2845 switch (pname) {
2846 case GL_CURRENT_VERTEX_ATTRIB:
2847 params[0] = state->attrib[index].value[0];
2848 params[1] = state->attrib[index].value[1];
2849 params[2] = state->attrib[index].value[2];
2850 params[3] = state->attrib[index].value[3];
2851 break;
2852
2853 //TODO: is this the best way to handle conversions? We duplicate
2854 //the entire switch statement.
2855 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2856 params[0] = state->attrib[index].enabled ? 1.0f : 0.0f;
2857 break;
2858 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2859 params[0] = (GLfloat)state->attrib[index].size;
2860 break;
2861 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2862 params[0] = (GLfloat)state->attrib[index].stride;
2863 break;
2864 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2865 params[0] = (GLfloat)state->attrib[index].type;
2866 break;
2867 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2868 params[0] = state->attrib[index].normalized ? 1.0f : 0.0f;
2869 break;
2870 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2871 params[0] = (GLfloat)state->attrib[index].buffer;
2872 break;
2873
2874 default:
2875 set_error(state, GL_INVALID_ENUM);
2876 break;
2877 }
2878 else
2879 set_error(state, GL_INVALID_VALUE);
2880 }
2881 }
2882
glGetVertexAttribiv(GLuint index,GLenum pname,GLint * params)2883 GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params)
2884 {
2885 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2886 if (IS_OPENGLES_20(thread)) {
2887 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
2888
2889 vcos_assert(state != NULL);
2890
2891 if (index < GL20_CONFIG_MAX_VERTEX_ATTRIBS)
2892 switch (pname) {
2893 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2894 params[0] = (GLint) state->attrib[index].enabled ? GL_TRUE : GL_FALSE;
2895 break;
2896 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2897 params[0] = (GLint) state->attrib[index].size;
2898 break;
2899 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2900 params[0] = (GLint) state->attrib[index].stride;
2901 break;
2902 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2903 params[0] = (GLint) state->attrib[index].type;
2904 break;
2905 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2906 params[0] = (GLint) state->attrib[index].normalized ? GL_TRUE : GL_FALSE;
2907 break;
2908 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2909 params[0] = (GLint) state->attrib[index].buffer;
2910 break;
2911
2912 //TODO: is this the best way to handle conversions? We duplicate
2913 //the entire switch statement.
2914 case GL_CURRENT_VERTEX_ATTRIB:
2915 params[0] = (GLint)state->attrib[index].value[0];
2916 params[1] = (GLint)state->attrib[index].value[1];
2917 params[2] = (GLint)state->attrib[index].value[2];
2918 params[3] = (GLint)state->attrib[index].value[3];
2919 break;
2920
2921 default:
2922 set_error(state, GL_INVALID_ENUM);
2923 break;
2924 }
2925 else
2926 set_error(state, GL_INVALID_VALUE);
2927 }
2928 }
2929
2930 /*
2931 GetVertexAttribPointer
2932
2933 VERTEX ATTRIB ARRAY POINTER NULL GetVertexAttribPointer
2934 */
2935
glGetVertexAttribPointerv(GLuint index,GLenum pname,void ** pointer)2936 GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer)
2937 {
2938 void *result = NULL;
2939
2940 if (pname == GL_VERTEX_ATTRIB_ARRAY_POINTER)
2941 result = glintAttribGetPointer(GLXX_API_20, index);
2942 else
2943 glxx_set_error_api(GLXX_API_20, GL_INVALID_ENUM);
2944
2945 if (result != NULL)
2946 *pointer = result;
2947 }
2948
glHint(GLenum target,GLenum mode)2949 GL_API void GL_APIENTRY glHint (GLenum target, GLenum mode)
2950 {
2951 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2952 if (IS_OPENGLES_11_OR_20(thread)) {
2953 RPC_CALL2(glHint_impl,
2954 thread,
2955 GLHINT_ID,
2956 RPC_ENUM(target),
2957 RPC_ENUM(mode));
2958 }
2959 }
2960
glIsBuffer(GLuint buffer)2961 GL_API GLboolean GL_APIENTRY glIsBuffer (GLuint buffer)
2962 {
2963 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2964 if (IS_OPENGLES_11_OR_20(thread)) {
2965 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsBuffer_impl,
2966 thread,
2967 GLISBUFFER_ID,
2968 RPC_UINT(buffer)));
2969 }
2970
2971 return 0;
2972 }
2973
glIsEnabled(GLenum cap)2974 GL_API GLboolean GL_APIENTRY glIsEnabled (GLenum cap)
2975 {
2976 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
2977 if (IS_OPENGLES_11(thread)) {
2978 switch (cap) {
2979 case GL_VERTEX_ARRAY:
2980 case GL_NORMAL_ARRAY:
2981 case GL_COLOR_ARRAY:
2982 case GL_POINT_SIZE_ARRAY_OES:
2983 case GL_TEXTURE_COORD_ARRAY:
2984 case GL_MATRIX_INDEX_ARRAY_OES:
2985 case GL_WEIGHT_ARRAY_OES:
2986 {
2987 GLboolean temp = 0;
2988 GLuint count = (GLuint) get_boolean_internal_11(thread, cap, &temp);
2989 UNUSED_NDEBUG(count);
2990 vcos_assert(count == 1);
2991
2992 return temp;
2993 }
2994 default:
2995 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsEnabled_impl,
2996 thread,
2997 GLISENABLED_ID,
2998 RPC_ENUM(cap)));
2999 }
3000 }
3001 else if (IS_OPENGLES_20(thread)) {
3002 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsEnabled_impl,
3003 thread,
3004 GLISENABLED_ID,
3005 RPC_ENUM(cap)));
3006 }
3007
3008 return 0;
3009 }
3010
glIsProgram(GLuint program)3011 GL_API GLboolean GL_APIENTRY glIsProgram (GLuint program)
3012 {
3013 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3014 if (IS_OPENGLES_20(thread)) {
3015 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsProgram_impl_20,
3016 thread,
3017 GLISPROGRAM_ID_20,
3018 RPC_UINT(program)));
3019 }
3020
3021 return 0;
3022 }
3023
glIsShader(GLuint shader)3024 GL_API GLboolean GL_APIENTRY glIsShader (GLuint shader)
3025 {
3026 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3027 if (IS_OPENGLES_20(thread)) {
3028 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsShader_impl_20,
3029 thread,
3030 GLISSHADER_ID_20,
3031 RPC_UINT(shader)));
3032 }
3033
3034 return 0;
3035 }
3036
glIsTexture(GLuint texture)3037 GL_API GLboolean GL_APIENTRY glIsTexture (GLuint texture)
3038 {
3039 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3040 if (IS_OPENGLES_11_OR_20(thread)) {
3041 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsTexture_impl,
3042 thread,
3043 GLISTEXTURE_ID,
3044 RPC_UINT(texture)));
3045 }
3046 return 0;
3047 }
3048
glLightModelf(GLenum pname,GLfloat param)3049 GL_API void GL_APIENTRY glLightModelf (GLenum pname, GLfloat param)
3050 {
3051 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3052 if (IS_OPENGLES_11(thread)) {
3053 RPC_CALL2(glLightModelf_impl_11,
3054 thread,
3055 GLLIGHTMODELF_ID_11,
3056 RPC_ENUM(pname),
3057 RPC_FLOAT(param));
3058 }
3059 }
3060
glLightModelfv(GLenum pname,const GLfloat * params)3061 GL_API void GL_APIENTRY glLightModelfv (GLenum pname, const GLfloat *params)
3062 {
3063 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3064 if (IS_OPENGLES_11(thread)) {
3065 /*
3066 the only supported lighting model params are
3067
3068 LIGHT_MODEL_AMBIENT (4)
3069 LIGHT_MODEL_TWO_SIDE (1)
3070
3071 so we need to transmit 4 words of parameter data
3072 */
3073
3074 RPC_CALL2_IN_CTRL(glLightModelfv_impl_11,
3075 thread,
3076 GLLIGHTMODELFV_ID_11,
3077 RPC_ENUM(pname),
3078 params,
3079 4 * sizeof(GLfloat));
3080 }
3081 }
3082
glLightModelx(GLenum pname,GLfixed param)3083 GL_API void GL_APIENTRY glLightModelx (GLenum pname, GLfixed param)
3084 {
3085 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3086 if (IS_OPENGLES_11(thread)) {
3087 RPC_CALL2(glLightModelx_impl_11,
3088 thread,
3089 GLLIGHTMODELX_ID_11,
3090 RPC_ENUM(pname),
3091 RPC_FIXED(param));
3092 }
3093 }
3094
glLightModelxv(GLenum pname,const GLfixed * params)3095 GL_API void GL_APIENTRY glLightModelxv (GLenum pname, const GLfixed *params)
3096 {
3097 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3098 if (IS_OPENGLES_11(thread)) {
3099 /*
3100 the only supported lighting model params are
3101
3102 LIGHT_MODEL_AMBIENT (4)
3103 LIGHT_MODEL_TWO_SIDE (1)
3104
3105 so we need to transmit 4 words of parameter data
3106 */
3107
3108 RPC_CALL2_IN_CTRL(glLightModelxv_impl_11,
3109 thread,
3110 GLLIGHTMODELXV_ID_11,
3111 RPC_ENUM(pname),
3112 params,
3113 4 * sizeof(GLfixed));
3114 }
3115 }
3116
glLightf(GLenum light,GLenum pname,GLfloat param)3117 GL_API void GL_APIENTRY glLightf (GLenum light, GLenum pname, GLfloat param)
3118 {
3119 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3120 if (IS_OPENGLES_11(thread)) {
3121 RPC_CALL3(glLightf_impl_11,
3122 thread,
3123 GLLIGHTF_ID_11,
3124 RPC_ENUM(light),
3125 RPC_ENUM(pname),
3126 RPC_FLOAT(param));
3127 }
3128 }
3129
glLightfv(GLenum light,GLenum pname,const GLfloat * params)3130 GL_API void GL_APIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params)
3131 {
3132 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3133 if (IS_OPENGLES_11(thread)) {
3134 /*
3135 the only supported light params are
3136
3137 AMBIENT (4)
3138 DIFFUSE (4)
3139 SPECULAR (4)
3140 POSITION (4)
3141 SPOT_DIRECTION (3)
3142 SPOT_EXPONENT (1)
3143 SPOT_CUTOFF (1)
3144 CONSTANT_ATTENUATION (1)
3145 LINEAR_ATTENUATION (1)
3146 QUADRATIC_ATTENUATION (1)
3147
3148 so we need to transmit 4 words of parameter data
3149 */
3150
3151 RPC_CALL3_IN_CTRL(glLightfv_impl_11,
3152 thread,
3153 GLLIGHTFV_ID_11,
3154 RPC_ENUM(light),
3155 RPC_ENUM(pname),
3156 params,
3157 4 * sizeof(GLfloat));
3158 }
3159 }
3160
glLightx(GLenum light,GLenum pname,GLfixed param)3161 GL_API void GL_APIENTRY glLightx (GLenum light, GLenum pname, GLfixed param)
3162 {
3163 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3164 if (IS_OPENGLES_11(thread)) {
3165 RPC_CALL3(glLightx_impl_11,
3166 thread,
3167 GLLIGHTX_ID_11,
3168 RPC_ENUM(light),
3169 RPC_ENUM(pname),
3170 RPC_FIXED(param));
3171 }
3172 }
3173
glLightxv(GLenum light,GLenum pname,const GLfixed * params)3174 GL_API void GL_APIENTRY glLightxv (GLenum light, GLenum pname, const GLfixed *params)
3175 {
3176 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3177 if (IS_OPENGLES_11(thread)) {
3178 /*
3179 the only supported light params are
3180
3181 AMBIENT (4)
3182 DIFFUSE (4)
3183 SPECULAR (4)
3184 POSITION (4)
3185 SPOT_DIRECTION (3)
3186 SPOT_EXPONENT (1)
3187 SPOT_CUTOFF (1)
3188 CONSTANT_ATTENUATION (1)
3189 LINEAR_ATTENUATION (1)
3190 QUADRATIC_ATTENUATION (1)
3191
3192 so we need to transmit 4 words of parameter data
3193 */
3194
3195 RPC_CALL3_IN_CTRL(glLightxv_impl_11,
3196 thread,
3197 GLLIGHTXV_ID_11,
3198 RPC_ENUM(light),
3199 RPC_ENUM(pname),
3200 params,
3201 4 * sizeof(GLfixed));
3202 }
3203 }
3204
glLineWidth(GLfloat width)3205 GL_API void GL_APIENTRY glLineWidth (GLfloat width)
3206 {
3207 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3208 if (IS_OPENGLES_11_OR_20(thread)) {
3209 RPC_CALL1(glLineWidth_impl,
3210 thread,
3211 GLLINEWIDTH_ID,
3212 RPC_FLOAT(width));
3213 }
3214 }
3215
glLineWidthx(GLfixed width)3216 GL_API void GL_APIENTRY glLineWidthx (GLfixed width)
3217 {
3218 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3219 if (IS_OPENGLES_11(thread)) {
3220 RPC_CALL1(glLineWidthx_impl_11,
3221 thread,
3222 GLLINEWIDTHX_ID_11,
3223 RPC_FIXED(width));
3224 }
3225 }
3226
glLinkProgram(GLuint program)3227 GL_API void GL_APIENTRY glLinkProgram (GLuint program)
3228 {
3229 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3230 if (IS_OPENGLES_20(thread)) {
3231 RPC_CALL1(glLinkProgram_impl_20,
3232 thread,
3233 GLLINKPROGRAM_ID_20,
3234 RPC_UINT(program));
3235 }
3236 }
3237
glLoadIdentity(void)3238 GL_API void GL_APIENTRY glLoadIdentity (void)
3239 {
3240 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3241 if (IS_OPENGLES_11(thread)) {
3242 RPC_CALL0(glLoadIdentity_impl_11,
3243 thread,
3244 GLLOADIDENTITY_ID_11);
3245 }
3246 }
3247
glLoadMatrixf(const GLfloat * m)3248 GL_API void GL_APIENTRY glLoadMatrixf (const GLfloat *m)
3249 {
3250 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3251 if (IS_OPENGLES_11(thread)) {
3252 RPC_CALL1_IN_CTRL(glLoadMatrixf_impl_11,
3253 thread,
3254 GLLOADMATRIXF_ID_11,
3255 m,
3256 16 * sizeof(GLfloat));
3257 }
3258 }
3259
glLoadMatrixx(const GLfixed * m)3260 GL_API void GL_APIENTRY glLoadMatrixx (const GLfixed *m)
3261 {
3262 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3263 if (IS_OPENGLES_11(thread)) {
3264 RPC_CALL1_IN_CTRL(glLoadMatrixx_impl_11,
3265 thread,
3266 GLLOADMATRIXX_ID_11,
3267 m,
3268 16 * sizeof(GLfixed));
3269 }
3270 }
3271
glLogicOp(GLenum opcode)3272 GL_API void GL_APIENTRY glLogicOp (GLenum opcode)
3273 {
3274 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3275 if (IS_OPENGLES_11(thread)) {
3276 RPC_CALL1(glLogicOp_impl_11,
3277 thread,
3278 GLLOGICOP_ID_11,
3279 RPC_ENUM(opcode));
3280 }
3281 }
3282
glMaterialf(GLenum face,GLenum pname,GLfloat param)3283 GL_API void GL_APIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param)
3284 {
3285 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3286 if (IS_OPENGLES_11(thread)) {
3287 RPC_CALL3(glMaterialf_impl_11,
3288 thread,
3289 GLMATERIALF_ID_11,
3290 RPC_ENUM(face),
3291 RPC_ENUM(pname),
3292 RPC_FLOAT(param));
3293 }
3294 }
3295
glMaterialfv(GLenum face,GLenum pname,const GLfloat * params)3296 GL_API void GL_APIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params)
3297 {
3298 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3299 if (IS_OPENGLES_11(thread)) {
3300 /*
3301 the only supported material params are
3302
3303 AMBIENT (4)
3304 DIFFUSE (4)
3305 SPECULAR (4)
3306 EMISSION (4)
3307 SHININESS (1)
3308
3309 so we need to transmit 4 words of parameter data
3310 */
3311
3312 RPC_CALL3_IN_CTRL(glMaterialfv_impl_11,
3313 thread,
3314 GLMATERIALFV_ID_11,
3315 RPC_ENUM(face),
3316 RPC_ENUM(pname),
3317 params,
3318 4 * sizeof(GLfloat));
3319 }
3320 }
3321
glMaterialx(GLenum face,GLenum pname,GLfixed param)3322 GL_API void GL_APIENTRY glMaterialx (GLenum face, GLenum pname, GLfixed param)
3323 {
3324 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3325 if (IS_OPENGLES_11(thread)) {
3326 RPC_CALL3(glMaterialx_impl_11,
3327 thread,
3328 GLMATERIALX_ID_11,
3329 RPC_ENUM(face),
3330 RPC_ENUM(pname),
3331 RPC_FIXED(param));
3332 }
3333 }
3334
glMaterialxv(GLenum face,GLenum pname,const GLfixed * params)3335 GL_API void GL_APIENTRY glMaterialxv (GLenum face, GLenum pname, const GLfixed *params)
3336 {
3337 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3338 if (IS_OPENGLES_11(thread)) {
3339 /*
3340 the only supported material params are
3341
3342 AMBIENT (4)
3343 DIFFUSE (4)
3344 SPECULAR (4)
3345 EMISSION (4)
3346 SHININESS (1)
3347
3348 so we need to transmit 4 words of parameter data
3349 */
3350
3351 RPC_CALL3_IN_CTRL(glMaterialxv_impl_11,
3352 thread,
3353 GLMATERIALXV_ID_11,
3354 RPC_ENUM(face),
3355 RPC_ENUM(pname),
3356 params,
3357 4 * sizeof(GLfixed));
3358 }
3359 }
3360
glMatrixMode(GLenum mode)3361 GL_API void GL_APIENTRY glMatrixMode (GLenum mode)
3362 {
3363 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3364 if (IS_OPENGLES_11(thread)) {
3365 RPC_CALL1(glMatrixMode_impl_11,
3366 thread,
3367 GLMATRIXMODE_ID_11,
3368 RPC_ENUM(mode));
3369 }
3370 }
3371
glMultMatrixf(const GLfloat * m)3372 GL_API void GL_APIENTRY glMultMatrixf (const GLfloat *m)
3373 {
3374 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3375 if (IS_OPENGLES_11(thread)) {
3376 RPC_CALL1_IN_CTRL(glMultMatrixf_impl_11,
3377 thread,
3378 GLMULTMATRIXF_ID_11,
3379 m,
3380 16 * sizeof(GLfloat));
3381 }
3382 }
3383
glMultMatrixx(const GLfixed * m)3384 GL_API void GL_APIENTRY glMultMatrixx (const GLfixed *m)
3385 {
3386 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3387 if (IS_OPENGLES_11(thread)) {
3388 RPC_CALL1_IN_CTRL(glMultMatrixx_impl_11,
3389 thread,
3390 GLMULTMATRIXX_ID_11,
3391 m,
3392 16 * sizeof(GLfixed));
3393 }
3394 }
3395
glMultiTexCoord4f(GLenum target,GLfloat s,GLfloat t,GLfloat r,GLfloat q)3396 GL_API void GL_APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
3397 {
3398 if (target >= GL_TEXTURE0 && target < GL_TEXTURE0 + GL11_CONFIG_MAX_TEXTURE_UNITS) {
3399 uint32_t indx = GL11_IX_TEXTURE_COORD + target - GL_TEXTURE0;
3400 glintAttrib(GLXX_API_11, indx, s, t, r, q);
3401 } else
3402 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
3403 }
3404
glMultiTexCoord4x(GLenum target,GLfixed s,GLfixed t,GLfixed r,GLfixed q)3405 GL_API void GL_APIENTRY glMultiTexCoord4x (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
3406 {
3407 if (target >= GL_TEXTURE0 && target < GL_TEXTURE0 + GL11_CONFIG_MAX_TEXTURE_UNITS) {
3408 uint32_t indx = GL11_IX_TEXTURE_COORD + target - GL_TEXTURE0;
3409 glintAttrib(GLXX_API_11, indx, fixed_to_float(s), fixed_to_float(t), fixed_to_float(r), fixed_to_float(q));
3410 } else
3411 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
3412 }
3413
glNormal3f(GLfloat nx,GLfloat ny,GLfloat nz)3414 GL_API void GL_APIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz)
3415 {
3416 glintAttrib(GLXX_API_11, GL11_IX_NORMAL, nx, ny, nz, 0.0f);
3417 }
3418
glNormal3x(GLfixed nx,GLfixed ny,GLfixed nz)3419 GL_API void GL_APIENTRY glNormal3x (GLfixed nx, GLfixed ny, GLfixed nz)
3420 {
3421 glintAttrib(GLXX_API_11, GL11_IX_NORMAL, fixed_to_float(nx), fixed_to_float(ny), fixed_to_float(nz), 0.0f);
3422 }
3423
is_normal_type(GLenum type)3424 static bool is_normal_type(GLenum type)
3425 {
3426 return type == GL_BYTE ||
3427 type == GL_SHORT ||
3428 type == GL_FIXED ||
3429 type == GL_FLOAT;
3430 }
3431
glNormalPointer(GLenum type,GLsizei stride,const GLvoid * pointer)3432 GL_API void GL_APIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer)
3433 {
3434 if (is_normal_type(type)) {
3435 if (is_aligned(type, (size_t)pointer) && is_aligned(type, (size_t)stride) && stride >= 0) {
3436 glintAttribPointer(GLXX_API_11, GL11_IX_NORMAL, 3, type, GL_TRUE, stride, pointer);
3437 } else
3438 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
3439 } else
3440 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
3441 }
3442
glOrthof(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)3443 GL_API void GL_APIENTRY glOrthof (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
3444 {
3445 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3446 if (IS_OPENGLES_11(thread)) {
3447 RPC_CALL6(glOrthof_impl_11,
3448 thread,
3449 GLORTHOF_ID_11,
3450 RPC_FLOAT(left),
3451 RPC_FLOAT(right),
3452 RPC_FLOAT(bottom),
3453 RPC_FLOAT(top),
3454 RPC_FLOAT(zNear),
3455 RPC_FLOAT(zFar));
3456 }
3457 }
3458
glOrthox(GLfixed left,GLfixed right,GLfixed bottom,GLfixed top,GLfixed zNear,GLfixed zFar)3459 GL_API void GL_APIENTRY glOrthox (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
3460 {
3461 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3462 if (IS_OPENGLES_11(thread)) {
3463 RPC_CALL6(glOrthox_impl_11,
3464 thread,
3465 GLORTHOX_ID_11,
3466 RPC_FIXED(left),
3467 RPC_FIXED(right),
3468 RPC_FIXED(bottom),
3469 RPC_FIXED(top),
3470 RPC_FIXED(zNear),
3471 RPC_FIXED(zFar));
3472 }
3473 }
3474
is_alignment(GLint param)3475 static GLboolean is_alignment(GLint param)
3476 {
3477 return param == 1 ||
3478 param == 2 ||
3479 param == 4 ||
3480 param == 8;
3481 }
3482
glPixelStorei(GLenum pname,GLint param)3483 GL_API void GL_APIENTRY glPixelStorei (GLenum pname, GLint param)
3484 {
3485 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3486 if (IS_OPENGLES_11_OR_20(thread)) {
3487 if (is_alignment(param)) {
3488 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
3489
3490 vcos_assert(state != NULL);
3491
3492 switch (pname) {
3493 case GL_PACK_ALIGNMENT:
3494 state->alignment.pack = param;
3495 break;
3496 case GL_UNPACK_ALIGNMENT:
3497 state->alignment.unpack = param;
3498 break;
3499 }
3500 }
3501 }
3502 }
3503
glPointParameterf(GLenum pname,GLfloat param)3504 GL_API void GL_APIENTRY glPointParameterf (GLenum pname, GLfloat param)
3505 {
3506 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3507 if (IS_OPENGLES_11(thread)) {
3508 RPC_CALL2(glPointParameterf_impl_11,
3509 thread,
3510 GLPOINTPARAMETERF_ID_11,
3511 RPC_ENUM(pname),
3512 RPC_FLOAT(param));
3513 }
3514 }
3515
glPointParameterfv(GLenum pname,const GLfloat * params)3516 GL_API void GL_APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params)
3517 {
3518 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3519 if (IS_OPENGLES_11(thread)) {
3520 /*
3521 the only supported material params are
3522
3523 POINT_SIZE_MIN (1)
3524 POINT_SIZE_MAX (1)
3525 POINT_FADE_THRESHOLD_SIZE (1)
3526 POINT_DISTANCE_ATTENUATION (3)
3527
3528 so we need to transmit 3 words of parameter data
3529 */
3530
3531 RPC_CALL2_IN_CTRL(glPointParameterfv_impl_11,
3532 thread,
3533 GLPOINTPARAMETERFV_ID_11,
3534 RPC_ENUM(pname),
3535 params,
3536 3 * sizeof(GLfloat));
3537 }
3538 }
3539
glPointParameterx(GLenum pname,GLfixed param)3540 GL_API void GL_APIENTRY glPointParameterx (GLenum pname, GLfixed param)
3541 {
3542 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3543 if (IS_OPENGLES_11(thread)) {
3544 RPC_CALL2(glPointParameterx_impl_11,
3545 thread,
3546 GLPOINTPARAMETERX_ID_11,
3547 RPC_ENUM(pname),
3548 RPC_FIXED(param));
3549 }
3550 }
3551
glPointParameterxv(GLenum pname,const GLfixed * params)3552 GL_API void GL_APIENTRY glPointParameterxv (GLenum pname, const GLfixed *params)
3553 {
3554 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3555 if (IS_OPENGLES_11(thread)) {
3556 /*
3557 the only supported material params are
3558
3559 POINT_SIZE_MIN (1)
3560 POINT_SIZE_MAX (1)
3561 POINT_FADE_THRESHOLD_SIZE (1)
3562 POINT_DISTANCE_ATTENUATION (3)
3563
3564 so we need to transmit 3 words of parameter data
3565 */
3566
3567 RPC_CALL2_IN_CTRL(glPointParameterxv_impl_11,
3568 thread,
3569 GLPOINTPARAMETERXV_ID_11,
3570 RPC_ENUM(pname),
3571 params,
3572 3 * sizeof(GLfixed));
3573 }
3574 }
3575
glPointSize(GLfloat size)3576 GL_API void GL_APIENTRY glPointSize (GLfloat size)
3577 {
3578 size = clean_float(size);
3579
3580 if (size > 0.0f)
3581 glintAttrib(GLXX_API_11, GL11_IX_POINT_SIZE, size, 0.0f, 0.0f, 0.0f);
3582 else
3583 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
3584 }
3585
glPointSizex(GLfixed size)3586 GL_API void GL_APIENTRY glPointSizex (GLfixed size)
3587 {
3588 if (size > 0)
3589 glintAttrib(GLXX_API_11, GL11_IX_POINT_SIZE, fixed_to_float(size), 0.0f, 0.0f, 0.0f);
3590 else
3591 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
3592 }
3593
glPolygonOffset(GLfloat factor,GLfloat units)3594 GL_API void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units)
3595 {
3596 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3597 if (IS_OPENGLES_11_OR_20(thread)) {
3598 RPC_CALL2(glPolygonOffset_impl,
3599 thread,
3600 GLPOLYGONOFFSET_ID,
3601 RPC_FLOAT(factor),
3602 RPC_FLOAT(units));
3603 }
3604 }
3605
glPolygonOffsetx(GLfixed factor,GLfixed units)3606 GL_API void GL_APIENTRY glPolygonOffsetx (GLfixed factor, GLfixed units)
3607 {
3608 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3609 if (IS_OPENGLES_11(thread)) {
3610 RPC_CALL2(glPolygonOffsetx_impl_11,
3611 thread,
3612 GLPOLYGONOFFSETX_ID_11,
3613 RPC_FIXED(factor),
3614 RPC_FIXED(units));
3615 }
3616 }
3617
glPopMatrix(void)3618 GL_API void GL_APIENTRY glPopMatrix (void)
3619 {
3620 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3621 if (IS_OPENGLES_11(thread)) {
3622 RPC_CALL0(glPopMatrix_impl_11,
3623 thread,
3624 GLPOPMATRIX_ID_11);
3625 }
3626 }
3627
glPushMatrix(void)3628 GL_API void GL_APIENTRY glPushMatrix (void)
3629 {
3630 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3631 if (IS_OPENGLES_11(thread)) {
3632 RPC_CALL0(glPushMatrix_impl_11,
3633 thread,
3634 GLPUSHMATRIX_ID_11);
3635 }
3636 }
3637
3638 /*
3639 we need to calculate on the client side how much data to transfer to the
3640 server on a call to glTexImage2D()
3641
3642 from section 3.6 of the OpenGL ES 1.1 spec
3643
3644 the first element of the Nth row is indicated by
3645
3646 p + Nk
3647
3648 where N is the row number (counting from zero) and k is defined as
3649
3650 k = nl if s >= a
3651 = a/s * ceil(snl/a) otherwise
3652
3653 where n is the number of elements in a group, l is the number of groups in
3654 the row, a is the value of UNPACK ALIGNMENT, and s is the size, in units of GL
3655 ubytes, of an element.
3656
3657 this code is
3658 */
3659
get_pitch(uint32_t w,GLenum format,GLenum type,uint32_t a)3660 static uint32_t get_pitch(uint32_t w, GLenum format, GLenum type, uint32_t a)
3661 {
3662 uint32_t n = 0;
3663 uint32_t s = 0;
3664 uint32_t k = 0;
3665
3666 switch (format) {
3667 case GL_RGBA:
3668 #if GL_EXT_texture_format_BGRA8888
3669 case GL_BGRA_EXT:
3670 #endif
3671 #if GL_texture_format_RGBX8888_BRCM
3672 case GL_RGBX_BRCM:
3673 #endif
3674 switch (type) {
3675 case GL_UNSIGNED_BYTE:
3676 n = 4;
3677 s = 1;
3678 break;
3679 case GL_UNSIGNED_SHORT_4_4_4_4:
3680 case GL_UNSIGNED_SHORT_5_5_5_1:
3681 n = 1;
3682 s = 2;
3683 break;
3684 }
3685 break;
3686 case GL_RGB:
3687 switch (type) {
3688 case GL_UNSIGNED_BYTE:
3689 n = 3;
3690 s = 1;
3691 break;
3692 case GL_UNSIGNED_SHORT_5_6_5:
3693 n = 1;
3694 s = 2;
3695 break;
3696 }
3697 break;
3698 case GL_LUMINANCE_ALPHA:
3699 n = 2;
3700 s = 1;
3701 break;
3702 case GL_LUMINANCE:
3703 case GL_ALPHA:
3704 n = 1;
3705 s = 1;
3706 break;
3707 #if GL_APPLE_rgb_422
3708 case GL_RGB_422_APPLE:
3709 n = 1;
3710 s = 2;
3711 break;
3712 #endif
3713 }
3714
3715 if (s != 0) { /* Avoid division by zero errors on invalid formats */
3716 if (s < a)
3717 k = (a / s) * ((s * n * w + a - 1) / a);
3718 else
3719 k = n * w;
3720 }
3721
3722 switch (format) {
3723 case GL_RGBA:
3724 #if GL_EXT_texture_format_BGRA8888
3725 case GL_BGRA_EXT:
3726 #endif
3727 #if GL_texture_format_RGBX8888_BRCM
3728 case GL_RGBX_BRCM:
3729 #endif
3730 switch (type) {
3731 case GL_UNSIGNED_BYTE:
3732 return k;
3733 case GL_UNSIGNED_SHORT_4_4_4_4:
3734 case GL_UNSIGNED_SHORT_5_5_5_1:
3735 return k * 2;
3736 }
3737 break;
3738 case GL_RGB:
3739 switch (type) {
3740 case GL_UNSIGNED_BYTE:
3741 return k;
3742 case GL_UNSIGNED_SHORT_5_6_5:
3743 return k * 2;
3744 }
3745 break;
3746 case GL_LUMINANCE_ALPHA:
3747 case GL_LUMINANCE:
3748 case GL_ALPHA:
3749 return k;
3750 #if GL_APPLE_rgb_422
3751 case GL_RGB_422_APPLE:
3752 return k * 2;
3753 #endif
3754 }
3755
3756 return 0; // transfer no data, format will be rejected by server
3757 }
3758
glReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)3759 GL_API void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
3760 {
3761 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3762 if (IS_OPENGLES_11_OR_20(thread)) {
3763 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
3764
3765 uint32_t pitch = get_pitch( (uint32_t)width, format, type, (uint32_t) state->alignment.pack);
3766 uint32_t lines = pitch ? (uint32_t) (KHDISPATCH_WORKSPACE_SIZE / pitch) : (uint32_t)height;
3767
3768 if (pixels && lines) {
3769 int offset = 0;
3770
3771 while (height > 0) {
3772 int32_t batch = _min(lines, (int32_t) height);
3773
3774 RPC_CALL8_OUT_BULK(glReadPixels_impl,
3775 thread,
3776 GLREADPIXELS_ID,
3777 RPC_INT(x),
3778 RPC_INT(y + offset),
3779 RPC_SIZEI(width),
3780 RPC_SIZEI(batch),
3781 RPC_ENUM(format),
3782 RPC_ENUM(type),
3783 RPC_INT(state->alignment.pack),
3784 (char *)pixels + offset * pitch);
3785
3786 offset += batch;
3787 height -= batch;
3788 }
3789 }
3790
3791 // We do not call flush_callback as the spec does not imply a full flush
3792 // at this point (I think).
3793 }
3794 }
3795
glRotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)3796 GL_API void GL_APIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3797 {
3798 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3799 if (IS_OPENGLES_11(thread)) {
3800 RPC_CALL4(glRotatef_impl_11,
3801 thread,
3802 GLROTATEF_ID_11,
3803 RPC_FLOAT(angle),
3804 RPC_FLOAT(x),
3805 RPC_FLOAT(y),
3806 RPC_FLOAT(z));
3807 }
3808 }
3809
glRotatex(GLfixed angle,GLfixed x,GLfixed y,GLfixed z)3810 GL_API void GL_APIENTRY glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
3811 {
3812 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3813 if (IS_OPENGLES_11(thread)) {
3814 RPC_CALL4(glRotatex_impl_11,
3815 thread,
3816 GLROTATEX_ID_11,
3817 RPC_FIXED(angle),
3818 RPC_FIXED(x),
3819 RPC_FIXED(y),
3820 RPC_FIXED(z));
3821 }
3822 }
3823
glSampleCoverage(GLclampf value,GLboolean invert)3824 GL_API void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert)
3825 {
3826 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3827 if (IS_OPENGLES_11_OR_20(thread)) {
3828 RPC_CALL2(glSampleCoverage_impl,
3829 thread,
3830 GLSAMPLECOVERAGE_ID,
3831 RPC_FLOAT(value),
3832 RPC_BOOLEAN(invert));
3833 }
3834 }
3835
glSampleCoveragex(GLclampx value,GLboolean invert)3836 GL_API void GL_APIENTRY glSampleCoveragex (GLclampx value, GLboolean invert)
3837 {
3838 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3839 if (IS_OPENGLES_11(thread)) {
3840 RPC_CALL2(glSampleCoveragex_impl_11,
3841 thread,
3842 GLSAMPLECOVERAGEX_ID_11,
3843 RPC_FIXED(value),
3844 RPC_BOOLEAN(invert));
3845 }
3846 }
3847
glScalef(GLfloat x,GLfloat y,GLfloat z)3848 GL_API void GL_APIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z)
3849 {
3850 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3851 if (IS_OPENGLES_11(thread)) {
3852 RPC_CALL3(glScalef_impl_11,
3853 thread,
3854 GLSCALEF_ID_11,
3855 RPC_FLOAT(x),
3856 RPC_FLOAT(y),
3857 RPC_FLOAT(z));
3858 }
3859 }
3860
glScalex(GLfixed x,GLfixed y,GLfixed z)3861 GL_API void GL_APIENTRY glScalex (GLfixed x, GLfixed y, GLfixed z)
3862 {
3863 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3864 if (IS_OPENGLES_11(thread)) {
3865 RPC_CALL3(glScalex_impl_11,
3866 thread,
3867 GLSCALEX_ID_11,
3868 RPC_FIXED(x),
3869 RPC_FIXED(y),
3870 RPC_FIXED(z));
3871 }
3872 }
3873
glScissor(GLint x,GLint y,GLsizei width,GLsizei height)3874 GL_API void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height)
3875 {
3876 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3877 if (IS_OPENGLES_11_OR_20(thread)) {
3878 RPC_CALL4(glScissor_impl,
3879 thread,
3880 GLSCISSOR_ID,
3881 RPC_INT(x),
3882 RPC_INT(y),
3883 RPC_SIZEI(width),
3884 RPC_SIZEI(height));
3885 }
3886 }
3887
glShadeModel(GLenum mode)3888 GL_API void GL_APIENTRY glShadeModel (GLenum mode)
3889 {
3890 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3891 if (IS_OPENGLES_11(thread)) {
3892 RPC_CALL1(glShadeModel_impl_11,
3893 thread,
3894 GLSHADEMODEL_ID_11,
3895 RPC_ENUM(mode));
3896 }
3897 }
3898
set_stencil_func(CLIENT_THREAD_STATE_T * thread,GLenum face,GLenum func,GLint ref,GLuint mask)3899 static void set_stencil_func(CLIENT_THREAD_STATE_T *thread, GLenum face, GLenum func, GLint ref, GLuint mask) {
3900 RPC_CALL4(glStencilFuncSeparate_impl,
3901 thread,
3902 GLSTENCILFUNCSEPARATE_ID,
3903 RPC_ENUM(face),
3904 RPC_ENUM(func),
3905 RPC_INT(ref),
3906 RPC_UINT(mask));
3907 }
3908
glStencilFunc(GLenum func,GLint ref,GLuint mask)3909 GL_API void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask)
3910 {
3911 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3912 if (IS_OPENGLES_11_OR_20(thread)) set_stencil_func(thread, GL_FRONT_AND_BACK, func, ref, mask);
3913 }
3914
glStencilFuncSeparate(GLenum face,GLenum func,GLint ref,GLuint mask)3915 GL_API void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask) // S
3916 {
3917 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3918 if (IS_OPENGLES_20(thread)) set_stencil_func(thread, face, func, ref, mask);
3919 }
3920
set_stencil_mask(CLIENT_THREAD_STATE_T * thread,GLenum face,GLuint mask)3921 static void set_stencil_mask(CLIENT_THREAD_STATE_T *thread, GLenum face, GLuint mask) {
3922 RPC_CALL2(glStencilMaskSeparate_impl,
3923 thread,
3924 GLSTENCILMASKSEPARATE_ID,
3925 RPC_ENUM(face),
3926 RPC_UINT(mask));
3927 }
3928
glStencilMask(GLuint mask)3929 GL_API void GL_APIENTRY glStencilMask (GLuint mask)
3930 {
3931 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3932 if (IS_OPENGLES_11_OR_20(thread)) set_stencil_mask(thread, GL_FRONT_AND_BACK, mask);
3933 }
3934
glStencilMaskSeparate(GLenum face,GLuint mask)3935 GL_API void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask) // S
3936 {
3937 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3938 if (IS_OPENGLES_20(thread)) set_stencil_mask(thread, face, mask);
3939 }
3940
set_stencil_op(CLIENT_THREAD_STATE_T * thread,GLenum face,GLenum fail,GLenum zfail,GLenum zpass)3941 static void set_stencil_op(CLIENT_THREAD_STATE_T *thread, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
3942 RPC_CALL4(glStencilOpSeparate_impl,
3943 thread,
3944 GLSTENCILOPSEPARATE_ID,
3945 RPC_ENUM(face),
3946 RPC_ENUM(fail),
3947 RPC_ENUM(zfail),
3948 RPC_ENUM(zpass));
3949 }
3950
glStencilOp(GLenum fail,GLenum zfail,GLenum zpass)3951 GL_API void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass)
3952 {
3953 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3954 if (IS_OPENGLES_11_OR_20(thread)) set_stencil_op(thread, GL_FRONT_AND_BACK, fail, zfail, zpass);
3955 }
3956
glStencilOpSeparate(GLenum face,GLenum fail,GLenum zfail,GLenum zpass)3957 GL_API void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass) // S
3958 {
3959 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3960 if (IS_OPENGLES_20(thread)) set_stencil_op(thread, face, fail, zfail, zpass);
3961 }
3962
is_texture_coord_size(GLint size)3963 static bool is_texture_coord_size(GLint size)
3964 {
3965 return size == 2 ||
3966 size == 3 ||
3967 size == 4;
3968 }
3969
is_texture_coord_type(GLenum type)3970 static bool is_texture_coord_type(GLenum type)
3971 {
3972 return type == GL_BYTE ||
3973 type == GL_SHORT ||
3974 type == GL_FIXED ||
3975 type == GL_FLOAT;
3976 }
3977
glTexCoordPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)3978 GL_API void GL_APIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
3979 {
3980 if (is_texture_coord_type(type)) {
3981 if (is_texture_coord_size(size) && is_aligned(type, (size_t)pointer) && is_aligned(type, (size_t)stride) && stride >= 0) {
3982 glintAttribPointer(GLXX_API_11, GL11_IX_CLIENT_ACTIVE_TEXTURE, size, type, GL_FALSE, stride, pointer);
3983 } else
3984 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
3985 } else
3986 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
3987 }
3988
glTexEnvi(GLenum target,GLenum pname,GLint param)3989 GL_API void GL_APIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param)
3990 {
3991 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
3992 if (IS_OPENGLES_11(thread)) {
3993 RPC_CALL3(glTexEnvi_impl_11,
3994 thread,
3995 GLTEXENVI_ID_11,
3996 RPC_ENUM(target),
3997 RPC_ENUM(pname),
3998 RPC_INT(param));
3999 }
4000 }
4001
glTexEnviv(GLenum target,GLenum pname,const GLint * params)4002 GL_API void GL_APIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params)
4003 {
4004 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4005 if (IS_OPENGLES_11(thread)) {
4006 /*
4007 the only supported texture environment params are
4008
4009 COORD_REPLACE_OES (1)
4010 TEXTURE_ENV_MODE (1)
4011 TEXTURE_ENV_COLOR (4)
4012 COMBINE_RGB (1)
4013 RGB_SCALE (1)
4014 SRC0_RGB (1)
4015 SRC1_RGB (1)
4016 SRC2_RGB (1)
4017 OPERAND0_RGB (1)
4018 OPERAND1_RGB (1)
4019 OPERAND2_RGB (1)
4020 COMBINE_ALPHA (1)
4021 ALPHA_SCALE (1)
4022 SRC0_ALPHA (1)
4023 SRC1_ALPHA (1)
4024 SRC2_ALPHA (1)
4025 OPERAND0_ALPHA (1)
4026 OPERAND1_ALPHA (1)
4027 OPERAND2_ALPHA (1)
4028
4029 so we need to transmit 4 words of parameter data
4030 */
4031
4032 RPC_CALL3_IN_CTRL(glTexEnviv_impl_11,
4033 thread,
4034 GLTEXENVIV_ID_11,
4035 RPC_ENUM(target),
4036 RPC_ENUM(pname),
4037 params,
4038 4 * sizeof(GLint));
4039 }
4040 }
4041
glTexEnvf(GLenum target,GLenum pname,GLfloat param)4042 GL_API void GL_APIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param)
4043 {
4044 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4045 if (IS_OPENGLES_11(thread)) {
4046 RPC_CALL3(glTexEnvf_impl_11,
4047 thread,
4048 GLTEXENVF_ID_11,
4049 RPC_ENUM(target),
4050 RPC_ENUM(pname),
4051 RPC_FLOAT(param));
4052 }
4053 }
4054
glTexEnvfv(GLenum target,GLenum pname,const GLfloat * params)4055 GL_API void GL_APIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params)
4056 {
4057 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4058 if (IS_OPENGLES_11(thread)) {
4059 /*
4060 the only supported texture environment params are
4061
4062 COORD_REPLACE_OES (1)
4063 TEXTURE_ENV_MODE (1)
4064 TEXTURE_ENV_COLOR (4)
4065 COMBINE_RGB (1)
4066 RGB_SCALE (1)
4067 SRC0_RGB (1)
4068 SRC1_RGB (1)
4069 SRC2_RGB (1)
4070 OPERAND0_RGB (1)
4071 OPERAND1_RGB (1)
4072 OPERAND2_RGB (1)
4073 COMBINE_ALPHA (1)
4074 ALPHA_SCALE (1)
4075 SRC0_ALPHA (1)
4076 SRC1_ALPHA (1)
4077 SRC2_ALPHA (1)
4078 OPERAND0_ALPHA (1)
4079 OPERAND1_ALPHA (1)
4080 OPERAND2_ALPHA (1)
4081
4082 so we need to transmit 4 words of parameter data
4083 */
4084
4085 RPC_CALL3_IN_CTRL(glTexEnvfv_impl_11,
4086 thread,
4087 GLTEXENVFV_ID_11,
4088 RPC_ENUM(target),
4089 RPC_ENUM(pname),
4090 params,
4091 4 * sizeof(GLfloat));
4092 }
4093 }
4094
glTexEnvx(GLenum target,GLenum pname,GLfixed param)4095 GL_API void GL_APIENTRY glTexEnvx (GLenum target, GLenum pname, GLfixed param)
4096 {
4097 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4098 if (IS_OPENGLES_11(thread)) {
4099 RPC_CALL3(glTexEnvx_impl_11,
4100 thread,
4101 GLTEXENVX_ID_11,
4102 RPC_ENUM(target),
4103 RPC_ENUM(pname),
4104 RPC_FIXED(param));
4105 }
4106 }
4107
glTexEnvxv(GLenum target,GLenum pname,const GLfixed * params)4108 GL_API void GL_APIENTRY glTexEnvxv (GLenum target, GLenum pname, const GLfixed *params)
4109 {
4110 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4111 if (IS_OPENGLES_11(thread)) {
4112 /*
4113 the only supported texture environment params are
4114
4115 COORD_REPLACE_OES (1)
4116 TEXTURE_ENV_MODE (1)
4117 TEXTURE_ENV_COLOR (4)
4118 COMBINE_RGB (1)
4119 RGB_SCALE (1)
4120 SRC0_RGB (1)
4121 SRC1_RGB (1)
4122 SRC2_RGB (1)
4123 OPERAND0_RGB (1)
4124 OPERAND1_RGB (1)
4125 OPERAND2_RGB (1)
4126 COMBINE_ALPHA (1)
4127 ALPHA_SCALE (1)
4128 SRC0_ALPHA (1)
4129 SRC1_ALPHA (1)
4130 SRC2_ALPHA (1)
4131 OPERAND0_ALPHA (1)
4132 OPERAND1_ALPHA (1)
4133 OPERAND2_ALPHA (1)
4134
4135 so we need to transmit 4 words of parameter data
4136 */
4137
4138 RPC_CALL3_IN_CTRL(glTexEnvxv_impl_11,
4139 thread,
4140 GLTEXENVXV_ID_11,
4141 RPC_ENUM(target),
4142 RPC_ENUM(pname),
4143 params,
4144 4 * sizeof(GLfixed));
4145 }
4146 }
4147
glTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)4148 GL_API void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
4149 {
4150 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4151 GLboolean res;
4152 if (IS_OPENGLES_11_OR_20(thread)) {
4153 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
4154
4155 uint32_t pitch = get_pitch( (uint32_t)width, format, type, (uint32_t)state->alignment.unpack);
4156 uint32_t lines = pitch ? (uint32_t)(KHDISPATCH_WORKSPACE_SIZE / pitch) : (uint32_t)height;
4157
4158 res = RPC_BOOLEAN_RES(RPC_CALL10_IN_BULK_RES(glTexImage2D_impl,
4159 thread,
4160 GLTEXIMAGE2D_ID,
4161 RPC_ENUM(target),
4162 RPC_INT(level),
4163 RPC_ENUM(internalformat),
4164 RPC_SIZEI(width),
4165 RPC_SIZEI(height),
4166 RPC_INT(border),
4167 RPC_ENUM(format),
4168 RPC_ENUM(type),
4169 RPC_INT(state->alignment.unpack),
4170 NULL,
4171 0));
4172
4173 if (res && pixels && lines) {
4174 int offset = 0;
4175
4176 while (height > 0) {
4177 int32_t batch = _min(lines, (int32_t)height);
4178
4179 RPC_CALL10_IN_BULK(glTexSubImage2D_impl,
4180 thread,
4181 GLTEXSUBIMAGE2D_ID,
4182 RPC_ENUM(target),
4183 RPC_INT(level),
4184 RPC_INT(0),
4185 RPC_INT(offset),
4186 RPC_SIZEI(width),
4187 RPC_SIZEI(batch),
4188 RPC_ENUM(format),
4189 RPC_ENUM(type),
4190 RPC_INT(state->alignment.unpack),
4191 (char *)pixels + offset * pitch,
4192 batch * pitch);
4193
4194 offset += batch;
4195 height -= batch;
4196 }
4197 }
4198 }
4199 }
4200
glTexParameteri(GLenum target,GLenum pname,GLint param)4201 GL_API void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param)
4202 {
4203 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4204 if (IS_OPENGLES_11_OR_20(thread)) {
4205 RPC_CALL3(glTexParameteri_impl,
4206 thread,
4207 GLTEXPARAMETERI_ID,
4208 RPC_ENUM(target),
4209 RPC_ENUM(pname),
4210 RPC_INT(param));
4211 }
4212 }
4213
glTexParameterf(GLenum target,GLenum pname,GLfloat param)4214 GL_API void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param)
4215 {
4216 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4217 if (IS_OPENGLES_11_OR_20(thread)) {
4218 RPC_CALL3(glTexParameterf_impl,
4219 thread,
4220 GLTEXPARAMETERF_ID,
4221 RPC_ENUM(target),
4222 RPC_ENUM(pname),
4223 RPC_FLOAT(param));
4224 }
4225 }
4226
glTexParameterx(GLenum target,GLenum pname,GLfixed param)4227 GL_API void GL_APIENTRY glTexParameterx (GLenum target, GLenum pname, GLfixed param)
4228 {
4229 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4230 if (IS_OPENGLES_11(thread)) {
4231 RPC_CALL3(glTexParameterx_impl_11,
4232 thread,
4233 GLTEXPARAMETERX_ID_11,
4234 RPC_ENUM(target),
4235 RPC_ENUM(pname),
4236 RPC_FIXED(param));
4237 }
4238 }
4239
glTexParameteriv(GLenum target,GLenum pname,const GLint * params)4240 GL_API void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params)
4241 {
4242 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4243 /*
4244 the only supported texture params are
4245
4246 TEXTURE_MIN_FILTER
4247 TEXTURE_MAG_FILTER
4248 TEXTURE_WRAP_S
4249 TEXTURE_WRAP_T
4250
4251 each of which takes a single argument
4252
4253 and for 1.1
4254 TEXTURE_CROP_RECT_OES
4255 which takes 4 ints
4256 */
4257
4258 if (IS_OPENGLES_11(thread)) {
4259 if(pname != GL_TEXTURE_CROP_RECT_OES) {
4260 glTexParameteri(target, pname, params[0]);
4261 }
4262 else {
4263 RPC_CALL3_IN_CTRL(glTexParameteriv_impl,
4264 thread,
4265 GLTEXPARAMETERIV_ID,
4266 RPC_ENUM(target),
4267 RPC_ENUM(pname),
4268 params,
4269 4 * sizeof(GLint));
4270 }
4271 }
4272 else if(IS_OPENGLES_20(thread))
4273 glTexParameteri(target, pname, params[0]);
4274 }
4275
glTexParameterfv(GLenum target,GLenum pname,const GLfloat * params)4276 GL_API void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params)
4277 {
4278 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4279 /*
4280 the only supported texture params are
4281
4282 TEXTURE_MIN_FILTER
4283 TEXTURE_MAG_FILTER
4284 TEXTURE_WRAP_S
4285 TEXTURE_WRAP_T
4286
4287 each of which takes a single argument
4288
4289 and for 1.1
4290 TEXTURE_CROP_RECT_OES
4291 which takes 4 ints
4292 */
4293
4294 if (IS_OPENGLES_11(thread)) {
4295 if(pname != GL_TEXTURE_CROP_RECT_OES) {
4296 glTexParameterf(target, pname, params[0]);
4297 }
4298 else {
4299 RPC_CALL3_IN_CTRL(glTexParameterfv_impl,
4300 thread,
4301 GLTEXPARAMETERFV_ID,
4302 RPC_ENUM(target),
4303 RPC_ENUM(pname),
4304 params,
4305 4 * sizeof(GLfloat));
4306 }
4307 }
4308 else if(IS_OPENGLES_20(thread))
4309 glTexParameterf(target, pname, params[0]);
4310 }
4311
glTexParameterxv(GLenum target,GLenum pname,const GLfixed * params)4312 GL_API void GL_APIENTRY glTexParameterxv (GLenum target, GLenum pname, const GLfixed *params)
4313 {
4314 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4315 /*
4316 the only supported texture params are
4317
4318 TEXTURE_MIN_FILTER
4319 TEXTURE_MAG_FILTER
4320 TEXTURE_WRAP_S
4321 TEXTURE_WRAP_T
4322
4323 each of which takes a single argument
4324
4325 and for 1.1
4326 TEXTURE_CROP_RECT_OES
4327 which takes 4 ints
4328 */
4329
4330 if (IS_OPENGLES_11(thread)) {
4331 if(pname != GL_TEXTURE_CROP_RECT_OES) {
4332 glTexParameterx(target, pname, params[0]);
4333 }
4334 else {
4335 RPC_CALL3_IN_CTRL(glTexParameterxv_impl_11,
4336 thread,
4337 GLTEXPARAMETERXV_ID_11,
4338 RPC_ENUM(target),
4339 RPC_ENUM(pname),
4340 params,
4341 4 * sizeof(GLfixed));
4342 }
4343 }
4344 else if(IS_OPENGLES_20(thread))
4345 glTexParameterx(target, pname, params[0]);
4346 }
4347
glTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4348 GL_API void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
4349 {
4350 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4351 if (IS_OPENGLES_11_OR_20(thread)) {
4352 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
4353
4354 uint32_t pitch = get_pitch( (uint32_t)width, format, type, (uint32_t)state->alignment.unpack);
4355 uint32_t lines = pitch ? (uint32_t)(KHDISPATCH_WORKSPACE_SIZE / pitch) : (uint32_t)height;
4356
4357 if (pixels && lines) {
4358 int offset = 0;
4359
4360 while (height > 0) {
4361 int32_t batch = _min(lines, (int32_t)height);
4362
4363 RPC_CALL10_IN_BULK(glTexSubImage2D_impl,
4364 thread,
4365 GLTEXSUBIMAGE2D_ID,
4366 RPC_ENUM(target),
4367 RPC_INT(level),
4368 RPC_INT(xoffset),
4369 RPC_INT(yoffset+offset),
4370 RPC_SIZEI(width),
4371 RPC_SIZEI(batch),
4372 RPC_ENUM(format),
4373 RPC_ENUM(type),
4374 RPC_INT(state->alignment.unpack),
4375 (char *)pixels + offset * pitch,
4376 batch * pitch);
4377
4378 offset += batch;
4379 height -= batch;
4380 }
4381 }
4382 }
4383 }
4384
texSubImage2DAsync(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLint hpixels)4385 GL_API void GL_APIENTRY texSubImage2DAsync (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLint hpixels)
4386 {
4387 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4388 if (IS_OPENGLES_11_OR_20(thread)) {
4389
4390 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
4391 RPC_CALL10(texSubImage2DAsync_impl,
4392 thread,
4393 TEXSUBIMAGE2DASYNC_ID,
4394 RPC_ENUM(target),
4395 RPC_INT(level),
4396 RPC_INT(xoffset),
4397 RPC_INT(yoffset),
4398 RPC_SIZEI(width),
4399 RPC_SIZEI(height),
4400 RPC_ENUM(format),
4401 RPC_ENUM(type),
4402 RPC_INT(state->alignment.unpack),
4403 RPC_INT(hpixels));
4404 }
4405 }
4406
glTranslatef(GLfloat x,GLfloat y,GLfloat z)4407 GL_API void GL_APIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z)
4408 {
4409 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4410 if (IS_OPENGLES_11(thread)) {
4411 RPC_CALL3(glTranslatef_impl_11,
4412 thread,
4413 GLTRANSLATEF_ID_11,
4414 RPC_FLOAT(x),
4415 RPC_FLOAT(y),
4416 RPC_FLOAT(z));
4417 }
4418 }
4419
glTranslatex(GLfixed x,GLfixed y,GLfixed z)4420 GL_API void GL_APIENTRY glTranslatex (GLfixed x, GLfixed y, GLfixed z)
4421 {
4422 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4423 if (IS_OPENGLES_11(thread)) {
4424 RPC_CALL3(glTranslatex_impl_11,
4425 thread,
4426 GLTRANSLATEX_ID_11,
4427 RPC_FIXED(x),
4428 RPC_FIXED(y),
4429 RPC_FIXED(z));
4430 }
4431 }
4432
glUniform1i(GLint location,GLint x)4433 GL_API void GL_APIENTRY glUniform1i (GLint location, GLint x)
4434 {
4435 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4436 if (IS_OPENGLES_20(thread)) {
4437 RPC_CALL2(glUniform1i_impl_20,
4438 thread,
4439 GLUNIFORM1I_ID_20,
4440 RPC_INT(location),
4441 RPC_INT(x));
4442 }
4443 }
4444
glUniform2i(GLint location,GLint x,GLint y)4445 GL_API void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y)
4446 {
4447 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4448 if (IS_OPENGLES_20(thread)) {
4449 RPC_CALL3(glUniform2i_impl_20,
4450 thread,
4451 GLUNIFORM2I_ID_20,
4452 RPC_INT(location),
4453 RPC_INT(x),
4454 RPC_INT(y));
4455 }
4456 }
4457
glUniform3i(GLint location,GLint x,GLint y,GLint z)4458 GL_API void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z)
4459 {
4460 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4461 if (IS_OPENGLES_20(thread)) {
4462 RPC_CALL4(glUniform3i_impl_20,
4463 thread,
4464 GLUNIFORM3I_ID_20,
4465 RPC_INT(location),
4466 RPC_INT(x),
4467 RPC_INT(y),
4468 RPC_INT(z));
4469 }
4470 }
4471
glUniform4i(GLint location,GLint x,GLint y,GLint z,GLint w)4472 GL_API void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w)
4473 {
4474 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4475 if (IS_OPENGLES_20(thread)) {
4476 RPC_CALL5(glUniform4i_impl_20,
4477 thread,
4478 GLUNIFORM4I_ID_20,
4479 RPC_INT(location),
4480 RPC_INT(x),
4481 RPC_INT(y),
4482 RPC_INT(z),
4483 RPC_INT(w));
4484 }
4485 }
4486
glUniform1f(GLint location,GLfloat x)4487 GL_API void GL_APIENTRY glUniform1f (GLint location, GLfloat x)
4488 {
4489 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4490 if (IS_OPENGLES_20(thread)) {
4491 RPC_CALL2(glUniform1f_impl_20,
4492 thread,
4493 GLUNIFORM1F_ID_20,
4494 RPC_INT(location),
4495 RPC_FLOAT(x));
4496 }
4497 }
4498
glUniform2f(GLint location,GLfloat x,GLfloat y)4499 GL_API void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y)
4500 {
4501 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4502 if (IS_OPENGLES_20(thread)) {
4503 RPC_CALL3(glUniform2f_impl_20,
4504 thread,
4505 GLUNIFORM2F_ID_20,
4506 RPC_INT(location),
4507 RPC_FLOAT(x),
4508 RPC_FLOAT(y));
4509 }
4510 }
4511
glUniform3f(GLint location,GLfloat x,GLfloat y,GLfloat z)4512 GL_API void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z)
4513 {
4514 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4515 if (IS_OPENGLES_20(thread)) {
4516 RPC_CALL4(glUniform3f_impl_20,
4517 thread,
4518 GLUNIFORM3F_ID_20,
4519 RPC_INT(location),
4520 RPC_FLOAT(x),
4521 RPC_FLOAT(y),
4522 RPC_FLOAT(z));
4523 }
4524 }
4525
glUniform4f(GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)4526 GL_API void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4527 {
4528 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4529 if (IS_OPENGLES_20(thread)) {
4530 RPC_CALL5(glUniform4f_impl_20,
4531 thread,
4532 GLUNIFORM4F_ID_20,
4533 RPC_INT(location),
4534 RPC_FLOAT(x),
4535 RPC_FLOAT(y),
4536 RPC_FLOAT(z),
4537 RPC_FLOAT(w));
4538 }
4539 }
4540
4541 /*
4542 clamp the size of uniform data to the maximum conceivable value (128 vec4s)
4543 */
4544
4545 #define MAX_UNIFORM_SIZE 2048
4546
clamp_uniform_size(int size)4547 static INLINE int clamp_uniform_size(int size)
4548 {
4549 return (int) _min( (int32_t)size, MAX_UNIFORM_SIZE);
4550 }
4551
glUniform1iv(GLint location,GLsizei count,const GLint * v)4552 GL_API void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *v)
4553 {
4554 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4555 if (IS_OPENGLES_20(thread)) {
4556 int size = clamp_uniform_size( (int)(count * 1 * sizeof(GLint)));
4557
4558 RPC_CALL4_IN_CTRL(glUniform1iv_impl_20,
4559 thread,
4560 GLUNIFORM1IV_ID_20,
4561 RPC_INT(location),
4562 RPC_SIZEI(count),
4563 RPC_INT(size),
4564 v,
4565 (size_t)size);
4566 }
4567 }
4568
glUniform2iv(GLint location,GLsizei count,const GLint * v)4569 GL_API void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *v)
4570 {
4571 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4572 if (IS_OPENGLES_20(thread)) {
4573 int size = clamp_uniform_size( (int)(count * 2 * sizeof(GLint)));
4574
4575 RPC_CALL4_IN_CTRL(glUniform2iv_impl_20,
4576 thread,
4577 GLUNIFORM2IV_ID_20,
4578 RPC_INT(location),
4579 RPC_SIZEI(count),
4580 RPC_INT(size),
4581 v,
4582 (size_t)size);
4583 }
4584 }
4585
glUniform3iv(GLint location,GLsizei count,const GLint * v)4586 GL_API void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *v)
4587 {
4588 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4589 if (IS_OPENGLES_20(thread)) {
4590 int size = clamp_uniform_size( (int)(count * 3 * sizeof(GLint)));
4591
4592 RPC_CALL4_IN_CTRL(glUniform3iv_impl_20,
4593 thread,
4594 GLUNIFORM3IV_ID_20,
4595 RPC_INT(location),
4596 RPC_SIZEI(count),
4597 RPC_INT(size),
4598 v,
4599 (size_t)size);
4600 }
4601 }
4602
glUniform4iv(GLint location,GLsizei count,const GLint * v)4603 GL_API void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *v)
4604 {
4605 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4606 if (IS_OPENGLES_20(thread)) {
4607 int size = clamp_uniform_size( (int)(count * 4 * sizeof(GLint)));
4608
4609 RPC_CALL4_IN_CTRL(glUniform4iv_impl_20,
4610 thread,
4611 GLUNIFORM4IV_ID_20,
4612 RPC_INT(location),
4613 RPC_SIZEI(count),
4614 RPC_INT(size),
4615 v,
4616 (size_t)size);
4617 }
4618 }
4619
glUniform1fv(GLint location,GLsizei count,const GLfloat * v)4620 GL_API void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *v)
4621 {
4622 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4623 if (IS_OPENGLES_20(thread)) {
4624 int size = clamp_uniform_size( (int)(count * 1 * sizeof(GLfloat)));
4625
4626 RPC_CALL4_IN_CTRL(glUniform1fv_impl_20,
4627 thread,
4628 GLUNIFORM1FV_ID_20,
4629 RPC_INT(location),
4630 RPC_SIZEI(count),
4631 RPC_INT(size),
4632 v,
4633 (size_t)size);
4634 }
4635 }
4636
glUniform2fv(GLint location,GLsizei count,const GLfloat * v)4637 GL_API void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *v)
4638 {
4639 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4640 if (IS_OPENGLES_20(thread)) {
4641 int size = clamp_uniform_size( (int)(count * 2 * sizeof(GLfloat)));
4642
4643 RPC_CALL4_IN_CTRL(glUniform2fv_impl_20,
4644 thread,
4645 GLUNIFORM2FV_ID_20,
4646 RPC_INT(location),
4647 RPC_SIZEI(count),
4648 RPC_INT(size),
4649 v,
4650 (size_t)size);
4651 }
4652 }
4653
glUniform3fv(GLint location,GLsizei count,const GLfloat * v)4654 GL_API void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *v)
4655 {
4656 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4657 if (IS_OPENGLES_20(thread)) {
4658 int size = clamp_uniform_size( (int)(count * 3 * sizeof(GLfloat)));
4659
4660 RPC_CALL4_IN_CTRL(glUniform3fv_impl_20,
4661 thread,
4662 GLUNIFORM3FV_ID_20,
4663 RPC_INT(location),
4664 RPC_SIZEI(count),
4665 RPC_INT(size),
4666 v,
4667 (size_t)size);
4668 }
4669 }
4670
glUniform4fv(GLint location,GLsizei count,const GLfloat * v)4671 GL_API void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *v)
4672 {
4673 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4674 if (IS_OPENGLES_20(thread)) {
4675 int size = clamp_uniform_size( (int)(count * 4 * sizeof(GLfloat)));
4676
4677 RPC_CALL4_IN_CTRL(glUniform4fv_impl_20,
4678 thread,
4679 GLUNIFORM4FV_ID_20,
4680 RPC_INT(location),
4681 RPC_SIZEI(count),
4682 RPC_INT(size),
4683 v,
4684 (size_t)size);
4685 }
4686 }
4687
4688 /*
4689 If transpose is GL_FALSE, each matrix is assumed to be supplied in column major order.
4690 If transpose is GL_TRUE, each matrix is assumed to be supplied in row major order.
4691 */
4692
glUniformMatrix2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4693 GL_API void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4694 {
4695 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4696 if (IS_OPENGLES_20(thread)) {
4697 int size = clamp_uniform_size( (int)(count * 2 * 2 * sizeof(GLfloat)));
4698
4699 RPC_CALL5_IN_CTRL(glUniformMatrix2fv_impl_20,
4700 thread,
4701 GLUNIFORMMATRIX2FV_ID_20,
4702 RPC_INT(location),
4703 RPC_SIZEI(count),
4704 RPC_BOOLEAN(transpose),
4705 RPC_INT(size),
4706 value,
4707 (size_t)size);
4708 }
4709 }
4710
glUniformMatrix3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4711 GL_API void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4712 {
4713 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4714 if (IS_OPENGLES_20(thread)) {
4715 int size = clamp_uniform_size( (int)(count * 3 * 3 * sizeof(GLfloat)));
4716
4717 RPC_CALL5_IN_CTRL(glUniformMatrix3fv_impl_20,
4718 thread,
4719 GLUNIFORMMATRIX3FV_ID_20,
4720 RPC_INT(location),
4721 RPC_SIZEI(count),
4722 RPC_BOOLEAN(transpose),
4723 RPC_INT(size),
4724 value,
4725 (size_t)size);
4726 }
4727 }
4728
glUniformMatrix4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)4729 GL_API void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
4730 {
4731 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4732 if (IS_OPENGLES_20(thread)) {
4733 int size = clamp_uniform_size( (int)(count * 4 * 4 * sizeof(GLfloat)));
4734
4735 RPC_CALL5_IN_CTRL(glUniformMatrix4fv_impl_20,
4736 thread,
4737 GLUNIFORMMATRIX4FV_ID_20,
4738 RPC_INT(location),
4739 RPC_SIZEI(count),
4740 RPC_BOOLEAN(transpose),
4741 RPC_INT(size),
4742 value,
4743 (size_t)size);
4744 }
4745 }
4746
glUseProgram(GLuint program)4747 GL_API void GL_APIENTRY glUseProgram (GLuint program) // S
4748 {
4749 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4750 if (IS_OPENGLES_20(thread)) {
4751 RPC_CALL1(glUseProgram_impl_20,
4752 thread,
4753 GLUSEPROGRAM_ID_20,
4754 RPC_UINT(program));
4755 }
4756 }
4757
glValidateProgram(GLuint program)4758 GL_API void GL_APIENTRY glValidateProgram (GLuint program)
4759 {
4760 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4761 if (IS_OPENGLES_20(thread)) {
4762 RPC_CALL1(glValidateProgram_impl_20,
4763 thread,
4764 GLVALIDATEPROGRAM_ID_20,
4765 RPC_UINT(program));
4766 }
4767 }
4768
glVertexAttrib1f(GLuint indx,GLfloat x)4769 GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x)
4770 {
4771 glintAttrib(GLXX_API_20, indx, x, 0.0f, 0.0f, 1.0f);
4772 }
4773
glVertexAttrib2f(GLuint indx,GLfloat x,GLfloat y)4774 GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y)
4775 {
4776 glintAttrib(GLXX_API_20, indx, x, y, 0.0f, 1.0f);
4777 }
4778
glVertexAttrib3f(GLuint indx,GLfloat x,GLfloat y,GLfloat z)4779 GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z)
4780 {
4781 glintAttrib(GLXX_API_20, indx, x, y, z, 1.0f);
4782 }
4783
glVertexAttrib4f(GLuint indx,GLfloat x,GLfloat y,GLfloat z,GLfloat w)4784 GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4785 {
4786 glintAttrib(GLXX_API_20, indx, x, y, z, w);
4787 }
4788
glVertexAttrib1fv(GLuint indx,const GLfloat * values)4789 GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat *values)
4790 {
4791 glintAttrib(GLXX_API_20, indx, values[0], 0.0f, 0.0f, 1.0f);
4792 }
4793
glVertexAttrib2fv(GLuint indx,const GLfloat * values)4794 GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat *values)
4795 {
4796 glintAttrib(GLXX_API_20, indx, values[0], values[1], 0.0f, 1.0f);
4797 }
4798
glVertexAttrib3fv(GLuint indx,const GLfloat * values)4799 GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat *values)
4800 {
4801 glintAttrib(GLXX_API_20, indx, values[0], values[1], values[2], 1.0f);
4802 }
4803
glVertexAttrib4fv(GLuint indx,const GLfloat * values)4804 GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat *values)
4805 {
4806 glintAttrib(GLXX_API_20, indx, values[0], values[1], values[2], values[3]);
4807 }
4808
is_vertex_attrib_size(GLint size)4809 static bool is_vertex_attrib_size(GLint size)
4810 {
4811 return size >= 1 && size <= 4;
4812 }
4813
is_vertex_attrib_type(GLenum type)4814 static bool is_vertex_attrib_type(GLenum type)
4815 {
4816 return type == GL_BYTE ||
4817 type == GL_UNSIGNED_BYTE ||
4818 type == GL_SHORT ||
4819 type == GL_UNSIGNED_SHORT ||
4820 type == GL_FLOAT ||
4821 type == GL_FIXED ||
4822 type == GL_HALF_FLOAT_OES;
4823 }
4824
glVertexAttribPointer(GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const void * ptr)4825 GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr)
4826 {
4827 if (is_vertex_attrib_size(size) && stride >= 0) {
4828 if (is_vertex_attrib_type(type) || type == GL_HALF_FLOAT_OES) {
4829 glintAttribPointer(GLXX_API_20, indx, size, type, normalized, stride, ptr);
4830 } else
4831 glxx_set_error_api(GLXX_API_20, GL_INVALID_ENUM);
4832 } else
4833 glxx_set_error_api(GLXX_API_20, GL_INVALID_VALUE);
4834 }
4835
is_vertex_size(GLint size)4836 static bool is_vertex_size(GLint size)
4837 {
4838 return size == 2 ||
4839 size == 3 ||
4840 size == 4;
4841 }
4842
is_vertex_type(GLenum type)4843 static bool is_vertex_type(GLenum type)
4844 {
4845 return type == GL_BYTE ||
4846 type == GL_SHORT ||
4847 type == GL_FIXED ||
4848 type == GL_FLOAT;
4849 }
4850
glVertexPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)4851 GL_API void GL_APIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
4852 {
4853 if (is_vertex_type(type)) {
4854 if (is_vertex_size(size) && is_aligned(type, (size_t)pointer) && is_aligned(type, (size_t)stride) && stride >= 0) {
4855 glintAttribPointer(GLXX_API_11, GL11_IX_VERTEX, size, type, GL_FALSE, stride, pointer);
4856 } else
4857 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
4858 } else
4859 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
4860 }
4861
glViewport(GLint x,GLint y,GLsizei width,GLsizei height)4862 GL_API void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height)
4863 {
4864 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4865 if (IS_OPENGLES_11_OR_20(thread)) {
4866 RPC_CALL4(glViewport_impl,
4867 thread,
4868 GLVIEWPORT_ID,
4869 RPC_INT(x),
4870 RPC_INT(y),
4871 RPC_SIZEI(width),
4872 RPC_SIZEI(height));
4873 }
4874 }
4875 /*****************************************************************************************/
4876 /* OES extension functions */
4877 /*****************************************************************************************/
4878
is_point_size_type(GLenum type)4879 static bool is_point_size_type(GLenum type)
4880 {
4881 return type == GL_FIXED ||
4882 type == GL_FLOAT;
4883 }
4884
glPointSizePointerOES(GLenum type,GLsizei stride,const GLvoid * pointer)4885 GL_API void GL_APIENTRY glPointSizePointerOES (GLenum type, GLsizei stride, const GLvoid *pointer)
4886 {
4887 if (is_point_size_type(type)) {
4888 if (is_aligned(type, (size_t)pointer) && is_aligned(type, (size_t)stride) && stride >= 0) {
4889 glintAttribPointer(GLXX_API_11, GL11_IX_POINT_SIZE, 1, type, GL_FALSE, stride, pointer);
4890 } else
4891 glxx_set_error_api(GLXX_API_11, GL_INVALID_VALUE);
4892 } else
4893 glxx_set_error_api(GLXX_API_11, GL_INVALID_ENUM);
4894 }
4895
4896 /* OES_shader_source */
glCompileShader(GLuint shader)4897 GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader)
4898 {
4899 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4900 if (IS_OPENGLES_20(thread)) {
4901 RPC_CALL1(glCompileShader_impl_20,
4902 thread,
4903 GLCOMPILESHADER_ID_20,
4904 RPC_UINT(shader));
4905 }
4906 }
4907
glGetShaderiv(GLuint shader,GLenum pname,GLint * params)4908 GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params)
4909 {
4910 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4911 if (IS_OPENGLES_20(thread)) {
4912 RPC_CALL3_OUT_CTRL(glGetShaderiv_impl_20,
4913 thread,
4914 GLGETSHADERIV_ID_20,
4915 RPC_ENUM(shader),
4916 RPC_ENUM(pname),
4917 params);
4918 }
4919 }
4920
glGetShaderInfoLog(GLuint shader,GLsizei bufsize,GLsizei * length,char * infolog)4921 GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei *length, char *infolog)
4922 {
4923 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4924 if (IS_OPENGLES_20(thread)) {
4925 #ifdef RPC_DIRECT
4926 RPC_CALL4(glGetShaderInfoLog_impl_20, thread, no_id, shader, bufsize, length, infolog);
4927 #else
4928 GLuint result[1];
4929
4930 rpc_begin(thread);
4931
4932 RPC_CALL3_OUT_CTRL(no_function,
4933 thread,
4934 GLGETSHADERINFOLOG_ID_20,
4935 RPC_UINT(shader),
4936 RPC_SIZEI(bufsize),
4937 result);
4938
4939 if (length)
4940 *length = (GLsizei)result[0];
4941
4942 read_out_bulk(thread, infolog);
4943
4944 rpc_end(thread);
4945 #endif
4946 }
4947 }
4948
glGetShaderSource(GLuint shader,GLsizei bufsize,GLsizei * length,char * source)4949 GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei *length, char *source)
4950 {
4951 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4952 if (IS_OPENGLES_20(thread)) {
4953 #ifdef RPC_DIRECT
4954 RPC_CALL4(glGetShaderSource_impl_20, thread, no_id, shader, bufsize, length, source);
4955 #else
4956 GLuint result[1];
4957
4958 rpc_begin(thread);
4959
4960 RPC_CALL3_OUT_CTRL(no_function,
4961 thread,
4962 GLGETSHADERSOURCE_ID_20,
4963 RPC_UINT(shader),
4964 RPC_SIZEI(bufsize),
4965 result);
4966
4967 if (length)
4968 *length = (GLsizei)result[0];
4969
4970 read_out_bulk(thread, source);
4971
4972 rpc_end(thread);
4973 #endif
4974 }
4975 }
4976
glReleaseShaderCompiler(void)4977 GL_APICALL void GL_APIENTRY glReleaseShaderCompiler(void)
4978 {
4979 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4980 if (IS_OPENGLES_20(thread)) {
4981 }
4982 }
4983
glShaderBinary(GLint n,const GLuint * shaders,GLenum binaryformat,const void * binary,GLint length)4984 GL_APICALL void GL_APIENTRY glShaderBinary (GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
4985 {
4986 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
4987 UNUSED(n);
4988 UNUSED(shaders);
4989 UNUSED(binaryformat);
4990 UNUSED(binary);
4991 UNUSED(length);
4992
4993 if (IS_OPENGLES_20(thread)) {
4994 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
4995 set_error(state, GL_INVALID_ENUM);
4996 }
4997 }
4998
glShaderSource(GLuint shader,GLsizei count,const char ** string,const GLint * length)4999 GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const char **string, const GLint *length)
5000 {
5001 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5002 if (IS_OPENGLES_20(thread)) {
5003 #ifdef RPC_DIRECT
5004 RPC_CALL4(glShaderSource_impl_20, thread, no_id, shader,
5005 count,
5006 string,
5007 length);
5008 #else
5009 /*
5010 calculate total workspace required for string, length and source
5011 */
5012 #ifdef __SYMBIAN32__
5013
5014 int total = (int)(rpc_pad_bulk(count * 4) + rpc_pad_bulk(count * 4));
5015 int i;
5016
5017 for (i = 0; i < count; i++) {
5018 if (!length || length[i] < 0)
5019 total += rpc_pad_bulk(string[i] ? (int)strlen(string[i]) + 1 : 1);
5020 else
5021 total += rpc_pad_bulk(length[i]);
5022 }
5023
5024 rpc_begin(thread);
5025
5026 // Assume worst-case (need to compute and send all lengths) - include
5027 // the 5 words we're sending in the RPC_CALL4() (do we need to do this?)
5028 //
5029 rpc_send_ctrl_begin(thread, (count + 5) * sizeof(GLint) );
5030
5031 RPC_CALL4(no_function,
5032 thread,
5033 GLSHADERSOURCE_ID_20,
5034 RPC_UINT(shader),
5035 RPC_SIZEI(count),
5036 RPC_INT(total),
5037 RPC_BOOLEAN(length ? 1 : 0));
5038
5039 if (length)
5040 rpc_send_bulk(thread, length, count * sizeof(GLint));
5041
5042 //Send all lengths before the first bulk transfer of a line of source code
5043 //NB this is a temporary fix until issues, with our bulk transfers and the
5044 //rpc assumptions, have been resolved
5045 //NB assumes that the line count numbers all fit in the merge buffer
5046 //which is why a more permanent fix is needed
5047 for (i = 0; i < count; i++) {
5048 GLint len;
5049
5050 if (!length || length[i] < 0) {
5051 len = string[i] ? (GLint) strlen(string[i]) + 1 : 1;
5052
5053 // rpc_send_bulk(&len, sizeof(GLint)); /* todo: this now violates the semantics of rpc_send_bulk. todo: check for other violations in GL */
5054
5055 rpc_send_ctrl_write(thread, (uint32_t *)&len, sizeof(GLint));
5056 }
5057 }
5058
5059 rpc_send_ctrl_end(thread); //no more ctrl data to send
5060
5061 for (i = 0; i < count; i++) {
5062 GLint len;
5063
5064 if (!length || length[i] < 0) {
5065 len = string[i] ? strlen(string[i]) + 1 : 1;
5066 } else
5067 len = length[i];
5068
5069 /* TODO: we currently treat null strings as empty strings
5070 * But we shouldn't need to deal with them (VND-116)
5071 */
5072 rpc_send_bulk(thread, string[i] ? string[i] : "", (uint32_t)len);
5073 }
5074 rpc_end(thread);
5075 #else
5076 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5077 int total = (int)(rpc_pad_bulk(count * 4) + rpc_pad_bulk(count * 4) + rpc_pad_bulk(sizeof(GLint)));
5078 int i;
5079
5080 for (i = 0; i < count; i++)
5081 if (!length || length[i] < 0)
5082 total += rpc_pad_bulk(string[i] ? (int)strlen(string[i]) + 1 : 1);
5083 else
5084 total += rpc_pad_bulk(length[i]);
5085
5086 rpc_begin(thread);
5087
5088 RPC_CALL4(no_function,
5089 thread,
5090 GLSHADERSOURCE_ID_20,
5091 RPC_UINT(shader),
5092 RPC_SIZEI(count),
5093 RPC_INT(total),
5094 RPC_BOOLEAN(length ? 1 : 0));
5095
5096 if (length)
5097 rpc_send_bulk(thread, length, count * sizeof(GLint));
5098
5099 for (i = 0; i < count; i++) {
5100 GLint len;
5101
5102 if (!length || length[i] < 0) {
5103 len = string[i] ? (GLint) strlen(string[i]) + 1 : 1;
5104
5105 rpc_send_bulk(thread, &len, sizeof(GLint)); /* todo: this now violates the semantics of rpc_send_bulk. todo: check for other violations in GL */
5106 } else
5107 len = length[i];
5108
5109 /* TODO: we currently treat null strings as empty strings
5110 * But we shouldn't need to deal with them (VND-116)
5111 */
5112 rpc_send_bulk(thread, string[i] ? string[i] : "", (uint32_t)len);
5113 }
5114
5115 rpc_end(thread);
5116 #endif
5117 #endif
5118 }
5119 }
5120
5121 /* OES_framebuffer_object */
5122
glxx_client_IsRenderbuffer(GLuint renderbuffer)5123 GLboolean glxx_client_IsRenderbuffer(GLuint renderbuffer)
5124 {
5125 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5126 if (IS_OPENGLES_11_OR_20(thread)) {
5127 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsRenderbuffer_impl,
5128 thread,
5129 GLISRENDERBUFFER_ID,
5130 RPC_UINT(renderbuffer)));
5131 }
5132
5133 return 0;
5134 }
5135
glIsRenderbuffer(GLuint renderbuffer)5136 GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
5137 {
5138 return glxx_client_IsRenderbuffer(renderbuffer);
5139 }
5140
glxx_client_BindRenderbuffer(GLenum target,GLuint renderbuffer)5141 void glxx_client_BindRenderbuffer(GLenum target, GLuint renderbuffer)
5142 {
5143 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5144 if (IS_OPENGLES_11_OR_20(thread)) {
5145 RPC_CALL2(glBindRenderbuffer_impl,
5146 thread,
5147 GLBINDRENDERBUFFER_ID,
5148 RPC_ENUM(target),
5149 RPC_UINT(renderbuffer));
5150 }
5151 }
5152
glBindRenderbuffer(GLenum target,GLuint renderbuffer)5153 GL_APICALL void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
5154 {
5155 glxx_client_BindRenderbuffer(target, renderbuffer);
5156 }
5157
glxx_client_DeleteRenderbuffers(GLsizei n,const GLuint * renderbuffers)5158 void glxx_client_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
5159 {
5160 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5161 int offset = 0;
5162
5163 do {
5164 int32_t items = (int32_t) (KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
5165 int32_t batch = _min(items, (int32_t)n);
5166
5167 if (IS_OPENGLES_11_OR_20(thread)) {
5168 RPC_CALL2_IN_BULK(glDeleteRenderbuffers_impl,
5169 thread,
5170 GLDELETERENDERBUFFERS_ID,
5171 RPC_SIZEI(batch),
5172 renderbuffers + offset,
5173 batch > 0 ? batch * sizeof(GLuint) : 0);
5174 }
5175
5176 offset += batch;
5177 n -= batch;
5178 } while (n > 0);
5179 }
5180
glDeleteRenderbuffers(GLsizei n,const GLuint * renderbuffers)5181 GL_APICALL void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
5182 {
5183 glxx_client_DeleteRenderbuffers(n, renderbuffers);
5184 }
5185
glxx_client_GenRenderbuffers(GLsizei n,GLuint * renderbuffers)5186 void glxx_client_GenRenderbuffers(GLsizei n, GLuint *renderbuffers)
5187 {
5188 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5189 int offset = 0;
5190
5191 do {
5192 int32_t items = (int32_t)(KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
5193 int32_t batch = _min(items, (int32_t)n);
5194
5195 if (IS_OPENGLES_11_OR_20(thread)) {
5196 RPC_CALL2_OUT_BULK(glGenRenderbuffers_impl,
5197 thread,
5198 GLGENRENDERBUFFERS_ID,
5199 RPC_SIZEI(batch),
5200 renderbuffers + offset);
5201 }
5202
5203 offset += batch;
5204 n -= batch;
5205 } while (n > 0);
5206 }
5207
glGenRenderbuffers(GLsizei n,GLuint * renderbuffers)5208 GL_APICALL void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint *renderbuffers)
5209 {
5210 glxx_client_GenRenderbuffers(n, renderbuffers);
5211 }
5212
glxx_client_RenderbufferStorage(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)5213 void glxx_client_RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
5214 {
5215 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5216 if (IS_OPENGLES_11_OR_20(thread)) {
5217 RPC_CALL4(glRenderbufferStorage_impl,
5218 thread,
5219 GLRENDERBUFFERSTORAGE_ID,
5220 RPC_ENUM(target),
5221 RPC_ENUM(internalformat),
5222 RPC_SIZEI(width),
5223 RPC_SIZEI(height));
5224 }
5225 }
5226
glRenderbufferStorage(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)5227 GL_APICALL void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
5228 {
5229 glxx_client_RenderbufferStorage(target, internalformat, width, height);
5230 }
5231
glxx_client_GetRenderbufferParameteriv(GLenum target,GLenum pname,GLint * params)5232 void glxx_client_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
5233 {
5234 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5235 if (IS_OPENGLES_11_OR_20(thread)) {
5236 RPC_CALL3_OUT_CTRL(glGetRenderbufferParameteriv_impl,
5237 thread,
5238 GLGETRENDERBUFFERPARAMETERIV_ID,
5239 RPC_ENUM(target),
5240 RPC_ENUM(pname),
5241 params);
5242 }
5243 }
5244
glGetRenderbufferParameteriv(GLenum target,GLenum pname,GLint * params)5245 GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
5246 {
5247 glxx_client_GetRenderbufferParameteriv(target, pname, params);
5248 }
5249
glxx_client_IsFramebuffer(GLuint framebuffer)5250 GLboolean glxx_client_IsFramebuffer(GLuint framebuffer)
5251 {
5252 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5253 if (IS_OPENGLES_11_OR_20(thread)) {
5254 return RPC_BOOLEAN_RES(RPC_CALL1_RES(glIsFramebuffer_impl,
5255 thread,
5256 GLISFRAMEBUFFER_ID,
5257 RPC_UINT(framebuffer)));
5258 }
5259
5260 return 0;
5261 }
5262
glIsFramebuffer(GLuint framebuffer)5263 GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
5264 {
5265 return glxx_client_IsFramebuffer(framebuffer);
5266 }
5267
5268 /*
5269 Spec deviation:
5270 eglMakeCurrent(gles2.0 context, pixmap surface)
5271 glBindFramebuffer(invalid framebuffer id)
5272 glDrawSomeStuff()
5273 glFinish()
5274 Pixmap will not have been updated, as client assumes that rendering is
5275 taking place outside of the default framebuffer
5276 */
5277
glxx_client_BindFramebuffer(GLenum target,GLuint framebuffer)5278 void glxx_client_BindFramebuffer(GLenum target, GLuint framebuffer)
5279 {
5280 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5281 if (IS_OPENGLES_11_OR_20(thread)) {
5282 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5283 RPC_CALL2(glBindFramebuffer_impl,
5284 thread,
5285 GLBINDFRAMEBUFFER_ID,
5286 RPC_ENUM(target),
5287 RPC_UINT(framebuffer));
5288
5289 //TODO: this may be set incorrectly if there's an error
5290 state->default_framebuffer = (framebuffer == 0);
5291 }
5292 }
5293
glBindFramebuffer(GLenum target,GLuint framebuffer)5294 GL_APICALL void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
5295 {
5296 glxx_client_BindFramebuffer(target, framebuffer);
5297 }
5298
glxx_client_DeleteFramebuffers(GLsizei n,const GLuint * framebuffers)5299 void glxx_client_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
5300 {
5301 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5302 int offset = 0;
5303
5304 do {
5305 int32_t items = (int32_t)(KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
5306 int32_t batch = _min(items, (int32_t)n);
5307
5308 if (IS_OPENGLES_11_OR_20(thread)) {
5309 RPC_CALL2_IN_BULK(glDeleteFramebuffers_impl,
5310 thread,
5311 GLDELETEFRAMEBUFFERS_ID,
5312 RPC_SIZEI(batch),
5313 framebuffers + offset,
5314 batch > 0 ? batch * sizeof(GLuint) : 0);
5315 }
5316
5317 offset += batch;
5318 n -= batch;
5319 } while (n > 0);
5320 }
5321
glDeleteFramebuffers(GLsizei n,const GLuint * framebuffers)5322 GL_APICALL void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
5323 {
5324 glxx_client_DeleteFramebuffers(n, framebuffers);
5325 }
5326
glxx_client_GenFramebuffers(GLsizei n,GLuint * framebuffers)5327 void glxx_client_GenFramebuffers(GLsizei n, GLuint *framebuffers)
5328 {
5329 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5330 int offset = 0;
5331
5332 do {
5333 int32_t items = (int32_t)(KHDISPATCH_WORKSPACE_SIZE / sizeof(GLuint));
5334 int32_t batch = _min(items, (int32_t)n);
5335
5336 if (IS_OPENGLES_11_OR_20(thread)) {
5337 RPC_CALL2_OUT_BULK(glGenFramebuffers_impl,
5338 thread,
5339 GLGENFRAMEBUFFERS_ID,
5340 RPC_SIZEI(batch),
5341 framebuffers + offset);
5342 }
5343
5344 offset += batch;
5345 n -= batch;
5346 } while (n > 0);
5347 }
5348
glGenFramebuffers(GLsizei n,GLuint * framebuffers)5349 GL_APICALL void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers)
5350 {
5351 glxx_client_GenFramebuffers(n, framebuffers);
5352 }
5353
glxx_client_CheckFramebufferStatus(GLenum target)5354 GLenum glxx_client_CheckFramebufferStatus(GLenum target)
5355 {
5356 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5357 if (IS_OPENGLES_11_OR_20(thread)) {
5358 return RPC_ENUM_RES(RPC_CALL1_RES(glCheckFramebufferStatus_impl,
5359 thread,
5360 GLCHECKFRAMEBUFFERSTATUS_ID,
5361 RPC_ENUM(target)));
5362 }
5363
5364 return GL_NONE;
5365 }
5366
glCheckFramebufferStatus(GLenum target)5367 GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
5368 {
5369 return glxx_client_CheckFramebufferStatus(target);
5370 }
5371
glxx_client_FramebufferTexture2D(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)5372 void glxx_client_FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
5373 {
5374 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5375 if (IS_OPENGLES_11_OR_20(thread)) {
5376 RPC_CALL5(glFramebufferTexture2D_impl,
5377 thread,
5378 GLFRAMEBUFFERTEXTURE2D_ID,
5379 RPC_ENUM(target),
5380 RPC_ENUM(attachment),
5381 RPC_ENUM(textarget),
5382 RPC_UINT(texture),
5383 RPC_INT(level));
5384 }
5385 }
5386
glFramebufferTexture2D(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)5387 GL_APICALL void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
5388 {
5389 glxx_client_FramebufferTexture2D(target, attachment, textarget, texture, level);
5390 }
5391
glxx_client_FramebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)5392 void glxx_client_FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
5393 {
5394 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5395 if (IS_OPENGLES_11_OR_20(thread)) {
5396 RPC_CALL4(glFramebufferRenderbuffer_impl,
5397 thread,
5398 GLFRAMEBUFFERRENDERBUFFER_ID,
5399 RPC_ENUM(target),
5400 RPC_ENUM(attachment),
5401 RPC_ENUM(renderbuffertarget),
5402 RPC_UINT(renderbuffer));
5403 }
5404 }
5405
glFramebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)5406 GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
5407 {
5408 glxx_client_FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
5409 }
5410
glxx_client_GetFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLint * params)5411 void glxx_client_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params)
5412 {
5413 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5414 if (IS_OPENGLES_11_OR_20(thread)) {
5415 RPC_CALL4_OUT_CTRL(glGetFramebufferAttachmentParameteriv_impl,
5416 thread,
5417 GLGETFRAMEBUFFERATTACHMENTPARAMETERIV_ID,
5418 RPC_ENUM(target),
5419 RPC_ENUM(attachment),
5420 RPC_ENUM(pname),
5421 params);
5422 }
5423 }
5424
glGetFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLint * params)5425 GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params)
5426 {
5427 glxx_client_GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
5428 }
5429
glxx_client_GenerateMipmap(GLenum target)5430 void glxx_client_GenerateMipmap(GLenum target)
5431 {
5432 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5433 if (IS_OPENGLES_11_OR_20(thread)) {
5434 RPC_CALL1(glGenerateMipmap_impl,
5435 thread,
5436 GLGENERATEMIPMAP_ID,
5437 RPC_ENUM(target));
5438 }
5439 }
5440
glGenerateMipmap(GLenum target)5441 GL_APICALL void GL_APIENTRY glGenerateMipmap(GLenum target)
5442 {
5443 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5444 if (IS_OPENGLES_20(thread)) {
5445 glxx_client_GenerateMipmap(target);
5446 }
5447 }
5448
5449 /* OES_shader_source + OES_shader_binary */
glGetShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)5450 GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision)
5451 {
5452 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5453 if (IS_OPENGLES_20(thread)) {
5454 GLint result[3];
5455
5456 RPC_CALL3_OUT_CTRL(glGetShaderPrecisionFormat_impl_20,
5457 thread,
5458 GLGETSHADERPRECISIONFORMAT_ID_20,
5459 RPC_ENUM(shadertype),
5460 RPC_ENUM(precisiontype),
5461 result);
5462
5463 if (range) {
5464 range[0] = result[0];
5465 range[1] = result[1];
5466 }
5467 if (precision)
5468 *precision = result[2];
5469 }
5470 }
5471
glDiscardFramebufferEXT(GLenum target,GLsizei numAttachments,const GLenum * attachments)5472 GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments)
5473 {
5474 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5475 if (IS_OPENGLES_11_OR_20(thread))
5476 {
5477 RPC_CALL3_IN_CTRL(glDiscardFramebufferEXT_impl,
5478 thread,
5479 GLDISCARDFRAMEBUFFEREXT_ID,
5480 RPC_ENUM(target),
5481 RPC_SIZEI(numAttachments),
5482 attachments,
5483 numAttachments * sizeof(GLenum));
5484 }
5485 }
5486
glxx_client_state_init(GLXX_CLIENT_STATE_T * state)5487 static void glxx_client_state_init(GLXX_CLIENT_STATE_T *state)
5488 {
5489 int i;
5490
5491 state->error = GL_NO_ERROR;
5492
5493 state->alignment.pack = 4;
5494 state->alignment.unpack = 4;
5495
5496 state->bound_buffer.array = 0;
5497 state->bound_buffer.element_array = 0;
5498
5499 for (i = 0; i < GLXX_CONFIG_MAX_VERTEX_ATTRIBS; i++) {
5500 state->attrib[i].enabled = GL_FALSE;
5501 state->attrib[i].size = 4;
5502 state->attrib[i].type = GL_FLOAT;
5503 state->attrib[i].normalized = GL_FALSE;
5504 state->attrib[i].stride = 0;
5505 state->attrib[i].pointer = NULL;
5506 state->attrib[i].buffer = 0;
5507 state->attrib[i].value[0] = 0.0f;
5508 state->attrib[i].value[1] = 0.0f;
5509 state->attrib[i].value[2] = 0.0f;
5510 state->attrib[i].value[3] = 1.0f;
5511 }
5512
5513 state->render_callback = NULL;
5514 state->flush_callback = NULL;
5515
5516 //buffer info
5517 khrn_pointer_map_init(&state->buffers,8);
5518
5519 }
5520
gl11_client_state_init(GLXX_CLIENT_STATE_T * state)5521 int gl11_client_state_init(GLXX_CLIENT_STATE_T *state)
5522 {
5523 state->type = OPENGL_ES_11;
5524
5525 //perform common initialisation
5526 glxx_client_state_init(state);
5527 //gl2.0 specific
5528
5529 state->active_texture.client = GL_TEXTURE0;
5530 state->active_texture.server = GL_TEXTURE0;
5531
5532 gl11_attrib_init(state->attrib);
5533
5534 #ifdef GLXX_NO_VERTEX_CACHE
5535 return 1;
5536 #else
5537 return khrn_cache_init(&state->cache);
5538 #endif
5539 }
5540
gl20_client_state_init(GLXX_CLIENT_STATE_T * state)5541 int gl20_client_state_init(GLXX_CLIENT_STATE_T *state)
5542 {
5543 state->type = OPENGL_ES_20;
5544
5545 //perform common initialisation
5546 glxx_client_state_init(state);
5547 //gl2.0 specific
5548
5549 state->default_framebuffer = true;
5550
5551 gl20_attrib_init(state->attrib);
5552
5553 #ifdef GLXX_NO_VERTEX_CACHE
5554 return 1;
5555 #else
5556 return khrn_cache_init(&state->cache);
5557 #endif
5558 }
5559
callback_delete_buffer_info(KHRN_POINTER_MAP_T * map,uint32_t key,void * value,void * data)5560 static void callback_delete_buffer_info(KHRN_POINTER_MAP_T *map, uint32_t key, void *value, void *data)
5561 {
5562 UNUSED(map);
5563 UNUSED(data);
5564 UNUSED(key);
5565 khrn_platform_free(value);
5566 }
5567
glxx_client_state_free(GLXX_CLIENT_STATE_T * state)5568 void glxx_client_state_free(GLXX_CLIENT_STATE_T *state)
5569 {
5570 khrn_pointer_map_iterate(&state->buffers, callback_delete_buffer_info, NULL);
5571 khrn_pointer_map_term(&state->buffers);
5572 #ifndef GLXX_NO_VERTEX_CACHE
5573 khrn_cache_term(&state->cache);
5574 #endif
5575 khrn_platform_free(state);
5576 }
5577
attrib_translate(GLXX_CLIENT_STATE_T * state,uint32_t * indx)5578 static bool attrib_translate(GLXX_CLIENT_STATE_T *state, uint32_t *indx)
5579 {
5580 if (state->type == OPENGL_ES_11)
5581 {
5582 if (*indx == GL11_IX_CLIENT_ACTIVE_TEXTURE)
5583 {
5584 *indx = GL11_IX_TEXTURE_COORD + state->active_texture.client - GL_TEXTURE0;
5585 }
5586 vcos_assert(*indx < GL11_IX_MAX_ATTRIBS);
5587 return true;
5588 }
5589 else
5590 {
5591 vcos_assert(state->type == OPENGL_ES_20);
5592 if (*indx < GL20_CONFIG_MAX_VERTEX_ATTRIBS)
5593 {
5594 return true;
5595 }
5596 else
5597 {
5598 glxx_set_error(state, GL_INVALID_VALUE);
5599 return false;
5600 }
5601 }
5602 }
5603
glintAttribPointer(uint32_t api,uint32_t indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)5604 void glintAttribPointer (uint32_t api, uint32_t indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr)
5605 {
5606 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5607 if (IS_OPENGLES_API(thread, api))
5608 {
5609 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5610 if (attrib_translate(state, &indx))
5611 {
5612 state->attrib[indx].size = size;
5613 state->attrib[indx].type = type;
5614 state->attrib[indx].normalized = normalized;
5615 state->attrib[indx].stride = stride;
5616 state->attrib[indx].pointer = ptr;
5617 state->attrib[indx].buffer = state->bound_buffer.array;
5618
5619 RPC_CALL7(glintAttribPointer_impl,
5620 thread,
5621 GLINTATTRIBPOINTER_ID,
5622 RPC_UINT(api),
5623 RPC_UINT(indx),
5624 RPC_INT(size),
5625 RPC_ENUM(type),
5626 RPC_BOOLEAN(normalized),
5627 RPC_SIZEI(stride),
5628 RPC_INTPTR((GLintptr)ptr));
5629 }
5630 }
5631 }
5632
glintAttrib(uint32_t api,uint32_t indx,float x,float y,float z,float w)5633 void glintAttrib (uint32_t api, uint32_t indx, float x, float y, float z, float w)
5634 {
5635 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5636 if (IS_OPENGLES_API(thread, api))
5637 {
5638 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5639 if (attrib_translate(state, &indx))
5640 {
5641 vcos_assert(indx < GLXX_CONFIG_MAX_VERTEX_ATTRIBS);
5642 state->attrib[indx].value[0] = x;
5643 state->attrib[indx].value[1] = y;
5644 state->attrib[indx].value[2] = z;
5645 state->attrib[indx].value[3] = w;
5646
5647 RPC_CALL6(glintAttrib_impl,
5648 thread,
5649 GLINTATTRIB_ID,
5650 RPC_UINT(api),
5651 RPC_UINT(indx),
5652 RPC_FLOAT(x),
5653 RPC_FLOAT(y),
5654 RPC_FLOAT(z),
5655 RPC_FLOAT(w));
5656 }
5657 }
5658 }
5659
5660 /*
5661 Separate path for glColor because it needs to update the material
5662 */
5663
glintColor(float x,float y,float z,float w)5664 void glintColor (float x, float y, float z, float w)
5665 {
5666 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5667 if (IS_OPENGLES_11(thread))
5668 {
5669 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5670
5671 state->attrib[GL11_IX_COLOR].value[0] = x;
5672 state->attrib[GL11_IX_COLOR].value[1] = y;
5673 state->attrib[GL11_IX_COLOR].value[2] = z;
5674 state->attrib[GL11_IX_COLOR].value[3] = w;
5675
5676 RPC_CALL4(glintColor_impl_11,
5677 thread,
5678 GLINTCOLOR_ID_11,
5679 RPC_FLOAT(x),
5680 RPC_FLOAT(y),
5681 RPC_FLOAT(z),
5682 RPC_FLOAT(w));
5683 }
5684 }
5685
glintAttribEnable(uint32_t api,uint32_t indx,bool enabled)5686 void glintAttribEnable(uint32_t api, uint32_t indx, bool enabled)
5687 {
5688 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5689 if (IS_OPENGLES_API(thread, api))
5690 {
5691 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5692 if (attrib_translate(state, &indx))
5693 {
5694 state->attrib[indx].enabled = enabled;
5695
5696 RPC_CALL3(glintAttribEnable_impl,
5697 thread,
5698 GLINTATTRIBENABLE_ID,
5699 RPC_UINT(api),
5700 RPC_UINT(indx),
5701 RPC_BOOLEAN(enabled));
5702 }
5703 }
5704 }
5705
glintAttribGetPointer(uint32_t api,uint32_t indx)5706 void *glintAttribGetPointer(uint32_t api, uint32_t indx)
5707 {
5708 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
5709 if (IS_OPENGLES_API(thread, api))
5710 {
5711 GLXX_CLIENT_STATE_T *state = GLXX_GET_CLIENT_STATE(thread);
5712 if (attrib_translate(state, &indx))
5713 return (void *)state->attrib[indx].pointer;
5714 }
5715 return NULL;
5716 }
5717
5718 //TODO we need these to get the conformance test to build
5719 #ifdef __cplusplus
5720 extern "C" {
5721 #endif
5722
glTexImage3DOES(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const GLvoid * pixels)5723 GL_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); }
glTexSubImage3DOES(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels)5724 GL_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); }
5725
5726 #ifdef __cplusplus
5727 }
5728 #endif
5729