1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27
28 #if ENABLE(3D_CANVAS)
29
30 #include "GraphicsContext3D.h"
31
32 #include "CanvasObject.h"
33 #include "CString.h"
34 #include "ImageBuffer.h"
35 #include "NotImplemented.h"
36 #include "WebGLActiveInfo.h"
37 #include "WebGLArray.h"
38 #include "WebGLBuffer.h"
39 #include "WebGLFramebuffer.h"
40 #include "WebGLFloatArray.h"
41 #include "WebGLIntArray.h"
42 #include "WebGLProgram.h"
43 #include "WebGLRenderbuffer.h"
44 #include "WebGLShader.h"
45 #include "WebGLTexture.h"
46 #include "WebGLUnsignedByteArray.h"
47 #include <CoreGraphics/CGBitmapContext.h>
48 #include <OpenGL/CGLRenderers.h>
49 #include <wtf/UnusedParam.h>
50
51 namespace WebCore {
52
setPixelFormat(Vector<CGLPixelFormatAttribute> & attribs,int colorBits,int depthBits,bool accelerated,bool supersample,bool closest)53 static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBits, int depthBits, bool accelerated, bool supersample, bool closest)
54 {
55 attribs.clear();
56
57 attribs.append(kCGLPFAColorSize);
58 attribs.append(static_cast<CGLPixelFormatAttribute>(colorBits));
59 attribs.append(kCGLPFADepthSize);
60 attribs.append(static_cast<CGLPixelFormatAttribute>(depthBits));
61
62 if (accelerated)
63 attribs.append(kCGLPFAAccelerated);
64 else {
65 attribs.append(kCGLPFARendererID);
66 attribs.append(static_cast<CGLPixelFormatAttribute>(kCGLRendererGenericFloatID));
67 }
68
69 if (supersample)
70 attribs.append(kCGLPFASupersample);
71
72 if (closest)
73 attribs.append(kCGLPFAClosestPolicy);
74
75 attribs.append(static_cast<CGLPixelFormatAttribute>(0));
76 }
77
create(GraphicsContext3D::Attributes attrs)78 PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs)
79 {
80 OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs));
81 return context->m_contextObj ? context.release() : 0;
82 }
83
GraphicsContext3D(GraphicsContext3D::Attributes attrs)84 GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs)
85 : m_attrs(attrs)
86 , m_contextObj(0)
87 , m_texture(0)
88 , m_fbo(0)
89 , m_depthBuffer(0)
90 {
91 // FIXME: we need to take into account the user's requested
92 // context creation attributes, in particular stencil and
93 // antialias, and determine which could and could not be honored
94 // based on the capabilities of the OpenGL implementation.
95 m_attrs.alpha = true;
96 m_attrs.depth = true;
97 m_attrs.stencil = false;
98 m_attrs.antialias = false;
99 m_attrs.premultipliedAlpha = true;
100
101 Vector<CGLPixelFormatAttribute> attribs;
102 CGLPixelFormatObj pixelFormatObj = 0;
103 GLint numPixelFormats = 0;
104
105 // We will try:
106 //
107 // 1) 32 bit RGBA/32 bit depth/accelerated/supersampled
108 // 2) 32 bit RGBA/32 bit depth/accelerated
109 // 3) 32 bit RGBA/16 bit depth/accelerated
110 // 4) closest to 32 bit RGBA/16 bit depth/software renderer
111 //
112 // If none of that works, we simply fail and set m_contextObj to 0.
113
114 setPixelFormat(attribs, 32, 32, true, true, false);
115 CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
116 if (numPixelFormats == 0) {
117 setPixelFormat(attribs, 32, 32, true, false, false);
118 CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
119
120 if (numPixelFormats == 0) {
121 setPixelFormat(attribs, 32, 16, true, false, false);
122 CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
123
124 if (numPixelFormats == 0) {
125 setPixelFormat(attribs, 32, 16, false, false, true);
126 CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
127
128 if (numPixelFormats == 0) {
129 // Could not find an acceptable renderer - fail
130 return;
131 }
132 }
133 }
134 }
135
136 CGLError err = CGLCreateContext(pixelFormatObj, 0, &m_contextObj);
137 CGLDestroyPixelFormat(pixelFormatObj);
138
139 if (err != kCGLNoError || !m_contextObj) {
140 // Could not create the context - fail
141 m_contextObj = 0;
142 return;
143 }
144
145 // Set the current context to the one given to us.
146 CGLSetCurrentContext(m_contextObj);
147
148 // create a texture to render into
149 ::glGenTextures(1, &m_texture);
150 ::glBindTexture(GL_TEXTURE_2D, m_texture);
151 ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
152 ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
153 ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
154 ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
155 ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
156 ::glBindTexture(GL_TEXTURE_2D, 0);
157
158 // create an FBO
159 ::glGenFramebuffersEXT(1, &m_fbo);
160 ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
161
162 ::glGenRenderbuffersEXT(1, &m_depthBuffer);
163 ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
164 ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, 1, 1);
165 ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
166
167 ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
168 ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
169
170 ::glClearColor(0, 0, 0, 0);
171 }
172
~GraphicsContext3D()173 GraphicsContext3D::~GraphicsContext3D()
174 {
175 if (m_contextObj) {
176 CGLSetCurrentContext(m_contextObj);
177 ::glDeleteRenderbuffersEXT(1, & m_depthBuffer);
178 ::glDeleteTextures(1, &m_texture);
179 ::glDeleteFramebuffersEXT(1, &m_fbo);
180 CGLSetCurrentContext(0);
181 CGLDestroyContext(m_contextObj);
182 }
183 }
184
makeContextCurrent()185 void GraphicsContext3D::makeContextCurrent()
186 {
187 CGLSetCurrentContext(m_contextObj);
188 }
189
beginPaint(WebGLRenderingContext * context)190 void GraphicsContext3D::beginPaint(WebGLRenderingContext* context)
191 {
192 UNUSED_PARAM(context);
193 }
194
endPaint()195 void GraphicsContext3D::endPaint()
196 {
197 }
198
reshape(int width,int height)199 void GraphicsContext3D::reshape(int width, int height)
200 {
201 if (width == m_currentWidth && height == m_currentHeight || !m_contextObj)
202 return;
203
204 m_currentWidth = width;
205 m_currentHeight = height;
206
207 CGLSetCurrentContext(m_contextObj);
208
209 ::glBindTexture(GL_TEXTURE_2D, m_texture);
210 ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
211 ::glBindTexture(GL_TEXTURE_2D, 0);
212
213 ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
214 ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
215 ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
216 ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
217
218 ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
219 ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
220 GLenum status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
221 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
222 // FIXME: cleanup
223 notImplemented();
224 }
225
226 ::glClear(GL_COLOR_BUFFER_BIT);
227 ::glFlush();
228 }
229
ensureContext(CGLContextObj context)230 static inline void ensureContext(CGLContextObj context)
231 {
232 if (!context)
233 return;
234
235 CGLContextObj currentContext = CGLGetCurrentContext();
236 if (currentContext != context)
237 CGLSetCurrentContext(context);
238 }
239
activeTexture(unsigned long texture)240 void GraphicsContext3D::activeTexture(unsigned long texture)
241 {
242 ensureContext(m_contextObj);
243 ::glActiveTexture(texture);
244 }
245
attachShader(WebGLProgram * program,WebGLShader * shader)246 void GraphicsContext3D::attachShader(WebGLProgram* program, WebGLShader* shader)
247 {
248 ASSERT(program);
249 ASSERT(shader);
250 ensureContext(m_contextObj);
251 ::glAttachShader((GLuint) program->object(), (GLuint) shader->object());
252 }
253
bindAttribLocation(WebGLProgram * program,unsigned long index,const String & name)254 void GraphicsContext3D::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name)
255 {
256 ASSERT(program);
257 ensureContext(m_contextObj);
258 ::glBindAttribLocation((GLuint) program->object(), index, name.utf8().data());
259 }
260
bindBuffer(unsigned long target,WebGLBuffer * buffer)261 void GraphicsContext3D::bindBuffer(unsigned long target, WebGLBuffer* buffer)
262 {
263 ensureContext(m_contextObj);
264 ::glBindBuffer(target, buffer ? (GLuint) buffer->object() : 0);
265 }
266
267
bindFramebuffer(unsigned long target,WebGLFramebuffer * buffer)268 void GraphicsContext3D::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer)
269 {
270 ensureContext(m_contextObj);
271 ::glBindFramebufferEXT(target, (buffer && buffer->object()) ? (GLuint) buffer->object() : m_fbo);
272 }
273
bindRenderbuffer(unsigned long target,WebGLRenderbuffer * renderbuffer)274 void GraphicsContext3D::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderbuffer)
275 {
276 ensureContext(m_contextObj);
277 ::glBindRenderbufferEXT(target, renderbuffer ? (GLuint) renderbuffer->object() : 0);
278 }
279
280
bindTexture(unsigned long target,WebGLTexture * texture)281 void GraphicsContext3D::bindTexture(unsigned long target, WebGLTexture* texture)
282 {
283 ensureContext(m_contextObj);
284 ::glBindTexture(target, texture ? (GLuint) texture->object() : 0);
285 }
286
blendColor(double red,double green,double blue,double alpha)287 void GraphicsContext3D::blendColor(double red, double green, double blue, double alpha)
288 {
289 ensureContext(m_contextObj);
290 ::glBlendColor(static_cast<float>(red), static_cast<float>(green), static_cast<float>(blue), static_cast<float>(alpha));
291 }
292
blendEquation(unsigned long mode)293 void GraphicsContext3D::blendEquation( unsigned long mode )
294 {
295 ensureContext(m_contextObj);
296 ::glBlendEquation(mode);
297 }
298
blendEquationSeparate(unsigned long modeRGB,unsigned long modeAlpha)299 void GraphicsContext3D::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha)
300 {
301 ensureContext(m_contextObj);
302 ::glBlendEquationSeparate(modeRGB, modeAlpha);
303 }
304
305
blendFunc(unsigned long sfactor,unsigned long dfactor)306 void GraphicsContext3D::blendFunc(unsigned long sfactor, unsigned long dfactor)
307 {
308 ensureContext(m_contextObj);
309 ::glBlendFunc(sfactor, dfactor);
310 }
311
blendFuncSeparate(unsigned long srcRGB,unsigned long dstRGB,unsigned long srcAlpha,unsigned long dstAlpha)312 void GraphicsContext3D::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha)
313 {
314 ensureContext(m_contextObj);
315 ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
316 }
317
bufferData(unsigned long target,int size,unsigned long usage)318 void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long usage)
319 {
320 ensureContext(m_contextObj);
321 ::glBufferData(target, size, 0, usage);
322 }
bufferData(unsigned long target,WebGLArray * array,unsigned long usage)323 void GraphicsContext3D::bufferData(unsigned long target, WebGLArray* array, unsigned long usage)
324 {
325 if (!array || !array->length())
326 return;
327
328 ensureContext(m_contextObj);
329 ::glBufferData(target, array->byteLength(), array->baseAddress(), usage);
330 }
331
bufferSubData(unsigned long target,long offset,WebGLArray * array)332 void GraphicsContext3D::bufferSubData(unsigned long target, long offset, WebGLArray* array)
333 {
334 if (!array || !array->length())
335 return;
336
337 ensureContext(m_contextObj);
338 ::glBufferSubData(target, offset, array->byteLength(), array->baseAddress());
339 }
340
checkFramebufferStatus(unsigned long target)341 unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target)
342 {
343 ensureContext(m_contextObj);
344 return ::glCheckFramebufferStatusEXT(target);
345 }
346
clearColor(double r,double g,double b,double a)347 void GraphicsContext3D::clearColor(double r, double g, double b, double a)
348 {
349 ensureContext(m_contextObj);
350 ::glClearColor(static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a));
351 }
352
clear(unsigned long mask)353 void GraphicsContext3D::clear(unsigned long mask)
354 {
355 ensureContext(m_contextObj);
356 ::glClear(mask);
357 }
358
clearDepth(double depth)359 void GraphicsContext3D::clearDepth(double depth)
360 {
361 ensureContext(m_contextObj);
362 ::glClearDepth(depth);
363 }
364
clearStencil(long s)365 void GraphicsContext3D::clearStencil(long s)
366 {
367 ensureContext(m_contextObj);
368 ::glClearStencil(s);
369 }
370
colorMask(bool red,bool green,bool blue,bool alpha)371 void GraphicsContext3D::colorMask(bool red, bool green, bool blue, bool alpha)
372 {
373 ensureContext(m_contextObj);
374 ::glColorMask(red, green, blue, alpha);
375 }
376
compileShader(WebGLShader * shader)377 void GraphicsContext3D::compileShader(WebGLShader* shader)
378 {
379 ASSERT(shader);
380 ensureContext(m_contextObj);
381 ::glCompileShader((GLuint) shader->object());
382 }
383
copyTexImage2D(unsigned long target,long level,unsigned long internalformat,long x,long y,unsigned long width,unsigned long height,long border)384 void GraphicsContext3D::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border)
385 {
386 ensureContext(m_contextObj);
387 ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
388 }
389
copyTexSubImage2D(unsigned long target,long level,long xoffset,long yoffset,long x,long y,unsigned long width,unsigned long height)390 void GraphicsContext3D::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height)
391 {
392 ensureContext(m_contextObj);
393 ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
394 }
395
cullFace(unsigned long mode)396 void GraphicsContext3D::cullFace(unsigned long mode)
397 {
398 ensureContext(m_contextObj);
399 ::glCullFace(mode);
400 }
401
depthFunc(unsigned long func)402 void GraphicsContext3D::depthFunc(unsigned long func)
403 {
404 ensureContext(m_contextObj);
405 ::glDepthFunc(func);
406 }
407
depthMask(bool flag)408 void GraphicsContext3D::depthMask(bool flag)
409 {
410 ensureContext(m_contextObj);
411 ::glDepthMask(flag);
412 }
413
depthRange(double zNear,double zFar)414 void GraphicsContext3D::depthRange(double zNear, double zFar)
415 {
416 ensureContext(m_contextObj);
417 ::glDepthRange(zNear, zFar);
418 }
419
detachShader(WebGLProgram * program,WebGLShader * shader)420 void GraphicsContext3D::detachShader(WebGLProgram* program, WebGLShader* shader)
421 {
422 ASSERT(program);
423 ASSERT(shader);
424 ensureContext(m_contextObj);
425 ::glDetachShader((GLuint) program->object(), (GLuint) shader->object());
426 }
427
disable(unsigned long cap)428 void GraphicsContext3D::disable(unsigned long cap)
429 {
430 ensureContext(m_contextObj);
431 ::glDisable(cap);
432 }
433
disableVertexAttribArray(unsigned long index)434 void GraphicsContext3D::disableVertexAttribArray(unsigned long index)
435 {
436 ensureContext(m_contextObj);
437 ::glDisableVertexAttribArray(index);
438 }
439
drawArrays(unsigned long mode,long first,long count)440 void GraphicsContext3D::drawArrays(unsigned long mode, long first, long count)
441 {
442 ensureContext(m_contextObj);
443 ::glDrawArrays(mode, first, count);
444 }
445
drawElements(unsigned long mode,unsigned long count,unsigned long type,long offset)446 void GraphicsContext3D::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset)
447 {
448 ensureContext(m_contextObj);
449 ::glDrawElements(mode, count, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
450 }
451
enable(unsigned long cap)452 void GraphicsContext3D::enable(unsigned long cap)
453 {
454 ensureContext(m_contextObj);
455 ::glEnable(cap);
456 }
457
enableVertexAttribArray(unsigned long index)458 void GraphicsContext3D::enableVertexAttribArray(unsigned long index)
459 {
460 ensureContext(m_contextObj);
461 ::glEnableVertexAttribArray(index);
462 }
463
finish()464 void GraphicsContext3D::finish()
465 {
466 ensureContext(m_contextObj);
467 ::glFinish();
468 }
469
flush()470 void GraphicsContext3D::flush()
471 {
472 ensureContext(m_contextObj);
473 ::glFlush();
474 }
475
framebufferRenderbuffer(unsigned long target,unsigned long attachment,unsigned long renderbuffertarget,WebGLRenderbuffer * buffer)476 void GraphicsContext3D::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer)
477 {
478 ensureContext(m_contextObj);
479 ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, buffer ? (GLuint) buffer->object() : 0);
480 }
481
framebufferTexture2D(unsigned long target,unsigned long attachment,unsigned long textarget,WebGLTexture * texture,long level)482 void GraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level)
483 {
484 ensureContext(m_contextObj);
485 ::glFramebufferTexture2DEXT(target, attachment, textarget, texture ? (GLuint) texture->object() : 0, level);
486 }
487
frontFace(unsigned long mode)488 void GraphicsContext3D::frontFace(unsigned long mode)
489 {
490 ensureContext(m_contextObj);
491 ::glFrontFace(mode);
492 }
493
generateMipmap(unsigned long target)494 void GraphicsContext3D::generateMipmap(unsigned long target)
495 {
496 ensureContext(m_contextObj);
497 ::glGenerateMipmapEXT(target);
498 }
499
getActiveAttrib(WebGLProgram * program,unsigned long index,ActiveInfo & info)500 bool GraphicsContext3D::getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo& info)
501 {
502 if (!program->object()) {
503 synthesizeGLError(INVALID_VALUE);
504 return false;
505 }
506 ensureContext(m_contextObj);
507 GLint maxAttributeSize = 0;
508 ::glGetProgramiv(static_cast<GLuint>(program->object()), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize);
509 GLchar name[maxAttributeSize]; // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination
510 GLsizei nameLength = 0;
511 GLint size = 0;
512 GLenum type = 0;
513 ::glGetActiveAttrib(static_cast<GLuint>(program->object()), index, maxAttributeSize, &nameLength, &size, &type, name);
514 if (!nameLength)
515 return false;
516 info.name = String(name, nameLength);
517 info.type = type;
518 info.size = size;
519 return true;
520 }
521
getActiveUniform(WebGLProgram * program,unsigned long index,ActiveInfo & info)522 bool GraphicsContext3D::getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo& info)
523 {
524 if (!program->object()) {
525 synthesizeGLError(INVALID_VALUE);
526 return false;
527 }
528 ensureContext(m_contextObj);
529 GLint maxUniformSize = 0;
530 ::glGetProgramiv(static_cast<GLuint>(program->object()), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize);
531 GLchar name[maxUniformSize]; // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination
532 GLsizei nameLength = 0;
533 GLint size = 0;
534 GLenum type = 0;
535 ::glGetActiveUniform(static_cast<GLuint>(program->object()), index, maxUniformSize, &nameLength, &size, &type, name);
536 if (!nameLength)
537 return false;
538 info.name = String(name, nameLength);
539 info.type = type;
540 info.size = size;
541 return true;
542 }
543
getAttribLocation(WebGLProgram * program,const String & name)544 int GraphicsContext3D::getAttribLocation(WebGLProgram* program, const String& name)
545 {
546 if (!program)
547 return -1;
548
549 ensureContext(m_contextObj);
550 return ::glGetAttribLocation((GLuint) program->object(), name.utf8().data());
551 }
552
getContextAttributes()553 GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
554 {
555 return m_attrs;
556 }
557
getError()558 unsigned long GraphicsContext3D::getError()
559 {
560 if (m_syntheticErrors.size() > 0) {
561 ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin();
562 unsigned long err = *iter;
563 m_syntheticErrors.remove(iter);
564 return err;
565 }
566
567 ensureContext(m_contextObj);
568 return ::glGetError();
569 }
570
getString(unsigned long name)571 String GraphicsContext3D::getString(unsigned long name)
572 {
573 ensureContext(m_contextObj);
574 return String((const char*) ::glGetString(name));
575 }
576
hint(unsigned long target,unsigned long mode)577 void GraphicsContext3D::hint(unsigned long target, unsigned long mode)
578 {
579 ensureContext(m_contextObj);
580 ::glHint(target, mode);
581 }
582
isBuffer(WebGLBuffer * buffer)583 bool GraphicsContext3D::isBuffer(WebGLBuffer* buffer)
584 {
585 if (!buffer)
586 return false;
587
588 ensureContext(m_contextObj);
589 return ::glIsBuffer((GLuint) buffer->object());
590 }
591
isEnabled(unsigned long cap)592 bool GraphicsContext3D::isEnabled(unsigned long cap)
593 {
594 ensureContext(m_contextObj);
595 return ::glIsEnabled(cap);
596 }
597
isFramebuffer(WebGLFramebuffer * framebuffer)598 bool GraphicsContext3D::isFramebuffer(WebGLFramebuffer* framebuffer)
599 {
600 if (!framebuffer)
601 return false;
602
603 ensureContext(m_contextObj);
604 return ::glIsFramebufferEXT((GLuint) framebuffer->object());
605 }
606
isProgram(WebGLProgram * program)607 bool GraphicsContext3D::isProgram(WebGLProgram* program)
608 {
609 if (!program)
610 return false;
611
612 ensureContext(m_contextObj);
613 return ::glIsProgram((GLuint) program->object());
614 }
615
isRenderbuffer(WebGLRenderbuffer * renderbuffer)616 bool GraphicsContext3D::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
617 {
618 if (!renderbuffer)
619 return false;
620
621 ensureContext(m_contextObj);
622 return ::glIsRenderbufferEXT((GLuint) renderbuffer->object());
623 }
624
isShader(WebGLShader * shader)625 bool GraphicsContext3D::isShader(WebGLShader* shader)
626 {
627 if (!shader)
628 return false;
629
630 ensureContext(m_contextObj);
631 return ::glIsShader((GLuint) shader->object());
632 }
633
isTexture(WebGLTexture * texture)634 bool GraphicsContext3D::isTexture(WebGLTexture* texture)
635 {
636 if (!texture)
637 return false;
638
639 ensureContext(m_contextObj);
640 return ::glIsTexture((GLuint) texture->object());
641 }
642
lineWidth(double width)643 void GraphicsContext3D::lineWidth(double width)
644 {
645 ensureContext(m_contextObj);
646 ::glLineWidth(static_cast<float>(width));
647 }
648
linkProgram(WebGLProgram * program)649 void GraphicsContext3D::linkProgram(WebGLProgram* program)
650 {
651 ASSERT(program);
652 ensureContext(m_contextObj);
653 ::glLinkProgram((GLuint) program->object());
654 }
655
pixelStorei(unsigned long pname,long param)656 void GraphicsContext3D::pixelStorei(unsigned long pname, long param)
657 {
658 ensureContext(m_contextObj);
659 ::glPixelStorei(pname, param);
660 }
661
polygonOffset(double factor,double units)662 void GraphicsContext3D::polygonOffset(double factor, double units)
663 {
664 ensureContext(m_contextObj);
665 ::glPolygonOffset(static_cast<float>(factor), static_cast<float>(units));
666 }
667
readPixels(long x,long y,unsigned long width,unsigned long height,unsigned long format,unsigned long type)668 PassRefPtr<WebGLArray> GraphicsContext3D::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type)
669 {
670 ensureContext(m_contextObj);
671
672 // FIXME: For now we only accept GL_UNSIGNED_BYTE/GL_RGBA. In reality OpenGL ES 2.0 accepts that pair and one other
673 // as specified by GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE. But for now we will
674 // not accept those.
675 // FIXME: Also, we should throw when an unacceptable value is passed
676 if (type != GL_UNSIGNED_BYTE || format != GL_RGBA)
677 return 0;
678
679 RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4);
680 ::glReadPixels(x, y, width, height, format, type, (GLvoid*) array->data());
681 return array;
682 }
683
releaseShaderCompiler()684 void GraphicsContext3D::releaseShaderCompiler()
685 {
686 // FIXME: This is not implemented on desktop OpenGL. We need to have ifdefs for the different GL variants
687 ensureContext(m_contextObj);
688 //::glReleaseShaderCompiler();
689 }
690
renderbufferStorage(unsigned long target,unsigned long internalformat,unsigned long width,unsigned long height)691 void GraphicsContext3D::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height)
692 {
693 ensureContext(m_contextObj);
694 ::glRenderbufferStorageEXT(target, internalformat, width, height);
695 }
696
sampleCoverage(double value,bool invert)697 void GraphicsContext3D::sampleCoverage(double value, bool invert)
698 {
699 ensureContext(m_contextObj);
700 ::glSampleCoverage(static_cast<float>(value), invert);
701 }
702
scissor(long x,long y,unsigned long width,unsigned long height)703 void GraphicsContext3D::scissor(long x, long y, unsigned long width, unsigned long height)
704 {
705 ensureContext(m_contextObj);
706 ::glScissor(x, y, width, height);
707 }
708
shaderSource(WebGLShader * shader,const String & string)709 void GraphicsContext3D::shaderSource(WebGLShader* shader, const String& string)
710 {
711 ASSERT(shader);
712
713 ensureContext(m_contextObj);
714 const CString& cs = string.utf8();
715 const char* s = cs.data();
716
717 int length = string.length();
718 ::glShaderSource((GLuint) shader->object(), 1, &s, &length);
719 }
720
stencilFunc(unsigned long func,long ref,unsigned long mask)721 void GraphicsContext3D::stencilFunc(unsigned long func, long ref, unsigned long mask)
722 {
723 ensureContext(m_contextObj);
724 ::glStencilFunc(func, ref, mask);
725 }
726
stencilFuncSeparate(unsigned long face,unsigned long func,long ref,unsigned long mask)727 void GraphicsContext3D::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask)
728 {
729 ensureContext(m_contextObj);
730 ::glStencilFuncSeparate(face, func, ref, mask);
731 }
732
stencilMask(unsigned long mask)733 void GraphicsContext3D::stencilMask(unsigned long mask)
734 {
735 ensureContext(m_contextObj);
736 ::glStencilMask(mask);
737 }
738
stencilMaskSeparate(unsigned long face,unsigned long mask)739 void GraphicsContext3D::stencilMaskSeparate(unsigned long face, unsigned long mask)
740 {
741 ensureContext(m_contextObj);
742 ::glStencilMaskSeparate(face, mask);
743 }
744
stencilOp(unsigned long fail,unsigned long zfail,unsigned long zpass)745 void GraphicsContext3D::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass)
746 {
747 ensureContext(m_contextObj);
748 ::glStencilOp(fail, zfail, zpass);
749 }
750
stencilOpSeparate(unsigned long face,unsigned long fail,unsigned long zfail,unsigned long zpass)751 void GraphicsContext3D::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass)
752 {
753 ensureContext(m_contextObj);
754 ::glStencilOpSeparate(face, fail, zfail, zpass);
755 }
756
texParameterf(unsigned target,unsigned pname,float value)757 void GraphicsContext3D::texParameterf(unsigned target, unsigned pname, float value)
758 {
759 ensureContext(m_contextObj);
760 ::glTexParameterf(target, pname, static_cast<float>(value));
761 }
762
texParameteri(unsigned target,unsigned pname,int value)763 void GraphicsContext3D::texParameteri(unsigned target, unsigned pname, int value)
764 {
765 ensureContext(m_contextObj);
766 ::glTexParameteri(target, pname, static_cast<float>(value));
767 }
768
uniform1f(long location,float v0)769 void GraphicsContext3D::uniform1f(long location, float v0)
770 {
771 ensureContext(m_contextObj);
772 ::glUniform1f(location, v0);
773 }
774
uniform1fv(long location,float * array,int size)775 void GraphicsContext3D::uniform1fv(long location, float* array, int size)
776 {
777 ensureContext(m_contextObj);
778 ::glUniform1fv(location, size, array);
779 }
780
uniform2f(long location,float v0,float v1)781 void GraphicsContext3D::uniform2f(long location, float v0, float v1)
782 {
783 ensureContext(m_contextObj);
784 ::glUniform2f(location, v0, v1);
785 }
786
uniform2fv(long location,float * array,int size)787 void GraphicsContext3D::uniform2fv(long location, float* array, int size)
788 {
789 // FIXME: length needs to be a multiple of 2
790 ensureContext(m_contextObj);
791 ::glUniform2fv(location, size, array);
792 }
793
uniform3f(long location,float v0,float v1,float v2)794 void GraphicsContext3D::uniform3f(long location, float v0, float v1, float v2)
795 {
796 ensureContext(m_contextObj);
797 ::glUniform3f(location, v0, v1, v2);
798 }
799
uniform3fv(long location,float * array,int size)800 void GraphicsContext3D::uniform3fv(long location, float* array, int size)
801 {
802 // FIXME: length needs to be a multiple of 3
803 ensureContext(m_contextObj);
804 ::glUniform3fv(location, size, array);
805 }
806
uniform4f(long location,float v0,float v1,float v2,float v3)807 void GraphicsContext3D::uniform4f(long location, float v0, float v1, float v2, float v3)
808 {
809 ensureContext(m_contextObj);
810 ::glUniform4f(location, v0, v1, v2, v3);
811 }
812
uniform4fv(long location,float * array,int size)813 void GraphicsContext3D::uniform4fv(long location, float* array, int size)
814 {
815 // FIXME: length needs to be a multiple of 4
816 ensureContext(m_contextObj);
817 ::glUniform4fv(location, size, array);
818 }
819
uniform1i(long location,int v0)820 void GraphicsContext3D::uniform1i(long location, int v0)
821 {
822 ensureContext(m_contextObj);
823 ::glUniform1i(location, v0);
824 }
825
uniform1iv(long location,int * array,int size)826 void GraphicsContext3D::uniform1iv(long location, int* array, int size)
827 {
828 ensureContext(m_contextObj);
829 ::glUniform1iv(location, size, array);
830 }
831
uniform2i(long location,int v0,int v1)832 void GraphicsContext3D::uniform2i(long location, int v0, int v1)
833 {
834 ensureContext(m_contextObj);
835 ::glUniform2i(location, v0, v1);
836 }
837
uniform2iv(long location,int * array,int size)838 void GraphicsContext3D::uniform2iv(long location, int* array, int size)
839 {
840 // FIXME: length needs to be a multiple of 2
841 ensureContext(m_contextObj);
842 ::glUniform2iv(location, size, array);
843 }
844
uniform3i(long location,int v0,int v1,int v2)845 void GraphicsContext3D::uniform3i(long location, int v0, int v1, int v2)
846 {
847 ensureContext(m_contextObj);
848 ::glUniform3i(location, v0, v1, v2);
849 }
850
uniform3iv(long location,int * array,int size)851 void GraphicsContext3D::uniform3iv(long location, int* array, int size)
852 {
853 // FIXME: length needs to be a multiple of 3
854 ensureContext(m_contextObj);
855 ::glUniform3iv(location, size, array);
856 }
857
uniform4i(long location,int v0,int v1,int v2,int v3)858 void GraphicsContext3D::uniform4i(long location, int v0, int v1, int v2, int v3)
859 {
860 ensureContext(m_contextObj);
861 ::glUniform4i(location, v0, v1, v2, v3);
862 }
863
uniform4iv(long location,int * array,int size)864 void GraphicsContext3D::uniform4iv(long location, int* array, int size)
865 {
866 // FIXME: length needs to be a multiple of 4
867 ensureContext(m_contextObj);
868 ::glUniform4iv(location, size, array);
869 }
870
uniformMatrix2fv(long location,bool transpose,float * array,int size)871 void GraphicsContext3D::uniformMatrix2fv(long location, bool transpose, float* array, int size)
872 {
873 // FIXME: length needs to be a multiple of 4
874 ensureContext(m_contextObj);
875 ::glUniformMatrix2fv(location, size, transpose, array);
876 }
877
uniformMatrix3fv(long location,bool transpose,float * array,int size)878 void GraphicsContext3D::uniformMatrix3fv(long location, bool transpose, float* array, int size)
879 {
880 // FIXME: length needs to be a multiple of 9
881 ensureContext(m_contextObj);
882 ::glUniformMatrix3fv(location, size, transpose, array);
883 }
884
uniformMatrix4fv(long location,bool transpose,float * array,int size)885 void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* array, int size)
886 {
887 // FIXME: length needs to be a multiple of 16
888 ensureContext(m_contextObj);
889 ::glUniformMatrix4fv(location, size, transpose, array);
890 }
891
useProgram(WebGLProgram * program)892 void GraphicsContext3D::useProgram(WebGLProgram* program)
893 {
894 ASSERT(program);
895
896 ensureContext(m_contextObj);
897 ::glUseProgram((GLuint) program->object());
898 }
899
validateProgram(WebGLProgram * program)900 void GraphicsContext3D::validateProgram(WebGLProgram* program)
901 {
902 ASSERT(program);
903
904 ensureContext(m_contextObj);
905 ::glValidateProgram((GLuint) program->object());
906 }
907
vertexAttrib1f(unsigned long indx,float v0)908 void GraphicsContext3D::vertexAttrib1f(unsigned long indx, float v0)
909 {
910 ensureContext(m_contextObj);
911 ::glVertexAttrib1f(indx, v0);
912 }
913
vertexAttrib1fv(unsigned long indx,float * array)914 void GraphicsContext3D::vertexAttrib1fv(unsigned long indx, float* array)
915 {
916 ensureContext(m_contextObj);
917 ::glVertexAttrib1fv(indx, array);
918 }
919
vertexAttrib2f(unsigned long indx,float v0,float v1)920 void GraphicsContext3D::vertexAttrib2f(unsigned long indx, float v0, float v1)
921 {
922 ensureContext(m_contextObj);
923 ::glVertexAttrib2f(indx, v0, v1);
924 }
925
vertexAttrib2fv(unsigned long indx,float * array)926 void GraphicsContext3D::vertexAttrib2fv(unsigned long indx, float* array)
927 {
928 ensureContext(m_contextObj);
929 ::glVertexAttrib2fv(indx, array);
930 }
931
vertexAttrib3f(unsigned long indx,float v0,float v1,float v2)932 void GraphicsContext3D::vertexAttrib3f(unsigned long indx, float v0, float v1, float v2)
933 {
934 ensureContext(m_contextObj);
935 ::glVertexAttrib3f(indx, v0, v1, v2);
936 }
937
vertexAttrib3fv(unsigned long indx,float * array)938 void GraphicsContext3D::vertexAttrib3fv(unsigned long indx, float* array)
939 {
940 ensureContext(m_contextObj);
941 ::glVertexAttrib3fv(indx, array);
942 }
943
vertexAttrib4f(unsigned long indx,float v0,float v1,float v2,float v3)944 void GraphicsContext3D::vertexAttrib4f(unsigned long indx, float v0, float v1, float v2, float v3)
945 {
946 ensureContext(m_contextObj);
947 ::glVertexAttrib4f(indx, v0, v1, v2, v3);
948 }
949
vertexAttrib4fv(unsigned long indx,float * array)950 void GraphicsContext3D::vertexAttrib4fv(unsigned long indx, float* array)
951 {
952 ensureContext(m_contextObj);
953 ::glVertexAttrib4fv(indx, array);
954 }
955
vertexAttribPointer(unsigned long indx,int size,int type,bool normalized,unsigned long stride,unsigned long offset)956 void GraphicsContext3D::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, unsigned long stride, unsigned long offset)
957 {
958 ensureContext(m_contextObj);
959 ::glVertexAttribPointer(indx, size, type, normalized, stride, reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
960 }
961
viewport(long x,long y,unsigned long width,unsigned long height)962 void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height)
963 {
964 ensureContext(m_contextObj);
965 ::glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
966 }
967
getBooleanv(unsigned long pname,unsigned char * value)968 void GraphicsContext3D::getBooleanv(unsigned long pname, unsigned char* value)
969 {
970 ensureContext(m_contextObj);
971 ::glGetBooleanv(pname, value);
972 }
973
getBufferParameteriv(unsigned long target,unsigned long pname,int * value)974 void GraphicsContext3D::getBufferParameteriv(unsigned long target, unsigned long pname, int* value)
975 {
976 ensureContext(m_contextObj);
977 ::glGetBufferParameteriv(target, pname, value);
978 }
979
getFloatv(unsigned long pname,float * value)980 void GraphicsContext3D::getFloatv(unsigned long pname, float* value)
981 {
982 ensureContext(m_contextObj);
983 ::glGetFloatv(pname, value);
984 }
985
getFramebufferAttachmentParameteriv(unsigned long target,unsigned long attachment,unsigned long pname,int * value)986 void GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname, int* value)
987 {
988 ensureContext(m_contextObj);
989 ::glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value);
990 }
991
getIntegerv(unsigned long pname,int * value)992 void GraphicsContext3D::getIntegerv(unsigned long pname, int* value)
993 {
994 ensureContext(m_contextObj);
995 ::glGetIntegerv(pname, value);
996 }
997
getProgramiv(WebGLProgram * program,unsigned long pname,int * value)998 void GraphicsContext3D::getProgramiv(WebGLProgram* program, unsigned long pname, int* value)
999 {
1000 ensureContext(m_contextObj);
1001 ::glGetProgramiv((GLuint) program->object(), pname, value);
1002 }
1003
getProgramInfoLog(WebGLProgram * program)1004 String GraphicsContext3D::getProgramInfoLog(WebGLProgram* program)
1005 {
1006 ASSERT(program);
1007
1008 ensureContext(m_contextObj);
1009 GLint length;
1010 ::glGetProgramiv((GLuint) program->object(), GL_INFO_LOG_LENGTH, &length);
1011
1012 GLsizei size;
1013 GLchar* info = (GLchar*) fastMalloc(length);
1014 if (!info)
1015 return "";
1016
1017 ::glGetProgramInfoLog((GLuint) program->object(), length, &size, info);
1018 String s(info);
1019 fastFree(info);
1020 return s;
1021 }
1022
getRenderbufferParameteriv(unsigned long target,unsigned long pname,int * value)1023 void GraphicsContext3D::getRenderbufferParameteriv(unsigned long target, unsigned long pname, int* value)
1024 {
1025 ensureContext(m_contextObj);
1026 ::glGetRenderbufferParameterivEXT(target, pname, value);
1027 }
1028
getShaderiv(WebGLShader * shader,unsigned long pname,int * value)1029 void GraphicsContext3D::getShaderiv(WebGLShader* shader, unsigned long pname, int* value)
1030 {
1031 ASSERT(shader);
1032
1033 ensureContext(m_contextObj);
1034 ::glGetShaderiv((GLuint) shader->object(), pname, value);
1035 }
1036
getShaderInfoLog(WebGLShader * shader)1037 String GraphicsContext3D::getShaderInfoLog(WebGLShader* shader)
1038 {
1039 ASSERT(shader);
1040
1041 ensureContext(m_contextObj);
1042 GLint length;
1043 ::glGetShaderiv((GLuint) shader->object(), GL_INFO_LOG_LENGTH, &length);
1044
1045 GLsizei size;
1046 GLchar* info = (GLchar*) fastMalloc(length);
1047 if (!info)
1048 return "";
1049
1050 ::glGetShaderInfoLog((GLuint) shader->object(), length, &size, info);
1051 String s(info);
1052 fastFree(info);
1053 return s;
1054 }
1055
getShaderSource(WebGLShader * shader)1056 String GraphicsContext3D::getShaderSource(WebGLShader* shader)
1057 {
1058 ASSERT(shader);
1059
1060 ensureContext(m_contextObj);
1061 GLint length;
1062 ::glGetShaderiv((GLuint) shader->object(), GL_SHADER_SOURCE_LENGTH, &length);
1063
1064 GLsizei size;
1065 GLchar* info = (GLchar*) fastMalloc(length);
1066 if (!info)
1067 return "";
1068
1069 ::glGetShaderSource((GLuint) shader->object(), length, &size, info);
1070 String s(info);
1071 fastFree(info);
1072 return s;
1073 }
1074
1075
getTexParameterfv(unsigned long target,unsigned long pname,float * value)1076 void GraphicsContext3D::getTexParameterfv(unsigned long target, unsigned long pname, float* value)
1077 {
1078 ensureContext(m_contextObj);
1079 ::glGetTexParameterfv(target, pname, value);
1080 }
1081
getTexParameteriv(unsigned long target,unsigned long pname,int * value)1082 void GraphicsContext3D::getTexParameteriv(unsigned long target, unsigned long pname, int* value)
1083 {
1084 ensureContext(m_contextObj);
1085 ::glGetTexParameteriv(target, pname, value);
1086 }
1087
getUniformfv(WebGLProgram * program,long location,float * value)1088 void GraphicsContext3D::getUniformfv(WebGLProgram* program, long location, float* value)
1089 {
1090 ensureContext(m_contextObj);
1091 ::glGetUniformfv((GLuint) program->object(), location, value);
1092 }
1093
getUniformiv(WebGLProgram * program,long location,int * value)1094 void GraphicsContext3D::getUniformiv(WebGLProgram* program, long location, int* value)
1095 {
1096 ensureContext(m_contextObj);
1097 ::glGetUniformiv((GLuint) program->object(), location, value);
1098 }
1099
getUniformLocation(WebGLProgram * program,const String & name)1100 long GraphicsContext3D::getUniformLocation(WebGLProgram* program, const String& name)
1101 {
1102 ASSERT(program);
1103
1104 ensureContext(m_contextObj);
1105 return ::glGetUniformLocation((GLuint) program->object(), name.utf8().data());
1106 }
1107
getVertexAttribfv(unsigned long index,unsigned long pname,float * value)1108 void GraphicsContext3D::getVertexAttribfv(unsigned long index, unsigned long pname, float* value)
1109 {
1110 ensureContext(m_contextObj);
1111 ::glGetVertexAttribfv(index, pname, value);
1112 }
1113
getVertexAttribiv(unsigned long index,unsigned long pname,int * value)1114 void GraphicsContext3D::getVertexAttribiv(unsigned long index, unsigned long pname, int* value)
1115 {
1116 ensureContext(m_contextObj);
1117 ::glGetVertexAttribiv(index, pname, value);
1118 }
1119
getVertexAttribOffset(unsigned long index,unsigned long pname)1120 long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long pname)
1121 {
1122 ensureContext(m_contextObj);
1123
1124 void* pointer;
1125 ::glGetVertexAttribPointerv(index, pname, &pointer);
1126 return reinterpret_cast<long>(pointer);
1127 }
1128
1129 // Returned pointer must be freed by fastFree()
imageToTexture(Image * image,GLubyte * & buffer,size_t & width,size_t & height)1130 static bool imageToTexture(Image* image, GLubyte*& buffer, size_t& width, size_t& height)
1131 {
1132 if (!image)
1133 return false;
1134
1135 CGImageRef textureImage = image->getCGImageRef();
1136 if (!textureImage)
1137 return false;
1138
1139 width = CGImageGetWidth(textureImage);
1140 height = CGImageGetHeight(textureImage);
1141
1142 buffer = (GLubyte*) fastMalloc(width * height * 4);
1143 if (!buffer)
1144 return false;
1145
1146 CGContextRef textureContext = CGBitmapContextCreate(buffer, width, height, 8, width * 4,
1147 CGImageGetColorSpace(textureImage), kCGImageAlphaPremultipliedLast);
1148 CGContextSetBlendMode(textureContext, kCGBlendModeCopy);
1149 CGContextDrawImage(textureContext, CGRectMake(0, 0, (CGFloat)width, (CGFloat)height), textureImage);
1150 CGContextRelease(textureContext);
1151 return true;
1152 }
1153
texImage2D(unsigned target,unsigned level,unsigned internalformat,unsigned width,unsigned height,unsigned border,unsigned format,unsigned type,void * pixels)1154 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels)
1155 {
1156 // FIXME: Need to do bounds checking on the buffer here.
1157 ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
1158 return 0;
1159 }
1160
texImage2D(unsigned target,unsigned level,Image * image,bool flipY,bool premultiplyAlpha)1161 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, Image* image, bool flipY, bool premultiplyAlpha)
1162 {
1163 // FIXME: need to support flipY and premultiplyAlpha
1164 UNUSED_PARAM(flipY);
1165 UNUSED_PARAM(premultiplyAlpha);
1166 ASSERT(image);
1167
1168 ensureContext(m_contextObj);
1169 GLubyte* buffer;
1170 size_t width;
1171 size_t height;
1172 if (!imageToTexture(image, buffer, width, height))
1173 return -1;
1174
1175 ::glTexImage2D(target, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
1176 fastFree(buffer);
1177 return 0;
1178 }
1179
texSubImage2D(unsigned target,unsigned level,unsigned xoff,unsigned yoff,unsigned width,unsigned height,unsigned format,unsigned type,void * pixels)1180 int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels)
1181 {
1182 // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size
1183 // FIXME: Need to do bounds checking on the buffer here.
1184 ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
1185 return 0;
1186 }
1187
texSubImage2D(unsigned target,unsigned level,unsigned xoff,unsigned yoff,Image * image,bool flipY,bool premultiplyAlpha)1188 int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, Image* image, bool flipY, bool premultiplyAlpha)
1189 {
1190 // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size
1191 // FIXME: need to support flipY and premultiplyAlpha
1192 UNUSED_PARAM(flipY);
1193 UNUSED_PARAM(premultiplyAlpha);
1194 ASSERT(image);
1195
1196 ensureContext(m_contextObj);
1197 GLubyte* buffer;
1198 size_t width;
1199 size_t height;
1200 if (!imageToTexture(image, buffer, width, height))
1201 return -1;
1202
1203 ::glTexSubImage2D(target, level, xoff, yoff, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
1204 fastFree(buffer);
1205 return 0;
1206 }
1207
createBuffer()1208 unsigned GraphicsContext3D::createBuffer()
1209 {
1210 ensureContext(m_contextObj);
1211 GLuint o;
1212 glGenBuffers(1, &o);
1213 return o;
1214 }
1215
createFramebuffer()1216 unsigned GraphicsContext3D::createFramebuffer()
1217 {
1218 ensureContext(m_contextObj);
1219 GLuint o;
1220 glGenFramebuffersEXT(1, &o);
1221 return o;
1222 }
1223
createProgram()1224 unsigned GraphicsContext3D::createProgram()
1225 {
1226 ensureContext(m_contextObj);
1227 return glCreateProgram();
1228 }
1229
createRenderbuffer()1230 unsigned GraphicsContext3D::createRenderbuffer()
1231 {
1232 ensureContext(m_contextObj);
1233 GLuint o;
1234 glGenRenderbuffersEXT(1, &o);
1235 return o;
1236 }
1237
createShader(unsigned long type)1238 unsigned GraphicsContext3D::createShader(unsigned long type)
1239 {
1240 ensureContext(m_contextObj);
1241 return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER);
1242 }
1243
createTexture()1244 unsigned GraphicsContext3D::createTexture()
1245 {
1246 ensureContext(m_contextObj);
1247 GLuint o;
1248 glGenTextures(1, &o);
1249 return o;
1250 }
1251
deleteBuffer(unsigned buffer)1252 void GraphicsContext3D::deleteBuffer(unsigned buffer)
1253 {
1254 ensureContext(m_contextObj);
1255 glDeleteBuffers(1, &buffer);
1256 }
1257
deleteFramebuffer(unsigned framebuffer)1258 void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer)
1259 {
1260 ensureContext(m_contextObj);
1261 glDeleteFramebuffersEXT(1, &framebuffer);
1262 }
1263
deleteProgram(unsigned program)1264 void GraphicsContext3D::deleteProgram(unsigned program)
1265 {
1266 ensureContext(m_contextObj);
1267 glDeleteProgram(program);
1268 }
1269
deleteRenderbuffer(unsigned renderbuffer)1270 void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer)
1271 {
1272 ensureContext(m_contextObj);
1273 glDeleteRenderbuffersEXT(1, &renderbuffer);
1274 }
1275
deleteShader(unsigned shader)1276 void GraphicsContext3D::deleteShader(unsigned shader)
1277 {
1278 ensureContext(m_contextObj);
1279 glDeleteShader(shader);
1280 }
1281
deleteTexture(unsigned texture)1282 void GraphicsContext3D::deleteTexture(unsigned texture)
1283 {
1284 ensureContext(m_contextObj);
1285 glDeleteTextures(1, &texture);
1286 }
1287
sizeInBytes(int type)1288 int GraphicsContext3D::sizeInBytes(int type)
1289 {
1290 switch (type) {
1291 case GL_BYTE:
1292 return sizeof(GLbyte);
1293 case GL_UNSIGNED_BYTE:
1294 return sizeof(GLubyte);
1295 case GL_SHORT:
1296 return sizeof(GLshort);
1297 case GL_UNSIGNED_SHORT:
1298 return sizeof(GLushort);
1299 case GL_INT:
1300 return sizeof(GLint);
1301 case GL_UNSIGNED_INT:
1302 return sizeof(GLuint);
1303 case GL_FLOAT:
1304 return sizeof(GLfloat);
1305 default:
1306 return 0;
1307 }
1308 }
1309
synthesizeGLError(unsigned long error)1310 void GraphicsContext3D::synthesizeGLError(unsigned long error)
1311 {
1312 m_syntheticErrors.add(error);
1313 }
1314
1315 }
1316
1317 #endif // ENABLE(3D_CANVAS)
1318