• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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