blob: eb4d4c3940a1b28772ee745a2794408fdc3aaecf [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +00002// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +000017#include "common/version.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000018
19#include "libGLESv2/main.h"
20#include "libGLESv2/mathutil.h"
21#include "libGLESv2/utilities.h"
22#include "libGLESv2/Buffer.h"
23#include "libGLESv2/Context.h"
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000024#include "libGLESv2/Fence.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000025#include "libGLESv2/Framebuffer.h"
26#include "libGLESv2/Program.h"
27#include "libGLESv2/Renderbuffer.h"
28#include "libGLESv2/Shader.h"
29#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000030
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +000031bool validImageSize(GLint level, GLsizei width, GLsizei height)
32{
33 if (level < 0 || width < 0 || height < 0)
34 {
35 return false;
36 }
37
38 if (gl::getContext() && gl::getContext()->supportsNonPower2Texture())
39 {
40 return true;
41 }
42
43 if (level == 0)
44 {
45 return true;
46 }
47
48 if (gl::isPow2(width) && gl::isPow2(height))
49 {
50 return true;
51 }
52
53 return false;
54}
55
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000056extern "C"
57{
58
59void __stdcall glActiveTexture(GLenum texture)
60{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000061 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000062
63 try
64 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +000065 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000066
67 if (context)
68 {
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +000069 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
70 {
71 return error(GL_INVALID_ENUM);
72 }
73
daniel@transgaming.com428d1582010-05-04 03:35:25 +000074 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000075 }
76 }
77 catch(std::bad_alloc&)
78 {
79 return error(GL_OUT_OF_MEMORY);
80 }
81}
82
83void __stdcall glAttachShader(GLuint program, GLuint shader)
84{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000085 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000086
87 try
88 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +000089 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090
91 if (context)
92 {
93 gl::Program *programObject = context->getProgram(program);
94 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000095
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000096 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000097 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000098 if (context->getShader(program))
99 {
100 return error(GL_INVALID_OPERATION);
101 }
102 else
103 {
104 return error(GL_INVALID_VALUE);
105 }
106 }
107
108 if (!shaderObject)
109 {
110 if (context->getProgram(shader))
111 {
112 return error(GL_INVALID_OPERATION);
113 }
114 else
115 {
116 return error(GL_INVALID_VALUE);
117 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000118 }
119
120 if (!programObject->attachShader(shaderObject))
121 {
122 return error(GL_INVALID_OPERATION);
123 }
124 }
125 }
126 catch(std::bad_alloc&)
127 {
128 return error(GL_OUT_OF_MEMORY);
129 }
130}
131
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000132void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000133{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000134 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000135
136 try
137 {
138 if (index >= gl::MAX_VERTEX_ATTRIBS)
139 {
140 return error(GL_INVALID_VALUE);
141 }
142
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000143 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000144
145 if (context)
146 {
147 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000148
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000149 if (!programObject)
150 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000151 if (context->getShader(program))
152 {
153 return error(GL_INVALID_OPERATION);
154 }
155 else
156 {
157 return error(GL_INVALID_VALUE);
158 }
159 }
160
161 if (strncmp(name, "gl_", 3) == 0)
162 {
163 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164 }
165
166 programObject->bindAttributeLocation(index, name);
167 }
168 }
169 catch(std::bad_alloc&)
170 {
171 return error(GL_OUT_OF_MEMORY);
172 }
173}
174
175void __stdcall glBindBuffer(GLenum target, GLuint buffer)
176{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000177 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000178
179 try
180 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000181 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000182
183 if (context)
184 {
185 switch (target)
186 {
187 case GL_ARRAY_BUFFER:
188 context->bindArrayBuffer(buffer);
189 return;
190 case GL_ELEMENT_ARRAY_BUFFER:
191 context->bindElementArrayBuffer(buffer);
192 return;
193 default:
194 return error(GL_INVALID_ENUM);
195 }
196 }
197 }
198 catch(std::bad_alloc&)
199 {
200 return error(GL_OUT_OF_MEMORY);
201 }
202}
203
204void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
205{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000206 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000207
208 try
209 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000210 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000211 {
212 return error(GL_INVALID_ENUM);
213 }
214
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000215 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000216
217 if (context)
218 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000219 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
220 {
221 context->bindReadFramebuffer(framebuffer);
222 }
223
224 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
225 {
226 context->bindDrawFramebuffer(framebuffer);
227 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228 }
229 }
230 catch(std::bad_alloc&)
231 {
232 return error(GL_OUT_OF_MEMORY);
233 }
234}
235
236void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
237{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000238 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000239
240 try
241 {
242 if (target != GL_RENDERBUFFER)
243 {
244 return error(GL_INVALID_ENUM);
245 }
246
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000247 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000248
249 if (context)
250 {
251 context->bindRenderbuffer(renderbuffer);
252 }
253 }
254 catch(std::bad_alloc&)
255 {
256 return error(GL_OUT_OF_MEMORY);
257 }
258}
259
260void __stdcall glBindTexture(GLenum target, GLuint texture)
261{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000262 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000263
264 try
265 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000266 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000267
268 if (context)
269 {
270 gl::Texture *textureObject = context->getTexture(texture);
271
272 if (textureObject && textureObject->getTarget() != target && texture != 0)
273 {
274 return error(GL_INVALID_OPERATION);
275 }
276
277 switch (target)
278 {
279 case GL_TEXTURE_2D:
280 context->bindTexture2D(texture);
281 return;
282 case GL_TEXTURE_CUBE_MAP:
283 context->bindTextureCubeMap(texture);
284 return;
285 default:
286 return error(GL_INVALID_ENUM);
287 }
288 }
289 }
290 catch(std::bad_alloc&)
291 {
292 return error(GL_OUT_OF_MEMORY);
293 }
294}
295
296void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
297{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000298 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000299 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000300
301 try
302 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000303 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000304
305 if (context)
306 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000307 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000308 }
309 }
310 catch(std::bad_alloc&)
311 {
312 return error(GL_OUT_OF_MEMORY);
313 }
314}
315
316void __stdcall glBlendEquation(GLenum mode)
317{
318 glBlendEquationSeparate(mode, mode);
319}
320
321void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
322{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000323 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000324
325 try
326 {
327 switch (modeRGB)
328 {
329 case GL_FUNC_ADD:
330 case GL_FUNC_SUBTRACT:
331 case GL_FUNC_REVERSE_SUBTRACT:
332 break;
333 default:
334 return error(GL_INVALID_ENUM);
335 }
336
337 switch (modeAlpha)
338 {
339 case GL_FUNC_ADD:
340 case GL_FUNC_SUBTRACT:
341 case GL_FUNC_REVERSE_SUBTRACT:
342 break;
343 default:
344 return error(GL_INVALID_ENUM);
345 }
346
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000347 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000348
349 if (context)
350 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000351 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000352 }
353 }
354 catch(std::bad_alloc&)
355 {
356 return error(GL_OUT_OF_MEMORY);
357 }
358}
359
360void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
361{
362 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
363}
364
365void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
366{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000367 EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000368 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000369
370 try
371 {
372 switch (srcRGB)
373 {
374 case GL_ZERO:
375 case GL_ONE:
376 case GL_SRC_COLOR:
377 case GL_ONE_MINUS_SRC_COLOR:
378 case GL_DST_COLOR:
379 case GL_ONE_MINUS_DST_COLOR:
380 case GL_SRC_ALPHA:
381 case GL_ONE_MINUS_SRC_ALPHA:
382 case GL_DST_ALPHA:
383 case GL_ONE_MINUS_DST_ALPHA:
384 case GL_CONSTANT_COLOR:
385 case GL_ONE_MINUS_CONSTANT_COLOR:
386 case GL_CONSTANT_ALPHA:
387 case GL_ONE_MINUS_CONSTANT_ALPHA:
388 case GL_SRC_ALPHA_SATURATE:
389 break;
390 default:
391 return error(GL_INVALID_ENUM);
392 }
393
394 switch (dstRGB)
395 {
396 case GL_ZERO:
397 case GL_ONE:
398 case GL_SRC_COLOR:
399 case GL_ONE_MINUS_SRC_COLOR:
400 case GL_DST_COLOR:
401 case GL_ONE_MINUS_DST_COLOR:
402 case GL_SRC_ALPHA:
403 case GL_ONE_MINUS_SRC_ALPHA:
404 case GL_DST_ALPHA:
405 case GL_ONE_MINUS_DST_ALPHA:
406 case GL_CONSTANT_COLOR:
407 case GL_ONE_MINUS_CONSTANT_COLOR:
408 case GL_CONSTANT_ALPHA:
409 case GL_ONE_MINUS_CONSTANT_ALPHA:
410 break;
411 default:
412 return error(GL_INVALID_ENUM);
413 }
414
415 switch (srcAlpha)
416 {
417 case GL_ZERO:
418 case GL_ONE:
419 case GL_SRC_COLOR:
420 case GL_ONE_MINUS_SRC_COLOR:
421 case GL_DST_COLOR:
422 case GL_ONE_MINUS_DST_COLOR:
423 case GL_SRC_ALPHA:
424 case GL_ONE_MINUS_SRC_ALPHA:
425 case GL_DST_ALPHA:
426 case GL_ONE_MINUS_DST_ALPHA:
427 case GL_CONSTANT_COLOR:
428 case GL_ONE_MINUS_CONSTANT_COLOR:
429 case GL_CONSTANT_ALPHA:
430 case GL_ONE_MINUS_CONSTANT_ALPHA:
431 case GL_SRC_ALPHA_SATURATE:
432 break;
433 default:
434 return error(GL_INVALID_ENUM);
435 }
436
437 switch (dstAlpha)
438 {
439 case GL_ZERO:
440 case GL_ONE:
441 case GL_SRC_COLOR:
442 case GL_ONE_MINUS_SRC_COLOR:
443 case GL_DST_COLOR:
444 case GL_ONE_MINUS_DST_COLOR:
445 case GL_SRC_ALPHA:
446 case GL_ONE_MINUS_SRC_ALPHA:
447 case GL_DST_ALPHA:
448 case GL_ONE_MINUS_DST_ALPHA:
449 case GL_CONSTANT_COLOR:
450 case GL_ONE_MINUS_CONSTANT_COLOR:
451 case GL_CONSTANT_ALPHA:
452 case GL_ONE_MINUS_CONSTANT_ALPHA:
453 break;
454 default:
455 return error(GL_INVALID_ENUM);
456 }
457
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000458 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
459 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
460
461 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
462 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
463
464 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000465 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000466 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
467 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000468 }
469
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000470 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000471
472 if (context)
473 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000474 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000475 }
476 }
477 catch(std::bad_alloc&)
478 {
479 return error(GL_OUT_OF_MEMORY);
480 }
481}
482
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000483void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000484{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000485 EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000486 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000487
488 try
489 {
490 if (size < 0)
491 {
492 return error(GL_INVALID_VALUE);
493 }
494
495 switch (usage)
496 {
497 case GL_STREAM_DRAW:
498 case GL_STATIC_DRAW:
499 case GL_DYNAMIC_DRAW:
500 break;
501 default:
502 return error(GL_INVALID_ENUM);
503 }
504
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000505 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000506
507 if (context)
508 {
509 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000510
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000511 switch (target)
512 {
513 case GL_ARRAY_BUFFER:
514 buffer = context->getArrayBuffer();
515 break;
516 case GL_ELEMENT_ARRAY_BUFFER:
517 buffer = context->getElementArrayBuffer();
518 break;
519 default:
520 return error(GL_INVALID_ENUM);
521 }
522
523 if (!buffer)
524 {
525 return error(GL_INVALID_OPERATION);
526 }
527
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000528 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000529 }
530 }
531 catch(std::bad_alloc&)
532 {
533 return error(GL_OUT_OF_MEMORY);
534 }
535}
536
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000537void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000538{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000539 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000540 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000541
542 try
543 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000544 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000545 {
546 return error(GL_INVALID_VALUE);
547 }
548
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000549 if (data == NULL)
550 {
551 return;
552 }
553
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000554 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000555
556 if (context)
557 {
558 gl::Buffer *buffer;
559
560 switch (target)
561 {
562 case GL_ARRAY_BUFFER:
563 buffer = context->getArrayBuffer();
564 break;
565 case GL_ELEMENT_ARRAY_BUFFER:
566 buffer = context->getElementArrayBuffer();
567 break;
568 default:
569 return error(GL_INVALID_ENUM);
570 }
571
572 if (!buffer)
573 {
574 return error(GL_INVALID_OPERATION);
575 }
576
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000577 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000578 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000579 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000580 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000581
582 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000583 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000584 }
585 catch(std::bad_alloc&)
586 {
587 return error(GL_OUT_OF_MEMORY);
588 }
589}
590
591GLenum __stdcall glCheckFramebufferStatus(GLenum target)
592{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000593 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000594
595 try
596 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000597 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000598 {
599 return error(GL_INVALID_ENUM, 0);
600 }
601
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000602 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000603
604 if (context)
605 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000606 gl::Framebuffer *framebuffer = NULL;
607 if (target == GL_READ_FRAMEBUFFER_ANGLE)
608 {
609 framebuffer = context->getReadFramebuffer();
610 }
611 else
612 {
613 framebuffer = context->getDrawFramebuffer();
614 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000615
616 return framebuffer->completeness();
617 }
618 }
619 catch(std::bad_alloc&)
620 {
621 return error(GL_OUT_OF_MEMORY, 0);
622 }
623
624 return 0;
625}
626
627void __stdcall glClear(GLbitfield mask)
628{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000629 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000630
631 try
632 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000633 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000634
635 if (context)
636 {
637 context->clear(mask);
638 }
639 }
640 catch(std::bad_alloc&)
641 {
642 return error(GL_OUT_OF_MEMORY);
643 }
644}
645
646void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
647{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000648 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000649 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000650
651 try
652 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000653 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000654
655 if (context)
656 {
657 context->setClearColor(red, green, blue, alpha);
658 }
659 }
660 catch(std::bad_alloc&)
661 {
662 return error(GL_OUT_OF_MEMORY);
663 }
664}
665
666void __stdcall glClearDepthf(GLclampf depth)
667{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000668 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000669
670 try
671 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000672 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000673
674 if (context)
675 {
676 context->setClearDepth(depth);
677 }
678 }
679 catch(std::bad_alloc&)
680 {
681 return error(GL_OUT_OF_MEMORY);
682 }
683}
684
685void __stdcall glClearStencil(GLint s)
686{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000687 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000688
689 try
690 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000691 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000692
693 if (context)
694 {
695 context->setClearStencil(s);
696 }
697 }
698 catch(std::bad_alloc&)
699 {
700 return error(GL_OUT_OF_MEMORY);
701 }
702}
703
704void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
705{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000706 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000707 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000708
709 try
710 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000711 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000712
713 if (context)
714 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000715 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000716 }
717 }
718 catch(std::bad_alloc&)
719 {
720 return error(GL_OUT_OF_MEMORY);
721 }
722}
723
724void __stdcall glCompileShader(GLuint shader)
725{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000726 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000727
728 try
729 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000730 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000731
732 if (context)
733 {
734 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000735
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000736 if (!shaderObject)
737 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000738 if (context->getProgram(shader))
739 {
740 return error(GL_INVALID_OPERATION);
741 }
742 else
743 {
744 return error(GL_INVALID_VALUE);
745 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000746 }
747
748 shaderObject->compile();
749 }
750 }
751 catch(std::bad_alloc&)
752 {
753 return error(GL_OUT_OF_MEMORY);
754 }
755}
756
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000757void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
758 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000759{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000760 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000761 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000762 target, level, internalformat, width, height, border, imageSize, data);
763
764 try
765 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000766 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000767 {
768 return error(GL_INVALID_VALUE);
769 }
770
daniel@transgaming.com01868132010-08-24 19:21:17 +0000771 switch (internalformat)
772 {
773 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
774 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +0000775 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
776 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +0000777 break;
778 default:
779 return error(GL_INVALID_ENUM);
780 }
781
782 if (border != 0)
783 {
784 return error(GL_INVALID_VALUE);
785 }
786
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000787 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000788
789 if (context)
790 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000791 if (level > context->getMaximumTextureLevel())
792 {
793 return error(GL_INVALID_VALUE);
794 }
795
796 switch (target)
797 {
798 case GL_TEXTURE_2D:
799 if (width > (context->getMaximumTextureDimension() >> level) ||
800 height > (context->getMaximumTextureDimension() >> level))
801 {
802 return error(GL_INVALID_VALUE);
803 }
804 break;
805 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
806 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
807 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
808 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
809 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
810 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
811 if (width != height)
812 {
813 return error(GL_INVALID_VALUE);
814 }
815
816 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
817 height > (context->getMaximumCubeTextureDimension() >> level))
818 {
819 return error(GL_INVALID_VALUE);
820 }
821 break;
822 default:
823 return error(GL_INVALID_ENUM);
824 }
825
gman@chromium.org50c526d2011-08-10 05:19:44 +0000826 switch (internalformat) {
827 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
828 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
829 if (!context->supportsDXT1Textures())
830 {
831 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
832 }
833 break;
834 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
835 if (!context->supportsDXT3Textures())
836 {
837 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
838 }
839 break;
840 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
841 if (!context->supportsDXT5Textures())
842 {
843 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
844 }
845 break;
846 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000847 }
848
849 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
850 {
851 return error(GL_INVALID_VALUE);
852 }
853
854 if (target == GL_TEXTURE_2D)
855 {
856 gl::Texture2D *texture = context->getTexture2D();
857
858 if (!texture)
859 {
860 return error(GL_INVALID_OPERATION);
861 }
862
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +0000863 if (texture->isImmutable())
864 {
865 return error(GL_INVALID_OPERATION);
866 }
867
daniel@transgaming.com01868132010-08-24 19:21:17 +0000868 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
869 }
870 else
871 {
872 gl::TextureCubeMap *texture = context->getTextureCubeMap();
873
874 if (!texture)
875 {
876 return error(GL_INVALID_OPERATION);
877 }
878
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +0000879 if (texture->isImmutable())
880 {
881 return error(GL_INVALID_OPERATION);
882 }
883
daniel@transgaming.com01868132010-08-24 19:21:17 +0000884 switch (target)
885 {
886 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
887 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
888 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
889 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
890 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
891 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
892 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
893 break;
894 default: UNREACHABLE();
895 }
896 }
897 }
898
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000899 }
900 catch(std::bad_alloc&)
901 {
902 return error(GL_OUT_OF_MEMORY);
903 }
904}
905
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000906void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
907 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000908{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000909 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000910 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000911 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000912 target, level, xoffset, yoffset, width, height, format, imageSize, data);
913
914 try
915 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000916 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000917 {
918 return error(GL_INVALID_ENUM);
919 }
920
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000921 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000922 {
923 return error(GL_INVALID_VALUE);
924 }
925
daniel@transgaming.com01868132010-08-24 19:21:17 +0000926 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000927 {
daniel@transgaming.com01868132010-08-24 19:21:17 +0000928 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
929 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +0000930 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
931 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +0000932 break;
933 default:
934 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +0000935 }
936
daniel@transgaming.com01868132010-08-24 19:21:17 +0000937 if (width == 0 || height == 0 || data == NULL)
938 {
939 return;
940 }
941
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000942 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000943
944 if (context)
945 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000946 if (level > context->getMaximumTextureLevel())
947 {
948 return error(GL_INVALID_VALUE);
949 }
950
gman@chromium.org50c526d2011-08-10 05:19:44 +0000951 switch (format) {
952 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
953 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
954 if (!context->supportsDXT1Textures())
955 {
956 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
957 }
958 break;
959 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
960 if (!context->supportsDXT3Textures())
961 {
962 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
963 }
964 break;
965 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
966 if (!context->supportsDXT5Textures())
967 {
968 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
969 }
970 break;
971 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000972 }
973
974 if (imageSize != gl::ComputeCompressedSize(width, height, format))
975 {
976 return error(GL_INVALID_VALUE);
977 }
978
979 if (xoffset % 4 != 0 || yoffset % 4 != 0)
980 {
981 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
gman@chromium.org50c526d2011-08-10 05:19:44 +0000982 // does not exist unless DXT textures are supported.
daniel@transgaming.com01868132010-08-24 19:21:17 +0000983 }
984
985 if (target == GL_TEXTURE_2D)
986 {
987 gl::Texture2D *texture = context->getTexture2D();
988
989 if (!texture)
990 {
991 return error(GL_INVALID_OPERATION);
992 }
993
994 if (!texture->isCompressed())
995 {
996 return error(GL_INVALID_OPERATION);
997 }
998
999 if ((width % 4 != 0 && width != texture->getWidth()) ||
1000 (height % 4 != 0 && height != texture->getHeight()))
1001 {
1002 return error(GL_INVALID_OPERATION);
1003 }
1004
1005 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
1006 }
1007 else if (gl::IsCubemapTextureTarget(target))
1008 {
1009 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1010
1011 if (!texture)
1012 {
1013 return error(GL_INVALID_OPERATION);
1014 }
1015
1016 if (!texture->isCompressed())
1017 {
1018 return error(GL_INVALID_OPERATION);
1019 }
1020
1021 if ((width % 4 != 0 && width != texture->getWidth()) ||
1022 (height % 4 != 0 && height != texture->getHeight()))
1023 {
1024 return error(GL_INVALID_OPERATION);
1025 }
1026
1027 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
1028 }
1029 else
1030 {
1031 UNREACHABLE();
1032 }
1033 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001034 }
1035 catch(std::bad_alloc&)
1036 {
1037 return error(GL_OUT_OF_MEMORY);
1038 }
1039}
1040
1041void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1042{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001043 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001044 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001045 target, level, internalformat, x, y, width, height, border);
1046
1047 try
1048 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001049 if (!validImageSize(level, width, height))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001050 {
1051 return error(GL_INVALID_VALUE);
1052 }
1053
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001054 if (border != 0)
1055 {
1056 return error(GL_INVALID_VALUE);
1057 }
1058
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001059 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001060
1061 if (context)
1062 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001063 switch (target)
1064 {
1065 case GL_TEXTURE_2D:
1066 if (width > (context->getMaximumTextureDimension() >> level) ||
1067 height > (context->getMaximumTextureDimension() >> level))
1068 {
1069 return error(GL_INVALID_VALUE);
1070 }
1071 break;
1072 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1073 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1074 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1075 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1076 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1077 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1078 if (width != height)
1079 {
1080 return error(GL_INVALID_VALUE);
1081 }
1082
1083 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1084 height > (context->getMaximumCubeTextureDimension() >> level))
1085 {
1086 return error(GL_INVALID_VALUE);
1087 }
1088 break;
1089 default:
1090 return error(GL_INVALID_ENUM);
1091 }
1092
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001093 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001094
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001095 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1096 {
1097 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1098 }
1099
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001100 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1101 {
1102 return error(GL_INVALID_OPERATION);
1103 }
1104
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001105 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001106 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001107
1108 // [OpenGL ES 2.0.24] table 3.9
1109 switch (internalformat)
1110 {
1111 case GL_ALPHA:
1112 if (colorbufferFormat != GL_ALPHA &&
1113 colorbufferFormat != GL_RGBA &&
1114 colorbufferFormat != GL_RGBA4 &&
1115 colorbufferFormat != GL_RGB5_A1 &&
1116 colorbufferFormat != GL_RGBA8_OES)
1117 {
1118 return error(GL_INVALID_OPERATION);
1119 }
1120 break;
1121 case GL_LUMINANCE:
1122 case GL_RGB:
1123 if (colorbufferFormat != GL_RGB &&
1124 colorbufferFormat != GL_RGB565 &&
1125 colorbufferFormat != GL_RGB8_OES &&
1126 colorbufferFormat != GL_RGBA &&
1127 colorbufferFormat != GL_RGBA4 &&
1128 colorbufferFormat != GL_RGB5_A1 &&
1129 colorbufferFormat != GL_RGBA8_OES)
1130 {
1131 return error(GL_INVALID_OPERATION);
1132 }
1133 break;
1134 case GL_LUMINANCE_ALPHA:
1135 case GL_RGBA:
1136 if (colorbufferFormat != GL_RGBA &&
1137 colorbufferFormat != GL_RGBA4 &&
1138 colorbufferFormat != GL_RGB5_A1 &&
1139 colorbufferFormat != GL_RGBA8_OES)
1140 {
1141 return error(GL_INVALID_OPERATION);
1142 }
1143 break;
1144 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1145 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001146 if (context->supportsDXT1Textures())
1147 {
1148 return error(GL_INVALID_OPERATION);
1149 }
1150 else
1151 {
1152 return error(GL_INVALID_ENUM);
1153 }
1154 break;
1155 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1156 if (context->supportsDXT3Textures())
1157 {
1158 return error(GL_INVALID_OPERATION);
1159 }
1160 else
1161 {
1162 return error(GL_INVALID_ENUM);
1163 }
1164 break;
1165 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1166 if (context->supportsDXT5Textures())
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001167 {
1168 return error(GL_INVALID_OPERATION);
1169 }
1170 else
1171 {
1172 return error(GL_INVALID_ENUM);
1173 }
1174 break;
1175 default:
1176 return error(GL_INVALID_ENUM);
1177 }
1178
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001179 if (target == GL_TEXTURE_2D)
1180 {
1181 gl::Texture2D *texture = context->getTexture2D();
1182
1183 if (!texture)
1184 {
1185 return error(GL_INVALID_OPERATION);
1186 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001187
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001188 if (texture->isImmutable())
1189 {
1190 return error(GL_INVALID_OPERATION);
1191 }
1192
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001193 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001194 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001195 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001196 {
1197 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1198
1199 if (!texture)
1200 {
1201 return error(GL_INVALID_OPERATION);
1202 }
1203
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001204 if (texture->isImmutable())
1205 {
1206 return error(GL_INVALID_OPERATION);
1207 }
1208
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001209 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001210 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001211 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001212 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001213 }
1214 catch(std::bad_alloc&)
1215 {
1216 return error(GL_OUT_OF_MEMORY);
1217 }
1218}
1219
1220void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1221{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001222 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001223 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001224 target, level, xoffset, yoffset, x, y, width, height);
1225
1226 try
1227 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001228 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001229 {
1230 return error(GL_INVALID_ENUM);
1231 }
1232
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001233 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001234 {
1235 return error(GL_INVALID_VALUE);
1236 }
1237
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001238 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1239 {
1240 return error(GL_INVALID_VALUE);
1241 }
1242
1243 if (width == 0 || height == 0)
1244 {
1245 return;
1246 }
1247
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001248 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001249
1250 if (context)
1251 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001252 if (level > context->getMaximumTextureLevel())
1253 {
1254 return error(GL_INVALID_VALUE);
1255 }
1256
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001257 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001258
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001259 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1260 {
1261 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1262 }
1263
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001264 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1265 {
1266 return error(GL_INVALID_OPERATION);
1267 }
1268
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001269 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001270 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001271 gl::Texture *texture = NULL;
1272
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001273 if (target == GL_TEXTURE_2D)
1274 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001275 texture = context->getTexture2D();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001276 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001277 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001278 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001279 texture = context->getTextureCubeMap();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001280 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001281 else UNREACHABLE();
1282
1283 if (!texture)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001284 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001285 return error(GL_INVALID_OPERATION);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001286 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001287
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001288 GLenum textureFormat = texture->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001289
1290 // [OpenGL ES 2.0.24] table 3.9
1291 switch (textureFormat)
1292 {
1293 case GL_ALPHA:
1294 if (colorbufferFormat != GL_ALPHA &&
1295 colorbufferFormat != GL_RGBA &&
1296 colorbufferFormat != GL_RGBA4 &&
1297 colorbufferFormat != GL_RGB5_A1 &&
1298 colorbufferFormat != GL_RGBA8_OES)
1299 {
1300 return error(GL_INVALID_OPERATION);
1301 }
1302 break;
1303 case GL_LUMINANCE:
1304 case GL_RGB:
1305 if (colorbufferFormat != GL_RGB &&
1306 colorbufferFormat != GL_RGB565 &&
1307 colorbufferFormat != GL_RGB8_OES &&
1308 colorbufferFormat != GL_RGBA &&
1309 colorbufferFormat != GL_RGBA4 &&
1310 colorbufferFormat != GL_RGB5_A1 &&
1311 colorbufferFormat != GL_RGBA8_OES)
1312 {
1313 return error(GL_INVALID_OPERATION);
1314 }
1315 break;
1316 case GL_LUMINANCE_ALPHA:
1317 case GL_RGBA:
1318 if (colorbufferFormat != GL_RGBA &&
1319 colorbufferFormat != GL_RGBA4 &&
1320 colorbufferFormat != GL_RGB5_A1 &&
1321 colorbufferFormat != GL_RGBA8_OES)
1322 {
1323 return error(GL_INVALID_OPERATION);
1324 }
1325 break;
1326 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1327 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001328 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1329 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001330 return error(GL_INVALID_OPERATION);
1331 default:
1332 return error(GL_INVALID_OPERATION);
1333 }
1334
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001335 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001336 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001337 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001338
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001339 catch(std::bad_alloc&)
1340 {
1341 return error(GL_OUT_OF_MEMORY);
1342 }
1343}
1344
1345GLuint __stdcall glCreateProgram(void)
1346{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001347 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001348
1349 try
1350 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001351 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001352
1353 if (context)
1354 {
1355 return context->createProgram();
1356 }
1357 }
1358 catch(std::bad_alloc&)
1359 {
1360 return error(GL_OUT_OF_MEMORY, 0);
1361 }
1362
1363 return 0;
1364}
1365
1366GLuint __stdcall glCreateShader(GLenum type)
1367{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001368 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001369
1370 try
1371 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001372 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001373
1374 if (context)
1375 {
1376 switch (type)
1377 {
1378 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001379 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001380 return context->createShader(type);
1381 default:
1382 return error(GL_INVALID_ENUM, 0);
1383 }
1384 }
1385 }
1386 catch(std::bad_alloc&)
1387 {
1388 return error(GL_OUT_OF_MEMORY, 0);
1389 }
1390
1391 return 0;
1392}
1393
1394void __stdcall glCullFace(GLenum mode)
1395{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001396 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001397
1398 try
1399 {
1400 switch (mode)
1401 {
1402 case GL_FRONT:
1403 case GL_BACK:
1404 case GL_FRONT_AND_BACK:
1405 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001406 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001407
1408 if (context)
1409 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001410 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001411 }
1412 }
1413 break;
1414 default:
1415 return error(GL_INVALID_ENUM);
1416 }
1417 }
1418 catch(std::bad_alloc&)
1419 {
1420 return error(GL_OUT_OF_MEMORY);
1421 }
1422}
1423
1424void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1425{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001426 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001427
1428 try
1429 {
1430 if (n < 0)
1431 {
1432 return error(GL_INVALID_VALUE);
1433 }
1434
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001435 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001436
1437 if (context)
1438 {
1439 for (int i = 0; i < n; i++)
1440 {
1441 context->deleteBuffer(buffers[i]);
1442 }
1443 }
1444 }
1445 catch(std::bad_alloc&)
1446 {
1447 return error(GL_OUT_OF_MEMORY);
1448 }
1449}
1450
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001451void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1452{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001453 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001454
1455 try
1456 {
1457 if (n < 0)
1458 {
1459 return error(GL_INVALID_VALUE);
1460 }
1461
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001462 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001463
1464 if (context)
1465 {
1466 for (int i = 0; i < n; i++)
1467 {
1468 context->deleteFence(fences[i]);
1469 }
1470 }
1471 }
1472 catch(std::bad_alloc&)
1473 {
1474 return error(GL_OUT_OF_MEMORY);
1475 }
1476}
1477
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001478void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1479{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001480 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001481
1482 try
1483 {
1484 if (n < 0)
1485 {
1486 return error(GL_INVALID_VALUE);
1487 }
1488
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001489 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001490
1491 if (context)
1492 {
1493 for (int i = 0; i < n; i++)
1494 {
1495 if (framebuffers[i] != 0)
1496 {
1497 context->deleteFramebuffer(framebuffers[i]);
1498 }
1499 }
1500 }
1501 }
1502 catch(std::bad_alloc&)
1503 {
1504 return error(GL_OUT_OF_MEMORY);
1505 }
1506}
1507
1508void __stdcall glDeleteProgram(GLuint program)
1509{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001510 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001511
1512 try
1513 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001514 if (program == 0)
1515 {
1516 return;
1517 }
1518
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001519 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001520
1521 if (context)
1522 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001523 if (!context->getProgram(program))
1524 {
1525 if(context->getShader(program))
1526 {
1527 return error(GL_INVALID_OPERATION);
1528 }
1529 else
1530 {
1531 return error(GL_INVALID_VALUE);
1532 }
1533 }
1534
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001535 context->deleteProgram(program);
1536 }
1537 }
1538 catch(std::bad_alloc&)
1539 {
1540 return error(GL_OUT_OF_MEMORY);
1541 }
1542}
1543
1544void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1545{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001546 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001547
1548 try
1549 {
1550 if (n < 0)
1551 {
1552 return error(GL_INVALID_VALUE);
1553 }
1554
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001555 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001556
1557 if (context)
1558 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001559 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001560 {
1561 context->deleteRenderbuffer(renderbuffers[i]);
1562 }
1563 }
1564 }
1565 catch(std::bad_alloc&)
1566 {
1567 return error(GL_OUT_OF_MEMORY);
1568 }
1569}
1570
1571void __stdcall glDeleteShader(GLuint shader)
1572{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001573 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001574
1575 try
1576 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001577 if (shader == 0)
1578 {
1579 return;
1580 }
1581
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001582 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001583
1584 if (context)
1585 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001586 if (!context->getShader(shader))
1587 {
1588 if(context->getProgram(shader))
1589 {
1590 return error(GL_INVALID_OPERATION);
1591 }
1592 else
1593 {
1594 return error(GL_INVALID_VALUE);
1595 }
1596 }
1597
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001598 context->deleteShader(shader);
1599 }
1600 }
1601 catch(std::bad_alloc&)
1602 {
1603 return error(GL_OUT_OF_MEMORY);
1604 }
1605}
1606
1607void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1608{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001609 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001610
1611 try
1612 {
1613 if (n < 0)
1614 {
1615 return error(GL_INVALID_VALUE);
1616 }
1617
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001618 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001619
1620 if (context)
1621 {
1622 for (int i = 0; i < n; i++)
1623 {
1624 if (textures[i] != 0)
1625 {
1626 context->deleteTexture(textures[i]);
1627 }
1628 }
1629 }
1630 }
1631 catch(std::bad_alloc&)
1632 {
1633 return error(GL_OUT_OF_MEMORY);
1634 }
1635}
1636
1637void __stdcall glDepthFunc(GLenum func)
1638{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001639 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001640
1641 try
1642 {
1643 switch (func)
1644 {
1645 case GL_NEVER:
1646 case GL_ALWAYS:
1647 case GL_LESS:
1648 case GL_LEQUAL:
1649 case GL_EQUAL:
1650 case GL_GREATER:
1651 case GL_GEQUAL:
1652 case GL_NOTEQUAL:
1653 break;
1654 default:
1655 return error(GL_INVALID_ENUM);
1656 }
1657
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001658 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001659
1660 if (context)
1661 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001662 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001663 }
1664 }
1665 catch(std::bad_alloc&)
1666 {
1667 return error(GL_OUT_OF_MEMORY);
1668 }
1669}
1670
1671void __stdcall glDepthMask(GLboolean flag)
1672{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001673 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001674
1675 try
1676 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001677 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001678
1679 if (context)
1680 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001681 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001682 }
1683 }
1684 catch(std::bad_alloc&)
1685 {
1686 return error(GL_OUT_OF_MEMORY);
1687 }
1688}
1689
1690void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1691{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001692 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001693
1694 try
1695 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001696 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001697
1698 if (context)
1699 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001700 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001701 }
1702 }
1703 catch(std::bad_alloc&)
1704 {
1705 return error(GL_OUT_OF_MEMORY);
1706 }
1707}
1708
1709void __stdcall glDetachShader(GLuint program, GLuint shader)
1710{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001711 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001712
1713 try
1714 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001715 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001716
1717 if (context)
1718 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001719
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001720 gl::Program *programObject = context->getProgram(program);
1721 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001722
1723 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001724 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001725 gl::Shader *shaderByProgramHandle;
1726 shaderByProgramHandle = context->getShader(program);
1727 if (!shaderByProgramHandle)
1728 {
1729 return error(GL_INVALID_VALUE);
1730 }
1731 else
1732 {
1733 return error(GL_INVALID_OPERATION);
1734 }
1735 }
1736
1737 if (!shaderObject)
1738 {
1739 gl::Program *programByShaderHandle = context->getProgram(shader);
1740 if (!programByShaderHandle)
1741 {
1742 return error(GL_INVALID_VALUE);
1743 }
1744 else
1745 {
1746 return error(GL_INVALID_OPERATION);
1747 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001748 }
1749
1750 if (!programObject->detachShader(shaderObject))
1751 {
1752 return error(GL_INVALID_OPERATION);
1753 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001754 }
1755 }
1756 catch(std::bad_alloc&)
1757 {
1758 return error(GL_OUT_OF_MEMORY);
1759 }
1760}
1761
1762void __stdcall glDisable(GLenum cap)
1763{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001764 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001765
1766 try
1767 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001768 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001769
1770 if (context)
1771 {
1772 switch (cap)
1773 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001774 case GL_CULL_FACE: context->setCullFace(false); break;
1775 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1776 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1777 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1778 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1779 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1780 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1781 case GL_BLEND: context->setBlend(false); break;
1782 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001783 default:
1784 return error(GL_INVALID_ENUM);
1785 }
1786 }
1787 }
1788 catch(std::bad_alloc&)
1789 {
1790 return error(GL_OUT_OF_MEMORY);
1791 }
1792}
1793
1794void __stdcall glDisableVertexAttribArray(GLuint index)
1795{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001796 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001797
1798 try
1799 {
1800 if (index >= gl::MAX_VERTEX_ATTRIBS)
1801 {
1802 return error(GL_INVALID_VALUE);
1803 }
1804
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001805 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001806
1807 if (context)
1808 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001809 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001810 }
1811 }
1812 catch(std::bad_alloc&)
1813 {
1814 return error(GL_OUT_OF_MEMORY);
1815 }
1816}
1817
1818void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1819{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001820 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001821
1822 try
1823 {
1824 if (count < 0 || first < 0)
1825 {
1826 return error(GL_INVALID_VALUE);
1827 }
1828
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001829 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001830
1831 if (context)
1832 {
1833 context->drawArrays(mode, first, count);
1834 }
1835 }
1836 catch(std::bad_alloc&)
1837 {
1838 return error(GL_OUT_OF_MEMORY);
1839 }
1840}
1841
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001842void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001843{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001844 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001845 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001846
1847 try
1848 {
1849 if (count < 0)
1850 {
1851 return error(GL_INVALID_VALUE);
1852 }
1853
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001854 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001855
1856 if (context)
1857 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001858 switch (type)
1859 {
1860 case GL_UNSIGNED_BYTE:
1861 case GL_UNSIGNED_SHORT:
1862 break;
1863 case GL_UNSIGNED_INT:
1864 if (!context->supports32bitIndices())
1865 {
1866 return error(GL_INVALID_ENUM);
1867 }
1868 break;
1869 default:
1870 return error(GL_INVALID_ENUM);
1871 }
1872
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001873 context->drawElements(mode, count, type, indices);
1874 }
1875 }
1876 catch(std::bad_alloc&)
1877 {
1878 return error(GL_OUT_OF_MEMORY);
1879 }
1880}
1881
1882void __stdcall glEnable(GLenum cap)
1883{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001884 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001885
1886 try
1887 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001888 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001889
1890 if (context)
1891 {
1892 switch (cap)
1893 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001894 case GL_CULL_FACE: context->setCullFace(true); break;
1895 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1896 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1897 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1898 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1899 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1900 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1901 case GL_BLEND: context->setBlend(true); break;
1902 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001903 default:
1904 return error(GL_INVALID_ENUM);
1905 }
1906 }
1907 }
1908 catch(std::bad_alloc&)
1909 {
1910 return error(GL_OUT_OF_MEMORY);
1911 }
1912}
1913
1914void __stdcall glEnableVertexAttribArray(GLuint index)
1915{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001916 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001917
1918 try
1919 {
1920 if (index >= gl::MAX_VERTEX_ATTRIBS)
1921 {
1922 return error(GL_INVALID_VALUE);
1923 }
1924
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001925 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001926
1927 if (context)
1928 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001929 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001930 }
1931 }
1932 catch(std::bad_alloc&)
1933 {
1934 return error(GL_OUT_OF_MEMORY);
1935 }
1936}
1937
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001938void __stdcall glFinishFenceNV(GLuint fence)
1939{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001940 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001941
1942 try
1943 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001944 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001945
1946 if (context)
1947 {
1948 gl::Fence* fenceObject = context->getFence(fence);
1949
1950 if (fenceObject == NULL)
1951 {
1952 return error(GL_INVALID_OPERATION);
1953 }
1954
1955 fenceObject->finishFence();
1956 }
1957 }
1958 catch(std::bad_alloc&)
1959 {
1960 return error(GL_OUT_OF_MEMORY);
1961 }
1962}
1963
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001964void __stdcall glFinish(void)
1965{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001966 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001967
1968 try
1969 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001970 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001971
1972 if (context)
1973 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00001974 context->sync(true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001975 }
1976 }
1977 catch(std::bad_alloc&)
1978 {
1979 return error(GL_OUT_OF_MEMORY);
1980 }
1981}
1982
1983void __stdcall glFlush(void)
1984{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001985 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001986
1987 try
1988 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001989 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001990
1991 if (context)
1992 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00001993 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001994 }
1995 }
1996 catch(std::bad_alloc&)
1997 {
1998 return error(GL_OUT_OF_MEMORY);
1999 }
2000}
2001
2002void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2003{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002004 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002005 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002006
2007 try
2008 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002009 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002010 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002011 {
2012 return error(GL_INVALID_ENUM);
2013 }
2014
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002015 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002016
2017 if (context)
2018 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002019 gl::Framebuffer *framebuffer = NULL;
2020 GLuint framebufferHandle = 0;
2021 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2022 {
2023 framebuffer = context->getReadFramebuffer();
2024 framebufferHandle = context->getReadFramebufferHandle();
2025 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002026 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002027 {
2028 framebuffer = context->getDrawFramebuffer();
2029 framebufferHandle = context->getDrawFramebufferHandle();
2030 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002031
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002032 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002033 {
2034 return error(GL_INVALID_OPERATION);
2035 }
2036
2037 switch (attachment)
2038 {
2039 case GL_COLOR_ATTACHMENT0:
2040 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2041 break;
2042 case GL_DEPTH_ATTACHMENT:
2043 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2044 break;
2045 case GL_STENCIL_ATTACHMENT:
2046 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2047 break;
2048 default:
2049 return error(GL_INVALID_ENUM);
2050 }
2051 }
2052 }
2053 catch(std::bad_alloc&)
2054 {
2055 return error(GL_OUT_OF_MEMORY);
2056 }
2057}
2058
2059void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2060{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002061 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002062 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002063
2064 try
2065 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002066 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002067 {
2068 return error(GL_INVALID_ENUM);
2069 }
2070
2071 switch (attachment)
2072 {
2073 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002074 case GL_DEPTH_ATTACHMENT:
2075 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002076 break;
2077 default:
2078 return error(GL_INVALID_ENUM);
2079 }
2080
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002081 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002082
2083 if (context)
2084 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002085 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002086 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002087 textarget = GL_NONE;
2088 }
2089 else
2090 {
2091 gl::Texture *tex = context->getTexture(texture);
2092
2093 if (tex == NULL)
2094 {
2095 return error(GL_INVALID_OPERATION);
2096 }
2097
daniel@transgaming.com01868132010-08-24 19:21:17 +00002098 if (tex->isCompressed())
2099 {
2100 return error(GL_INVALID_OPERATION);
2101 }
2102
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002103 switch (textarget)
2104 {
2105 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002106 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002107 {
2108 return error(GL_INVALID_OPERATION);
2109 }
2110 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002111
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002112 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002113 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002114 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002115 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002116 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002117 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002118 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2119 {
2120 return error(GL_INVALID_OPERATION);
2121 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002122 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002123
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002124 default:
2125 return error(GL_INVALID_ENUM);
2126 }
2127
2128 if (level != 0)
2129 {
2130 return error(GL_INVALID_VALUE);
2131 }
2132 }
2133
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002134 gl::Framebuffer *framebuffer = NULL;
2135 GLuint framebufferHandle = 0;
2136 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2137 {
2138 framebuffer = context->getReadFramebuffer();
2139 framebufferHandle = context->getReadFramebufferHandle();
2140 }
2141 else
2142 {
2143 framebuffer = context->getDrawFramebuffer();
2144 framebufferHandle = context->getDrawFramebufferHandle();
2145 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002146
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002147 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002148 {
2149 return error(GL_INVALID_OPERATION);
2150 }
2151
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002152 switch (attachment)
2153 {
2154 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2155 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2156 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2157 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002158 }
2159 }
2160 catch(std::bad_alloc&)
2161 {
2162 return error(GL_OUT_OF_MEMORY);
2163 }
2164}
2165
2166void __stdcall glFrontFace(GLenum mode)
2167{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002168 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002169
2170 try
2171 {
2172 switch (mode)
2173 {
2174 case GL_CW:
2175 case GL_CCW:
2176 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002177 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002178
2179 if (context)
2180 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002181 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002182 }
2183 }
2184 break;
2185 default:
2186 return error(GL_INVALID_ENUM);
2187 }
2188 }
2189 catch(std::bad_alloc&)
2190 {
2191 return error(GL_OUT_OF_MEMORY);
2192 }
2193}
2194
2195void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2196{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002197 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002198
2199 try
2200 {
2201 if (n < 0)
2202 {
2203 return error(GL_INVALID_VALUE);
2204 }
2205
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002206 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002207
2208 if (context)
2209 {
2210 for (int i = 0; i < n; i++)
2211 {
2212 buffers[i] = context->createBuffer();
2213 }
2214 }
2215 }
2216 catch(std::bad_alloc&)
2217 {
2218 return error(GL_OUT_OF_MEMORY);
2219 }
2220}
2221
2222void __stdcall glGenerateMipmap(GLenum target)
2223{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002224 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002225
2226 try
2227 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002228 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002229
2230 if (context)
2231 {
2232 gl::Texture *texture;
2233
2234 switch (target)
2235 {
2236 case GL_TEXTURE_2D:
2237 texture = context->getTexture2D();
2238 break;
2239
2240 case GL_TEXTURE_CUBE_MAP:
2241 texture = context->getTextureCubeMap();
2242 break;
2243
2244 default:
2245 return error(GL_INVALID_ENUM);
2246 }
2247
daniel@transgaming.com01868132010-08-24 19:21:17 +00002248 if (texture->isCompressed())
2249 {
2250 return error(GL_INVALID_OPERATION);
2251 }
2252
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002253 texture->generateMipmaps();
2254 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002255 }
2256 catch(std::bad_alloc&)
2257 {
2258 return error(GL_OUT_OF_MEMORY);
2259 }
2260}
2261
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002262void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2263{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002264 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002265
2266 try
2267 {
2268 if (n < 0)
2269 {
2270 return error(GL_INVALID_VALUE);
2271 }
2272
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002273 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002274
2275 if (context)
2276 {
2277 for (int i = 0; i < n; i++)
2278 {
2279 fences[i] = context->createFence();
2280 }
2281 }
2282 }
2283 catch(std::bad_alloc&)
2284 {
2285 return error(GL_OUT_OF_MEMORY);
2286 }
2287}
2288
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002289void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2290{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002291 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002292
2293 try
2294 {
2295 if (n < 0)
2296 {
2297 return error(GL_INVALID_VALUE);
2298 }
2299
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002300 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002301
2302 if (context)
2303 {
2304 for (int i = 0; i < n; i++)
2305 {
2306 framebuffers[i] = context->createFramebuffer();
2307 }
2308 }
2309 }
2310 catch(std::bad_alloc&)
2311 {
2312 return error(GL_OUT_OF_MEMORY);
2313 }
2314}
2315
2316void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2317{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002318 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002319
2320 try
2321 {
2322 if (n < 0)
2323 {
2324 return error(GL_INVALID_VALUE);
2325 }
2326
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002327 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002328
2329 if (context)
2330 {
2331 for (int i = 0; i < n; i++)
2332 {
2333 renderbuffers[i] = context->createRenderbuffer();
2334 }
2335 }
2336 }
2337 catch(std::bad_alloc&)
2338 {
2339 return error(GL_OUT_OF_MEMORY);
2340 }
2341}
2342
2343void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2344{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002345 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002346
2347 try
2348 {
2349 if (n < 0)
2350 {
2351 return error(GL_INVALID_VALUE);
2352 }
2353
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002354 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002355
2356 if (context)
2357 {
2358 for (int i = 0; i < n; i++)
2359 {
2360 textures[i] = context->createTexture();
2361 }
2362 }
2363 }
2364 catch(std::bad_alloc&)
2365 {
2366 return error(GL_OUT_OF_MEMORY);
2367 }
2368}
2369
daniel@transgaming.com85423182010-04-22 13:35:27 +00002370void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002371{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002372 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002373 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002374 program, index, bufsize, length, size, type, name);
2375
2376 try
2377 {
2378 if (bufsize < 0)
2379 {
2380 return error(GL_INVALID_VALUE);
2381 }
2382
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002383 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002384
2385 if (context)
2386 {
2387 gl::Program *programObject = context->getProgram(program);
2388
2389 if (!programObject)
2390 {
2391 if (context->getShader(program))
2392 {
2393 return error(GL_INVALID_OPERATION);
2394 }
2395 else
2396 {
2397 return error(GL_INVALID_VALUE);
2398 }
2399 }
2400
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002401 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002402 {
2403 return error(GL_INVALID_VALUE);
2404 }
2405
2406 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2407 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002408 }
2409 catch(std::bad_alloc&)
2410 {
2411 return error(GL_OUT_OF_MEMORY);
2412 }
2413}
2414
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002415void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002416{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002417 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002418 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002419 program, index, bufsize, length, size, type, name);
2420
2421 try
2422 {
2423 if (bufsize < 0)
2424 {
2425 return error(GL_INVALID_VALUE);
2426 }
2427
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002428 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002429
2430 if (context)
2431 {
2432 gl::Program *programObject = context->getProgram(program);
2433
2434 if (!programObject)
2435 {
2436 if (context->getShader(program))
2437 {
2438 return error(GL_INVALID_OPERATION);
2439 }
2440 else
2441 {
2442 return error(GL_INVALID_VALUE);
2443 }
2444 }
2445
2446 if (index >= (GLuint)programObject->getActiveUniformCount())
2447 {
2448 return error(GL_INVALID_VALUE);
2449 }
2450
2451 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2452 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002453 }
2454 catch(std::bad_alloc&)
2455 {
2456 return error(GL_OUT_OF_MEMORY);
2457 }
2458}
2459
2460void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2461{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002462 EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002463 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002464
2465 try
2466 {
2467 if (maxcount < 0)
2468 {
2469 return error(GL_INVALID_VALUE);
2470 }
2471
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002472 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002473
2474 if (context)
2475 {
2476 gl::Program *programObject = context->getProgram(program);
2477
2478 if (!programObject)
2479 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002480 if (context->getShader(program))
2481 {
2482 return error(GL_INVALID_OPERATION);
2483 }
2484 else
2485 {
2486 return error(GL_INVALID_VALUE);
2487 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002488 }
2489
2490 return programObject->getAttachedShaders(maxcount, count, shaders);
2491 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002492 }
2493 catch(std::bad_alloc&)
2494 {
2495 return error(GL_OUT_OF_MEMORY);
2496 }
2497}
2498
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002499int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002500{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002501 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002502
2503 try
2504 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002505 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002506
2507 if (context)
2508 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002509
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002510 gl::Program *programObject = context->getProgram(program);
2511
2512 if (!programObject)
2513 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002514 if (context->getShader(program))
2515 {
2516 return error(GL_INVALID_OPERATION, -1);
2517 }
2518 else
2519 {
2520 return error(GL_INVALID_VALUE, -1);
2521 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002522 }
2523
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002524 if (!programObject->isLinked())
2525 {
2526 return error(GL_INVALID_OPERATION, -1);
2527 }
2528
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002529 return programObject->getAttributeLocation(name);
2530 }
2531 }
2532 catch(std::bad_alloc&)
2533 {
2534 return error(GL_OUT_OF_MEMORY, -1);
2535 }
2536
2537 return -1;
2538}
2539
2540void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2541{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002542 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002543
2544 try
2545 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002546 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002547
2548 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002549 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002550 if (!(context->getBooleanv(pname, params)))
2551 {
2552 GLenum nativeType;
2553 unsigned int numParams = 0;
2554 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2555 return error(GL_INVALID_ENUM);
2556
2557 if (numParams == 0)
2558 return; // it is known that the pname is valid, but there are no parameters to return
2559
2560 if (nativeType == GL_FLOAT)
2561 {
2562 GLfloat *floatParams = NULL;
2563 floatParams = new GLfloat[numParams];
2564
2565 context->getFloatv(pname, floatParams);
2566
2567 for (unsigned int i = 0; i < numParams; ++i)
2568 {
2569 if (floatParams[i] == 0.0f)
2570 params[i] = GL_FALSE;
2571 else
2572 params[i] = GL_TRUE;
2573 }
2574
2575 delete [] floatParams;
2576 }
2577 else if (nativeType == GL_INT)
2578 {
2579 GLint *intParams = NULL;
2580 intParams = new GLint[numParams];
2581
2582 context->getIntegerv(pname, intParams);
2583
2584 for (unsigned int i = 0; i < numParams; ++i)
2585 {
2586 if (intParams[i] == 0)
2587 params[i] = GL_FALSE;
2588 else
2589 params[i] = GL_TRUE;
2590 }
2591
2592 delete [] intParams;
2593 }
2594 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002595 }
2596 }
2597 catch(std::bad_alloc&)
2598 {
2599 return error(GL_OUT_OF_MEMORY);
2600 }
2601}
2602
2603void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2604{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002605 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002606
2607 try
2608 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002609 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002610
2611 if (context)
2612 {
2613 gl::Buffer *buffer;
2614
2615 switch (target)
2616 {
2617 case GL_ARRAY_BUFFER:
2618 buffer = context->getArrayBuffer();
2619 break;
2620 case GL_ELEMENT_ARRAY_BUFFER:
2621 buffer = context->getElementArrayBuffer();
2622 break;
2623 default: return error(GL_INVALID_ENUM);
2624 }
2625
2626 if (!buffer)
2627 {
2628 // A null buffer means that "0" is bound to the requested buffer target
2629 return error(GL_INVALID_OPERATION);
2630 }
2631
2632 switch (pname)
2633 {
2634 case GL_BUFFER_USAGE:
2635 *params = buffer->usage();
2636 break;
2637 case GL_BUFFER_SIZE:
2638 *params = buffer->size();
2639 break;
2640 default: return error(GL_INVALID_ENUM);
2641 }
2642 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002643 }
2644 catch(std::bad_alloc&)
2645 {
2646 return error(GL_OUT_OF_MEMORY);
2647 }
2648}
2649
2650GLenum __stdcall glGetError(void)
2651{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002652 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002653
2654 gl::Context *context = gl::getContext();
2655
2656 if (context)
2657 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002658 if (context->isContextLost())
2659 return GL_OUT_OF_MEMORY;
2660 else
2661 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002662 }
2663
2664 return GL_NO_ERROR;
2665}
2666
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002667void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2668{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002669 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002670
2671 try
2672 {
2673
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002674 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002675
2676 if (context)
2677 {
2678 gl::Fence *fenceObject = context->getFence(fence);
2679
2680 if (fenceObject == NULL)
2681 {
2682 return error(GL_INVALID_OPERATION);
2683 }
2684
2685 fenceObject->getFenceiv(pname, params);
2686 }
2687 }
2688 catch(std::bad_alloc&)
2689 {
2690 return error(GL_OUT_OF_MEMORY);
2691 }
2692}
2693
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002694void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2695{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002696 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002697
2698 try
2699 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002700 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002701
2702 if (context)
2703 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002704 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002705 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002706 GLenum nativeType;
2707 unsigned int numParams = 0;
2708 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2709 return error(GL_INVALID_ENUM);
2710
2711 if (numParams == 0)
2712 return; // it is known that the pname is valid, but that there are no parameters to return.
2713
2714 if (nativeType == GL_BOOL)
2715 {
2716 GLboolean *boolParams = NULL;
2717 boolParams = new GLboolean[numParams];
2718
2719 context->getBooleanv(pname, boolParams);
2720
2721 for (unsigned int i = 0; i < numParams; ++i)
2722 {
2723 if (boolParams[i] == GL_FALSE)
2724 params[i] = 0.0f;
2725 else
2726 params[i] = 1.0f;
2727 }
2728
2729 delete [] boolParams;
2730 }
2731 else if (nativeType == GL_INT)
2732 {
2733 GLint *intParams = NULL;
2734 intParams = new GLint[numParams];
2735
2736 context->getIntegerv(pname, intParams);
2737
2738 for (unsigned int i = 0; i < numParams; ++i)
2739 {
2740 params[i] = (GLfloat)intParams[i];
2741 }
2742
2743 delete [] intParams;
2744 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002745 }
2746 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002747 }
2748 catch(std::bad_alloc&)
2749 {
2750 return error(GL_OUT_OF_MEMORY);
2751 }
2752}
2753
2754void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2755{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002756 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002757 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002758
2759 try
2760 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002761 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002762
2763 if (context)
2764 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002765 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002766 {
2767 return error(GL_INVALID_ENUM);
2768 }
2769
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002770 gl::Framebuffer *framebuffer = NULL;
2771 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2772 {
2773 if(context->getReadFramebufferHandle() == 0)
2774 {
2775 return error(GL_INVALID_OPERATION);
2776 }
2777
2778 framebuffer = context->getReadFramebuffer();
2779 }
2780 else
2781 {
2782 if (context->getDrawFramebufferHandle() == 0)
2783 {
2784 return error(GL_INVALID_OPERATION);
2785 }
2786
2787 framebuffer = context->getDrawFramebuffer();
2788 }
2789
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002790 GLenum attachmentType;
2791 GLuint attachmentHandle;
2792 switch (attachment)
2793 {
2794 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002795 attachmentType = framebuffer->getColorbufferType();
2796 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002797 break;
2798 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002799 attachmentType = framebuffer->getDepthbufferType();
2800 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002801 break;
2802 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002803 attachmentType = framebuffer->getStencilbufferType();
2804 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002805 break;
2806 default: return error(GL_INVALID_ENUM);
2807 }
2808
2809 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002810 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002811 {
2812 attachmentObjectType = attachmentType;
2813 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002814 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002815 {
2816 attachmentObjectType = GL_TEXTURE;
2817 }
2818 else UNREACHABLE();
2819
2820 switch (pname)
2821 {
2822 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2823 *params = attachmentObjectType;
2824 break;
2825 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2826 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2827 {
2828 *params = attachmentHandle;
2829 }
2830 else
2831 {
2832 return error(GL_INVALID_ENUM);
2833 }
2834 break;
2835 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2836 if (attachmentObjectType == GL_TEXTURE)
2837 {
2838 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2839 }
2840 else
2841 {
2842 return error(GL_INVALID_ENUM);
2843 }
2844 break;
2845 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2846 if (attachmentObjectType == GL_TEXTURE)
2847 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002848 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002849 {
2850 *params = attachmentType;
2851 }
2852 else
2853 {
2854 *params = 0;
2855 }
2856 }
2857 else
2858 {
2859 return error(GL_INVALID_ENUM);
2860 }
2861 break;
2862 default:
2863 return error(GL_INVALID_ENUM);
2864 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002865 }
2866 }
2867 catch(std::bad_alloc&)
2868 {
2869 return error(GL_OUT_OF_MEMORY);
2870 }
2871}
2872
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00002873GLenum __stdcall glGetGraphicsResetStatusEXT(void)
2874{
2875 EVENT("()");
2876
2877 try
2878 {
2879 gl::Context *context = gl::getContext();
2880
2881 if (context)
2882 {
2883 return context->getResetStatus();
2884 }
2885
2886 return GL_NO_ERROR;
2887 }
2888 catch(std::bad_alloc&)
2889 {
2890 return GL_OUT_OF_MEMORY;
2891 }
2892}
2893
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002894void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2895{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002896 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002897
2898 try
2899 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002900 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002901
2902 if (context)
2903 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002904 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002905 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002906 GLenum nativeType;
2907 unsigned int numParams = 0;
2908 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2909 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002910
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002911 if (numParams == 0)
2912 return; // it is known that pname is valid, but there are no parameters to return
2913
2914 if (nativeType == GL_BOOL)
2915 {
2916 GLboolean *boolParams = NULL;
2917 boolParams = new GLboolean[numParams];
2918
2919 context->getBooleanv(pname, boolParams);
2920
2921 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002922 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002923 if (boolParams[i] == GL_FALSE)
2924 params[i] = 0;
2925 else
2926 params[i] = 1;
2927 }
2928
2929 delete [] boolParams;
2930 }
2931 else if (nativeType == GL_FLOAT)
2932 {
2933 GLfloat *floatParams = NULL;
2934 floatParams = new GLfloat[numParams];
2935
2936 context->getFloatv(pname, floatParams);
2937
2938 for (unsigned int i = 0; i < numParams; ++i)
2939 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002940 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002941 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002942 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002943 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002944 else
2945 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002946 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002947
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002948 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002949 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002950 }
2951 }
2952 }
2953 catch(std::bad_alloc&)
2954 {
2955 return error(GL_OUT_OF_MEMORY);
2956 }
2957}
2958
2959void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2960{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002961 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002962
2963 try
2964 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002965 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002966
2967 if (context)
2968 {
2969 gl::Program *programObject = context->getProgram(program);
2970
2971 if (!programObject)
2972 {
2973 return error(GL_INVALID_VALUE);
2974 }
2975
2976 switch (pname)
2977 {
2978 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002979 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002980 return;
2981 case GL_LINK_STATUS:
2982 *params = programObject->isLinked();
2983 return;
2984 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002985 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002986 return;
2987 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002988 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002989 return;
2990 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002991 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002992 return;
2993 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002994 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002995 return;
2996 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002997 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002998 return;
2999 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003000 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003001 return;
3002 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003003 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003004 return;
3005 default:
3006 return error(GL_INVALID_ENUM);
3007 }
3008 }
3009 }
3010 catch(std::bad_alloc&)
3011 {
3012 return error(GL_OUT_OF_MEMORY);
3013 }
3014}
3015
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003016void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003017{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003018 EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003019 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003020
3021 try
3022 {
3023 if (bufsize < 0)
3024 {
3025 return error(GL_INVALID_VALUE);
3026 }
3027
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003028 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003029
3030 if (context)
3031 {
3032 gl::Program *programObject = context->getProgram(program);
3033
3034 if (!programObject)
3035 {
3036 return error(GL_INVALID_VALUE);
3037 }
3038
3039 programObject->getInfoLog(bufsize, length, infolog);
3040 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003041 }
3042 catch(std::bad_alloc&)
3043 {
3044 return error(GL_OUT_OF_MEMORY);
3045 }
3046}
3047
3048void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3049{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003050 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003051
3052 try
3053 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003054 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003055
3056 if (context)
3057 {
3058 if (target != GL_RENDERBUFFER)
3059 {
3060 return error(GL_INVALID_ENUM);
3061 }
3062
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003063 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003064 {
3065 return error(GL_INVALID_OPERATION);
3066 }
3067
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003068 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003069
3070 switch (pname)
3071 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003072 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3073 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3074 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3075 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3076 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3077 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3078 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3079 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3080 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003081 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003082 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003083 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003084 *params = renderbuffer->getSamples();
3085 }
3086 else
3087 {
3088 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003089 }
3090 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003091 default:
3092 return error(GL_INVALID_ENUM);
3093 }
3094 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003095 }
3096 catch(std::bad_alloc&)
3097 {
3098 return error(GL_OUT_OF_MEMORY);
3099 }
3100}
3101
3102void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3103{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003104 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003105
3106 try
3107 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003108 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003109
3110 if (context)
3111 {
3112 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003113
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003114 if (!shaderObject)
3115 {
3116 return error(GL_INVALID_VALUE);
3117 }
3118
3119 switch (pname)
3120 {
3121 case GL_SHADER_TYPE:
3122 *params = shaderObject->getType();
3123 return;
3124 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003125 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003126 return;
3127 case GL_COMPILE_STATUS:
3128 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3129 return;
3130 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003131 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003132 return;
3133 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003134 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003135 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003136 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3137 *params = shaderObject->getTranslatedSourceLength();
3138 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003139 default:
3140 return error(GL_INVALID_ENUM);
3141 }
3142 }
3143 }
3144 catch(std::bad_alloc&)
3145 {
3146 return error(GL_OUT_OF_MEMORY);
3147 }
3148}
3149
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003150void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003151{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003152 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003153 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003154
3155 try
3156 {
3157 if (bufsize < 0)
3158 {
3159 return error(GL_INVALID_VALUE);
3160 }
3161
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003162 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003163
3164 if (context)
3165 {
3166 gl::Shader *shaderObject = context->getShader(shader);
3167
3168 if (!shaderObject)
3169 {
3170 return error(GL_INVALID_VALUE);
3171 }
3172
3173 shaderObject->getInfoLog(bufsize, length, infolog);
3174 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003175 }
3176 catch(std::bad_alloc&)
3177 {
3178 return error(GL_OUT_OF_MEMORY);
3179 }
3180}
3181
3182void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3183{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003184 EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003185 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003186
3187 try
3188 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003189 switch (shadertype)
3190 {
3191 case GL_VERTEX_SHADER:
3192 case GL_FRAGMENT_SHADER:
3193 break;
3194 default:
3195 return error(GL_INVALID_ENUM);
3196 }
3197
3198 switch (precisiontype)
3199 {
3200 case GL_LOW_FLOAT:
3201 case GL_MEDIUM_FLOAT:
3202 case GL_HIGH_FLOAT:
3203 // Assume IEEE 754 precision
3204 range[0] = 127;
3205 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003206 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003207 break;
3208 case GL_LOW_INT:
3209 case GL_MEDIUM_INT:
3210 case GL_HIGH_INT:
3211 // Some (most) hardware only supports single-precision floating-point numbers,
3212 // which can accurately represent integers up to +/-16777216
3213 range[0] = 24;
3214 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003215 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003216 break;
3217 default:
3218 return error(GL_INVALID_ENUM);
3219 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003220 }
3221 catch(std::bad_alloc&)
3222 {
3223 return error(GL_OUT_OF_MEMORY);
3224 }
3225}
3226
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003227void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003228{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003229 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003230 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003231
3232 try
3233 {
3234 if (bufsize < 0)
3235 {
3236 return error(GL_INVALID_VALUE);
3237 }
3238
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003239 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003240
3241 if (context)
3242 {
3243 gl::Shader *shaderObject = context->getShader(shader);
3244
3245 if (!shaderObject)
3246 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003247 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003248 }
3249
3250 shaderObject->getSource(bufsize, length, source);
3251 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003252 }
3253 catch(std::bad_alloc&)
3254 {
3255 return error(GL_OUT_OF_MEMORY);
3256 }
3257}
3258
zmo@google.coma574f782011-10-03 21:45:23 +00003259void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3260{
3261 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3262 shader, bufsize, length, source);
3263
3264 try
3265 {
3266 if (bufsize < 0)
3267 {
3268 return error(GL_INVALID_VALUE);
3269 }
3270
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003271 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003272
3273 if (context)
3274 {
3275 gl::Shader *shaderObject = context->getShader(shader);
3276
3277 if (!shaderObject)
3278 {
3279 return error(GL_INVALID_OPERATION);
3280 }
3281
3282 shaderObject->getTranslatedSource(bufsize, length, source);
3283 }
3284 }
3285 catch(std::bad_alloc&)
3286 {
3287 return error(GL_OUT_OF_MEMORY);
3288 }
3289}
3290
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003291const GLubyte* __stdcall glGetString(GLenum name)
3292{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003293 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003294
3295 try
3296 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003297 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003298
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003299 switch (name)
3300 {
3301 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003302 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003303 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003304 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003305 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003306 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003307 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003308 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003309 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003310 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003311 default:
3312 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3313 }
3314 }
3315 catch(std::bad_alloc&)
3316 {
3317 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3318 }
3319
3320 return NULL;
3321}
3322
3323void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3324{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003325 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003326
3327 try
3328 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003329 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003330
3331 if (context)
3332 {
3333 gl::Texture *texture;
3334
3335 switch (target)
3336 {
3337 case GL_TEXTURE_2D:
3338 texture = context->getTexture2D();
3339 break;
3340 case GL_TEXTURE_CUBE_MAP:
3341 texture = context->getTextureCubeMap();
3342 break;
3343 default:
3344 return error(GL_INVALID_ENUM);
3345 }
3346
3347 switch (pname)
3348 {
3349 case GL_TEXTURE_MAG_FILTER:
3350 *params = (GLfloat)texture->getMagFilter();
3351 break;
3352 case GL_TEXTURE_MIN_FILTER:
3353 *params = (GLfloat)texture->getMinFilter();
3354 break;
3355 case GL_TEXTURE_WRAP_S:
3356 *params = (GLfloat)texture->getWrapS();
3357 break;
3358 case GL_TEXTURE_WRAP_T:
3359 *params = (GLfloat)texture->getWrapT();
3360 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003361 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3362 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3363 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003364 case GL_TEXTURE_USAGE_ANGLE:
3365 *params = (GLfloat)texture->getUsage();
3366 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003367 default:
3368 return error(GL_INVALID_ENUM);
3369 }
3370 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003371 }
3372 catch(std::bad_alloc&)
3373 {
3374 return error(GL_OUT_OF_MEMORY);
3375 }
3376}
3377
3378void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3379{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003380 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003381
3382 try
3383 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003384 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003385
3386 if (context)
3387 {
3388 gl::Texture *texture;
3389
3390 switch (target)
3391 {
3392 case GL_TEXTURE_2D:
3393 texture = context->getTexture2D();
3394 break;
3395 case GL_TEXTURE_CUBE_MAP:
3396 texture = context->getTextureCubeMap();
3397 break;
3398 default:
3399 return error(GL_INVALID_ENUM);
3400 }
3401
3402 switch (pname)
3403 {
3404 case GL_TEXTURE_MAG_FILTER:
3405 *params = texture->getMagFilter();
3406 break;
3407 case GL_TEXTURE_MIN_FILTER:
3408 *params = texture->getMinFilter();
3409 break;
3410 case GL_TEXTURE_WRAP_S:
3411 *params = texture->getWrapS();
3412 break;
3413 case GL_TEXTURE_WRAP_T:
3414 *params = texture->getWrapT();
3415 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003416 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3417 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3418 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003419 case GL_TEXTURE_USAGE_ANGLE:
3420 *params = texture->getUsage();
3421 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003422 default:
3423 return error(GL_INVALID_ENUM);
3424 }
3425 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003426 }
3427 catch(std::bad_alloc&)
3428 {
3429 return error(GL_OUT_OF_MEMORY);
3430 }
3431}
3432
3433void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3434{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003435 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003436
3437 try
3438 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003439 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003440
3441 if (context)
3442 {
3443 if (program == 0)
3444 {
3445 return error(GL_INVALID_VALUE);
3446 }
3447
3448 gl::Program *programObject = context->getProgram(program);
3449
3450 if (!programObject || !programObject->isLinked())
3451 {
3452 return error(GL_INVALID_OPERATION);
3453 }
3454
3455 if (!programObject->getUniformfv(location, params))
3456 {
3457 return error(GL_INVALID_OPERATION);
3458 }
3459 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003460 }
3461 catch(std::bad_alloc&)
3462 {
3463 return error(GL_OUT_OF_MEMORY);
3464 }
3465}
3466
3467void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3468{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003469 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003470
3471 try
3472 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003473 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003474
3475 if (context)
3476 {
3477 if (program == 0)
3478 {
3479 return error(GL_INVALID_VALUE);
3480 }
3481
3482 gl::Program *programObject = context->getProgram(program);
3483
3484 if (!programObject || !programObject->isLinked())
3485 {
3486 return error(GL_INVALID_OPERATION);
3487 }
3488
3489 if (!programObject)
3490 {
3491 return error(GL_INVALID_OPERATION);
3492 }
3493
3494 if (!programObject->getUniformiv(location, params))
3495 {
3496 return error(GL_INVALID_OPERATION);
3497 }
3498 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003499 }
3500 catch(std::bad_alloc&)
3501 {
3502 return error(GL_OUT_OF_MEMORY);
3503 }
3504}
3505
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003506int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003507{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003508 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003509
3510 try
3511 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003512 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003513
3514 if (strstr(name, "gl_") == name)
3515 {
3516 return -1;
3517 }
3518
3519 if (context)
3520 {
3521 gl::Program *programObject = context->getProgram(program);
3522
3523 if (!programObject)
3524 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003525 if (context->getShader(program))
3526 {
3527 return error(GL_INVALID_OPERATION, -1);
3528 }
3529 else
3530 {
3531 return error(GL_INVALID_VALUE, -1);
3532 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003533 }
3534
3535 if (!programObject->isLinked())
3536 {
3537 return error(GL_INVALID_OPERATION, -1);
3538 }
3539
daniel@transgaming.com024f1a92011-09-20 16:06:25 +00003540 return programObject->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003541 }
3542 }
3543 catch(std::bad_alloc&)
3544 {
3545 return error(GL_OUT_OF_MEMORY, -1);
3546 }
3547
3548 return -1;
3549}
3550
3551void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3552{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003553 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003554
3555 try
3556 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003557 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003558
daniel@transgaming.come0078962010-04-15 20:45:08 +00003559 if (context)
3560 {
3561 if (index >= gl::MAX_VERTEX_ATTRIBS)
3562 {
3563 return error(GL_INVALID_VALUE);
3564 }
3565
daniel@transgaming.com83921382011-01-08 05:46:00 +00003566 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003567
daniel@transgaming.come0078962010-04-15 20:45:08 +00003568 switch (pname)
3569 {
3570 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003571 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003572 break;
3573 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003574 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003575 break;
3576 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003577 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003578 break;
3579 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003580 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003581 break;
3582 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003583 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003584 break;
3585 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003586 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003587 break;
3588 case GL_CURRENT_VERTEX_ATTRIB:
3589 for (int i = 0; i < 4; ++i)
3590 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003591 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003592 }
3593 break;
3594 default: return error(GL_INVALID_ENUM);
3595 }
3596 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003597 }
3598 catch(std::bad_alloc&)
3599 {
3600 return error(GL_OUT_OF_MEMORY);
3601 }
3602}
3603
3604void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3605{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003606 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003607
3608 try
3609 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003610 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003611
daniel@transgaming.come0078962010-04-15 20:45:08 +00003612 if (context)
3613 {
3614 if (index >= gl::MAX_VERTEX_ATTRIBS)
3615 {
3616 return error(GL_INVALID_VALUE);
3617 }
3618
daniel@transgaming.com83921382011-01-08 05:46:00 +00003619 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003620
daniel@transgaming.come0078962010-04-15 20:45:08 +00003621 switch (pname)
3622 {
3623 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003624 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003625 break;
3626 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003627 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003628 break;
3629 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003630 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003631 break;
3632 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003633 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003634 break;
3635 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003636 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003637 break;
3638 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003639 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003640 break;
3641 case GL_CURRENT_VERTEX_ATTRIB:
3642 for (int i = 0; i < 4; ++i)
3643 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003644 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003645 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3646 }
3647 break;
3648 default: return error(GL_INVALID_ENUM);
3649 }
3650 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003651 }
3652 catch(std::bad_alloc&)
3653 {
3654 return error(GL_OUT_OF_MEMORY);
3655 }
3656}
3657
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003658void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003659{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003660 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003661
3662 try
3663 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003664 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003665
daniel@transgaming.come0078962010-04-15 20:45:08 +00003666 if (context)
3667 {
3668 if (index >= gl::MAX_VERTEX_ATTRIBS)
3669 {
3670 return error(GL_INVALID_VALUE);
3671 }
3672
3673 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3674 {
3675 return error(GL_INVALID_ENUM);
3676 }
3677
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003678 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003679 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003680 }
3681 catch(std::bad_alloc&)
3682 {
3683 return error(GL_OUT_OF_MEMORY);
3684 }
3685}
3686
3687void __stdcall glHint(GLenum target, GLenum mode)
3688{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003689 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003690
3691 try
3692 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003693 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003694 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003695 case GL_FASTEST:
3696 case GL_NICEST:
3697 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003698 break;
3699 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003700 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003701 }
3702
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003703 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003704 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003705 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003706 case GL_GENERATE_MIPMAP_HINT:
3707 if (context) context->setGenerateMipmapHint(mode);
3708 break;
3709 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3710 if (context) context->setFragmentShaderDerivativeHint(mode);
3711 break;
3712 default:
3713 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003714 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003715 }
3716 catch(std::bad_alloc&)
3717 {
3718 return error(GL_OUT_OF_MEMORY);
3719 }
3720}
3721
3722GLboolean __stdcall glIsBuffer(GLuint buffer)
3723{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003724 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003725
3726 try
3727 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003728 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003729
3730 if (context && buffer)
3731 {
3732 gl::Buffer *bufferObject = context->getBuffer(buffer);
3733
3734 if (bufferObject)
3735 {
3736 return GL_TRUE;
3737 }
3738 }
3739 }
3740 catch(std::bad_alloc&)
3741 {
3742 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3743 }
3744
3745 return GL_FALSE;
3746}
3747
3748GLboolean __stdcall glIsEnabled(GLenum cap)
3749{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003750 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003751
3752 try
3753 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003754 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003755
3756 if (context)
3757 {
3758 switch (cap)
3759 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003760 case GL_CULL_FACE: return context->isCullFaceEnabled();
3761 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3762 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3763 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3764 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3765 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3766 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3767 case GL_BLEND: return context->isBlendEnabled();
3768 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003769 default:
3770 return error(GL_INVALID_ENUM, false);
3771 }
3772 }
3773 }
3774 catch(std::bad_alloc&)
3775 {
3776 return error(GL_OUT_OF_MEMORY, false);
3777 }
3778
3779 return false;
3780}
3781
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003782GLboolean __stdcall glIsFenceNV(GLuint fence)
3783{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003784 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003785
3786 try
3787 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003788 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003789
3790 if (context)
3791 {
3792 gl::Fence *fenceObject = context->getFence(fence);
3793
3794 if (fenceObject == NULL)
3795 {
3796 return GL_FALSE;
3797 }
3798
3799 return fenceObject->isFence();
3800 }
3801 }
3802 catch(std::bad_alloc&)
3803 {
3804 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3805 }
3806
3807 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003808}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003809
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003810GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3811{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003812 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003813
3814 try
3815 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003816 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003817
3818 if (context && framebuffer)
3819 {
3820 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3821
3822 if (framebufferObject)
3823 {
3824 return GL_TRUE;
3825 }
3826 }
3827 }
3828 catch(std::bad_alloc&)
3829 {
3830 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3831 }
3832
3833 return GL_FALSE;
3834}
3835
3836GLboolean __stdcall glIsProgram(GLuint program)
3837{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003838 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003839
3840 try
3841 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003842 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003843
3844 if (context && program)
3845 {
3846 gl::Program *programObject = context->getProgram(program);
3847
3848 if (programObject)
3849 {
3850 return GL_TRUE;
3851 }
3852 }
3853 }
3854 catch(std::bad_alloc&)
3855 {
3856 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3857 }
3858
3859 return GL_FALSE;
3860}
3861
3862GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3863{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003864 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003865
3866 try
3867 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003868 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003869
3870 if (context && renderbuffer)
3871 {
3872 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3873
3874 if (renderbufferObject)
3875 {
3876 return GL_TRUE;
3877 }
3878 }
3879 }
3880 catch(std::bad_alloc&)
3881 {
3882 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3883 }
3884
3885 return GL_FALSE;
3886}
3887
3888GLboolean __stdcall glIsShader(GLuint shader)
3889{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003890 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003891
3892 try
3893 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003894 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003895
3896 if (context && shader)
3897 {
3898 gl::Shader *shaderObject = context->getShader(shader);
3899
3900 if (shaderObject)
3901 {
3902 return GL_TRUE;
3903 }
3904 }
3905 }
3906 catch(std::bad_alloc&)
3907 {
3908 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3909 }
3910
3911 return GL_FALSE;
3912}
3913
3914GLboolean __stdcall glIsTexture(GLuint texture)
3915{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003916 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003917
3918 try
3919 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003920 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003921
3922 if (context && texture)
3923 {
3924 gl::Texture *textureObject = context->getTexture(texture);
3925
3926 if (textureObject)
3927 {
3928 return GL_TRUE;
3929 }
3930 }
3931 }
3932 catch(std::bad_alloc&)
3933 {
3934 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3935 }
3936
3937 return GL_FALSE;
3938}
3939
3940void __stdcall glLineWidth(GLfloat width)
3941{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003942 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003943
3944 try
3945 {
3946 if (width <= 0.0f)
3947 {
3948 return error(GL_INVALID_VALUE);
3949 }
3950
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003951 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003952
3953 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003954 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003955 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003956 }
3957 }
3958 catch(std::bad_alloc&)
3959 {
3960 return error(GL_OUT_OF_MEMORY);
3961 }
3962}
3963
3964void __stdcall glLinkProgram(GLuint program)
3965{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003966 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003967
3968 try
3969 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003970 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003971
3972 if (context)
3973 {
3974 gl::Program *programObject = context->getProgram(program);
3975
3976 if (!programObject)
3977 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003978 if (context->getShader(program))
3979 {
3980 return error(GL_INVALID_OPERATION);
3981 }
3982 else
3983 {
3984 return error(GL_INVALID_VALUE);
3985 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003986 }
3987
3988 programObject->link();
3989 }
3990 }
3991 catch(std::bad_alloc&)
3992 {
3993 return error(GL_OUT_OF_MEMORY);
3994 }
3995}
3996
3997void __stdcall glPixelStorei(GLenum pname, GLint param)
3998{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003999 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004000
4001 try
4002 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004003 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004004
4005 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004006 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004007 switch (pname)
4008 {
4009 case GL_UNPACK_ALIGNMENT:
4010 if (param != 1 && param != 2 && param != 4 && param != 8)
4011 {
4012 return error(GL_INVALID_VALUE);
4013 }
4014
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004015 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004016 break;
4017
4018 case GL_PACK_ALIGNMENT:
4019 if (param != 1 && param != 2 && param != 4 && param != 8)
4020 {
4021 return error(GL_INVALID_VALUE);
4022 }
4023
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004024 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004025 break;
4026
4027 default:
4028 return error(GL_INVALID_ENUM);
4029 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004030 }
4031 }
4032 catch(std::bad_alloc&)
4033 {
4034 return error(GL_OUT_OF_MEMORY);
4035 }
4036}
4037
4038void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4039{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004040 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004041
4042 try
4043 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004044 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004045
4046 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004047 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004048 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004049 }
4050 }
4051 catch(std::bad_alloc&)
4052 {
4053 return error(GL_OUT_OF_MEMORY);
4054 }
4055}
4056
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004057void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004058{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004059 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004060 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004061 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004062
4063 try
4064 {
4065 if (width < 0 || height < 0)
4066 {
4067 return error(GL_INVALID_VALUE);
4068 }
4069
4070 switch (format)
4071 {
4072 case GL_RGBA:
4073 switch (type)
4074 {
4075 case GL_UNSIGNED_BYTE:
4076 break;
4077 default:
4078 return error(GL_INVALID_OPERATION);
4079 }
4080 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004081 case GL_BGRA_EXT:
4082 switch (type)
4083 {
4084 case GL_UNSIGNED_BYTE:
4085 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
4086 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
4087 break;
4088 default:
4089 return error(GL_INVALID_OPERATION);
4090 }
4091 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004092 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
4093 switch (type)
4094 {
4095 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
4096 break;
4097 default:
4098 return error(GL_INVALID_OPERATION);
4099 }
4100 break;
4101 default:
4102 return error(GL_INVALID_OPERATION);
4103 }
4104
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004105 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004106
4107 if (context)
4108 {
4109 context->readPixels(x, y, width, height, format, type, pixels);
4110 }
4111 }
4112 catch(std::bad_alloc&)
4113 {
4114 return error(GL_OUT_OF_MEMORY);
4115 }
4116}
4117
4118void __stdcall glReleaseShaderCompiler(void)
4119{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004120 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004121
4122 try
4123 {
4124 gl::Shader::releaseCompiler();
4125 }
4126 catch(std::bad_alloc&)
4127 {
4128 return error(GL_OUT_OF_MEMORY);
4129 }
4130}
4131
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004132void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004133{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004134 EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004135 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004136
4137 try
4138 {
4139 switch (target)
4140 {
4141 case GL_RENDERBUFFER:
4142 break;
4143 default:
4144 return error(GL_INVALID_ENUM);
4145 }
4146
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004147 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004148 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004149 return error(GL_INVALID_ENUM);
4150 }
4151
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004152 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004153 {
4154 return error(GL_INVALID_VALUE);
4155 }
4156
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004157 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004158
4159 if (context)
4160 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004161 if (width > context->getMaximumRenderbufferDimension() ||
4162 height > context->getMaximumRenderbufferDimension() ||
4163 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004164 {
4165 return error(GL_INVALID_VALUE);
4166 }
4167
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004168 GLuint handle = context->getRenderbufferHandle();
4169 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004170 {
4171 return error(GL_INVALID_OPERATION);
4172 }
4173
4174 switch (internalformat)
4175 {
4176 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004177 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004178 break;
4179 case GL_RGBA4:
4180 case GL_RGB5_A1:
4181 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004182 case GL_RGB8_OES:
4183 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004184 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004185 break;
4186 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004187 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004188 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004189 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004190 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004191 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004192 default:
4193 return error(GL_INVALID_ENUM);
4194 }
4195 }
4196 }
4197 catch(std::bad_alloc&)
4198 {
4199 return error(GL_OUT_OF_MEMORY);
4200 }
4201}
4202
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004203void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4204{
4205 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4206}
4207
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004208void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4209{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004210 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004211
4212 try
4213 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004214 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004215
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004216 if (context)
4217 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004218 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004219 }
4220 }
4221 catch(std::bad_alloc&)
4222 {
4223 return error(GL_OUT_OF_MEMORY);
4224 }
4225}
4226
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004227void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4228{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004229 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004230
4231 try
4232 {
4233 if (condition != GL_ALL_COMPLETED_NV)
4234 {
4235 return error(GL_INVALID_ENUM);
4236 }
4237
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004238 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004239
4240 if (context)
4241 {
4242 gl::Fence *fenceObject = context->getFence(fence);
4243
4244 if (fenceObject == NULL)
4245 {
4246 return error(GL_INVALID_OPERATION);
4247 }
4248
4249 fenceObject->setFence(condition);
4250 }
4251 }
4252 catch(std::bad_alloc&)
4253 {
4254 return error(GL_OUT_OF_MEMORY);
4255 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004256}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004257
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004258void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4259{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004260 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004261
4262 try
4263 {
4264 if (width < 0 || height < 0)
4265 {
4266 return error(GL_INVALID_VALUE);
4267 }
4268
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004269 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004270
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004271 if (context)
4272 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004273 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004274 }
4275 }
4276 catch(std::bad_alloc&)
4277 {
4278 return error(GL_OUT_OF_MEMORY);
4279 }
4280}
4281
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004282void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004283{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004284 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004285 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004286 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004287
4288 try
4289 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004290 // No binary shader formats are supported.
4291 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004292 }
4293 catch(std::bad_alloc&)
4294 {
4295 return error(GL_OUT_OF_MEMORY);
4296 }
4297}
4298
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004299void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004300{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004301 EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004302 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004303
4304 try
4305 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004306 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004307 {
4308 return error(GL_INVALID_VALUE);
4309 }
4310
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004311 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004312
4313 if (context)
4314 {
4315 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004316
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004317 if (!shaderObject)
4318 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004319 if (context->getProgram(shader))
4320 {
4321 return error(GL_INVALID_OPERATION);
4322 }
4323 else
4324 {
4325 return error(GL_INVALID_VALUE);
4326 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004327 }
4328
4329 shaderObject->setSource(count, string, length);
4330 }
4331 }
4332 catch(std::bad_alloc&)
4333 {
4334 return error(GL_OUT_OF_MEMORY);
4335 }
4336}
4337
4338void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4339{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004340 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004341}
4342
4343void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4344{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004345 EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004346
4347 try
4348 {
4349 switch (face)
4350 {
4351 case GL_FRONT:
4352 case GL_BACK:
4353 case GL_FRONT_AND_BACK:
4354 break;
4355 default:
4356 return error(GL_INVALID_ENUM);
4357 }
4358
4359 switch (func)
4360 {
4361 case GL_NEVER:
4362 case GL_ALWAYS:
4363 case GL_LESS:
4364 case GL_LEQUAL:
4365 case GL_EQUAL:
4366 case GL_GEQUAL:
4367 case GL_GREATER:
4368 case GL_NOTEQUAL:
4369 break;
4370 default:
4371 return error(GL_INVALID_ENUM);
4372 }
4373
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004374 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004375
4376 if (context)
4377 {
4378 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4379 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004380 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004381 }
4382
4383 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4384 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004385 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004386 }
4387 }
4388 }
4389 catch(std::bad_alloc&)
4390 {
4391 return error(GL_OUT_OF_MEMORY);
4392 }
4393}
4394
4395void __stdcall glStencilMask(GLuint mask)
4396{
4397 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4398}
4399
4400void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4401{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004402 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004403
4404 try
4405 {
4406 switch (face)
4407 {
4408 case GL_FRONT:
4409 case GL_BACK:
4410 case GL_FRONT_AND_BACK:
4411 break;
4412 default:
4413 return error(GL_INVALID_ENUM);
4414 }
4415
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004416 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004417
4418 if (context)
4419 {
4420 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4421 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004422 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004423 }
4424
4425 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4426 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004427 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004428 }
4429 }
4430 }
4431 catch(std::bad_alloc&)
4432 {
4433 return error(GL_OUT_OF_MEMORY);
4434 }
4435}
4436
4437void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4438{
4439 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4440}
4441
4442void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4443{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004444 EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004445 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004446
4447 try
4448 {
4449 switch (face)
4450 {
4451 case GL_FRONT:
4452 case GL_BACK:
4453 case GL_FRONT_AND_BACK:
4454 break;
4455 default:
4456 return error(GL_INVALID_ENUM);
4457 }
4458
4459 switch (fail)
4460 {
4461 case GL_ZERO:
4462 case GL_KEEP:
4463 case GL_REPLACE:
4464 case GL_INCR:
4465 case GL_DECR:
4466 case GL_INVERT:
4467 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004468 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004469 break;
4470 default:
4471 return error(GL_INVALID_ENUM);
4472 }
4473
4474 switch (zfail)
4475 {
4476 case GL_ZERO:
4477 case GL_KEEP:
4478 case GL_REPLACE:
4479 case GL_INCR:
4480 case GL_DECR:
4481 case GL_INVERT:
4482 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004483 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004484 break;
4485 default:
4486 return error(GL_INVALID_ENUM);
4487 }
4488
4489 switch (zpass)
4490 {
4491 case GL_ZERO:
4492 case GL_KEEP:
4493 case GL_REPLACE:
4494 case GL_INCR:
4495 case GL_DECR:
4496 case GL_INVERT:
4497 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004498 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004499 break;
4500 default:
4501 return error(GL_INVALID_ENUM);
4502 }
4503
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004504 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004505
4506 if (context)
4507 {
4508 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4509 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004510 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004511 }
4512
4513 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4514 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004515 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004516 }
4517 }
4518 }
4519 catch(std::bad_alloc&)
4520 {
4521 return error(GL_OUT_OF_MEMORY);
4522 }
4523}
4524
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004525GLboolean __stdcall glTestFenceNV(GLuint fence)
4526{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004527 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004528
4529 try
4530 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004531 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004532
4533 if (context)
4534 {
4535 gl::Fence *fenceObject = context->getFence(fence);
4536
4537 if (fenceObject == NULL)
4538 {
4539 return error(GL_INVALID_OPERATION, GL_TRUE);
4540 }
4541
4542 return fenceObject->testFence();
4543 }
4544 }
4545 catch(std::bad_alloc&)
4546 {
4547 error(GL_OUT_OF_MEMORY);
4548 }
4549
4550 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004551}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004552
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004553void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4554 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004555{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004556 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004557 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004558 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004559
4560 try
4561 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00004562 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004563 {
4564 return error(GL_INVALID_VALUE);
4565 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004566
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004567 if (internalformat != format)
4568 {
4569 return error(GL_INVALID_OPERATION);
4570 }
4571
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004572 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004573 {
4574 case GL_ALPHA:
4575 case GL_LUMINANCE:
4576 case GL_LUMINANCE_ALPHA:
4577 switch (type)
4578 {
4579 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004580 case GL_FLOAT:
4581 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004582 break;
4583 default:
4584 return error(GL_INVALID_ENUM);
4585 }
4586 break;
4587 case GL_RGB:
4588 switch (type)
4589 {
4590 case GL_UNSIGNED_BYTE:
4591 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004592 case GL_FLOAT:
4593 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004594 break;
4595 default:
4596 return error(GL_INVALID_ENUM);
4597 }
4598 break;
4599 case GL_RGBA:
4600 switch (type)
4601 {
4602 case GL_UNSIGNED_BYTE:
4603 case GL_UNSIGNED_SHORT_4_4_4_4:
4604 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004605 case GL_FLOAT:
4606 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004607 break;
4608 default:
4609 return error(GL_INVALID_ENUM);
4610 }
4611 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004612 case GL_BGRA_EXT:
4613 switch (type)
4614 {
4615 case GL_UNSIGNED_BYTE:
4616 break;
4617 default:
4618 return error(GL_INVALID_ENUM);
4619 }
4620 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004621 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4622 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00004623 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4624 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00004625 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004626 default:
4627 return error(GL_INVALID_VALUE);
4628 }
4629
4630 if (border != 0)
4631 {
4632 return error(GL_INVALID_VALUE);
4633 }
4634
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004635 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004636
4637 if (context)
4638 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004639 switch (target)
4640 {
4641 case GL_TEXTURE_2D:
4642 if (width > (context->getMaximumTextureDimension() >> level) ||
4643 height > (context->getMaximumTextureDimension() >> level))
4644 {
4645 return error(GL_INVALID_VALUE);
4646 }
4647 break;
4648 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4649 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4650 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4651 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4652 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4653 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4654 if (width != height)
4655 {
4656 return error(GL_INVALID_VALUE);
4657 }
4658
4659 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4660 height > (context->getMaximumCubeTextureDimension() >> level))
4661 {
4662 return error(GL_INVALID_VALUE);
4663 }
4664 break;
4665 default:
4666 return error(GL_INVALID_ENUM);
4667 }
4668
gman@chromium.org50c526d2011-08-10 05:19:44 +00004669 switch (format) {
4670 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4671 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4672 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00004673 {
4674 return error(GL_INVALID_OPERATION);
4675 }
4676 else
4677 {
4678 return error(GL_INVALID_ENUM);
4679 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00004680 break;
4681 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4682 if (context->supportsDXT3Textures())
4683 {
4684 return error(GL_INVALID_OPERATION);
4685 }
4686 else
4687 {
4688 return error(GL_INVALID_ENUM);
4689 }
4690 break;
4691 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
4692 if (context->supportsDXT5Textures())
4693 {
4694 return error(GL_INVALID_OPERATION);
4695 }
4696 else
4697 {
4698 return error(GL_INVALID_ENUM);
4699 }
4700 break;
4701 default:
4702 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004703 }
4704
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004705 if (type == GL_FLOAT)
4706 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004707 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004708 {
4709 return error(GL_INVALID_ENUM);
4710 }
4711 }
4712 else if (type == GL_HALF_FLOAT_OES)
4713 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004714 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004715 {
4716 return error(GL_INVALID_ENUM);
4717 }
4718 }
4719
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004720 if (target == GL_TEXTURE_2D)
4721 {
4722 gl::Texture2D *texture = context->getTexture2D();
4723
4724 if (!texture)
4725 {
4726 return error(GL_INVALID_OPERATION);
4727 }
4728
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004729 if (texture->isImmutable())
4730 {
4731 return error(GL_INVALID_OPERATION);
4732 }
4733
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004734 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004735 }
4736 else
4737 {
4738 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4739
4740 if (!texture)
4741 {
4742 return error(GL_INVALID_OPERATION);
4743 }
4744
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004745 if (texture->isImmutable())
4746 {
4747 return error(GL_INVALID_OPERATION);
4748 }
4749
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004750 switch (target)
4751 {
4752 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004753 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004754 break;
4755 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004756 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004757 break;
4758 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004759 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004760 break;
4761 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004762 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004763 break;
4764 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004765 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004766 break;
4767 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004768 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004769 break;
4770 default: UNREACHABLE();
4771 }
4772 }
4773 }
4774 }
4775 catch(std::bad_alloc&)
4776 {
4777 return error(GL_OUT_OF_MEMORY);
4778 }
4779}
4780
4781void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4782{
4783 glTexParameteri(target, pname, (GLint)param);
4784}
4785
4786void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4787{
4788 glTexParameteri(target, pname, (GLint)*params);
4789}
4790
4791void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4792{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004793 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004794
4795 try
4796 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004797 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004798
4799 if (context)
4800 {
4801 gl::Texture *texture;
4802
4803 switch (target)
4804 {
4805 case GL_TEXTURE_2D:
4806 texture = context->getTexture2D();
4807 break;
4808 case GL_TEXTURE_CUBE_MAP:
4809 texture = context->getTextureCubeMap();
4810 break;
4811 default:
4812 return error(GL_INVALID_ENUM);
4813 }
4814
4815 switch (pname)
4816 {
4817 case GL_TEXTURE_WRAP_S:
4818 if (!texture->setWrapS((GLenum)param))
4819 {
4820 return error(GL_INVALID_ENUM);
4821 }
4822 break;
4823 case GL_TEXTURE_WRAP_T:
4824 if (!texture->setWrapT((GLenum)param))
4825 {
4826 return error(GL_INVALID_ENUM);
4827 }
4828 break;
4829 case GL_TEXTURE_MIN_FILTER:
4830 if (!texture->setMinFilter((GLenum)param))
4831 {
4832 return error(GL_INVALID_ENUM);
4833 }
4834 break;
4835 case GL_TEXTURE_MAG_FILTER:
4836 if (!texture->setMagFilter((GLenum)param))
4837 {
4838 return error(GL_INVALID_ENUM);
4839 }
4840 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00004841 case GL_TEXTURE_USAGE_ANGLE:
4842 if (!texture->setUsage((GLenum)param))
4843 {
4844 return error(GL_INVALID_ENUM);
4845 }
4846 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004847 default:
4848 return error(GL_INVALID_ENUM);
4849 }
4850 }
4851 }
4852 catch(std::bad_alloc&)
4853 {
4854 return error(GL_OUT_OF_MEMORY);
4855 }
4856}
4857
4858void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4859{
4860 glTexParameteri(target, pname, *params);
4861}
4862
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004863void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
4864{
4865 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4866 target, levels, internalformat, width, height);
4867
4868 try
4869 {
4870 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
4871 {
4872 return error(GL_INVALID_ENUM);
4873 }
4874
4875 if (width < 1 || height < 1 || levels < 1)
4876 {
4877 return error(GL_INVALID_VALUE);
4878 }
4879
4880 if (target == GL_TEXTURE_CUBE_MAP && width != height)
4881 {
4882 return error(GL_INVALID_VALUE);
4883 }
4884
4885 if (levels > gl::log2(std::max(width, height)) + 1)
4886 {
4887 return error(GL_INVALID_OPERATION);
4888 }
4889
4890 GLenum format = gl::ExtractFormat(internalformat);
4891 GLenum type = gl::ExtractType(internalformat);
4892
4893 if (format == GL_NONE || type == GL_NONE)
4894 {
4895 return error(GL_INVALID_ENUM);
4896 }
4897
4898 gl::Context *context = gl::getNonLostContext();
4899
4900 if (context)
4901 {
4902 if (levels != 1 && !context->supportsNonPower2Texture())
4903 {
4904 if (!gl::isPow2(width) || !gl::isPow2(height))
4905 {
4906 return error(GL_INVALID_OPERATION);
4907 }
4908 }
4909
daniel@transgaming.come1077362011-11-11 04:16:50 +00004910 switch (internalformat)
4911 {
4912 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4913 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4914 if (!context->supportsDXT1Textures())
4915 {
4916 return error(GL_INVALID_ENUM);
4917 }
4918 break;
4919 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4920 if (!context->supportsDXT3Textures())
4921 {
4922 return error(GL_INVALID_ENUM);
4923 }
4924 break;
4925 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
4926 if (!context->supportsDXT5Textures())
4927 {
4928 return error(GL_INVALID_ENUM);
4929 }
4930 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00004931 case GL_RGBA32F_EXT:
4932 case GL_RGB32F_EXT:
4933 case GL_ALPHA32F_EXT:
4934 case GL_LUMINANCE32F_EXT:
4935 case GL_LUMINANCE_ALPHA32F_EXT:
4936 if (!context->supportsFloat32Textures())
4937 {
4938 return error(GL_INVALID_ENUM);
4939 }
4940 break;
4941 case GL_RGBA16F_EXT:
4942 case GL_RGB16F_EXT:
4943 case GL_ALPHA16F_EXT:
4944 case GL_LUMINANCE16F_EXT:
4945 case GL_LUMINANCE_ALPHA16F_EXT:
4946 if (!context->supportsFloat16Textures())
4947 {
4948 return error(GL_INVALID_ENUM);
4949 }
4950 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00004951 }
4952
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004953 if (target == GL_TEXTURE_2D)
4954 {
4955 gl::Texture2D *texture = context->getTexture2D();
4956
4957 if (!texture || texture->id() == 0)
4958 {
4959 return error(GL_INVALID_OPERATION);
4960 }
4961
4962 if (texture->isImmutable())
4963 {
4964 return error(GL_INVALID_OPERATION);
4965 }
4966
4967 texture->storage(levels, internalformat, width, height);
4968 }
4969 else if (target == GL_TEXTURE_CUBE_MAP)
4970 {
4971 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4972
4973 if (!texture || texture->id() == 0)
4974 {
4975 return error(GL_INVALID_OPERATION);
4976 }
4977
4978 if (texture->isImmutable())
4979 {
4980 return error(GL_INVALID_OPERATION);
4981 }
4982
4983 texture->storage(levels, internalformat, width);
4984 }
4985 else UNREACHABLE();
4986 }
4987 }
4988 catch(std::bad_alloc&)
4989 {
4990 return error(GL_OUT_OF_MEMORY);
4991 }
4992}
4993
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004994void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4995 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004996{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004997 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004998 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004999 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005000 target, level, xoffset, yoffset, width, height, format, type, pixels);
5001
5002 try
5003 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005004 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005005 {
5006 return error(GL_INVALID_ENUM);
5007 }
5008
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005009 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005010 {
5011 return error(GL_INVALID_VALUE);
5012 }
5013
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005014 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5015 {
5016 return error(GL_INVALID_VALUE);
5017 }
5018
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005019 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005020 {
5021 return error(GL_INVALID_ENUM);
5022 }
5023
5024 if (width == 0 || height == 0 || pixels == NULL)
5025 {
5026 return;
5027 }
5028
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005029 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005030
5031 if (context)
5032 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005033 if (level > context->getMaximumTextureLevel())
5034 {
5035 return error(GL_INVALID_VALUE);
5036 }
5037
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005038 if (format == GL_FLOAT)
5039 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005040 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005041 {
5042 return error(GL_INVALID_ENUM);
5043 }
5044 }
5045 else if (format == GL_HALF_FLOAT_OES)
5046 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005047 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005048 {
5049 return error(GL_INVALID_ENUM);
5050 }
5051 }
5052
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005053 if (target == GL_TEXTURE_2D)
5054 {
5055 gl::Texture2D *texture = context->getTexture2D();
5056
5057 if (!texture)
5058 {
5059 return error(GL_INVALID_OPERATION);
5060 }
5061
daniel@transgaming.com01868132010-08-24 19:21:17 +00005062 if (texture->isCompressed())
5063 {
5064 return error(GL_INVALID_OPERATION);
5065 }
5066
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00005067 if (format != texture->getInternalFormat())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005068 {
5069 return error(GL_INVALID_OPERATION);
5070 }
5071
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005072 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005073 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005074 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005075 {
5076 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5077
5078 if (!texture)
5079 {
5080 return error(GL_INVALID_OPERATION);
5081 }
5082
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005083 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005084 }
5085 else
5086 {
5087 UNREACHABLE();
5088 }
5089 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005090 }
5091 catch(std::bad_alloc&)
5092 {
5093 return error(GL_OUT_OF_MEMORY);
5094 }
5095}
5096
5097void __stdcall glUniform1f(GLint location, GLfloat x)
5098{
5099 glUniform1fv(location, 1, &x);
5100}
5101
5102void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5103{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005104 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005105
5106 try
5107 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005108 if (count < 0)
5109 {
5110 return error(GL_INVALID_VALUE);
5111 }
5112
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005113 if (location == -1)
5114 {
5115 return;
5116 }
5117
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005118 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005119
5120 if (context)
5121 {
5122 gl::Program *program = context->getCurrentProgram();
5123
5124 if (!program)
5125 {
5126 return error(GL_INVALID_OPERATION);
5127 }
5128
5129 if (!program->setUniform1fv(location, count, v))
5130 {
5131 return error(GL_INVALID_OPERATION);
5132 }
5133 }
5134 }
5135 catch(std::bad_alloc&)
5136 {
5137 return error(GL_OUT_OF_MEMORY);
5138 }
5139}
5140
5141void __stdcall glUniform1i(GLint location, GLint x)
5142{
5143 glUniform1iv(location, 1, &x);
5144}
5145
5146void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5147{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005148 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005149
5150 try
5151 {
5152 if (count < 0)
5153 {
5154 return error(GL_INVALID_VALUE);
5155 }
5156
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005157 if (location == -1)
5158 {
5159 return;
5160 }
5161
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005162 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005163
5164 if (context)
5165 {
5166 gl::Program *program = context->getCurrentProgram();
5167
5168 if (!program)
5169 {
5170 return error(GL_INVALID_OPERATION);
5171 }
5172
5173 if (!program->setUniform1iv(location, count, v))
5174 {
5175 return error(GL_INVALID_OPERATION);
5176 }
5177 }
5178 }
5179 catch(std::bad_alloc&)
5180 {
5181 return error(GL_OUT_OF_MEMORY);
5182 }
5183}
5184
5185void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5186{
5187 GLfloat xy[2] = {x, y};
5188
5189 glUniform2fv(location, 1, (GLfloat*)&xy);
5190}
5191
5192void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5193{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005194 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005195
5196 try
5197 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005198 if (count < 0)
5199 {
5200 return error(GL_INVALID_VALUE);
5201 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005202
5203 if (location == -1)
5204 {
5205 return;
5206 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005207
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005208 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005209
5210 if (context)
5211 {
5212 gl::Program *program = context->getCurrentProgram();
5213
5214 if (!program)
5215 {
5216 return error(GL_INVALID_OPERATION);
5217 }
5218
5219 if (!program->setUniform2fv(location, count, v))
5220 {
5221 return error(GL_INVALID_OPERATION);
5222 }
5223 }
5224 }
5225 catch(std::bad_alloc&)
5226 {
5227 return error(GL_OUT_OF_MEMORY);
5228 }
5229}
5230
5231void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5232{
5233 GLint xy[4] = {x, y};
5234
5235 glUniform2iv(location, 1, (GLint*)&xy);
5236}
5237
5238void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5239{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005240 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005241
5242 try
5243 {
5244 if (count < 0)
5245 {
5246 return error(GL_INVALID_VALUE);
5247 }
5248
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005249 if (location == -1)
5250 {
5251 return;
5252 }
5253
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005254 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005255
5256 if (context)
5257 {
5258 gl::Program *program = context->getCurrentProgram();
5259
5260 if (!program)
5261 {
5262 return error(GL_INVALID_OPERATION);
5263 }
5264
5265 if (!program->setUniform2iv(location, count, v))
5266 {
5267 return error(GL_INVALID_OPERATION);
5268 }
5269 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005270 }
5271 catch(std::bad_alloc&)
5272 {
5273 return error(GL_OUT_OF_MEMORY);
5274 }
5275}
5276
5277void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5278{
5279 GLfloat xyz[3] = {x, y, z};
5280
5281 glUniform3fv(location, 1, (GLfloat*)&xyz);
5282}
5283
5284void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5285{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005286 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005287
5288 try
5289 {
5290 if (count < 0)
5291 {
5292 return error(GL_INVALID_VALUE);
5293 }
5294
5295 if (location == -1)
5296 {
5297 return;
5298 }
5299
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005300 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005301
5302 if (context)
5303 {
5304 gl::Program *program = context->getCurrentProgram();
5305
5306 if (!program)
5307 {
5308 return error(GL_INVALID_OPERATION);
5309 }
5310
5311 if (!program->setUniform3fv(location, count, v))
5312 {
5313 return error(GL_INVALID_OPERATION);
5314 }
5315 }
5316 }
5317 catch(std::bad_alloc&)
5318 {
5319 return error(GL_OUT_OF_MEMORY);
5320 }
5321}
5322
5323void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5324{
5325 GLint xyz[3] = {x, y, z};
5326
5327 glUniform3iv(location, 1, (GLint*)&xyz);
5328}
5329
5330void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5331{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005332 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005333
5334 try
5335 {
5336 if (count < 0)
5337 {
5338 return error(GL_INVALID_VALUE);
5339 }
5340
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005341 if (location == -1)
5342 {
5343 return;
5344 }
5345
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005346 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005347
5348 if (context)
5349 {
5350 gl::Program *program = context->getCurrentProgram();
5351
5352 if (!program)
5353 {
5354 return error(GL_INVALID_OPERATION);
5355 }
5356
5357 if (!program->setUniform3iv(location, count, v))
5358 {
5359 return error(GL_INVALID_OPERATION);
5360 }
5361 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005362 }
5363 catch(std::bad_alloc&)
5364 {
5365 return error(GL_OUT_OF_MEMORY);
5366 }
5367}
5368
5369void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5370{
5371 GLfloat xyzw[4] = {x, y, z, w};
5372
5373 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5374}
5375
5376void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5377{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005378 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005379
5380 try
5381 {
5382 if (count < 0)
5383 {
5384 return error(GL_INVALID_VALUE);
5385 }
5386
5387 if (location == -1)
5388 {
5389 return;
5390 }
5391
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005392 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005393
5394 if (context)
5395 {
5396 gl::Program *program = context->getCurrentProgram();
5397
5398 if (!program)
5399 {
5400 return error(GL_INVALID_OPERATION);
5401 }
5402
5403 if (!program->setUniform4fv(location, count, v))
5404 {
5405 return error(GL_INVALID_OPERATION);
5406 }
5407 }
5408 }
5409 catch(std::bad_alloc&)
5410 {
5411 return error(GL_OUT_OF_MEMORY);
5412 }
5413}
5414
5415void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5416{
5417 GLint xyzw[4] = {x, y, z, w};
5418
5419 glUniform4iv(location, 1, (GLint*)&xyzw);
5420}
5421
5422void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5423{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005424 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005425
5426 try
5427 {
5428 if (count < 0)
5429 {
5430 return error(GL_INVALID_VALUE);
5431 }
5432
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005433 if (location == -1)
5434 {
5435 return;
5436 }
5437
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005438 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005439
5440 if (context)
5441 {
5442 gl::Program *program = context->getCurrentProgram();
5443
5444 if (!program)
5445 {
5446 return error(GL_INVALID_OPERATION);
5447 }
5448
5449 if (!program->setUniform4iv(location, count, v))
5450 {
5451 return error(GL_INVALID_OPERATION);
5452 }
5453 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005454 }
5455 catch(std::bad_alloc&)
5456 {
5457 return error(GL_OUT_OF_MEMORY);
5458 }
5459}
5460
5461void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5462{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005463 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005464 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005465
5466 try
5467 {
5468 if (count < 0 || transpose != GL_FALSE)
5469 {
5470 return error(GL_INVALID_VALUE);
5471 }
5472
5473 if (location == -1)
5474 {
5475 return;
5476 }
5477
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005478 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005479
5480 if (context)
5481 {
5482 gl::Program *program = context->getCurrentProgram();
5483
5484 if (!program)
5485 {
5486 return error(GL_INVALID_OPERATION);
5487 }
5488
5489 if (!program->setUniformMatrix2fv(location, count, value))
5490 {
5491 return error(GL_INVALID_OPERATION);
5492 }
5493 }
5494 }
5495 catch(std::bad_alloc&)
5496 {
5497 return error(GL_OUT_OF_MEMORY);
5498 }
5499}
5500
5501void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5502{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005503 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005504 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005505
5506 try
5507 {
5508 if (count < 0 || transpose != GL_FALSE)
5509 {
5510 return error(GL_INVALID_VALUE);
5511 }
5512
5513 if (location == -1)
5514 {
5515 return;
5516 }
5517
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005518 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005519
5520 if (context)
5521 {
5522 gl::Program *program = context->getCurrentProgram();
5523
5524 if (!program)
5525 {
5526 return error(GL_INVALID_OPERATION);
5527 }
5528
5529 if (!program->setUniformMatrix3fv(location, count, value))
5530 {
5531 return error(GL_INVALID_OPERATION);
5532 }
5533 }
5534 }
5535 catch(std::bad_alloc&)
5536 {
5537 return error(GL_OUT_OF_MEMORY);
5538 }
5539}
5540
5541void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5542{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005543 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005544 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005545
5546 try
5547 {
5548 if (count < 0 || transpose != GL_FALSE)
5549 {
5550 return error(GL_INVALID_VALUE);
5551 }
5552
5553 if (location == -1)
5554 {
5555 return;
5556 }
5557
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005558 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005559
5560 if (context)
5561 {
5562 gl::Program *program = context->getCurrentProgram();
5563
5564 if (!program)
5565 {
5566 return error(GL_INVALID_OPERATION);
5567 }
5568
5569 if (!program->setUniformMatrix4fv(location, count, value))
5570 {
5571 return error(GL_INVALID_OPERATION);
5572 }
5573 }
5574 }
5575 catch(std::bad_alloc&)
5576 {
5577 return error(GL_OUT_OF_MEMORY);
5578 }
5579}
5580
5581void __stdcall glUseProgram(GLuint program)
5582{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005583 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005584
5585 try
5586 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005587 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005588
5589 if (context)
5590 {
5591 gl::Program *programObject = context->getProgram(program);
5592
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005593 if (!programObject && program != 0)
5594 {
5595 if (context->getShader(program))
5596 {
5597 return error(GL_INVALID_OPERATION);
5598 }
5599 else
5600 {
5601 return error(GL_INVALID_VALUE);
5602 }
5603 }
5604
5605 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005606 {
5607 return error(GL_INVALID_OPERATION);
5608 }
5609
5610 context->useProgram(program);
5611 }
5612 }
5613 catch(std::bad_alloc&)
5614 {
5615 return error(GL_OUT_OF_MEMORY);
5616 }
5617}
5618
5619void __stdcall glValidateProgram(GLuint program)
5620{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005621 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005622
5623 try
5624 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005625 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005626
5627 if (context)
5628 {
5629 gl::Program *programObject = context->getProgram(program);
5630
5631 if (!programObject)
5632 {
5633 if (context->getShader(program))
5634 {
5635 return error(GL_INVALID_OPERATION);
5636 }
5637 else
5638 {
5639 return error(GL_INVALID_VALUE);
5640 }
5641 }
5642
5643 programObject->validate();
5644 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005645 }
5646 catch(std::bad_alloc&)
5647 {
5648 return error(GL_OUT_OF_MEMORY);
5649 }
5650}
5651
5652void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5653{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005654 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005655
5656 try
5657 {
5658 if (index >= gl::MAX_VERTEX_ATTRIBS)
5659 {
5660 return error(GL_INVALID_VALUE);
5661 }
5662
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005663 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005664
5665 if (context)
5666 {
5667 GLfloat vals[4] = { x, 0, 0, 1 };
5668 context->setVertexAttrib(index, vals);
5669 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005670 }
5671 catch(std::bad_alloc&)
5672 {
5673 return error(GL_OUT_OF_MEMORY);
5674 }
5675}
5676
5677void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5678{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005679 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005680
5681 try
5682 {
5683 if (index >= gl::MAX_VERTEX_ATTRIBS)
5684 {
5685 return error(GL_INVALID_VALUE);
5686 }
5687
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005688 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005689
5690 if (context)
5691 {
5692 GLfloat vals[4] = { values[0], 0, 0, 1 };
5693 context->setVertexAttrib(index, vals);
5694 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005695 }
5696 catch(std::bad_alloc&)
5697 {
5698 return error(GL_OUT_OF_MEMORY);
5699 }
5700}
5701
5702void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5703{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005704 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005705
5706 try
5707 {
5708 if (index >= gl::MAX_VERTEX_ATTRIBS)
5709 {
5710 return error(GL_INVALID_VALUE);
5711 }
5712
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005713 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005714
5715 if (context)
5716 {
5717 GLfloat vals[4] = { x, y, 0, 1 };
5718 context->setVertexAttrib(index, vals);
5719 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005720 }
5721 catch(std::bad_alloc&)
5722 {
5723 return error(GL_OUT_OF_MEMORY);
5724 }
5725}
5726
5727void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5728{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005729 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005730
5731 try
5732 {
5733 if (index >= gl::MAX_VERTEX_ATTRIBS)
5734 {
5735 return error(GL_INVALID_VALUE);
5736 }
5737
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005738 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005739
5740 if (context)
5741 {
5742 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5743 context->setVertexAttrib(index, vals);
5744 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005745 }
5746 catch(std::bad_alloc&)
5747 {
5748 return error(GL_OUT_OF_MEMORY);
5749 }
5750}
5751
5752void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5753{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005754 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005755
5756 try
5757 {
5758 if (index >= gl::MAX_VERTEX_ATTRIBS)
5759 {
5760 return error(GL_INVALID_VALUE);
5761 }
5762
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005763 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005764
5765 if (context)
5766 {
5767 GLfloat vals[4] = { x, y, z, 1 };
5768 context->setVertexAttrib(index, vals);
5769 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005770 }
5771 catch(std::bad_alloc&)
5772 {
5773 return error(GL_OUT_OF_MEMORY);
5774 }
5775}
5776
5777void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5778{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005779 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005780
5781 try
5782 {
5783 if (index >= gl::MAX_VERTEX_ATTRIBS)
5784 {
5785 return error(GL_INVALID_VALUE);
5786 }
5787
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005788 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005789
5790 if (context)
5791 {
5792 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5793 context->setVertexAttrib(index, vals);
5794 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005795 }
5796 catch(std::bad_alloc&)
5797 {
5798 return error(GL_OUT_OF_MEMORY);
5799 }
5800}
5801
5802void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5803{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005804 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005805
5806 try
5807 {
5808 if (index >= gl::MAX_VERTEX_ATTRIBS)
5809 {
5810 return error(GL_INVALID_VALUE);
5811 }
5812
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005813 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005814
5815 if (context)
5816 {
5817 GLfloat vals[4] = { x, y, z, w };
5818 context->setVertexAttrib(index, vals);
5819 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005820 }
5821 catch(std::bad_alloc&)
5822 {
5823 return error(GL_OUT_OF_MEMORY);
5824 }
5825}
5826
5827void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5828{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005829 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005830
5831 try
5832 {
5833 if (index >= gl::MAX_VERTEX_ATTRIBS)
5834 {
5835 return error(GL_INVALID_VALUE);
5836 }
5837
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005838 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005839
5840 if (context)
5841 {
5842 context->setVertexAttrib(index, values);
5843 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005844 }
5845 catch(std::bad_alloc&)
5846 {
5847 return error(GL_OUT_OF_MEMORY);
5848 }
5849}
5850
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005851void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005852{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005853 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005854 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005855 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005856
5857 try
5858 {
5859 if (index >= gl::MAX_VERTEX_ATTRIBS)
5860 {
5861 return error(GL_INVALID_VALUE);
5862 }
5863
5864 if (size < 1 || size > 4)
5865 {
5866 return error(GL_INVALID_VALUE);
5867 }
5868
5869 switch (type)
5870 {
5871 case GL_BYTE:
5872 case GL_UNSIGNED_BYTE:
5873 case GL_SHORT:
5874 case GL_UNSIGNED_SHORT:
5875 case GL_FIXED:
5876 case GL_FLOAT:
5877 break;
5878 default:
5879 return error(GL_INVALID_ENUM);
5880 }
5881
5882 if (stride < 0)
5883 {
5884 return error(GL_INVALID_VALUE);
5885 }
5886
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005887 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005888
5889 if (context)
5890 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005891 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005892 }
5893 }
5894 catch(std::bad_alloc&)
5895 {
5896 return error(GL_OUT_OF_MEMORY);
5897 }
5898}
5899
5900void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5901{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005902 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005903
5904 try
5905 {
5906 if (width < 0 || height < 0)
5907 {
5908 return error(GL_INVALID_VALUE);
5909 }
5910
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005911 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005912
5913 if (context)
5914 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005915 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005916 }
5917 }
5918 catch(std::bad_alloc&)
5919 {
5920 return error(GL_OUT_OF_MEMORY);
5921 }
5922}
5923
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005924void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5925 GLbitfield mask, GLenum filter)
5926{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005927 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005928 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5929 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5930 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5931
5932 try
5933 {
5934 switch (filter)
5935 {
5936 case GL_NEAREST:
5937 break;
5938 default:
5939 return error(GL_INVALID_ENUM);
5940 }
5941
5942 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5943 {
5944 return error(GL_INVALID_VALUE);
5945 }
5946
5947 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5948 {
5949 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5950 return error(GL_INVALID_OPERATION);
5951 }
5952
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005953 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005954
5955 if (context)
5956 {
5957 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5958 {
5959 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5960 return error(GL_INVALID_OPERATION);
5961 }
5962
5963 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5964 }
5965 }
5966 catch(std::bad_alloc&)
5967 {
5968 return error(GL_OUT_OF_MEMORY);
5969 }
5970}
5971
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005972void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5973 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005974{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005975 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005976 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005977 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005978 target, level, internalformat, width, height, depth, border, format, type, pixels);
5979
5980 try
5981 {
5982 UNIMPLEMENTED(); // FIXME
5983 }
5984 catch(std::bad_alloc&)
5985 {
5986 return error(GL_OUT_OF_MEMORY);
5987 }
5988}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005989
5990__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5991{
5992 struct Extension
5993 {
5994 const char *name;
5995 __eglMustCastToProperFunctionPointerType address;
5996 };
5997
5998 static const Extension glExtensions[] =
5999 {
6000 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006001 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006002 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006003 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6004 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006005 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006006 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6007 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6008 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6009 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6010 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006011 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006012 };
6013
6014 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6015 {
6016 if (strcmp(procname, glExtensions[ext].name) == 0)
6017 {
6018 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6019 }
6020 }
6021
6022 return NULL;
6023}
6024
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006025// Non-public functions used by EGL
6026
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006027bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006028{
6029 EVENT("(egl::Surface* surface = 0x%0.8p)",
6030 surface);
6031
6032 try
6033 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006034 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006035
6036 if (context)
6037 {
6038 gl::Texture2D *textureObject = context->getTexture2D();
6039
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006040 if (textureObject->isImmutable())
6041 {
6042 return false;
6043 }
6044
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006045 if (textureObject)
6046 {
6047 textureObject->bindTexImage(surface);
6048 }
6049 }
6050 }
6051 catch(std::bad_alloc&)
6052 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006053 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006054 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006055
6056 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006057}
6058
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006059}