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