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