2010-08-16 Paul Sawaya <psawaya@apple.com>
[WebKit-https.git] / WebCore / platform / graphics / mac / GraphicsContext3DMac.mm
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 #import "BlockExceptions.h"
33
34 #include "ANGLE/ResourceLimits.h"
35 #include "ArrayBuffer.h"
36 #include "ArrayBufferView.h"
37 #include "WebGLObject.h"
38 #include "CanvasRenderingContext.h"
39 #include "Float32Array.h"
40 #include "GraphicsContext.h"
41 #include "HTMLCanvasElement.h"
42 #include "ImageBuffer.h"
43 #include "Int32Array.h"
44 #include "NotImplemented.h"
45 #include "Uint8Array.h"
46 #include "WebGLLayer.h"
47 #include <CoreGraphics/CGBitmapContext.h>
48 #include <OpenGL/CGLRenderers.h>
49 #include <OpenGL/gl.h>
50 #include <wtf/UnusedParam.h>
51 #include <wtf/text/CString.h>
52
53 namespace WebCore {
54
55 static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBits, int depthBits, bool accelerated, bool supersample, bool closest)
56 {
57     attribs.clear();
58     
59     attribs.append(kCGLPFAColorSize);
60     attribs.append(static_cast<CGLPixelFormatAttribute>(colorBits));
61     attribs.append(kCGLPFADepthSize);
62     attribs.append(static_cast<CGLPixelFormatAttribute>(depthBits));
63     
64     if (accelerated)
65         attribs.append(kCGLPFAAccelerated);
66     else {
67         attribs.append(kCGLPFARendererID);
68         attribs.append(static_cast<CGLPixelFormatAttribute>(kCGLRendererGenericFloatID));
69     }
70         
71     if (supersample)
72         attribs.append(kCGLPFASupersample);
73         
74     if (closest)
75         attribs.append(kCGLPFAClosestPolicy);
76         
77     attribs.append(static_cast<CGLPixelFormatAttribute>(0));
78 }
79
80 PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow)
81 {
82     OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs, hostWindow));
83     return context->m_contextObj ? context.release() : 0;
84 }
85
86 GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow)
87     : m_currentWidth(0)
88     , m_currentHeight(0)
89     , m_attrs(attrs)
90     , m_contextObj(0)
91     , m_texture(0)
92     , m_fbo(0)
93     , m_depthStencilBuffer(0)
94     , m_boundFBO(0)
95     , m_multisampleFBO(0)
96     , m_multisampleDepthStencilBuffer(0)
97     , m_multisampleColorBuffer(0)
98 {
99     UNUSED_PARAM(hostWindow);
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     validateAttributes();
149
150     // Create the WebGLLayer
151     BEGIN_BLOCK_OBJC_EXCEPTIONS
152         m_webGLLayer.adoptNS([[WebGLLayer alloc] initWithGraphicsContext3D:this]);
153 #ifndef NDEBUG
154         [m_webGLLayer.get() setName:@"WebGL Layer"];
155 #endif    
156     END_BLOCK_OBJC_EXCEPTIONS
157     
158     // create a texture to render into
159     ::glGenTextures(1, &m_texture);
160     ::glBindTexture(GL_TEXTURE_2D, m_texture);
161     ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
162     ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
163     ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
164     ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
165     ::glBindTexture(GL_TEXTURE_2D, 0);
166     
167     // create an FBO
168     ::glGenFramebuffersEXT(1, &m_fbo);
169     ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
170     
171     m_boundFBO = m_fbo;
172     if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth))
173         ::glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
174
175     // create an multisample FBO
176     if (m_attrs.antialias) {
177         ::glGenFramebuffersEXT(1, &m_multisampleFBO);
178         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
179         m_boundFBO = m_multisampleFBO;
180         ::glGenRenderbuffersEXT(1, &m_multisampleColorBuffer);
181         if (m_attrs.stencil || m_attrs.depth)
182             ::glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
183     }
184     
185     // ANGLE initialization.
186
187     TBuiltInResource ANGLEResources;
188
189     ANGLEResources.maxVertexAttribs = 0;
190     getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.maxVertexAttribs);
191     ANGLEResources.maxVertexUniformVectors = 0;
192     getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.maxVertexUniformVectors);
193     ANGLEResources.maxVaryingVectors = 0;
194     getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.maxVaryingVectors);
195     ANGLEResources.maxVertexTextureImageUnits = 0;
196     getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.maxVertexTextureImageUnits);
197     ANGLEResources.maxCombinedTextureImageUnits = 0;
198     getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.maxCombinedTextureImageUnits);
199     ANGLEResources.maxTextureImageUnits = 0;
200     getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.maxTextureImageUnits);
201     ANGLEResources.maxFragmentUniformVectors = 0;
202     getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.maxFragmentUniformVectors);
203
204     // Always set to 1 for OpenGL ES.
205     ANGLEResources.maxDrawBuffers = 1;
206     
207     m_compiler.setResources(ANGLEResources);
208     
209     ::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
210     ::glClearColor(0, 0, 0, 0);
211 }
212
213 GraphicsContext3D::~GraphicsContext3D()
214 {
215     if (m_contextObj) {
216         CGLSetCurrentContext(m_contextObj);
217         ::glDeleteTextures(1, &m_texture);
218         if (m_attrs.antialias) {
219             ::glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer);
220             if (m_attrs.stencil || m_attrs.depth)
221                 ::glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
222             ::glDeleteFramebuffersEXT(1, &m_multisampleFBO);
223         } else {
224             if (m_attrs.stencil || m_attrs.depth)
225                 ::glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer);
226         }
227         ::glDeleteFramebuffersEXT(1, &m_fbo);
228         CGLSetCurrentContext(0);
229         CGLDestroyContext(m_contextObj);
230     }
231 }
232
233 void GraphicsContext3D::validateAttributes()
234 {
235     const char* extensions = reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS));
236     if (m_attrs.stencil) {
237         if (std::strstr(extensions, "GL_EXT_packed_depth_stencil")) {
238             if (!m_attrs.depth)
239                 m_attrs.depth = true;
240         } else
241             m_attrs.stencil = false;
242     }
243     if (m_attrs.antialias) {
244         bool isValidVendor = true;
245         // Currently in Mac we only turn on antialias if vendor is NVIDIA.
246         const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR));
247         if (!std::strstr(vendor, "NVIDIA"))
248             isValidVendor = false;
249         if (!isValidVendor || !std::strstr(extensions, "GL_EXT_framebuffer_multisample"))
250             m_attrs.antialias = false;
251     }
252     // FIXME: instead of enforcing premultipliedAlpha = true, implement the
253     // correct behavior when premultipliedAlpha = false is requested.
254     m_attrs.premultipliedAlpha = true;
255 }
256
257 void GraphicsContext3D::makeContextCurrent()
258 {
259     CGLSetCurrentContext(m_contextObj);
260 }
261
262 void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
263 {
264     HTMLCanvasElement* canvas = context->canvas();
265     ImageBuffer* imageBuffer = canvas->buffer();
266
267     int rowBytes = m_currentWidth * 4;
268     int totalBytes = rowBytes * m_currentHeight;
269
270     OwnArrayPtr<unsigned char> pixels(new unsigned char[totalBytes]);
271     if (!pixels)
272         return;
273
274     CGLSetCurrentContext(m_contextObj);
275
276     bool mustRestoreFBO = false;
277     if (m_attrs.antialias) {
278         ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
279         ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
280         ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
281         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
282         mustRestoreFBO = true;
283     } else {
284         if (m_boundFBO != m_fbo) {
285             mustRestoreFBO = true;
286             ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
287         }
288     }
289
290     GLint packAlignment = 4;
291     bool mustRestorePackAlignment = false;
292     ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment);
293     if (packAlignment > 4) {
294         ::glPixelStorei(GL_PACK_ALIGNMENT, 4);
295         mustRestorePackAlignment = true;
296     }
297
298     ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels.get());
299
300     if (mustRestorePackAlignment)
301         ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment);
302
303     if (mustRestoreFBO)
304         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
305
306     paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight,
307                   canvas->width(), canvas->height(), imageBuffer->context()->platformContext());
308 }
309
310 void GraphicsContext3D::beginPaint(CanvasRenderingContext* context)
311 {
312     UNUSED_PARAM(context);
313 }
314
315 void GraphicsContext3D::endPaint()
316 {
317 }
318
319 bool GraphicsContext3D::isGLES2Compliant() const
320 {
321     return false;
322 }
323
324 void GraphicsContext3D::reshape(int width, int height)
325 {
326     if (width == m_currentWidth && height == m_currentHeight || !m_contextObj)
327         return;
328     
329     m_currentWidth = width;
330     m_currentHeight = height;
331     
332     CGLSetCurrentContext(m_contextObj);
333     
334     GLuint internalColorFormat, colorFormat, internalDepthStencilFormat = 0;
335     if (m_attrs.alpha) {
336         internalColorFormat = GL_RGBA8;
337         colorFormat = GL_RGBA;
338     } else {
339         internalColorFormat = GL_RGB8;
340         colorFormat = GL_RGB;
341     }
342     if (m_attrs.stencil || m_attrs.depth) {
343         // We don't allow the logic where stencil is required and depth is not.
344         // See GraphicsContext3D constructor.
345         if (m_attrs.stencil && m_attrs.depth)
346             internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
347         else
348             internalDepthStencilFormat = GL_DEPTH_COMPONENT;
349     }
350
351     bool mustRestoreFBO = false;
352
353     // resize multisample FBO
354     if (m_attrs.antialias) {
355         GLint maxSampleCount;
356         ::glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
357         GLint sampleCount = std::min(8, maxSampleCount);
358         if (sampleCount > maxSampleCount)
359             sampleCount = maxSampleCount;
360         if (m_boundFBO != m_multisampleFBO) {
361             ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
362             mustRestoreFBO = true;
363         }
364         ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
365         ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height);
366         ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
367         if (m_attrs.stencil || m_attrs.depth) {
368             ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
369             ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height);
370             if (m_attrs.stencil)
371                 ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
372             if (m_attrs.depth)
373                 ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
374         }
375         ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
376         if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
377             // FIXME: cleanup.
378             notImplemented();
379         }
380     }
381
382     // resize regular FBO
383     if (m_boundFBO != m_fbo) {
384         mustRestoreFBO = true;
385         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
386     }
387     ::glBindTexture(GL_TEXTURE_2D, m_texture);
388     ::glTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
389     ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
390     ::glBindTexture(GL_TEXTURE_2D, 0);
391     if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) {
392         ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
393         ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
394         if (m_attrs.stencil)
395             ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
396         if (m_attrs.depth)
397             ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
398         ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
399     }
400     if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
401         // FIXME: cleanup
402         notImplemented();
403     }
404
405     if (m_attrs.antialias) {
406         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
407         if (m_boundFBO == m_multisampleFBO)
408             mustRestoreFBO = false;
409     }
410
411     // Initialize renderbuffers to 0.
412     GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMask = GL_TRUE, stencilMask = GL_TRUE;
413     GLboolean isScissorEnabled = GL_FALSE;
414     GLboolean isDitherEnabled = GL_FALSE;
415     GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
416     ::glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
417     ::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
418     if (m_attrs.depth) {
419         ::glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
420         ::glDepthMask(GL_TRUE);
421         clearMask |= GL_DEPTH_BUFFER_BIT;
422     }
423     if (m_attrs.stencil) {
424         ::glGetBooleanv(GL_STENCIL_WRITEMASK, &stencilMask);
425         ::glStencilMask(GL_TRUE);
426         clearMask |= GL_STENCIL_BUFFER_BIT;
427     }
428     isScissorEnabled = ::glIsEnabled(GL_SCISSOR_TEST);
429     ::glDisable(GL_SCISSOR_TEST);
430     isDitherEnabled = ::glIsEnabled(GL_DITHER);
431     ::glDisable(GL_DITHER);
432
433     ::glClear(clearMask);
434
435     ::glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
436     if (m_attrs.depth)
437         ::glDepthMask(depthMask);
438     if (m_attrs.stencil)
439         ::glStencilMask(stencilMask);
440     if (isScissorEnabled)
441         ::glEnable(GL_SCISSOR_TEST);
442     else
443         ::glDisable(GL_SCISSOR_TEST);
444     if (isDitherEnabled)
445         ::glEnable(GL_DITHER);
446     else
447         ::glDisable(GL_DITHER);
448
449     if (mustRestoreFBO)
450         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
451
452     ::glFlush();
453 }
454
455 static inline void ensureContext(CGLContextObj context)
456 {
457     if (!context)
458         return;
459         
460     CGLContextObj currentContext = CGLGetCurrentContext();
461     if (currentContext != context)
462         CGLSetCurrentContext(context);
463 }
464
465 void GraphicsContext3D::prepareTexture()
466 {
467     ensureContext(m_contextObj);
468     if (m_attrs.antialias) {
469         ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
470         ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
471         ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
472         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
473     }
474     ::glFinish();
475 }
476
477 void GraphicsContext3D::activeTexture(unsigned long texture)
478 {
479     ensureContext(m_contextObj);
480     ::glActiveTexture(texture);
481 }
482
483 void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject shader)
484 {
485     ASSERT(program);
486     ASSERT(shader);
487     ensureContext(m_contextObj);
488     ::glAttachShader((GLuint) program, (GLuint) shader);
489 }
490
491 void GraphicsContext3D::bindAttribLocation(Platform3DObject program, unsigned long index, const String& name)
492 {
493     ASSERT(program);
494     ensureContext(m_contextObj);
495     ::glBindAttribLocation((GLuint) program, index, name.utf8().data());
496 }
497
498 void GraphicsContext3D::bindBuffer(unsigned long target, Platform3DObject buffer)
499 {
500     ensureContext(m_contextObj);
501     ::glBindBuffer(target, (GLuint) buffer);
502 }
503
504
505 void GraphicsContext3D::bindFramebuffer(unsigned long target, Platform3DObject buffer)
506 {
507     ensureContext(m_contextObj);
508     GLuint fbo;
509     if (buffer)
510         fbo = (GLuint)buffer;
511     else
512         fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo);
513     if (fbo != m_boundFBO) {
514         ::glBindFramebufferEXT(target, fbo);
515         m_boundFBO = fbo;
516     }
517 }
518
519 void GraphicsContext3D::bindRenderbuffer(unsigned long target, Platform3DObject renderbuffer)
520 {
521     ensureContext(m_contextObj);
522     ::glBindRenderbufferEXT(target, (GLuint) renderbuffer);
523 }
524
525
526 void GraphicsContext3D::bindTexture(unsigned long target, Platform3DObject texture)
527 {
528     ensureContext(m_contextObj);
529     ::glBindTexture(target, (GLuint) texture);
530 }
531
532 void GraphicsContext3D::blendColor(double red, double green, double blue, double alpha)
533 {
534     ensureContext(m_contextObj);
535     ::glBlendColor(static_cast<float>(red), static_cast<float>(green), static_cast<float>(blue), static_cast<float>(alpha));
536 }
537
538 void GraphicsContext3D::blendEquation( unsigned long mode )
539 {
540     ensureContext(m_contextObj);
541     ::glBlendEquation(mode);
542 }
543
544 void GraphicsContext3D::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha)
545 {
546     ensureContext(m_contextObj);
547     ::glBlendEquationSeparate(modeRGB, modeAlpha);
548 }
549
550
551 void GraphicsContext3D::blendFunc(unsigned long sfactor, unsigned long dfactor)
552 {
553     ensureContext(m_contextObj);
554     ::glBlendFunc(sfactor, dfactor);
555 }       
556
557 void GraphicsContext3D::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha)
558 {
559     ensureContext(m_contextObj);
560     ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
561 }
562
563 void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long usage)
564 {
565     ensureContext(m_contextObj);
566     ::glBufferData(target, size, 0, usage);
567 }
568
569 void GraphicsContext3D::bufferData(unsigned long target, ArrayBuffer* array, unsigned long usage)
570 {
571     if (!array || !array->byteLength())
572         return;
573     
574     ensureContext(m_contextObj);
575     ::glBufferData(target, array->byteLength(), array->data(), usage);
576 }
577
578 void GraphicsContext3D::bufferData(unsigned long target, ArrayBufferView* array, unsigned long usage)
579 {
580     if (!array || !array->length())
581         return;
582     
583     ensureContext(m_contextObj);
584     ::glBufferData(target, array->byteLength(), array->baseAddress(), usage);
585 }
586
587 void GraphicsContext3D::bufferSubData(unsigned long target, long offset, ArrayBuffer* array)
588 {
589     if (!array || !array->byteLength())
590         return;
591     
592     ensureContext(m_contextObj);
593     ::glBufferSubData(target, offset, array->byteLength(), array->data());
594 }
595
596 void GraphicsContext3D::bufferSubData(unsigned long target, long offset, ArrayBufferView* array)
597 {
598     if (!array || !array->length())
599         return;
600     
601     ensureContext(m_contextObj);
602     ::glBufferSubData(target, offset, array->byteLength(), array->baseAddress());
603 }
604
605 unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target)
606 {
607     ensureContext(m_contextObj);
608     return ::glCheckFramebufferStatusEXT(target);
609 }
610
611 void GraphicsContext3D::clearColor(double r, double g, double b, double a)
612 {
613     ensureContext(m_contextObj);
614     ::glClearColor(static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a));
615 }
616
617 void GraphicsContext3D::clear(unsigned long mask)
618 {
619     ensureContext(m_contextObj);
620     ::glClear(mask);
621 }
622
623 void GraphicsContext3D::clearDepth(double depth)
624 {
625     ensureContext(m_contextObj);
626     ::glClearDepth(depth);
627 }
628
629 void GraphicsContext3D::clearStencil(long s)
630 {
631     ensureContext(m_contextObj);
632     ::glClearStencil(s);
633 }
634
635 void GraphicsContext3D::colorMask(bool red, bool green, bool blue, bool alpha)
636 {
637     ensureContext(m_contextObj);
638     ::glColorMask(red, green, blue, alpha);
639 }
640
641 void GraphicsContext3D::compileShader(Platform3DObject shader)
642 {
643     ASSERT(shader);
644     ensureContext(m_contextObj);
645
646     int GLshaderType;
647     ANGLEShaderType shaderType;
648
649     glGetShaderiv(shader, SHADER_TYPE, &GLshaderType);
650     
651     if (GLshaderType == VERTEX_SHADER)
652         shaderType = SHADER_TYPE_VERTEX;
653     else if (GLshaderType == FRAGMENT_SHADER)
654         shaderType = SHADER_TYPE_FRAGMENT;
655     else
656         return; // Invalid shader type.
657
658     HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
659
660     if (result == m_shaderSourceMap.end())
661         return;
662
663     ShaderSourceEntry& entry = result->second;
664
665     String translatedShaderSource;
666     String shaderInfoLog;
667
668     bool isValid = m_compiler.validateShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog);
669
670     entry.log = shaderInfoLog;
671     entry.isValid = isValid;
672
673     if (!isValid)
674         return; // Shader didn't validate, don't move forward with compiling translated source    
675
676     int translatedShaderLength = translatedShaderSource.length();
677
678     const CString& translatedShaderCString = translatedShaderSource.utf8();
679     const char* translatedShaderPtr = translatedShaderCString.data();
680     
681     ::glShaderSource((GLuint) shader, 1, &translatedShaderPtr, &translatedShaderLength);
682     
683     ::glCompileShader((GLuint) shader);
684     
685     int GLCompileSuccess;
686     
687     ::glGetShaderiv((GLuint) shader, COMPILE_STATUS, &GLCompileSuccess);
688     
689     // ASSERT that ANGLE generated GLSL will be accepted by OpenGL
690     ASSERT(GLCompileSuccess == GL_TRUE);
691 }
692
693 void GraphicsContext3D::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border)
694 {
695     ensureContext(m_contextObj);
696     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
697         ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
698         ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
699         ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
700         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
701     }
702     ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
703     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
704         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
705 }
706
707 void GraphicsContext3D::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height)
708 {
709     ensureContext(m_contextObj);
710     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
711         ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
712         ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
713         ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
714         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
715     }
716     ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
717     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
718         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
719 }
720
721 void GraphicsContext3D::cullFace(unsigned long mode)
722 {
723     ensureContext(m_contextObj);
724     ::glCullFace(mode);
725 }
726
727 void GraphicsContext3D::depthFunc(unsigned long func)
728 {
729     ensureContext(m_contextObj);
730     ::glDepthFunc(func);
731 }
732
733 void GraphicsContext3D::depthMask(bool flag)
734 {
735     ensureContext(m_contextObj);
736     ::glDepthMask(flag);
737 }
738
739 void GraphicsContext3D::depthRange(double zNear, double zFar)
740 {
741     ensureContext(m_contextObj);
742     ::glDepthRange(zNear, zFar);
743 }
744
745 void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject shader)
746 {
747     ASSERT(program);
748     ASSERT(shader);
749     ensureContext(m_contextObj);
750     ::glDetachShader((GLuint) program, (GLuint) shader);
751 }
752
753 void GraphicsContext3D::disable(unsigned long cap)
754 {
755     ensureContext(m_contextObj);
756     ::glDisable(cap);
757 }
758
759 void GraphicsContext3D::disableVertexAttribArray(unsigned long index)
760 {
761     ensureContext(m_contextObj);
762     ::glDisableVertexAttribArray(index);
763 }
764
765 void GraphicsContext3D::drawArrays(unsigned long mode, long first, long count)
766 {
767     ensureContext(m_contextObj);
768     ::glDrawArrays(mode, first, count);
769 }
770
771 void GraphicsContext3D::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset)
772 {
773     ensureContext(m_contextObj);
774     ::glDrawElements(mode, count, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
775 }
776
777 void GraphicsContext3D::enable(unsigned long cap)
778 {
779     ensureContext(m_contextObj);
780     ::glEnable(cap);
781 }
782
783 void GraphicsContext3D::enableVertexAttribArray(unsigned long index)
784 {
785     ensureContext(m_contextObj);
786     ::glEnableVertexAttribArray(index);
787 }
788
789 void GraphicsContext3D::finish()
790 {
791     ensureContext(m_contextObj);
792     ::glFinish();
793 }
794
795 void GraphicsContext3D::flush()
796 {
797     ensureContext(m_contextObj);
798     ::glFlush();
799 }
800
801 void GraphicsContext3D::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, Platform3DObject buffer)
802 {
803     ensureContext(m_contextObj);
804     GLuint renderbuffer = (GLuint) buffer;
805     if (attachment == DEPTH_STENCIL_ATTACHMENT) {
806         ::glFramebufferRenderbufferEXT(target, DEPTH_ATTACHMENT, renderbuffertarget, renderbuffer);
807         ::glFramebufferRenderbufferEXT(target, STENCIL_ATTACHMENT, renderbuffertarget, renderbuffer);
808     } else
809         ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer);
810 }
811
812 void GraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, Platform3DObject texture, long level)
813 {
814     ensureContext(m_contextObj);
815     ::glFramebufferTexture2DEXT(target, attachment, textarget, (GLuint) texture, level);
816 }
817
818 void GraphicsContext3D::frontFace(unsigned long mode)
819 {
820     ensureContext(m_contextObj);
821     ::glFrontFace(mode);
822 }
823
824 void GraphicsContext3D::generateMipmap(unsigned long target)
825 {
826     ensureContext(m_contextObj);
827     ::glGenerateMipmapEXT(target);
828 }
829
830 bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, unsigned long index, ActiveInfo& info)
831 {
832     if (!program) {
833         synthesizeGLError(INVALID_VALUE);
834         return false;
835     }
836     ensureContext(m_contextObj);
837     GLint maxAttributeSize = 0;
838     ::glGetProgramiv(static_cast<GLuint>(program), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize);
839     GLchar name[maxAttributeSize]; // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination
840     GLsizei nameLength = 0;
841     GLint size = 0;
842     GLenum type = 0;
843     ::glGetActiveAttrib(static_cast<GLuint>(program), index, maxAttributeSize, &nameLength, &size, &type, name);
844     if (!nameLength)
845         return false;
846     info.name = String(name, nameLength);
847     info.type = type;
848     info.size = size;
849     return true;
850 }
851     
852 bool GraphicsContext3D::getActiveUniform(Platform3DObject program, unsigned long index, ActiveInfo& info)
853 {
854     if (!program) {
855         synthesizeGLError(INVALID_VALUE);
856         return false;
857     }
858     ensureContext(m_contextObj);
859     GLint maxUniformSize = 0;
860     ::glGetProgramiv(static_cast<GLuint>(program), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize);
861     GLchar name[maxUniformSize]; // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination
862     GLsizei nameLength = 0;
863     GLint size = 0;
864     GLenum type = 0;
865     ::glGetActiveUniform(static_cast<GLuint>(program), index, maxUniformSize, &nameLength, &size, &type, name);
866     if (!nameLength)
867         return false;
868     info.name = String(name, nameLength);
869     info.type = type;
870     info.size = size;
871     return true;
872 }
873
874 void GraphicsContext3D::getAttachedShaders(Platform3DObject program, int maxCount, int* count, unsigned int* shaders)
875 {
876     if (!program) {
877         synthesizeGLError(INVALID_VALUE);
878         return;
879     }
880     ensureContext(m_contextObj);
881     ::glGetAttachedShaders(static_cast<GLuint>(program), maxCount, count, shaders);
882 }
883
884 int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name)
885 {
886     if (!program)
887         return -1;
888     
889     ensureContext(m_contextObj);
890     return ::glGetAttribLocation((GLuint) program, name.utf8().data());
891 }
892
893 GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
894 {
895     return m_attrs;
896 }
897
898 unsigned long GraphicsContext3D::getError()
899 {
900     if (m_syntheticErrors.size() > 0) {
901         ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin();
902         unsigned long err = *iter;
903         m_syntheticErrors.remove(iter);
904         return err;
905     }
906
907     ensureContext(m_contextObj);
908     return ::glGetError();
909 }
910
911 String GraphicsContext3D::getString(unsigned long name)
912 {
913     ensureContext(m_contextObj);
914     return String((const char*) ::glGetString(name));
915 }
916
917 void GraphicsContext3D::hint(unsigned long target, unsigned long mode)
918 {
919     ensureContext(m_contextObj);
920     ::glHint(target, mode);
921 }
922
923 bool GraphicsContext3D::isBuffer(Platform3DObject buffer)
924 {
925     if (!buffer)
926         return false;
927     
928     ensureContext(m_contextObj);
929     return ::glIsBuffer((GLuint) buffer);
930 }
931
932 bool GraphicsContext3D::isEnabled(unsigned long cap)
933 {
934     ensureContext(m_contextObj);
935     return ::glIsEnabled(cap);
936 }
937
938 bool GraphicsContext3D::isFramebuffer(Platform3DObject framebuffer)
939 {
940     if (!framebuffer)
941         return false;
942     
943     ensureContext(m_contextObj);
944     return ::glIsFramebufferEXT((GLuint) framebuffer);
945 }
946
947 bool GraphicsContext3D::isProgram(Platform3DObject program)
948 {
949     if (!program)
950         return false;
951     
952     ensureContext(m_contextObj);
953     return ::glIsProgram((GLuint) program);
954 }
955
956 bool GraphicsContext3D::isRenderbuffer(Platform3DObject renderbuffer)
957 {
958     if (!renderbuffer)
959         return false;
960     
961     ensureContext(m_contextObj);
962     return ::glIsRenderbufferEXT((GLuint) renderbuffer);
963 }
964
965 bool GraphicsContext3D::isShader(Platform3DObject shader)
966 {
967     if (!shader)
968         return false;
969     
970     ensureContext(m_contextObj);
971     return ::glIsShader((GLuint) shader);
972 }
973
974 bool GraphicsContext3D::isTexture(Platform3DObject texture)
975 {
976     if (!texture)
977         return false;
978     
979     ensureContext(m_contextObj);
980     return ::glIsTexture((GLuint) texture);
981 }
982
983 void GraphicsContext3D::lineWidth(double width)
984 {
985     ensureContext(m_contextObj);
986     ::glLineWidth(static_cast<float>(width));
987 }
988
989 void GraphicsContext3D::linkProgram(Platform3DObject program)
990 {
991     ASSERT(program);
992     ensureContext(m_contextObj);
993     ::glLinkProgram((GLuint) program);
994 }
995
996 void GraphicsContext3D::pixelStorei(unsigned long pname, long param)
997 {
998     ensureContext(m_contextObj);
999     ::glPixelStorei(pname, param);
1000 }
1001
1002 void GraphicsContext3D::polygonOffset(double factor, double units)
1003 {
1004     ensureContext(m_contextObj);
1005     ::glPolygonOffset(static_cast<float>(factor), static_cast<float>(units));
1006 }
1007
1008 void GraphicsContext3D::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* data)
1009 {
1010     // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e.,
1011     // all previous rendering calls should be done before reading pixels.
1012     ensureContext(m_contextObj);
1013     ::glFlush();
1014     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
1015         ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
1016         ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
1017         ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
1018         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
1019         ::glFlush();
1020     }
1021     ::glReadPixels(x, y, width, height, format, type, data);
1022     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
1023         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
1024 }
1025
1026 void GraphicsContext3D::releaseShaderCompiler()
1027 {
1028     // FIXME: This is not implemented on desktop OpenGL. We need to have ifdefs for the different GL variants
1029     ensureContext(m_contextObj);
1030     //::glReleaseShaderCompiler();
1031 }
1032
1033 void GraphicsContext3D::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height)
1034 {
1035     ensureContext(m_contextObj);
1036     switch (internalformat) {
1037     case DEPTH_STENCIL:
1038         internalformat = GL_DEPTH24_STENCIL8_EXT;
1039         break;
1040     case DEPTH_COMPONENT16:
1041         internalformat = GL_DEPTH_COMPONENT;
1042         break;
1043     case RGBA4:
1044     case RGB5_A1:
1045         internalformat = GL_RGBA;
1046         break;
1047     case RGB565:
1048         internalformat = GL_RGB;
1049         break;
1050     }
1051     ::glRenderbufferStorageEXT(target, internalformat, width, height);
1052 }
1053
1054 void GraphicsContext3D::sampleCoverage(double value, bool invert)
1055 {
1056     ensureContext(m_contextObj);
1057     ::glSampleCoverage(static_cast<float>(value), invert);
1058 }
1059
1060 void GraphicsContext3D::scissor(long x, long y, unsigned long width, unsigned long height)
1061 {
1062     ensureContext(m_contextObj);
1063     ::glScissor(x, y, width, height);
1064 }
1065
1066 void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& string)
1067 {
1068     ASSERT(shader);
1069     
1070     ensureContext(m_contextObj);
1071
1072     ShaderSourceEntry entry;
1073
1074     entry.source = string;
1075
1076     m_shaderSourceMap.set(shader, entry);
1077 }
1078
1079 void GraphicsContext3D::stencilFunc(unsigned long func, long ref, unsigned long mask)
1080 {
1081     ensureContext(m_contextObj);
1082     ::glStencilFunc(func, ref, mask);
1083 }
1084
1085 void GraphicsContext3D::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask)
1086 {
1087     ensureContext(m_contextObj);
1088     ::glStencilFuncSeparate(face, func, ref, mask);
1089 }
1090
1091 void GraphicsContext3D::stencilMask(unsigned long mask)
1092 {
1093     ensureContext(m_contextObj);
1094     ::glStencilMask(mask);
1095 }
1096
1097 void GraphicsContext3D::stencilMaskSeparate(unsigned long face, unsigned long mask)
1098 {
1099     ensureContext(m_contextObj);
1100     ::glStencilMaskSeparate(face, mask);
1101 }
1102
1103 void GraphicsContext3D::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass)
1104 {
1105     ensureContext(m_contextObj);
1106     ::glStencilOp(fail, zfail, zpass);
1107 }
1108
1109 void GraphicsContext3D::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass)
1110 {
1111     ensureContext(m_contextObj);
1112     ::glStencilOpSeparate(face, fail, zfail, zpass);
1113 }
1114
1115 void GraphicsContext3D::texParameterf(unsigned target, unsigned pname, float value)
1116 {
1117     ensureContext(m_contextObj);
1118     ::glTexParameterf(target, pname, static_cast<float>(value));
1119 }
1120
1121 void GraphicsContext3D::texParameteri(unsigned target, unsigned pname, int value)
1122 {
1123     ensureContext(m_contextObj);
1124     ::glTexParameteri(target, pname, static_cast<float>(value));
1125 }
1126
1127 void GraphicsContext3D::uniform1f(long location, float v0)
1128 {
1129     ensureContext(m_contextObj);
1130     ::glUniform1f(location, v0);
1131 }
1132
1133 void GraphicsContext3D::uniform1fv(long location, float* array, int size)
1134 {
1135     ensureContext(m_contextObj);
1136     ::glUniform1fv(location, size, array);
1137 }
1138
1139 void GraphicsContext3D::uniform2f(long location, float v0, float v1)
1140 {
1141     ensureContext(m_contextObj);
1142     ::glUniform2f(location, v0, v1);
1143 }
1144
1145 void GraphicsContext3D::uniform2fv(long location, float* array, int size)
1146 {
1147     // FIXME: length needs to be a multiple of 2
1148     ensureContext(m_contextObj);
1149     ::glUniform2fv(location, size, array);
1150 }
1151
1152 void GraphicsContext3D::uniform3f(long location, float v0, float v1, float v2)
1153 {
1154     ensureContext(m_contextObj);
1155     ::glUniform3f(location, v0, v1, v2);
1156 }
1157
1158 void GraphicsContext3D::uniform3fv(long location, float* array, int size)
1159 {
1160     // FIXME: length needs to be a multiple of 3
1161     ensureContext(m_contextObj);
1162     ::glUniform3fv(location, size, array);
1163 }
1164
1165 void GraphicsContext3D::uniform4f(long location, float v0, float v1, float v2, float v3)
1166 {
1167     ensureContext(m_contextObj);
1168     ::glUniform4f(location, v0, v1, v2, v3);
1169 }
1170
1171 void GraphicsContext3D::uniform4fv(long location, float* array, int size)
1172 {
1173     // FIXME: length needs to be a multiple of 4
1174     ensureContext(m_contextObj);
1175     ::glUniform4fv(location, size, array);
1176 }
1177
1178 void GraphicsContext3D::uniform1i(long location, int v0)
1179 {
1180     ensureContext(m_contextObj);
1181     ::glUniform1i(location, v0);
1182 }
1183
1184 void GraphicsContext3D::uniform1iv(long location, int* array, int size)
1185 {
1186     ensureContext(m_contextObj);
1187     ::glUniform1iv(location, size, array);
1188 }
1189
1190 void GraphicsContext3D::uniform2i(long location, int v0, int v1)
1191 {
1192     ensureContext(m_contextObj);
1193     ::glUniform2i(location, v0, v1);
1194 }
1195
1196 void GraphicsContext3D::uniform2iv(long location, int* array, int size)
1197 {
1198     // FIXME: length needs to be a multiple of 2
1199     ensureContext(m_contextObj);
1200     ::glUniform2iv(location, size, array);
1201 }
1202
1203 void GraphicsContext3D::uniform3i(long location, int v0, int v1, int v2)
1204 {
1205     ensureContext(m_contextObj);
1206     ::glUniform3i(location, v0, v1, v2);
1207 }
1208
1209 void GraphicsContext3D::uniform3iv(long location, int* array, int size)
1210 {
1211     // FIXME: length needs to be a multiple of 3
1212     ensureContext(m_contextObj);
1213     ::glUniform3iv(location, size, array);
1214 }
1215
1216 void GraphicsContext3D::uniform4i(long location, int v0, int v1, int v2, int v3)
1217 {
1218     ensureContext(m_contextObj);
1219     ::glUniform4i(location, v0, v1, v2, v3);
1220 }
1221
1222 void GraphicsContext3D::uniform4iv(long location, int* array, int size)
1223 {
1224     // FIXME: length needs to be a multiple of 4
1225     ensureContext(m_contextObj);
1226     ::glUniform4iv(location, size, array);
1227 }
1228
1229 void GraphicsContext3D::uniformMatrix2fv(long location, bool transpose, float* array, int size)
1230 {
1231     // FIXME: length needs to be a multiple of 4
1232     ensureContext(m_contextObj);
1233     ::glUniformMatrix2fv(location, size, transpose, array);
1234 }
1235
1236 void GraphicsContext3D::uniformMatrix3fv(long location, bool transpose, float* array, int size)
1237 {
1238     // FIXME: length needs to be a multiple of 9
1239     ensureContext(m_contextObj);
1240     ::glUniformMatrix3fv(location, size, transpose, array);
1241 }
1242
1243 void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* array, int size)
1244 {
1245     // FIXME: length needs to be a multiple of 16
1246     ensureContext(m_contextObj);
1247     ::glUniformMatrix4fv(location, size, transpose, array);
1248 }
1249
1250 void GraphicsContext3D::useProgram(Platform3DObject program)
1251 {
1252     ensureContext(m_contextObj);
1253     ::glUseProgram((GLuint) program);
1254 }
1255
1256 void GraphicsContext3D::validateProgram(Platform3DObject program)
1257 {
1258     ASSERT(program);
1259     
1260     ensureContext(m_contextObj);
1261     ::glValidateProgram((GLuint) program);
1262 }
1263
1264 void GraphicsContext3D::vertexAttrib1f(unsigned long indx, float v0)
1265 {
1266     ensureContext(m_contextObj);
1267     ::glVertexAttrib1f(indx, v0);
1268 }
1269
1270 void GraphicsContext3D::vertexAttrib1fv(unsigned long indx, float* array)
1271 {
1272     ensureContext(m_contextObj);
1273     ::glVertexAttrib1fv(indx, array);
1274 }
1275
1276 void GraphicsContext3D::vertexAttrib2f(unsigned long indx, float v0, float v1)
1277 {
1278     ensureContext(m_contextObj);
1279     ::glVertexAttrib2f(indx, v0, v1);
1280 }
1281
1282 void GraphicsContext3D::vertexAttrib2fv(unsigned long indx, float* array)
1283 {
1284     ensureContext(m_contextObj);
1285     ::glVertexAttrib2fv(indx, array);
1286 }
1287
1288 void GraphicsContext3D::vertexAttrib3f(unsigned long indx, float v0, float v1, float v2)
1289 {
1290     ensureContext(m_contextObj);
1291     ::glVertexAttrib3f(indx, v0, v1, v2);
1292 }
1293
1294 void GraphicsContext3D::vertexAttrib3fv(unsigned long indx, float* array)
1295 {
1296     ensureContext(m_contextObj);
1297     ::glVertexAttrib3fv(indx, array);
1298 }
1299
1300 void GraphicsContext3D::vertexAttrib4f(unsigned long indx, float v0, float v1, float v2, float v3)
1301 {
1302     ensureContext(m_contextObj);
1303     ::glVertexAttrib4f(indx, v0, v1, v2, v3);
1304 }
1305
1306 void GraphicsContext3D::vertexAttrib4fv(unsigned long indx, float* array)
1307 {
1308     ensureContext(m_contextObj);
1309     ::glVertexAttrib4fv(indx, array);
1310 }
1311
1312 void GraphicsContext3D::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, unsigned long stride, unsigned long offset)
1313 {
1314     ensureContext(m_contextObj);
1315     ::glVertexAttribPointer(indx, size, type, normalized, stride, reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
1316 }
1317
1318 void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height)
1319 {
1320     ensureContext(m_contextObj);
1321     ::glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
1322 }
1323
1324 void GraphicsContext3D::getBooleanv(unsigned long pname, unsigned char* value)
1325 {
1326     ensureContext(m_contextObj);
1327     ::glGetBooleanv(pname, value);
1328 }
1329
1330 void GraphicsContext3D::getBufferParameteriv(unsigned long target, unsigned long pname, int* value)
1331 {
1332     ensureContext(m_contextObj);
1333     ::glGetBufferParameteriv(target, pname, value);
1334 }
1335
1336 void GraphicsContext3D::getFloatv(unsigned long pname, float* value)
1337 {
1338     ensureContext(m_contextObj);
1339     ::glGetFloatv(pname, value);
1340 }
1341
1342 void GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname, int* value)
1343 {
1344     ensureContext(m_contextObj);
1345     if (attachment == DEPTH_STENCIL_ATTACHMENT)
1346         attachment = DEPTH_ATTACHMENT; // Or STENCIL_ATTACHMENT, either works.
1347     ::glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value);
1348 }
1349
1350 void GraphicsContext3D::getIntegerv(unsigned long pname, int* value)
1351 {
1352     // Need to emulate IMPLEMENTATION_COLOR_READ_FORMAT/TYPE for GL.  Any valid
1353     // combination should work, but GL_RGB/GL_UNSIGNED_BYTE might be the most
1354     // useful for desktop WebGL users.
1355     // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS
1356     // because desktop GL's corresponding queries return the number of components
1357     // whereas GLES2 return the number of vectors (each vector has 4 components).
1358     // Therefore, the value returned by desktop GL needs to be divided by 4.
1359     ensureContext(m_contextObj);
1360     switch (pname) {
1361     case IMPLEMENTATION_COLOR_READ_FORMAT:
1362         *value = GL_RGB;
1363         break;
1364     case IMPLEMENTATION_COLOR_READ_TYPE:
1365         *value = GL_UNSIGNED_BYTE;
1366         break;
1367     case MAX_FRAGMENT_UNIFORM_VECTORS:
1368         ::glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value);
1369         *value /= 4;
1370         break;
1371     case MAX_VERTEX_UNIFORM_VECTORS:
1372         ::glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value);
1373         *value /= 4;
1374         break;
1375     case MAX_VARYING_VECTORS:
1376         ::glGetIntegerv(GL_MAX_VARYING_FLOATS, value);
1377         *value /= 4;
1378         break;
1379     default:
1380         ::glGetIntegerv(pname, value);
1381     }
1382 }
1383
1384 void GraphicsContext3D::getProgramiv(Platform3DObject program, unsigned long pname, int* value)
1385 {
1386     ensureContext(m_contextObj);
1387     ::glGetProgramiv((GLuint) program, pname, value);
1388 }
1389
1390 String GraphicsContext3D::getProgramInfoLog(Platform3DObject program)
1391 {
1392     ASSERT(program);
1393     
1394     ensureContext(m_contextObj);
1395     GLint length;
1396     ::glGetProgramiv((GLuint) program, GL_INFO_LOG_LENGTH, &length);
1397     
1398     GLsizei size;
1399     GLchar* info = (GLchar*) fastMalloc(length);
1400     if (!info)
1401         return "";
1402
1403     ::glGetProgramInfoLog((GLuint) program, length, &size, info);
1404     String s(info);
1405     fastFree(info);
1406     return s;
1407 }
1408
1409 void GraphicsContext3D::getRenderbufferParameteriv(unsigned long target, unsigned long pname, int* value)
1410 {
1411     ensureContext(m_contextObj);
1412     ::glGetRenderbufferParameterivEXT(target, pname, value);
1413 }
1414
1415 void GraphicsContext3D::getShaderiv(Platform3DObject shader, unsigned long pname, int* value)
1416 {
1417     ASSERT(shader);
1418     
1419     ensureContext(m_contextObj);
1420     
1421     HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
1422     
1423     switch (pname) {
1424         case DELETE_STATUS:
1425         case SHADER_TYPE:
1426             // Let OpenGL handle these.
1427         
1428             ::glGetShaderiv((GLuint) shader, pname, value);
1429             break;
1430
1431         case COMPILE_STATUS:
1432             if (result == m_shaderSourceMap.end()) {
1433                 (*value) = static_cast<int>(false);
1434                 return;
1435             }
1436                 
1437             (*value) = static_cast<int>(result->second.isValid);
1438             break;
1439             
1440         case INFO_LOG_LENGTH:
1441             if (result == m_shaderSourceMap.end()) {
1442                 (*value) = 0;
1443                 return;
1444             }
1445             
1446             (*value) = getShaderInfoLog(shader).length();
1447             break;
1448             
1449         case SHADER_SOURCE_LENGTH:
1450             (*value) = getShaderSource(shader).length();
1451             break;
1452         
1453         default:
1454             synthesizeGLError(INVALID_ENUM);
1455     }
1456 }
1457
1458 String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader)
1459 {
1460     ASSERT(shader);
1461
1462     ensureContext(m_contextObj);
1463     GLint length;
1464     ::glGetShaderiv((GLuint) shader, GL_INFO_LOG_LENGTH, &length);
1465
1466     HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
1467
1468     if (result == m_shaderSourceMap.end())
1469          return "";
1470
1471      ShaderSourceEntry entry = result->second;
1472
1473      if (entry.isValid) {
1474          GLint length;
1475          ::glGetShaderiv((GLuint) shader, GL_INFO_LOG_LENGTH, &length);
1476
1477          GLsizei size;
1478          GLchar* info = (GLchar*) fastMalloc(length);
1479          if (!info)
1480              return "";
1481
1482          ::glGetShaderInfoLog((GLuint) shader, length, &size, info);
1483
1484          String s(info);
1485          fastFree(info);
1486          return s;
1487      }
1488      else {
1489          return entry.log;
1490      }
1491 }
1492
1493 String GraphicsContext3D::getShaderSource(Platform3DObject shader)
1494 {
1495     ASSERT(shader);
1496
1497     ensureContext(m_contextObj);
1498
1499     HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
1500
1501     if (result == m_shaderSourceMap.end())
1502         return "";
1503
1504     return result->second.source;
1505 }
1506
1507
1508 void GraphicsContext3D::getTexParameterfv(unsigned long target, unsigned long pname, float* value)
1509 {
1510     ensureContext(m_contextObj);
1511     ::glGetTexParameterfv(target, pname, value);
1512 }
1513
1514 void GraphicsContext3D::getTexParameteriv(unsigned long target, unsigned long pname, int* value)
1515 {
1516     ensureContext(m_contextObj);
1517     ::glGetTexParameteriv(target, pname, value);
1518 }
1519
1520 void GraphicsContext3D::getUniformfv(Platform3DObject program, long location, float* value)
1521 {
1522     ensureContext(m_contextObj);
1523     ::glGetUniformfv((GLuint) program, location, value);
1524 }
1525
1526 void GraphicsContext3D::getUniformiv(Platform3DObject program, long location, int* value)
1527 {
1528     ensureContext(m_contextObj);
1529     ::glGetUniformiv((GLuint) program, location, value);
1530 }
1531
1532 long GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name)
1533 {
1534     ASSERT(program);
1535     
1536     ensureContext(m_contextObj);
1537     return ::glGetUniformLocation((GLuint) program, name.utf8().data());
1538 }
1539
1540 void GraphicsContext3D::getVertexAttribfv(unsigned long index, unsigned long pname, float* value)
1541 {
1542     ensureContext(m_contextObj);
1543     ::glGetVertexAttribfv(index, pname, value);
1544 }
1545
1546 void GraphicsContext3D::getVertexAttribiv(unsigned long index, unsigned long pname, int* value)
1547 {
1548     ensureContext(m_contextObj);
1549     ::glGetVertexAttribiv(index, pname, value);
1550 }
1551
1552 long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long pname)
1553 {
1554     ensureContext(m_contextObj);
1555     
1556     void* pointer;
1557     ::glGetVertexAttribPointerv(index, pname, &pointer);
1558     return reinterpret_cast<long>(pointer);
1559 }
1560
1561 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels)
1562 {
1563     ensureContext(m_contextObj);
1564
1565     ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
1566     return 0;
1567 }
1568
1569 int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels)
1570 {
1571     ensureContext(m_contextObj);
1572
1573     // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size
1574     ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
1575     return 0;
1576 }
1577
1578 unsigned GraphicsContext3D::createBuffer()
1579 {
1580     ensureContext(m_contextObj);
1581     GLuint o;
1582     glGenBuffers(1, &o);
1583     return o;
1584 }
1585
1586 unsigned GraphicsContext3D::createFramebuffer()
1587 {
1588     ensureContext(m_contextObj);
1589     GLuint o;
1590     glGenFramebuffersEXT(1, &o);
1591     return o;
1592 }
1593
1594 unsigned GraphicsContext3D::createProgram()
1595 {
1596     ensureContext(m_contextObj);
1597     return glCreateProgram();
1598 }
1599
1600 unsigned GraphicsContext3D::createRenderbuffer()
1601 {
1602     ensureContext(m_contextObj);
1603     GLuint o;
1604     glGenRenderbuffersEXT(1, &o);
1605     return o;
1606 }
1607
1608 unsigned GraphicsContext3D::createShader(unsigned long type)
1609 {
1610     ensureContext(m_contextObj);
1611     return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER);
1612 }
1613
1614 unsigned GraphicsContext3D::createTexture()
1615 {
1616     ensureContext(m_contextObj);
1617     GLuint o;
1618     glGenTextures(1, &o);
1619     return o;
1620 }
1621
1622 void GraphicsContext3D::deleteBuffer(unsigned buffer)
1623 {
1624     ensureContext(m_contextObj);
1625     glDeleteBuffers(1, &buffer);
1626 }
1627
1628 void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer)
1629 {
1630     ensureContext(m_contextObj);
1631     glDeleteFramebuffersEXT(1, &framebuffer);
1632 }
1633
1634 void GraphicsContext3D::deleteProgram(unsigned program)
1635 {
1636     ensureContext(m_contextObj);
1637     glDeleteProgram(program);
1638 }
1639
1640 void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer)
1641 {
1642     ensureContext(m_contextObj);
1643     glDeleteRenderbuffersEXT(1, &renderbuffer);
1644 }
1645
1646 void GraphicsContext3D::deleteShader(unsigned shader)
1647 {
1648     ensureContext(m_contextObj);
1649     glDeleteShader(shader);
1650 }
1651
1652 void GraphicsContext3D::deleteTexture(unsigned texture)
1653 {
1654     ensureContext(m_contextObj);
1655     glDeleteTextures(1, &texture);
1656 }
1657
1658 int GraphicsContext3D::sizeInBytes(int type)
1659 {
1660     switch (type) {
1661         case GL_BYTE:
1662             return sizeof(GLbyte);
1663         case GL_UNSIGNED_BYTE:
1664             return sizeof(GLubyte);
1665         case GL_SHORT:
1666             return sizeof(GLshort);
1667         case GL_UNSIGNED_SHORT:
1668             return sizeof(GLushort);
1669         case GL_INT:
1670             return sizeof(GLint);
1671         case GL_UNSIGNED_INT:
1672             return sizeof(GLuint);
1673         case GL_FLOAT:
1674             return sizeof(GLfloat);
1675         default:
1676             return 0;
1677     }
1678 }
1679
1680 void GraphicsContext3D::synthesizeGLError(unsigned long error)
1681 {
1682     m_syntheticErrors.add(error);
1683 }
1684
1685 }
1686
1687 #endif // ENABLE(3D_CANVAS)