Replace use of OwnArrayPtr<Foo> with std::unique_ptr<Foo[]> in WebCore
[WebKit-https.git] / Source / WebCore / platform / graphics / opengl / GraphicsContext3DOpenGLCommon.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2011 Google Inc. All rights reserved.
4  * Copyright (C) 2012 ChangSeok Oh <shivamidow@gmail.com>
5  * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
27  */
28
29 #include "config.h"
30
31 #if USE(3D_GRAPHICS)
32
33 #include "GraphicsContext3D.h"
34
35 #if USE(OPENGL_ES_2)
36 #include "Extensions3DOpenGLES.h"
37 #else
38 #include "Extensions3DOpenGL.h"
39 #endif
40 #include "GraphicsContext.h"
41 #include "ImageBuffer.h"
42 #include "ImageData.h"
43 #include "IntRect.h"
44 #include "IntSize.h"
45 #include "NotImplemented.h"
46 #include <cstring>
47 #include <runtime/ArrayBuffer.h>
48 #include <runtime/ArrayBufferView.h>
49 #include <runtime/Float32Array.h>
50 #include <runtime/Int32Array.h>
51 #include <runtime/Uint8Array.h>
52 #include <wtf/MainThread.h>
53 #include <wtf/text/CString.h>
54
55 #if USE(OPENGL_ES_2)
56 #include "OpenGLESShims.h"
57 #elif PLATFORM(MAC)
58 #include <OpenGL/gl.h>
59 #elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(QT) || PLATFORM(WIN) || PLATFORM(NIX)
60 #include "OpenGLShims.h"
61 #endif
62
63 #if PLATFORM(BLACKBERRY)
64 #include <BlackBerryPlatformLog.h>
65 #endif
66
67 namespace WebCore {
68
69 PassRefPtr<GraphicsContext3D> GraphicsContext3D::createForCurrentGLContext()
70 {
71     RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(Attributes(), 0, GraphicsContext3D::RenderToCurrentGLContext));
72     return context->m_private ? context.release() : 0;
73 }
74
75 void GraphicsContext3D::validateDepthStencil(const char* packedDepthStencilExtension)
76 {
77     Extensions3D* extensions = getExtensions();
78     if (m_attrs.stencil) {
79         if (extensions->supports(packedDepthStencilExtension)) {
80             extensions->ensureEnabled(packedDepthStencilExtension);
81             // Force depth if stencil is true.
82             m_attrs.depth = true;
83         } else
84             m_attrs.stencil = false;
85     }
86     if (m_attrs.antialias) {
87         if (!extensions->maySupportMultisampling() || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
88             m_attrs.antialias = false;
89         else
90             extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");
91     }
92 }
93
94 bool GraphicsContext3D::isResourceSafe()
95 {
96     return false;
97 }
98
99 void GraphicsContext3D::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer, DrawingBuffer*)
100 {
101     int rowBytes = m_currentWidth * 4;
102     int totalBytes = rowBytes * m_currentHeight;
103
104     auto pixels = std::make_unique<unsigned char[]>(totalBytes);
105     if (!pixels)
106         return;
107
108     readRenderingResults(pixels.get(), totalBytes);
109
110     if (!m_attrs.premultipliedAlpha) {
111         for (int i = 0; i < totalBytes; i += 4) {
112             // Premultiply alpha.
113             pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255);
114             pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255);
115             pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255);
116         }
117     }
118
119 #if PLATFORM(BLACKBERRY) || USE(CG)
120     paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight,
121                   imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context());
122 #else
123     paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight,
124                   imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context()->platformContext());
125 #endif
126 }
127
128 bool GraphicsContext3D::paintCompositedResultsToCanvas(ImageBuffer*)
129 {
130     // Not needed at the moment, so return that nothing was done.
131     return false;
132 }
133
134 PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData(DrawingBuffer*)
135 {
136     // Reading premultiplied alpha would involve unpremultiplying, which is
137     // lossy.
138     if (m_attrs.premultipliedAlpha)
139         return 0;
140
141     RefPtr<ImageData> imageData = ImageData::create(IntSize(m_currentWidth, m_currentHeight));
142     unsigned char* pixels = imageData->data()->data();
143     int totalBytes = 4 * m_currentWidth * m_currentHeight;
144
145     readRenderingResults(pixels, totalBytes);
146
147     // Convert to RGBA.
148     for (int i = 0; i < totalBytes; i += 4)
149         std::swap(pixels[i], pixels[i + 2]);
150
151     return imageData.release();
152 }
153
154 #if !PLATFORM(BLACKBERRY)
155 void GraphicsContext3D::prepareTexture()
156 {
157     if (m_layerComposited)
158         return;
159
160     makeContextCurrent();
161     if (m_attrs.antialias)
162         resolveMultisamplingIfNecessary();
163
164     ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
165     ::glActiveTexture(GL_TEXTURE0);
166     ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
167     ::glCopyTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, 0, 0, m_currentWidth, m_currentHeight, 0);
168     ::glBindTexture(GL_TEXTURE_2D, m_state.boundTexture0);
169     ::glActiveTexture(m_state.activeTexture);
170     if (m_state.boundFBO != m_fbo)
171         ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO);
172     ::glFinish();
173     m_layerComposited = true;
174 }
175 #endif
176
177 void GraphicsContext3D::readRenderingResults(unsigned char *pixels, int pixelsSize)
178 {
179     if (pixelsSize < m_currentWidth * m_currentHeight * 4)
180         return;
181
182     makeContextCurrent();
183
184     bool mustRestoreFBO = false;
185     if (m_attrs.antialias) {
186         resolveMultisamplingIfNecessary();
187         ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
188         mustRestoreFBO = true;
189     } else {
190         if (m_state.boundFBO != m_fbo) {
191             mustRestoreFBO = true;
192             ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
193         }
194     }
195
196     GLint packAlignment = 4;
197     bool mustRestorePackAlignment = false;
198     ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment);
199     if (packAlignment > 4) {
200         ::glPixelStorei(GL_PACK_ALIGNMENT, 4);
201         mustRestorePackAlignment = true;
202     }
203
204     readPixelsAndConvertToBGRAIfNecessary(0, 0, m_currentWidth, m_currentHeight, pixels);
205
206     if (mustRestorePackAlignment)
207         ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment);
208
209     if (mustRestoreFBO)
210         ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO);
211 }
212
213 void GraphicsContext3D::reshape(int width, int height)
214 {
215     if (!platformGraphicsContext3D())
216         return;
217
218     if (width == m_currentWidth && height == m_currentHeight)
219         return;
220
221 #if (PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(NIX)) && USE(GRAPHICS_SURFACE)
222     ::glFlush(); // Make sure all GL calls have been committed before resizing.
223     createGraphicsSurfaces(IntSize(width, height));
224 #endif
225
226     m_currentWidth = width;
227     m_currentHeight = height;
228
229     makeContextCurrent();
230     validateAttributes();
231
232     bool mustRestoreFBO = reshapeFBOs(IntSize(width, height));
233
234     // Initialize renderbuffers to 0.
235     GLfloat clearColor[] = {0, 0, 0, 0}, clearDepth = 0;
236     GLint clearStencil = 0;
237     GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMask = GL_TRUE;
238     GLuint stencilMask = 0xffffffff;
239     GLboolean isScissorEnabled = GL_FALSE;
240     GLboolean isDitherEnabled = GL_FALSE;
241     GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
242     ::glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
243     ::glClearColor(0, 0, 0, 0);
244     ::glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
245     ::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
246     if (m_attrs.depth) {
247         ::glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
248         GraphicsContext3D::clearDepth(1);
249         ::glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
250         ::glDepthMask(GL_TRUE);
251         clearMask |= GL_DEPTH_BUFFER_BIT;
252     }
253     if (m_attrs.stencil) {
254         ::glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil);
255         ::glClearStencil(0);
256         ::glGetIntegerv(GL_STENCIL_WRITEMASK, reinterpret_cast<GLint*>(&stencilMask));
257         ::glStencilMaskSeparate(GL_FRONT, 0xffffffff);
258         clearMask |= GL_STENCIL_BUFFER_BIT;
259     }
260     isScissorEnabled = ::glIsEnabled(GL_SCISSOR_TEST);
261     ::glDisable(GL_SCISSOR_TEST);
262     isDitherEnabled = ::glIsEnabled(GL_DITHER);
263     ::glDisable(GL_DITHER);
264
265     ::glClear(clearMask);
266
267     ::glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
268     ::glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
269     if (m_attrs.depth) {
270         GraphicsContext3D::clearDepth(clearDepth);
271         ::glDepthMask(depthMask);
272     }
273     if (m_attrs.stencil) {
274         ::glClearStencil(clearStencil);
275         ::glStencilMaskSeparate(GL_FRONT, stencilMask);
276     }
277     if (isScissorEnabled)
278         ::glEnable(GL_SCISSOR_TEST);
279     else
280         ::glDisable(GL_SCISSOR_TEST);
281     if (isDitherEnabled)
282         ::glEnable(GL_DITHER);
283     else
284         ::glDisable(GL_DITHER);
285
286     if (mustRestoreFBO)
287         ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO);
288
289     ::glFlush();
290 }
291
292 IntSize GraphicsContext3D::getInternalFramebufferSize() const
293 {
294     return IntSize(m_currentWidth, m_currentHeight);
295 }
296
297 void GraphicsContext3D::activeTexture(GC3Denum texture)
298 {
299     makeContextCurrent();
300     m_state.activeTexture = texture;
301     ::glActiveTexture(texture);
302 }
303
304 void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject shader)
305 {
306     ASSERT(program);
307     ASSERT(shader);
308     makeContextCurrent();
309     ::glAttachShader(program, shader);
310 }
311
312 void GraphicsContext3D::bindAttribLocation(Platform3DObject program, GC3Duint index, const String& name)
313 {
314     ASSERT(program);
315     makeContextCurrent();
316     ::glBindAttribLocation(program, index, name.utf8().data());
317 }
318
319 void GraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer)
320 {
321     makeContextCurrent();
322     ::glBindBuffer(target, buffer);
323 }
324
325 void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject buffer)
326 {
327     makeContextCurrent();
328     GLuint fbo;
329     if (buffer)
330         fbo = buffer;
331     else
332 #if PLATFORM(BLACKBERRY)
333         fbo = m_fbo;
334 #else
335         fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo);
336 #endif
337     if (fbo != m_state.boundFBO) {
338         ::glBindFramebufferEXT(target, fbo);
339         m_state.boundFBO = fbo;
340     }
341 }
342
343 void GraphicsContext3D::bindRenderbuffer(GC3Denum target, Platform3DObject renderbuffer)
344 {
345     makeContextCurrent();
346     ::glBindRenderbufferEXT(target, renderbuffer);
347 }
348
349
350 void GraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture)
351 {
352     makeContextCurrent();
353     if (m_state.activeTexture == GL_TEXTURE0 && target == GL_TEXTURE_2D)
354         m_state.boundTexture0 = texture;
355     ::glBindTexture(target, texture);
356 }
357
358 void GraphicsContext3D::blendColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha)
359 {
360     makeContextCurrent();
361     ::glBlendColor(red, green, blue, alpha);
362 }
363
364 void GraphicsContext3D::blendEquation(GC3Denum mode)
365 {
366     makeContextCurrent();
367     ::glBlendEquation(mode);
368 }
369
370 void GraphicsContext3D::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
371 {
372     makeContextCurrent();
373     ::glBlendEquationSeparate(modeRGB, modeAlpha);
374 }
375
376
377 void GraphicsContext3D::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
378 {
379     makeContextCurrent();
380     ::glBlendFunc(sfactor, dfactor);
381 }       
382
383 void GraphicsContext3D::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
384 {
385     makeContextCurrent();
386     ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
387 }
388
389 void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage)
390 {
391     makeContextCurrent();
392     ::glBufferData(target, size, 0, usage);
393 }
394
395 void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage)
396 {
397     makeContextCurrent();
398     ::glBufferData(target, size, data, usage);
399 }
400
401 void GraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data)
402 {
403     makeContextCurrent();
404     ::glBufferSubData(target, offset, size, data);
405 }
406
407 GC3Denum GraphicsContext3D::checkFramebufferStatus(GC3Denum target)
408 {
409     makeContextCurrent();
410     return ::glCheckFramebufferStatusEXT(target);
411 }
412
413 void GraphicsContext3D::clearColor(GC3Dclampf r, GC3Dclampf g, GC3Dclampf b, GC3Dclampf a)
414 {
415     makeContextCurrent();
416     ::glClearColor(r, g, b, a);
417 }
418
419 void GraphicsContext3D::clear(GC3Dbitfield mask)
420 {
421     makeContextCurrent();
422     ::glClear(mask);
423 }
424
425 void GraphicsContext3D::clearStencil(GC3Dint s)
426 {
427     makeContextCurrent();
428     ::glClearStencil(s);
429 }
430
431 void GraphicsContext3D::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha)
432 {
433     makeContextCurrent();
434     ::glColorMask(red, green, blue, alpha);
435 }
436
437 void GraphicsContext3D::compileShader(Platform3DObject shader)
438 {
439     ASSERT(shader);
440     makeContextCurrent();
441
442     String translatedShaderSource = m_extensions->getTranslatedShaderSourceANGLE(shader);
443
444     if (!translatedShaderSource.length())
445         return;
446
447     const CString& translatedShaderCString = translatedShaderSource.utf8();
448     const char* translatedShaderPtr = translatedShaderCString.data();
449     int translatedShaderLength = translatedShaderCString.length();
450     
451     ::glShaderSource(shader, 1, &translatedShaderPtr, &translatedShaderLength);
452     
453     ::glCompileShader(shader);
454     
455     int GLCompileSuccess;
456     
457     ::glGetShaderiv(shader, COMPILE_STATUS, &GLCompileSuccess);
458
459     // Populate the shader log
460     GLint length = 0;
461     ::glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
462
463     if (length) {
464         ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
465         GraphicsContext3D::ShaderSourceEntry& entry = result->value;
466
467         GLsizei size = 0;
468         auto info = std::make_unique<GLchar[]>(length);
469         ::glGetShaderInfoLog(shader, length, &size, info.get());
470
471         entry.log = info.get();
472     }
473     
474     // ASSERT that ANGLE generated GLSL will be accepted by OpenGL.
475     ASSERT(GLCompileSuccess == GL_TRUE);
476 #if PLATFORM(BLACKBERRY) && !defined(NDEBUG)
477     if (GLCompileSuccess != GL_TRUE)
478         BBLOG(BlackBerry::Platform::LogLevelWarn, "The shader validated, but didn't compile.\n");
479 #endif
480 }
481
482 void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
483 {
484     makeContextCurrent();
485 #if !PLATFORM(BLACKBERRY)
486     if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO) {
487         resolveMultisamplingIfNecessary(IntRect(x, y, width, height));
488         ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
489     }
490 #endif
491     ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
492 #if !PLATFORM(BLACKBERRY)
493     if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO)
494         ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
495 #endif
496 }
497
498 void GraphicsContext3D::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
499 {
500     makeContextCurrent();
501 #if !PLATFORM(BLACKBERRY)
502     if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO) {
503         resolveMultisamplingIfNecessary(IntRect(x, y, width, height));
504         ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
505     }
506 #endif
507     ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
508 #if !PLATFORM(BLACKBERRY)
509     if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO)
510         ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
511 #endif
512 }
513
514 void GraphicsContext3D::cullFace(GC3Denum mode)
515 {
516     makeContextCurrent();
517     ::glCullFace(mode);
518 }
519
520 void GraphicsContext3D::depthFunc(GC3Denum func)
521 {
522     makeContextCurrent();
523     ::glDepthFunc(func);
524 }
525
526 void GraphicsContext3D::depthMask(GC3Dboolean flag)
527 {
528     makeContextCurrent();
529     ::glDepthMask(flag);
530 }
531
532 void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject shader)
533 {
534     ASSERT(program);
535     ASSERT(shader);
536     makeContextCurrent();
537     ::glDetachShader(program, shader);
538 }
539
540 void GraphicsContext3D::disable(GC3Denum cap)
541 {
542     makeContextCurrent();
543     ::glDisable(cap);
544 }
545
546 void GraphicsContext3D::disableVertexAttribArray(GC3Duint index)
547 {
548     makeContextCurrent();
549     ::glDisableVertexAttribArray(index);
550 }
551
552 void GraphicsContext3D::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
553 {
554     makeContextCurrent();
555     ::glDrawArrays(mode, first, count);
556 }
557
558 void GraphicsContext3D::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset)
559 {
560     makeContextCurrent();
561     ::glDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)));
562 }
563
564 void GraphicsContext3D::enable(GC3Denum cap)
565 {
566     makeContextCurrent();
567     ::glEnable(cap);
568 }
569
570 void GraphicsContext3D::enableVertexAttribArray(GC3Duint index)
571 {
572     makeContextCurrent();
573     ::glEnableVertexAttribArray(index);
574 }
575
576 void GraphicsContext3D::finish()
577 {
578     makeContextCurrent();
579     ::glFinish();
580 }
581
582 void GraphicsContext3D::flush()
583 {
584     makeContextCurrent();
585     ::glFlush();
586 }
587
588 void GraphicsContext3D::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, Platform3DObject buffer)
589 {
590     makeContextCurrent();
591     ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, buffer);
592 }
593
594 void GraphicsContext3D::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, Platform3DObject texture, GC3Dint level)
595 {
596     makeContextCurrent();
597     ::glFramebufferTexture2DEXT(target, attachment, textarget, texture, level);
598 }
599
600 void GraphicsContext3D::frontFace(GC3Denum mode)
601 {
602     makeContextCurrent();
603     ::glFrontFace(mode);
604 }
605
606 void GraphicsContext3D::generateMipmap(GC3Denum target)
607 {
608     makeContextCurrent();
609     ::glGenerateMipmapEXT(target);
610 }
611
612 bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info)
613 {
614     if (!program) {
615         synthesizeGLError(INVALID_VALUE);
616         return false;
617     }
618     makeContextCurrent();
619     GLint maxAttributeSize = 0;
620     ::glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize);
621     auto name = std::make_unique<GLchar[]>(maxAttributeSize); // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination.
622     GLsizei nameLength = 0;
623     GLint size = 0;
624     GLenum type = 0;
625     ::glGetActiveAttrib(program, index, maxAttributeSize, &nameLength, &size, &type, name.get());
626     if (!nameLength)
627         return false;
628     
629     String originalName = originalSymbolName(program, SHADER_SYMBOL_TYPE_ATTRIBUTE, String(name.get(), nameLength));
630     
631     info.name = originalName;
632     info.type = type;
633     info.size = size;
634     return true;
635 }
636
637 bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
638 {
639     if (!program) {
640         synthesizeGLError(INVALID_VALUE);
641         return false;
642     }
643
644     makeContextCurrent();
645     GLint maxUniformSize = 0;
646     ::glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize);
647
648     auto name = std::make_unique<GLchar[]>(maxUniformSize); // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination.
649     GLsizei nameLength = 0;
650     GLint size = 0;
651     GLenum type = 0;
652     ::glGetActiveUniform(program, index, maxUniformSize, &nameLength, &size, &type, name.get());
653     if (!nameLength)
654         return false;
655     
656     String originalName = originalSymbolName(program, SHADER_SYMBOL_TYPE_UNIFORM, String(name.get(), nameLength));
657     
658     info.name = originalName;
659     info.type = type;
660     info.size = size;
661     return true;
662 }
663     
664 void GraphicsContext3D::getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount, GC3Dsizei* count, Platform3DObject* shaders)
665 {
666     if (!program) {
667         synthesizeGLError(INVALID_VALUE);
668         return;
669     }
670     makeContextCurrent();
671     ::glGetAttachedShaders(program, maxCount, count, shaders);
672 }
673
674 String GraphicsContext3D::mappedSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name)
675 {
676     GC3Dsizei count;
677     Platform3DObject shaders[2];
678     getAttachedShaders(program, 2, &count, shaders);
679
680     for (GC3Dsizei i = 0; i < count; ++i) {
681         ShaderSourceMap::iterator result = m_shaderSourceMap.find(shaders[i]);
682         if (result == m_shaderSourceMap.end())
683             continue;
684
685         const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType);
686         ShaderSymbolMap::const_iterator symbolEntry = symbolMap.find(name);
687         if (symbolEntry != symbolMap.end())
688             return symbolEntry->value.mappedName;
689     }
690     return name;
691 }
692     
693 String GraphicsContext3D::originalSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name)
694 {
695     GC3Dsizei count;
696     Platform3DObject shaders[2];
697     getAttachedShaders(program, 2, &count, shaders);
698     
699     for (GC3Dsizei i = 0; i < count; ++i) {
700         ShaderSourceMap::iterator result = m_shaderSourceMap.find(shaders[i]);
701         if (result == m_shaderSourceMap.end())
702             continue;
703         
704         const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType);
705         ShaderSymbolMap::const_iterator symbolEntry;
706         for (symbolEntry = symbolMap.begin(); symbolEntry != symbolMap.end(); ++symbolEntry) {
707             if (symbolEntry->value.mappedName == name)
708                 return symbolEntry->key;
709         }
710     }
711     return name;
712 }
713
714 int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name)
715 {
716     if (!program)
717         return -1;
718
719     makeContextCurrent();
720
721     // The attribute name may have been translated during ANGLE compilation.
722     // Look through the corresponding ShaderSourceMap to make sure we
723     // reference the mapped name rather than the external name.
724     String mappedName = mappedSymbolName(program, SHADER_SYMBOL_TYPE_ATTRIBUTE, name);
725
726     return ::glGetAttribLocation(program, mappedName.utf8().data());
727 }
728
729 GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
730 {
731     return m_attrs;
732 }
733
734 GC3Denum GraphicsContext3D::getError()
735 {
736     if (m_syntheticErrors.size() > 0) {
737         ListHashSet<GC3Denum>::iterator iter = m_syntheticErrors.begin();
738         GC3Denum err = *iter;
739         m_syntheticErrors.remove(iter);
740         return err;
741     }
742
743     makeContextCurrent();
744     return ::glGetError();
745 }
746
747 String GraphicsContext3D::getString(GC3Denum name)
748 {
749     makeContextCurrent();
750     return String(reinterpret_cast<const char*>(::glGetString(name)));
751 }
752
753 void GraphicsContext3D::hint(GC3Denum target, GC3Denum mode)
754 {
755     makeContextCurrent();
756     ::glHint(target, mode);
757 }
758
759 GC3Dboolean GraphicsContext3D::isBuffer(Platform3DObject buffer)
760 {
761     if (!buffer)
762         return GL_FALSE;
763
764     makeContextCurrent();
765     return ::glIsBuffer(buffer);
766 }
767
768 GC3Dboolean GraphicsContext3D::isEnabled(GC3Denum cap)
769 {
770     makeContextCurrent();
771     return ::glIsEnabled(cap);
772 }
773
774 GC3Dboolean GraphicsContext3D::isFramebuffer(Platform3DObject framebuffer)
775 {
776     if (!framebuffer)
777         return GL_FALSE;
778
779     makeContextCurrent();
780     return ::glIsFramebufferEXT(framebuffer);
781 }
782
783 GC3Dboolean GraphicsContext3D::isProgram(Platform3DObject program)
784 {
785     if (!program)
786         return GL_FALSE;
787
788     makeContextCurrent();
789     return ::glIsProgram(program);
790 }
791
792 GC3Dboolean GraphicsContext3D::isRenderbuffer(Platform3DObject renderbuffer)
793 {
794     if (!renderbuffer)
795         return GL_FALSE;
796
797     makeContextCurrent();
798     return ::glIsRenderbufferEXT(renderbuffer);
799 }
800
801 GC3Dboolean GraphicsContext3D::isShader(Platform3DObject shader)
802 {
803     if (!shader)
804         return GL_FALSE;
805
806     makeContextCurrent();
807     return ::glIsShader(shader);
808 }
809
810 GC3Dboolean GraphicsContext3D::isTexture(Platform3DObject texture)
811 {
812     if (!texture)
813         return GL_FALSE;
814
815     makeContextCurrent();
816     return ::glIsTexture(texture);
817 }
818
819 void GraphicsContext3D::lineWidth(GC3Dfloat width)
820 {
821     makeContextCurrent();
822     ::glLineWidth(width);
823 }
824
825 void GraphicsContext3D::linkProgram(Platform3DObject program)
826 {
827     ASSERT(program);
828     makeContextCurrent();
829     ::glLinkProgram(program);
830 }
831
832 void GraphicsContext3D::pixelStorei(GC3Denum pname, GC3Dint param)
833 {
834     makeContextCurrent();
835     ::glPixelStorei(pname, param);
836 }
837
838 void GraphicsContext3D::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
839 {
840     makeContextCurrent();
841     ::glPolygonOffset(factor, units);
842 }
843
844 void GraphicsContext3D::sampleCoverage(GC3Dclampf value, GC3Dboolean invert)
845 {
846     makeContextCurrent();
847     ::glSampleCoverage(value, invert);
848 }
849
850 void GraphicsContext3D::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
851 {
852     makeContextCurrent();
853     ::glScissor(x, y, width, height);
854 }
855
856 void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& string)
857 {
858     ASSERT(shader);
859
860     makeContextCurrent();
861
862     ShaderSourceEntry entry;
863
864     entry.source = string;
865
866     m_shaderSourceMap.set(shader, entry);
867 }
868
869 void GraphicsContext3D::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
870 {
871     makeContextCurrent();
872     ::glStencilFunc(func, ref, mask);
873 }
874
875 void GraphicsContext3D::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
876 {
877     makeContextCurrent();
878     ::glStencilFuncSeparate(face, func, ref, mask);
879 }
880
881 void GraphicsContext3D::stencilMask(GC3Duint mask)
882 {
883     makeContextCurrent();
884     ::glStencilMask(mask);
885 }
886
887 void GraphicsContext3D::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
888 {
889     makeContextCurrent();
890     ::glStencilMaskSeparate(face, mask);
891 }
892
893 void GraphicsContext3D::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
894 {
895     makeContextCurrent();
896     ::glStencilOp(fail, zfail, zpass);
897 }
898
899 void GraphicsContext3D::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
900 {
901     makeContextCurrent();
902     ::glStencilOpSeparate(face, fail, zfail, zpass);
903 }
904
905 void GraphicsContext3D::texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat value)
906 {
907     makeContextCurrent();
908     ::glTexParameterf(target, pname, value);
909 }
910
911 void GraphicsContext3D::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint value)
912 {
913     makeContextCurrent();
914     ::glTexParameteri(target, pname, value);
915 }
916
917 void GraphicsContext3D::uniform1f(GC3Dint location, GC3Dfloat v0)
918 {
919     makeContextCurrent();
920     ::glUniform1f(location, v0);
921 }
922
923 void GraphicsContext3D::uniform1fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
924 {
925     makeContextCurrent();
926     ::glUniform1fv(location, size, array);
927 }
928
929 void GraphicsContext3D::uniform2f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1)
930 {
931     makeContextCurrent();
932     ::glUniform2f(location, v0, v1);
933 }
934
935 void GraphicsContext3D::uniform2fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
936 {
937     // FIXME: length needs to be a multiple of 2.
938     makeContextCurrent();
939     ::glUniform2fv(location, size, array);
940 }
941
942 void GraphicsContext3D::uniform3f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
943 {
944     makeContextCurrent();
945     ::glUniform3f(location, v0, v1, v2);
946 }
947
948 void GraphicsContext3D::uniform3fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
949 {
950     // FIXME: length needs to be a multiple of 3.
951     makeContextCurrent();
952     ::glUniform3fv(location, size, array);
953 }
954
955 void GraphicsContext3D::uniform4f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
956 {
957     makeContextCurrent();
958     ::glUniform4f(location, v0, v1, v2, v3);
959 }
960
961 void GraphicsContext3D::uniform4fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
962 {
963     // FIXME: length needs to be a multiple of 4.
964     makeContextCurrent();
965     ::glUniform4fv(location, size, array);
966 }
967
968 void GraphicsContext3D::uniform1i(GC3Dint location, GC3Dint v0)
969 {
970     makeContextCurrent();
971     ::glUniform1i(location, v0);
972 }
973
974 void GraphicsContext3D::uniform1iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
975 {
976     makeContextCurrent();
977     ::glUniform1iv(location, size, array);
978 }
979
980 void GraphicsContext3D::uniform2i(GC3Dint location, GC3Dint v0, GC3Dint v1)
981 {
982     makeContextCurrent();
983     ::glUniform2i(location, v0, v1);
984 }
985
986 void GraphicsContext3D::uniform2iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
987 {
988     // FIXME: length needs to be a multiple of 2.
989     makeContextCurrent();
990     ::glUniform2iv(location, size, array);
991 }
992
993 void GraphicsContext3D::uniform3i(GC3Dint location, GC3Dint v0, GC3Dint v1, GC3Dint v2)
994 {
995     makeContextCurrent();
996     ::glUniform3i(location, v0, v1, v2);
997 }
998
999 void GraphicsContext3D::uniform3iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
1000 {
1001     // FIXME: length needs to be a multiple of 3.
1002     makeContextCurrent();
1003     ::glUniform3iv(location, size, array);
1004 }
1005
1006 void GraphicsContext3D::uniform4i(GC3Dint location, GC3Dint v0, GC3Dint v1, GC3Dint v2, GC3Dint v3)
1007 {
1008     makeContextCurrent();
1009     ::glUniform4i(location, v0, v1, v2, v3);
1010 }
1011
1012 void GraphicsContext3D::uniform4iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
1013 {
1014     // FIXME: length needs to be a multiple of 4.
1015     makeContextCurrent();
1016     ::glUniform4iv(location, size, array);
1017 }
1018
1019 void GraphicsContext3D::uniformMatrix2fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* array)
1020 {
1021     // FIXME: length needs to be a multiple of 4.
1022     makeContextCurrent();
1023     ::glUniformMatrix2fv(location, size, transpose, array);
1024 }
1025
1026 void GraphicsContext3D::uniformMatrix3fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* array)
1027 {
1028     // FIXME: length needs to be a multiple of 9.
1029     makeContextCurrent();
1030     ::glUniformMatrix3fv(location, size, transpose, array);
1031 }
1032
1033 void GraphicsContext3D::uniformMatrix4fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* array)
1034 {
1035     // FIXME: length needs to be a multiple of 16.
1036     makeContextCurrent();
1037     ::glUniformMatrix4fv(location, size, transpose, array);
1038 }
1039
1040 void GraphicsContext3D::useProgram(Platform3DObject program)
1041 {
1042     makeContextCurrent();
1043     ::glUseProgram(program);
1044 }
1045
1046 void GraphicsContext3D::validateProgram(Platform3DObject program)
1047 {
1048     ASSERT(program);
1049
1050     makeContextCurrent();
1051     ::glValidateProgram(program);
1052 }
1053
1054 void GraphicsContext3D::vertexAttrib1f(GC3Duint index, GC3Dfloat v0)
1055 {
1056     makeContextCurrent();
1057     ::glVertexAttrib1f(index, v0);
1058 }
1059
1060 void GraphicsContext3D::vertexAttrib1fv(GC3Duint index, GC3Dfloat* array)
1061 {
1062     makeContextCurrent();
1063     ::glVertexAttrib1fv(index, array);
1064 }
1065
1066 void GraphicsContext3D::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1)
1067 {
1068     makeContextCurrent();
1069     ::glVertexAttrib2f(index, v0, v1);
1070 }
1071
1072 void GraphicsContext3D::vertexAttrib2fv(GC3Duint index, GC3Dfloat* array)
1073 {
1074     makeContextCurrent();
1075     ::glVertexAttrib2fv(index, array);
1076 }
1077
1078 void GraphicsContext3D::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
1079 {
1080     makeContextCurrent();
1081     ::glVertexAttrib3f(index, v0, v1, v2);
1082 }
1083
1084 void GraphicsContext3D::vertexAttrib3fv(GC3Duint index, GC3Dfloat* array)
1085 {
1086     makeContextCurrent();
1087     ::glVertexAttrib3fv(index, array);
1088 }
1089
1090 void GraphicsContext3D::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
1091 {
1092     makeContextCurrent();
1093     ::glVertexAttrib4f(index, v0, v1, v2, v3);
1094 }
1095
1096 void GraphicsContext3D::vertexAttrib4fv(GC3Duint index, GC3Dfloat* array)
1097 {
1098     makeContextCurrent();
1099     ::glVertexAttrib4fv(index, array);
1100 }
1101
1102 void GraphicsContext3D::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset)
1103 {
1104     makeContextCurrent();
1105     ::glVertexAttribPointer(index, size, type, normalized, stride, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)));
1106 }
1107
1108 void GraphicsContext3D::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
1109 {
1110     makeContextCurrent();
1111     ::glViewport(x, y, width, height);
1112 }
1113
1114 void GraphicsContext3D::getBooleanv(GC3Denum pname, GC3Dboolean* value)
1115 {
1116     makeContextCurrent();
1117     ::glGetBooleanv(pname, value);
1118 }
1119
1120 void GraphicsContext3D::getBufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
1121 {
1122     makeContextCurrent();
1123     ::glGetBufferParameteriv(target, pname, value);
1124 }
1125
1126 void GraphicsContext3D::getFloatv(GC3Denum pname, GC3Dfloat* value)
1127 {
1128     makeContextCurrent();
1129     ::glGetFloatv(pname, value);
1130 }
1131
1132 void GraphicsContext3D::getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment, GC3Denum pname, GC3Dint* value)
1133 {
1134     makeContextCurrent();
1135     if (attachment == DEPTH_STENCIL_ATTACHMENT)
1136         attachment = DEPTH_ATTACHMENT; // Or STENCIL_ATTACHMENT, either works.
1137     ::glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value);
1138 }
1139
1140 void GraphicsContext3D::getProgramiv(Platform3DObject program, GC3Denum pname, GC3Dint* value)
1141 {
1142     makeContextCurrent();
1143     ::glGetProgramiv(program, pname, value);
1144 }
1145
1146 String GraphicsContext3D::getProgramInfoLog(Platform3DObject program)
1147 {
1148     ASSERT(program);
1149
1150     makeContextCurrent();
1151     GLint length = 0;
1152     ::glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
1153     if (!length)
1154         return String(); 
1155
1156     GLsizei size = 0;
1157     auto info = std::make_unique<GLchar[]>(length);
1158     ::glGetProgramInfoLog(program, length, &size, info.get());
1159
1160     return String(info.get());
1161 }
1162
1163 void GraphicsContext3D::getRenderbufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
1164 {
1165     makeContextCurrent();
1166     ::glGetRenderbufferParameterivEXT(target, pname, value);
1167 }
1168
1169 void GraphicsContext3D::getShaderiv(Platform3DObject shader, GC3Denum pname, GC3Dint* value)
1170 {
1171     ASSERT(shader);
1172
1173     makeContextCurrent();
1174
1175     ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
1176     
1177     switch (pname) {
1178     case DELETE_STATUS:
1179     case SHADER_TYPE:
1180         ::glGetShaderiv(shader, pname, value);
1181         break;
1182     case COMPILE_STATUS:
1183         if (result == m_shaderSourceMap.end()) {
1184             *value = static_cast<int>(false);
1185             return;
1186         }
1187         *value = static_cast<int>(result->value.isValid);
1188         break;
1189     case INFO_LOG_LENGTH:
1190         if (result == m_shaderSourceMap.end()) {
1191             *value = 0;
1192             return;
1193         }
1194         *value = getShaderInfoLog(shader).length();
1195         break;
1196     case SHADER_SOURCE_LENGTH:
1197         *value = getShaderSource(shader).length();
1198         break;
1199     default:
1200         synthesizeGLError(INVALID_ENUM);
1201     }
1202 }
1203
1204 String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader)
1205 {
1206     ASSERT(shader);
1207
1208     makeContextCurrent();
1209
1210     ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
1211     if (result == m_shaderSourceMap.end())
1212         return String(); 
1213
1214     ShaderSourceEntry entry = result->value;
1215     if (!entry.isValid)
1216         return entry.log;
1217
1218     GLint length = 0;
1219     ::glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
1220     if (!length)
1221         return String(); 
1222
1223     GLsizei size = 0;
1224     auto info = std::make_unique<GLchar[]>(length);
1225     ::glGetShaderInfoLog(shader, length, &size, info.get());
1226
1227     return String(info.get());
1228 }
1229
1230 String GraphicsContext3D::getShaderSource(Platform3DObject shader)
1231 {
1232     ASSERT(shader);
1233
1234     makeContextCurrent();
1235
1236     ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
1237     if (result == m_shaderSourceMap.end())
1238         return String(); 
1239
1240     return result->value.source;
1241 }
1242
1243
1244 void GraphicsContext3D::getTexParameterfv(GC3Denum target, GC3Denum pname, GC3Dfloat* value)
1245 {
1246     makeContextCurrent();
1247     ::glGetTexParameterfv(target, pname, value);
1248 }
1249
1250 void GraphicsContext3D::getTexParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
1251 {
1252     makeContextCurrent();
1253     ::glGetTexParameteriv(target, pname, value);
1254 }
1255
1256 void GraphicsContext3D::getUniformfv(Platform3DObject program, GC3Dint location, GC3Dfloat* value)
1257 {
1258     makeContextCurrent();
1259     ::glGetUniformfv(program, location, value);
1260 }
1261
1262 void GraphicsContext3D::getUniformiv(Platform3DObject program, GC3Dint location, GC3Dint* value)
1263 {
1264     makeContextCurrent();
1265     ::glGetUniformiv(program, location, value);
1266 }
1267
1268 GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name)
1269 {
1270     ASSERT(program);
1271
1272     makeContextCurrent();
1273
1274     // The uniform name may have been translated during ANGLE compilation.
1275     // Look through the corresponding ShaderSourceMap to make sure we
1276     // reference the mapped name rather than the external name.
1277     String mappedName = mappedSymbolName(program, SHADER_SYMBOL_TYPE_UNIFORM, name);
1278
1279     return ::glGetUniformLocation(program, mappedName.utf8().data());
1280 }
1281
1282 void GraphicsContext3D::getVertexAttribfv(GC3Duint index, GC3Denum pname, GC3Dfloat* value)
1283 {
1284     makeContextCurrent();
1285     ::glGetVertexAttribfv(index, pname, value);
1286 }
1287
1288 void GraphicsContext3D::getVertexAttribiv(GC3Duint index, GC3Denum pname, GC3Dint* value)
1289 {
1290     makeContextCurrent();
1291     ::glGetVertexAttribiv(index, pname, value);
1292 }
1293
1294 GC3Dsizeiptr GraphicsContext3D::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
1295 {
1296     makeContextCurrent();
1297
1298     GLvoid* pointer = 0;
1299     ::glGetVertexAttribPointerv(index, pname, &pointer);
1300     return static_cast<GC3Dsizeiptr>(reinterpret_cast<intptr_t>(pointer));
1301 }
1302
1303 void GraphicsContext3D::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoff, GC3Dint yoff, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels)
1304 {
1305     makeContextCurrent();
1306
1307     // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size.
1308     ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
1309 }
1310
1311 void GraphicsContext3D::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Dsizei imageSize, const void* data)
1312 {
1313     makeContextCurrent();
1314     ::glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
1315 }
1316
1317 void GraphicsContext3D::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Dsizei imageSize, const void* data)
1318 {
1319     makeContextCurrent();
1320     ::glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
1321 }
1322
1323 Platform3DObject GraphicsContext3D::createBuffer()
1324 {
1325     makeContextCurrent();
1326     GLuint o = 0;
1327     glGenBuffers(1, &o);
1328     return o;
1329 }
1330
1331 Platform3DObject GraphicsContext3D::createFramebuffer()
1332 {
1333     makeContextCurrent();
1334     GLuint o = 0;
1335     glGenFramebuffersEXT(1, &o);
1336     return o;
1337 }
1338
1339 Platform3DObject GraphicsContext3D::createProgram()
1340 {
1341     makeContextCurrent();
1342     return glCreateProgram();
1343 }
1344
1345 Platform3DObject GraphicsContext3D::createRenderbuffer()
1346 {
1347     makeContextCurrent();
1348     GLuint o = 0;
1349     glGenRenderbuffersEXT(1, &o);
1350     return o;
1351 }
1352
1353 Platform3DObject GraphicsContext3D::createShader(GC3Denum type)
1354 {
1355     makeContextCurrent();
1356     return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER);
1357 }
1358
1359 Platform3DObject GraphicsContext3D::createTexture()
1360 {
1361     makeContextCurrent();
1362     GLuint o = 0;
1363     glGenTextures(1, &o);
1364     return o;
1365 }
1366
1367 void GraphicsContext3D::deleteBuffer(Platform3DObject buffer)
1368 {
1369     makeContextCurrent();
1370     glDeleteBuffers(1, &buffer);
1371 }
1372
1373 void GraphicsContext3D::deleteFramebuffer(Platform3DObject framebuffer)
1374 {
1375     makeContextCurrent();
1376     if (framebuffer == m_state.boundFBO) {
1377         // Make sure the framebuffer is not going to be used for drawing
1378         // operations after it gets deleted.
1379         bindFramebuffer(FRAMEBUFFER, 0);
1380     }
1381     glDeleteFramebuffersEXT(1, &framebuffer);
1382 }
1383
1384 void GraphicsContext3D::deleteProgram(Platform3DObject program)
1385 {
1386     makeContextCurrent();
1387     glDeleteProgram(program);
1388 }
1389
1390 void GraphicsContext3D::deleteRenderbuffer(Platform3DObject renderbuffer)
1391 {
1392     makeContextCurrent();
1393     glDeleteRenderbuffersEXT(1, &renderbuffer);
1394 }
1395
1396 void GraphicsContext3D::deleteShader(Platform3DObject shader)
1397 {
1398     makeContextCurrent();
1399     glDeleteShader(shader);
1400 }
1401
1402 void GraphicsContext3D::deleteTexture(Platform3DObject texture)
1403 {
1404     makeContextCurrent();
1405     if (m_state.boundTexture0 == texture)
1406         m_state.boundTexture0 = 0;
1407     glDeleteTextures(1, &texture);
1408 }
1409
1410 void GraphicsContext3D::synthesizeGLError(GC3Denum error)
1411 {
1412     m_syntheticErrors.add(error);
1413 }
1414
1415 void GraphicsContext3D::markContextChanged()
1416 {
1417     m_layerComposited = false;
1418 }
1419
1420 void GraphicsContext3D::markLayerComposited()
1421 {
1422     m_layerComposited = true;
1423 }
1424
1425 bool GraphicsContext3D::layerComposited() const
1426 {
1427     return m_layerComposited;
1428 }
1429
1430 void GraphicsContext3D::texImage2DDirect(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
1431 {
1432     makeContextCurrent();
1433     ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
1434 }
1435
1436 }
1437
1438 #endif // USE(3D_GRAPHICS)