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