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