1/*
2    Copyright (C) 2010 Tieto Corporation.
3
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with this library; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17*/
18
19#include "config.h"
20
21#include "GraphicsContext3D.h"
22
23#include "WebGLObject.h"
24#include "CanvasRenderingContext.h"
25#include "Extensions3DQt.h"
26#include "GraphicsContext.h"
27#include "HTMLCanvasElement.h"
28#include "HostWindow.h"
29#include "ImageBuffer.h"
30#include "ImageData.h"
31#include "NotImplemented.h"
32#include "QWebPageClient.h"
33#include "qwebpage.h"
34#include <QAbstractScrollArea>
35#include <QGraphicsObject>
36#include <QGLContext>
37#include <QStyleOptionGraphicsItem>
38#include <wtf/UnusedParam.h>
39#include <wtf/text/CString.h>
40
41#if ENABLE(WEBGL)
42
43namespace WebCore {
44
45#if !defined(GLchar)
46typedef char GLchar;
47#endif
48
49#if !defined(GL_DEPTH24_STENCIL8)
50#define GL_DEPTH24_STENCIL8 0x88F0
51#endif
52
53#if !defined(APIENTRY)
54#define APIENTRY
55#endif
56
57#ifdef QT_OPENGL_ES_2
58typedef GLsizeiptr GLsizeiptrType;
59typedef GLintptr GLintptrType;
60#else
61typedef ptrdiff_t GLsizeiptrType;
62typedef ptrdiff_t GLintptrType;
63#endif
64
65typedef void (APIENTRY* glActiveTextureType) (GLenum);
66typedef void (APIENTRY* glAttachShaderType) (GLuint, GLuint);
67typedef void (APIENTRY* glBindAttribLocationType) (GLuint, GLuint, const char*);
68typedef void (APIENTRY* glBindBufferType) (GLenum, GLuint);
69typedef void (APIENTRY* glBindFramebufferType) (GLenum, GLuint);
70typedef void (APIENTRY* glBindRenderbufferType) (GLenum, GLuint);
71typedef void (APIENTRY* glBlendColorType) (GLclampf, GLclampf, GLclampf, GLclampf);
72typedef void (APIENTRY* glBlendEquationType) (GLenum);
73typedef void (APIENTRY* glBlendEquationSeparateType)(GLenum, GLenum);
74typedef void (APIENTRY* glBlendFuncSeparateType)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
75typedef void (APIENTRY* glBufferDataType) (GLenum, GLsizeiptrType, const GLvoid*, GLenum);
76typedef void (APIENTRY* glBufferSubDataType) (GLenum, GLintptrType, GLsizeiptrType, const GLvoid*);
77typedef GLenum (APIENTRY* glCheckFramebufferStatusType) (GLenum);
78typedef void (APIENTRY* glCompileShaderType) (GLuint);
79typedef GLuint (APIENTRY* glCreateProgramType) ();
80typedef GLuint (APIENTRY* glCreateShaderType) (GLenum);
81typedef void (APIENTRY* glDeleteBuffersType) (GLsizei, const GLuint*);
82typedef void (APIENTRY* glDeleteFramebuffersType) (GLsizei n, const GLuint*);
83typedef void (APIENTRY* glDeleteProgramType) (GLuint);
84typedef void (APIENTRY* glDeleteRenderbuffersType) (GLsizei n, const GLuint*);
85typedef void (APIENTRY* glDeleteShaderType) (GLuint);
86typedef void (APIENTRY* glDetachShaderType) (GLuint, GLuint);
87typedef void (APIENTRY* glDisableVertexAttribArrayType) (GLuint);
88typedef void (APIENTRY* glEnableVertexAttribArrayType) (GLuint);
89typedef void (APIENTRY* glFramebufferRenderbufferType) (GLenum, GLenum, GLenum, GLuint);
90typedef void (APIENTRY* glFramebufferTexture2DType) (GLenum, GLenum, GLenum, GLuint, GLint);
91typedef void (APIENTRY* glGenBuffersType) (GLsizei, GLuint*);
92typedef void (APIENTRY* glGenerateMipmapType) (GLenum target);
93typedef void (APIENTRY* glGenFramebuffersType) (GLsizei, GLuint*);
94typedef void (APIENTRY* glGenRenderbuffersType) (GLsizei, GLuint*);
95typedef void (APIENTRY* glGetActiveAttribType) (GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*);
96typedef void (APIENTRY* glGetActiveUniformType) (GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*);
97typedef void (APIENTRY* glGetAttachedShadersType) (GLuint, GLsizei, GLsizei*, GLuint*);
98typedef GLint (APIENTRY* glGetAttribLocationType) (GLuint, const char*);
99typedef void (APIENTRY* glGetBufferParameterivType) (GLenum, GLenum, GLint*);
100typedef void (APIENTRY* glGetFramebufferAttachmentParameterivType) (GLenum, GLenum, GLenum, GLint* params);
101typedef void (APIENTRY* glGetProgramInfoLogType) (GLuint, GLsizei, GLsizei*, char*);
102typedef void (APIENTRY* glGetProgramivType) (GLuint, GLenum, GLint*);
103typedef void (APIENTRY* glGetRenderbufferParameterivType) (GLenum, GLenum, GLint*);
104typedef void (APIENTRY* glGetShaderInfoLogType) (GLuint, GLsizei, GLsizei*, char*);
105typedef void (APIENTRY* glGetShaderivType) (GLuint, GLenum, GLint*);
106typedef void (APIENTRY* glGetShaderSourceType) (GLuint, GLsizei, GLsizei*, char*);
107typedef GLint (APIENTRY* glGetUniformLocationType) (GLuint, const char*);
108typedef void (APIENTRY* glGetUniformfvType) (GLuint, GLint, GLfloat*);
109typedef void (APIENTRY* glGetUniformivType) (GLuint, GLint, GLint*);
110typedef void (APIENTRY* glGetVertexAttribfvType) (GLuint, GLenum, GLfloat*);
111typedef void (APIENTRY* glGetVertexAttribivType) (GLuint, GLenum, GLint*);
112typedef void (APIENTRY* glGetVertexAttribPointervType) (GLuint, GLenum, GLvoid**);
113typedef GLboolean (APIENTRY* glIsBufferType) (GLuint);
114typedef GLboolean (APIENTRY* glIsFramebufferType) (GLuint);
115typedef GLboolean (APIENTRY* glIsProgramType) (GLuint);
116typedef GLboolean (APIENTRY* glIsRenderbufferType) (GLuint);
117typedef GLboolean (APIENTRY* glIsShaderType) (GLuint);
118typedef void (APIENTRY* glLinkProgramType) (GLuint);
119typedef void (APIENTRY* glRenderbufferStorageType) (GLenum, GLenum, GLsizei, GLsizei);
120typedef void (APIENTRY* glSampleCoverageType) (GLclampf, GLboolean);
121typedef void (APIENTRY* glShaderSourceType) (GLuint, GLsizei, const char**, const GLint*);
122typedef void (APIENTRY* glStencilFuncSeparateType) (GLenum, GLenum, GLint, GLuint);
123typedef void (APIENTRY* glStencilMaskSeparateType) (GLenum, GLuint);
124typedef void (APIENTRY* glStencilOpSeparateType) (GLenum, GLenum, GLenum, GLenum);
125typedef void (APIENTRY* glUniform1fType) (GLint, GLfloat);
126typedef void (APIENTRY* glUniform1fvType) (GLint, GLsizei, const GLfloat*);
127typedef void (APIENTRY* glUniform1iType) (GLint, GLint);
128typedef void (APIENTRY* glUniform1ivType) (GLint, GLsizei, const GLint*);
129typedef void (APIENTRY* glUniform2fType) (GLint, GLfloat, GLfloat);
130typedef void (APIENTRY* glUniform2fvType) (GLint, GLsizei, const GLfloat*);
131typedef void (APIENTRY* glUniform2iType) (GLint, GLint, GLint);
132typedef void (APIENTRY* glUniform2ivType) (GLint, GLsizei, const GLint*);
133typedef void (APIENTRY* glUniform3fType) (GLint, GLfloat, GLfloat, GLfloat);
134typedef void (APIENTRY* glUniform3fvType) (GLint, GLsizei, const GLfloat*);
135typedef void (APIENTRY* glUniform3iType) (GLint, GLint, GLint, GLint);
136typedef void (APIENTRY* glUniform3ivType) (GLint, GLsizei, const GLint*);
137typedef void (APIENTRY* glUniform4fType) (GLint, GLfloat, GLfloat, GLfloat, GLfloat);
138typedef void (APIENTRY* glUniform4fvType) (GLint, GLsizei, const GLfloat*);
139typedef void (APIENTRY* glUniform4iType) (GLint, GLint, GLint, GLint, GLint);
140typedef void (APIENTRY* glUniform4ivType) (GLint, GLsizei, const GLint*);
141typedef void (APIENTRY* glUniformMatrix2fvType) (GLint, GLsizei, GLboolean, const GLfloat*);
142typedef void (APIENTRY* glUniformMatrix3fvType) (GLint, GLsizei, GLboolean, const GLfloat*);
143typedef void (APIENTRY* glUniformMatrix4fvType) (GLint, GLsizei, GLboolean, const GLfloat*);
144typedef void (APIENTRY* glUseProgramType) (GLuint);
145typedef void (APIENTRY* glValidateProgramType) (GLuint);
146typedef void (APIENTRY* glVertexAttrib1fType) (GLuint, const GLfloat);
147typedef void (APIENTRY* glVertexAttrib1fvType) (GLuint, const GLfloat*);
148typedef void (APIENTRY* glVertexAttrib2fType) (GLuint, const GLfloat, const GLfloat);
149typedef void (APIENTRY* glVertexAttrib2fvType) (GLuint, const GLfloat*);
150typedef void (APIENTRY* glVertexAttrib3fType) (GLuint, const GLfloat, const GLfloat, const GLfloat);
151typedef void (APIENTRY* glVertexAttrib3fvType) (GLuint, const GLfloat*);
152typedef void (APIENTRY* glVertexAttrib4fType) (GLuint, const GLfloat, const GLfloat, const GLfloat, const GLfloat);
153typedef void (APIENTRY* glVertexAttrib4fvType) (GLuint, const GLfloat*);
154typedef void (APIENTRY* glVertexAttribPointerType) (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*);
155
156class GraphicsContext3DInternal : public QGraphicsObject {
157public:
158    GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow);
159    ~GraphicsContext3DInternal();
160
161    bool isValid() { return m_valid; }
162
163    QGLWidget* getViewportGLWidget();
164    void reshape(int width, int height);
165    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
166    QRectF boundingRect() const;
167
168    glActiveTextureType activeTexture;
169    glAttachShaderType attachShader;
170    glBindAttribLocationType bindAttribLocation;
171    glBindBufferType bindBuffer;
172    glBindFramebufferType bindFramebuffer;
173    glBindRenderbufferType bindRenderbuffer;
174    glBlendColorType blendColor;
175    glBlendEquationType blendEquation;
176    glBlendEquationSeparateType blendEquationSeparate;
177    glBlendFuncSeparateType blendFuncSeparate;
178    glBufferDataType bufferData;
179    glBufferSubDataType bufferSubData;
180    glCheckFramebufferStatusType checkFramebufferStatus;
181    glCompileShaderType compileShader;
182    glCreateProgramType createProgram;
183    glCreateShaderType createShader;
184    glDeleteBuffersType deleteBuffers;
185    glDeleteFramebuffersType deleteFramebuffers;
186    glDeleteProgramType deleteProgram;
187    glDeleteRenderbuffersType deleteRenderbuffers;
188    glDeleteShaderType deleteShader;
189    glDetachShaderType detachShader;
190    glDisableVertexAttribArrayType disableVertexAttribArray;
191    glEnableVertexAttribArrayType enableVertexAttribArray;
192    glFramebufferRenderbufferType framebufferRenderbuffer;
193    glFramebufferTexture2DType framebufferTexture2D;
194    glGenBuffersType genBuffers;
195    glGenerateMipmapType generateMipmap;
196    glGenFramebuffersType genFramebuffers;
197    glGenRenderbuffersType genRenderbuffers;
198    glGetActiveAttribType getActiveAttrib;
199    glGetActiveUniformType getActiveUniform;
200    glGetAttachedShadersType getAttachedShaders;
201    glGetAttribLocationType getAttribLocation;
202    glGetBufferParameterivType getBufferParameteriv;
203    glGetFramebufferAttachmentParameterivType getFramebufferAttachmentParameteriv;
204    glGetProgramInfoLogType getProgramInfoLog;
205    glGetProgramivType getProgramiv;
206    glGetRenderbufferParameterivType getRenderbufferParameteriv;
207    glGetShaderInfoLogType getShaderInfoLog;
208    glGetShaderivType getShaderiv;
209    glGetShaderSourceType getShaderSource;
210    glGetUniformfvType getUniformfv;
211    glGetUniformivType getUniformiv;
212    glGetUniformLocationType getUniformLocation;
213    glGetVertexAttribfvType getVertexAttribfv;
214    glGetVertexAttribivType getVertexAttribiv;
215    glGetVertexAttribPointervType getVertexAttribPointerv;
216    glIsBufferType isBuffer;
217    glIsFramebufferType isFramebuffer;
218    glIsProgramType isProgram;
219    glIsRenderbufferType isRenderbuffer;
220    glIsShaderType isShader;
221    glLinkProgramType linkProgram;
222    glRenderbufferStorageType renderbufferStorage;
223    glSampleCoverageType sampleCoverage;
224    glShaderSourceType shaderSource;
225    glStencilFuncSeparateType stencilFuncSeparate;
226    glStencilMaskSeparateType stencilMaskSeparate;
227    glStencilOpSeparateType stencilOpSeparate;
228    glUniform1fType uniform1f;
229    glUniform1fvType uniform1fv;
230    glUniform1iType uniform1i;
231    glUniform1ivType uniform1iv;
232    glUniform2fType uniform2f;
233    glUniform2fvType uniform2fv;
234    glUniform2iType uniform2i;
235    glUniform2ivType uniform2iv;
236    glUniform3fType uniform3f;
237    glUniform3fvType uniform3fv;
238    glUniform3iType uniform3i;
239    glUniform3ivType uniform3iv;
240    glUniform4fType uniform4f;
241    glUniform4fvType uniform4fv;
242    glUniform4iType uniform4i;
243    glUniform4ivType uniform4iv;
244    glUniformMatrix2fvType uniformMatrix2fv;
245    glUniformMatrix3fvType uniformMatrix3fv;
246    glUniformMatrix4fvType uniformMatrix4fv;
247    glUseProgramType useProgram;
248    glValidateProgramType validateProgram;
249    glVertexAttrib1fType vertexAttrib1f;
250    glVertexAttrib1fvType vertexAttrib1fv;
251    glVertexAttrib2fType vertexAttrib2f;
252    glVertexAttrib2fvType vertexAttrib2fv;
253    glVertexAttrib3fType vertexAttrib3f;
254    glVertexAttrib3fvType vertexAttrib3fv;
255    glVertexAttrib4fType vertexAttrib4f;
256    glVertexAttrib4fvType vertexAttrib4fv;
257    glVertexAttribPointerType vertexAttribPointer;
258
259    GraphicsContext3D::Attributes m_attrs;
260    HostWindow* m_hostWindow;
261    QGLWidget* m_glWidget;
262    QGLWidget* m_viewportGLWidget;
263    QRectF m_boundingRect;
264    GLuint m_texture;
265    GLuint m_canvasFbo;
266    GLuint m_currentFbo;
267    GLuint m_depthBuffer;
268    bool m_layerComposited;
269    ListHashSet<unsigned int> m_syntheticErrors;
270
271    OwnPtr<Extensions3DQt> m_extensions;
272
273private:
274
275    void* getProcAddress(const String& proc);
276    bool m_valid;
277};
278
279#if defined (QT_OPENGL_ES_2)
280#define GET_PROC_ADDRESS(Proc) Proc
281#else
282#define GET_PROC_ADDRESS(Proc) reinterpret_cast<Proc##Type>(getProcAddress(#Proc));
283#endif
284
285bool GraphicsContext3D::isGLES2Compliant() const
286{
287#if defined (QT_OPENGL_ES_2)
288    return true;
289#else
290    return false;
291#endif
292}
293
294GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow)
295    : m_attrs(attrs)
296    , m_hostWindow(hostWindow)
297    , m_glWidget(0)
298    , m_viewportGLWidget(0)
299    , m_texture(0)
300    , m_canvasFbo(0)
301    , m_currentFbo(0)
302    , m_depthBuffer(0)
303    , m_layerComposited(false)
304    , m_valid(true)
305{
306    m_viewportGLWidget = getViewportGLWidget();
307
308    if (m_viewportGLWidget)
309        m_glWidget = new QGLWidget(0, m_viewportGLWidget);
310    else
311        m_glWidget = new QGLWidget();
312
313    if (!m_glWidget->isValid()) {
314        LOG_ERROR("GraphicsContext3D: QGLWidget initialization failed.");
315        m_valid = false;
316        return;
317    }
318
319    // Geometry can be set to zero because m_glWidget is used only for its QGLContext.
320    m_glWidget->setGeometry(0, 0, 0, 0);
321
322#if defined(QT_OPENGL_ES_2)
323    m_attrs.stencil = false;
324#else
325    if (m_attrs.stencil)
326        m_attrs.depth = true;
327#endif
328    m_attrs.antialias = false;
329
330    m_glWidget->makeCurrent();
331
332    activeTexture = GET_PROC_ADDRESS(glActiveTexture);
333    attachShader = GET_PROC_ADDRESS(glAttachShader);
334    bindAttribLocation = GET_PROC_ADDRESS(glBindAttribLocation);
335    bindBuffer = GET_PROC_ADDRESS(glBindBuffer);
336    bindFramebuffer = GET_PROC_ADDRESS(glBindFramebuffer);
337    bindRenderbuffer = GET_PROC_ADDRESS(glBindRenderbuffer);
338    blendColor = GET_PROC_ADDRESS(glBlendColor);
339    blendEquation = GET_PROC_ADDRESS(glBlendEquation);
340    blendEquationSeparate = GET_PROC_ADDRESS(glBlendEquationSeparate);
341    blendFuncSeparate = GET_PROC_ADDRESS(glBlendFuncSeparate);
342    bufferData = GET_PROC_ADDRESS(glBufferData);
343    bufferSubData = GET_PROC_ADDRESS(glBufferSubData);
344    checkFramebufferStatus = GET_PROC_ADDRESS(glCheckFramebufferStatus);
345    compileShader = GET_PROC_ADDRESS(glCompileShader);
346    createProgram = GET_PROC_ADDRESS(glCreateProgram);
347    createShader = GET_PROC_ADDRESS(glCreateShader);
348    deleteBuffers = GET_PROC_ADDRESS(glDeleteBuffers);
349    deleteFramebuffers = GET_PROC_ADDRESS(glDeleteFramebuffers);
350    deleteProgram = GET_PROC_ADDRESS(glDeleteProgram);
351    deleteRenderbuffers = GET_PROC_ADDRESS(glDeleteRenderbuffers);
352    deleteShader = GET_PROC_ADDRESS(glDeleteShader);
353    detachShader = GET_PROC_ADDRESS(glDetachShader);
354    disableVertexAttribArray = GET_PROC_ADDRESS(glDisableVertexAttribArray);
355    enableVertexAttribArray = GET_PROC_ADDRESS(glEnableVertexAttribArray);
356    framebufferRenderbuffer = GET_PROC_ADDRESS(glFramebufferRenderbuffer);
357    framebufferTexture2D = GET_PROC_ADDRESS(glFramebufferTexture2D);
358    genBuffers = GET_PROC_ADDRESS(glGenBuffers);
359    generateMipmap = GET_PROC_ADDRESS(glGenerateMipmap);
360    genFramebuffers = GET_PROC_ADDRESS(glGenFramebuffers);
361    genRenderbuffers = GET_PROC_ADDRESS(glGenRenderbuffers);
362    getActiveAttrib = GET_PROC_ADDRESS(glGetActiveAttrib);
363    getActiveUniform = GET_PROC_ADDRESS(glGetActiveUniform);
364    getAttachedShaders = GET_PROC_ADDRESS(glGetAttachedShaders);
365    getAttribLocation = GET_PROC_ADDRESS(glGetAttribLocation);
366    getBufferParameteriv = GET_PROC_ADDRESS(glGetBufferParameteriv);
367    getFramebufferAttachmentParameteriv = GET_PROC_ADDRESS(glGetFramebufferAttachmentParameteriv);
368    getProgramInfoLog = GET_PROC_ADDRESS(glGetProgramInfoLog);
369    getProgramiv = GET_PROC_ADDRESS(glGetProgramiv);
370    getRenderbufferParameteriv = GET_PROC_ADDRESS(glGetRenderbufferParameteriv);
371    getShaderInfoLog = GET_PROC_ADDRESS(glGetShaderInfoLog);
372    getShaderiv = GET_PROC_ADDRESS(glGetShaderiv);
373    getShaderSource = GET_PROC_ADDRESS(glGetShaderSource);
374    getUniformfv = GET_PROC_ADDRESS(glGetUniformfv);
375    getUniformiv = GET_PROC_ADDRESS(glGetUniformiv);
376    getUniformLocation = GET_PROC_ADDRESS(glGetUniformLocation);
377    getVertexAttribfv = GET_PROC_ADDRESS(glGetVertexAttribfv);
378    getVertexAttribiv = GET_PROC_ADDRESS(glGetVertexAttribiv);
379    getVertexAttribPointerv = GET_PROC_ADDRESS(glGetVertexAttribPointerv);
380    isBuffer = GET_PROC_ADDRESS(glIsBuffer);
381    isFramebuffer = GET_PROC_ADDRESS(glIsFramebuffer);
382    isProgram = GET_PROC_ADDRESS(glIsProgram);
383    isRenderbuffer = GET_PROC_ADDRESS(glIsRenderbuffer);
384    isShader = GET_PROC_ADDRESS(glIsShader);
385    linkProgram = GET_PROC_ADDRESS(glLinkProgram);
386    renderbufferStorage = GET_PROC_ADDRESS(glRenderbufferStorage);
387    sampleCoverage = GET_PROC_ADDRESS(glSampleCoverage);
388    shaderSource = GET_PROC_ADDRESS(glShaderSource);
389    stencilFuncSeparate = GET_PROC_ADDRESS(glStencilFuncSeparate);
390    stencilMaskSeparate = GET_PROC_ADDRESS(glStencilMaskSeparate);
391    stencilOpSeparate = GET_PROC_ADDRESS(glStencilOpSeparate);
392    uniform1f = GET_PROC_ADDRESS(glUniform1f);
393    uniform1fv = GET_PROC_ADDRESS(glUniform1fv);
394    uniform1i = GET_PROC_ADDRESS(glUniform1i);
395    uniform1iv = GET_PROC_ADDRESS(glUniform1iv);
396    uniform2f = GET_PROC_ADDRESS(glUniform2f);
397    uniform2fv = GET_PROC_ADDRESS(glUniform2fv);
398    uniform2i = GET_PROC_ADDRESS(glUniform2i);
399    uniform2iv = GET_PROC_ADDRESS(glUniform2iv);
400    uniform3f = GET_PROC_ADDRESS(glUniform3f);
401    uniform3fv = GET_PROC_ADDRESS(glUniform3fv);
402    uniform3i = GET_PROC_ADDRESS(glUniform3i);
403    uniform3iv = GET_PROC_ADDRESS(glUniform3iv);
404    uniform4f = GET_PROC_ADDRESS(glUniform4f);
405    uniform4fv = GET_PROC_ADDRESS(glUniform4fv);
406    uniform4i = GET_PROC_ADDRESS(glUniform4i);
407    uniform4iv = GET_PROC_ADDRESS(glUniform4iv);
408    uniformMatrix2fv = GET_PROC_ADDRESS(glUniformMatrix2fv);
409    uniformMatrix3fv = GET_PROC_ADDRESS(glUniformMatrix3fv);
410    uniformMatrix4fv = GET_PROC_ADDRESS(glUniformMatrix4fv);
411    useProgram = GET_PROC_ADDRESS(glUseProgram);
412    validateProgram = GET_PROC_ADDRESS(glValidateProgram);
413    vertexAttrib1f = GET_PROC_ADDRESS(glVertexAttrib1f);
414    vertexAttrib1fv = GET_PROC_ADDRESS(glVertexAttrib1fv);
415    vertexAttrib2f = GET_PROC_ADDRESS(glVertexAttrib2f);
416    vertexAttrib2fv = GET_PROC_ADDRESS(glVertexAttrib2fv);
417    vertexAttrib3f = GET_PROC_ADDRESS(glVertexAttrib3f);
418    vertexAttrib3fv = GET_PROC_ADDRESS(glVertexAttrib3fv);
419    vertexAttrib4f = GET_PROC_ADDRESS(glVertexAttrib4f);
420    vertexAttrib4fv = GET_PROC_ADDRESS(glVertexAttrib4fv);
421    vertexAttribPointer = GET_PROC_ADDRESS(glVertexAttribPointer);
422
423    if (!m_valid) {
424        LOG_ERROR("GraphicsContext3D: All needed OpenGL extensions are not available");
425        return;
426    }
427
428    // Create buffers for the canvas FBO.
429    genFramebuffers(/* count */ 1, &m_canvasFbo);
430
431    glGenTextures(1, &m_texture);
432    glBindTexture(GraphicsContext3D::TEXTURE_2D, m_texture);
433    glTexParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
434    glTexParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
435    glTexParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
436    glTexParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
437    glBindTexture(GraphicsContext3D::TEXTURE_2D, 0);
438
439    if (m_attrs.depth)
440        genRenderbuffers(/* count */ 1, &m_depthBuffer);
441
442    // Bind canvas FBO and set initial clear color to black.
443    m_currentFbo = m_canvasFbo;
444    bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_canvasFbo);
445    glClearColor(0.0, 0.0, 0.0, 0.0);
446}
447
448GraphicsContext3DInternal::~GraphicsContext3DInternal()
449{
450    m_glWidget->makeCurrent();
451    if (m_glWidget->isValid()) {
452        ::glDeleteTextures(1, &m_texture);
453        deleteRenderbuffers(1, &m_depthBuffer);
454        deleteFramebuffers(1, &m_canvasFbo);
455    }
456    delete m_glWidget;
457    m_glWidget = 0;
458}
459
460QGLWidget* GraphicsContext3DInternal::getViewportGLWidget()
461{
462    QWebPageClient* webPageClient = m_hostWindow->platformPageClient();
463    if (!webPageClient)
464        return 0;
465
466    QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>(webPageClient->ownerWidget());
467    if (scrollArea)
468        return qobject_cast<QGLWidget*>(scrollArea->viewport());
469
470    return 0;
471}
472
473static inline quint32 swapBgrToRgb(quint32 pixel)
474{
475    return ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
476}
477
478void GraphicsContext3DInternal::reshape(int width, int height)
479{
480    if (width == m_boundingRect.width() && height == m_boundingRect.height())
481        return;
482
483    m_boundingRect = QRectF(QPointF(0, 0), QSizeF(width, height));
484
485    m_glWidget->makeCurrent();
486
487    // Create color buffer
488    glBindTexture(GraphicsContext3D::TEXTURE_2D, m_texture);
489    if (m_attrs.alpha)
490        glTexImage2D(GraphicsContext3D::TEXTURE_2D, /* level */ 0, GraphicsContext3D::RGBA, width, height, /* border */ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, /* data */ 0);
491    else
492        glTexImage2D(GraphicsContext3D::TEXTURE_2D, /* level */ 0, GraphicsContext3D::RGB, width, height, /* border */ 0, GraphicsContext3D::RGB, GraphicsContext3D::UNSIGNED_BYTE, /* data */ 0);
493    glBindTexture(GraphicsContext3D::TEXTURE_2D, 0);
494
495    if (m_attrs.depth) {
496        // Create depth and stencil buffers.
497        bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
498#if defined(QT_OPENGL_ES_2)
499        renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT16, width, height);
500#else
501        if (m_attrs.stencil)
502            renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
503        else
504            renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT, width, height);
505#endif
506        bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
507    }
508
509    // Construct canvas FBO.
510    bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_canvasFbo);
511    framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_texture, 0);
512    if (m_attrs.depth)
513        framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
514#if !defined(QT_OPENGL_ES_2)
515    if (m_attrs.stencil)
516        framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
517#endif
518
519    GLenum status = checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER);
520    if (status != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
521        LOG_ERROR("GraphicsContext3D: Canvas FBO initialization failed.");
522        return;
523    }
524
525    int clearFlags = GraphicsContext3D::COLOR_BUFFER_BIT;
526    if (m_attrs.depth)
527        clearFlags |= GraphicsContext3D::DEPTH_BUFFER_BIT;
528    if (m_attrs.stencil)
529        clearFlags |= GraphicsContext3D::STENCIL_BUFFER_BIT;
530
531    glClear(clearFlags);
532    glFlush();
533}
534
535void GraphicsContext3DInternal::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
536{
537    Q_UNUSED(widget);
538
539    QRectF rect = option ? option->rect : boundingRect();
540
541    // Use direct texture mapping if WebGL canvas has a shared OpenGL context
542    // with browsers OpenGL context.
543    QGLWidget* viewportGLWidget = getViewportGLWidget();
544    if (viewportGLWidget && viewportGLWidget == m_viewportGLWidget && viewportGLWidget == painter->device()) {
545        viewportGLWidget->drawTexture(rect, m_texture);
546        return;
547    }
548
549    // Alternatively read pixels to a memory buffer.
550    QImage offscreenImage(rect.width(), rect.height(), QImage::Format_ARGB32);
551    quint32* imagePixels = reinterpret_cast<quint32*>(offscreenImage.bits());
552
553    m_glWidget->makeCurrent();
554    bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_canvasFbo);
555    glReadPixels(/* x */ 0, /* y */ 0, rect.width(), rect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, imagePixels);
556
557    bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_currentFbo);
558
559    // OpenGL gives us ABGR on 32 bits, and with the origin at the bottom left
560    // We need RGB32 or ARGB32_PM, with the origin at the top left.
561    quint32* pixelsSrc = imagePixels;
562    const int height = static_cast<int>(rect.height());
563    const int width = static_cast<int>(rect.width());
564    const int halfHeight = height / 2;
565    for (int row = 0; row < halfHeight; ++row) {
566        const int targetIdx = (height - 1 - row) * width;
567        quint32* pixelsDst = imagePixels + targetIdx;
568        for (int column = 0; column < width; ++column) {
569            quint32 tempPixel = *pixelsSrc;
570            *pixelsSrc = swapBgrToRgb(*pixelsDst);
571            *pixelsDst = swapBgrToRgb(tempPixel);
572            ++pixelsSrc;
573            ++pixelsDst;
574        }
575    }
576    if (static_cast<int>(height) % 2) {
577        for (int column = 0; column < width; ++column) {
578            *pixelsSrc = swapBgrToRgb(*pixelsSrc);
579            ++pixelsSrc;
580        }
581    }
582    painter->drawImage(/* x */ 0, /* y */ 0, offscreenImage);
583}
584
585QRectF GraphicsContext3DInternal::boundingRect() const
586{
587    return m_boundingRect;
588}
589
590void* GraphicsContext3DInternal::getProcAddress(const String& proc)
591{
592    String ext[3] = { "", "ARB", "EXT" };
593
594    for (int i = 0; i < 3; i++) {
595        String nameWithExt = proc + ext[i];
596
597        void* addr = m_glWidget->context()->getProcAddress(QString(nameWithExt));
598        if (addr)
599            return addr;
600    }
601
602    LOG_ERROR("GraphicsContext3D: Did not find GL function %s", proc.utf8().data());
603    m_valid = false;
604    return 0;
605}
606
607PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
608{
609    // This implementation doesn't currently support rendering directly to the HostWindow.
610    if (renderStyle == RenderDirectlyToHostWindow)
611        return 0;
612    RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(attrs, hostWindow, false));
613    return context->m_internal ? context.release() : 0;
614}
615
616GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, bool)
617    : m_internal(new GraphicsContext3DInternal(attrs, hostWindow))
618{
619    if (!m_internal->isValid())
620        m_internal = 0;
621}
622
623GraphicsContext3D::~GraphicsContext3D()
624{
625}
626
627PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D()
628{
629    return m_internal->m_glWidget;
630}
631
632Platform3DObject GraphicsContext3D::platformTexture() const
633{
634    return m_internal->m_texture;
635}
636
637PlatformLayer* GraphicsContext3D::platformLayer() const
638{
639    return m_internal.get();
640}
641
642void GraphicsContext3D::makeContextCurrent()
643{
644    m_internal->m_glWidget->makeCurrent();
645}
646
647void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
648{
649    m_internal->m_glWidget->makeCurrent();
650    HTMLCanvasElement* canvas = context->canvas();
651    ImageBuffer* imageBuffer = canvas->buffer();
652    QPainter* painter = imageBuffer->context()->platformContext();
653    m_internal->paint(painter, 0, 0);
654}
655
656PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData()
657{
658    // FIXME: This needs to be implemented for proper non-premultiplied-alpha
659    // support.
660    return 0;
661}
662
663void GraphicsContext3D::reshape(int width, int height)
664{
665    if ((width == m_currentWidth && height == m_currentHeight) || (!m_internal))
666        return;
667
668    m_currentWidth = width;
669    m_currentHeight = height;
670
671    m_internal->reshape(width, height);
672}
673
674IntSize GraphicsContext3D::getInternalFramebufferSize()
675{
676    return IntSize(m_currentWidth, m_currentHeight);
677}
678
679void GraphicsContext3D::activeTexture(GC3Denum texture)
680{
681    m_internal->m_glWidget->makeCurrent();
682    m_internal->activeTexture(texture);
683}
684
685void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject shader)
686{
687    ASSERT(program);
688    ASSERT(shader);
689    m_internal->m_glWidget->makeCurrent();
690    m_internal->attachShader(program, shader);
691}
692
693void GraphicsContext3D::getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount, GC3Dsizei* count, Platform3DObject* shaders)
694{
695    if (!program) {
696        synthesizeGLError(INVALID_VALUE);
697        return;
698    }
699
700    m_internal->m_glWidget->makeCurrent();
701    getAttachedShaders(program, maxCount, count, shaders);
702}
703
704void GraphicsContext3D::bindAttribLocation(Platform3DObject program, GC3Duint index, const String& name)
705{
706    ASSERT(program);
707    m_internal->m_glWidget->makeCurrent();
708    m_internal->bindAttribLocation(program, index, name.utf8().data());
709}
710
711void GraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer)
712{
713    m_internal->m_glWidget->makeCurrent();
714    m_internal->bindBuffer(target, buffer);
715}
716
717void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject buffer)
718{
719    m_internal->m_glWidget->makeCurrent();
720    m_internal->m_currentFbo = buffer ? buffer : m_internal->m_canvasFbo;
721    m_internal->bindFramebuffer(target, m_internal->m_currentFbo);
722}
723
724void GraphicsContext3D::bindRenderbuffer(GC3Denum target, Platform3DObject renderbuffer)
725{
726    m_internal->m_glWidget->makeCurrent();
727    m_internal->bindRenderbuffer(target, renderbuffer);
728}
729
730void GraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture)
731{
732    m_internal->m_glWidget->makeCurrent();
733    glBindTexture(target, texture);
734}
735
736void GraphicsContext3D::blendColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha)
737{
738    m_internal->m_glWidget->makeCurrent();
739    m_internal->blendColor(red, green, blue, alpha);
740}
741
742void GraphicsContext3D::blendEquation(GC3Denum mode)
743{
744    m_internal->m_glWidget->makeCurrent();
745    m_internal->blendEquation(mode);
746}
747
748void GraphicsContext3D::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
749{
750    m_internal->m_glWidget->makeCurrent();
751    m_internal->blendEquationSeparate(modeRGB, modeAlpha);
752}
753
754void GraphicsContext3D::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
755{
756    m_internal->m_glWidget->makeCurrent();
757    glBlendFunc(sfactor, dfactor);
758}
759
760void GraphicsContext3D::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
761{
762    m_internal->m_glWidget->makeCurrent();
763    m_internal->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
764}
765
766void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage)
767{
768    m_internal->m_glWidget->makeCurrent();
769    m_internal->bufferData(target, size, /* data */ 0, usage);
770}
771
772void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage)
773{
774    m_internal->m_glWidget->makeCurrent();
775    m_internal->bufferData(target, size, data, usage);
776}
777
778void GraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data)
779{
780    m_internal->m_glWidget->makeCurrent();
781    m_internal->bufferSubData(target, offset, size, data);
782}
783
784GC3Denum GraphicsContext3D::checkFramebufferStatus(GC3Denum target)
785{
786    m_internal->m_glWidget->makeCurrent();
787    return m_internal->checkFramebufferStatus(target);
788}
789
790void GraphicsContext3D::clearColor(GC3Dclampf r, GC3Dclampf g, GC3Dclampf b, GC3Dclampf a)
791{
792    m_internal->m_glWidget->makeCurrent();
793    glClearColor(r, g, b, a);
794}
795
796void GraphicsContext3D::clear(GC3Dbitfield mask)
797{
798    m_internal->m_glWidget->makeCurrent();
799    glClear(mask);
800}
801
802void GraphicsContext3D::clearDepth(GC3Dclampf depth)
803{
804    m_internal->m_glWidget->makeCurrent();
805#if defined(QT_OPENGL_ES_2)
806    glClearDepthf(depth);
807#else
808    glClearDepth(depth);
809#endif
810}
811
812void GraphicsContext3D::clearStencil(GC3Dint s)
813{
814    m_internal->m_glWidget->makeCurrent();
815    glClearStencil(s);
816}
817
818void GraphicsContext3D::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha)
819{
820    m_internal->m_glWidget->makeCurrent();
821    glColorMask(red, green, blue, alpha);
822}
823
824void GraphicsContext3D::compileShader(Platform3DObject shader)
825{
826    ASSERT(shader);
827    m_internal->m_glWidget->makeCurrent();
828    m_internal->compileShader(shader);
829}
830
831void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
832{
833    m_internal->m_glWidget->makeCurrent();
834    glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
835}
836
837void GraphicsContext3D::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
838{
839    m_internal->m_glWidget->makeCurrent();
840    glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
841}
842
843void GraphicsContext3D::cullFace(GC3Denum mode)
844{
845    m_internal->m_glWidget->makeCurrent();
846    glCullFace(mode);
847}
848
849void GraphicsContext3D::depthFunc(GC3Denum func)
850{
851    m_internal->m_glWidget->makeCurrent();
852    glDepthFunc(func);
853}
854
855void GraphicsContext3D::depthMask(GC3Dboolean flag)
856{
857    m_internal->m_glWidget->makeCurrent();
858    glDepthMask(flag);
859}
860
861void GraphicsContext3D::depthRange(GC3Dclampf zNear, GC3Dclampf zFar)
862{
863    m_internal->m_glWidget->makeCurrent();
864#if defined(QT_OPENGL_ES_2)
865    glDepthRangef(zNear, zFar);
866#else
867    glDepthRange(zNear, zFar);
868#endif
869}
870
871void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject shader)
872{
873    ASSERT(program);
874    ASSERT(shader);
875    m_internal->m_glWidget->makeCurrent();
876    m_internal->detachShader(program, shader);
877}
878
879void GraphicsContext3D::disable(GC3Denum cap)
880{
881    m_internal->m_glWidget->makeCurrent();
882    glDisable(cap);
883}
884
885void GraphicsContext3D::disableVertexAttribArray(GC3Duint index)
886{
887    m_internal->m_glWidget->makeCurrent();
888    m_internal->disableVertexAttribArray(index);
889}
890
891void GraphicsContext3D::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
892{
893    m_internal->m_glWidget->makeCurrent();
894    glDrawArrays(mode, first, count);
895}
896
897void GraphicsContext3D::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset)
898{
899    m_internal->m_glWidget->makeCurrent();
900    glDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)));
901}
902
903void GraphicsContext3D::enable(GC3Denum cap)
904{
905    m_internal->m_glWidget->makeCurrent();
906    glEnable(cap);
907}
908
909void GraphicsContext3D::enableVertexAttribArray(GC3Duint index)
910{
911    m_internal->m_glWidget->makeCurrent();
912    m_internal->enableVertexAttribArray(index);
913}
914
915void GraphicsContext3D::finish()
916{
917    m_internal->m_glWidget->makeCurrent();
918    glFinish();
919}
920
921void GraphicsContext3D::flush()
922{
923    m_internal->m_glWidget->makeCurrent();
924    glFlush();
925}
926
927void GraphicsContext3D::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, Platform3DObject buffer)
928{
929    m_internal->m_glWidget->makeCurrent();
930    m_internal->framebufferRenderbuffer(target, attachment, renderbuffertarget, buffer);
931}
932
933void GraphicsContext3D::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, Platform3DObject texture, GC3Dint level)
934{
935    m_internal->m_glWidget->makeCurrent();
936    m_internal->framebufferTexture2D(target, attachment, textarget, texture, level);
937}
938
939void GraphicsContext3D::frontFace(GC3Denum mode)
940{
941    m_internal->m_glWidget->makeCurrent();
942    glFrontFace(mode);
943}
944
945void GraphicsContext3D::generateMipmap(GC3Denum target)
946{
947    m_internal->m_glWidget->makeCurrent();
948    m_internal->generateMipmap(target);
949}
950
951bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info)
952{
953    if (!program) {
954        synthesizeGLError(INVALID_VALUE);
955        return false;
956    }
957
958    m_internal->m_glWidget->makeCurrent();
959
960    GLint maxLength = 0;
961    m_internal->getProgramiv(program, GraphicsContext3D::ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength);
962
963    GLchar* name = (GLchar*) fastMalloc(maxLength);
964    GLsizei nameLength = 0;
965    GLint size = 0;
966    GLenum type = 0;
967
968    m_internal->getActiveAttrib(program, index, maxLength, &nameLength, &size, &type, name);
969
970    if (!nameLength) {
971        fastFree(name);
972        return false;
973    }
974
975    info.name = String(name, nameLength);
976    info.type = type;
977    info.size = size;
978
979    fastFree(name);
980    return true;
981}
982
983bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
984{
985    if (!program) {
986        synthesizeGLError(INVALID_VALUE);
987        return false;
988    }
989
990    m_internal->m_glWidget->makeCurrent();
991
992    GLint maxLength = 0;
993    m_internal->getProgramiv(static_cast<GLuint>(program), GraphicsContext3D::ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
994
995    GLchar* name = (GLchar*) fastMalloc(maxLength);
996    GLsizei nameLength = 0;
997    GLint size = 0;
998    GLenum type = 0;
999
1000    m_internal->getActiveUniform(static_cast<GLuint>(program), index, maxLength, &nameLength, &size, &type, name);
1001
1002    if (!nameLength) {
1003        fastFree(name);
1004        return false;
1005    }
1006
1007    info.name = String(name, nameLength);
1008    info.type = type;
1009    info.size = size;
1010
1011    fastFree(name);
1012    return true;
1013}
1014
1015int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name)
1016{
1017    if (!program)
1018        return -1;
1019
1020    m_internal->m_glWidget->makeCurrent();
1021    return m_internal->getAttribLocation(program, name.utf8().data());
1022}
1023
1024GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
1025{
1026    return m_internal->m_attrs;
1027}
1028
1029GC3Denum GraphicsContext3D::getError()
1030{
1031    if (m_internal->m_syntheticErrors.size() > 0) {
1032        ListHashSet<GC3Denum>::iterator iter = m_internal->m_syntheticErrors.begin();
1033        GC3Denum err = *iter;
1034        m_internal->m_syntheticErrors.remove(iter);
1035        return err;
1036    }
1037
1038    m_internal->m_glWidget->makeCurrent();
1039    return glGetError();
1040}
1041
1042String GraphicsContext3D::getString(GC3Denum name)
1043{
1044    m_internal->m_glWidget->makeCurrent();
1045    return String((const char*) glGetString(name));
1046}
1047
1048void GraphicsContext3D::hint(GC3Denum target, GC3Denum mode)
1049{
1050    m_internal->m_glWidget->makeCurrent();
1051    glHint(target, mode);
1052}
1053
1054GC3Dboolean GraphicsContext3D::isBuffer(Platform3DObject buffer)
1055{
1056    if (!buffer)
1057        return GL_FALSE;
1058
1059    m_internal->m_glWidget->makeCurrent();
1060    return m_internal->isBuffer(buffer);
1061}
1062
1063GC3Dboolean GraphicsContext3D::isEnabled(GC3Denum cap)
1064{
1065    m_internal->m_glWidget->makeCurrent();
1066    return glIsEnabled(cap);
1067}
1068
1069GC3Dboolean GraphicsContext3D::isFramebuffer(Platform3DObject framebuffer)
1070{
1071    if (!framebuffer)
1072        return GL_FALSE;
1073
1074    m_internal->m_glWidget->makeCurrent();
1075    return m_internal->isFramebuffer(framebuffer);
1076}
1077
1078GC3Dboolean GraphicsContext3D::isProgram(Platform3DObject program)
1079{
1080    if (!program)
1081        return GL_FALSE;
1082
1083    m_internal->m_glWidget->makeCurrent();
1084    return m_internal->isProgram(program);
1085}
1086
1087GC3Dboolean GraphicsContext3D::isRenderbuffer(Platform3DObject renderbuffer)
1088{
1089    if (!renderbuffer)
1090        return GL_FALSE;
1091
1092    m_internal->m_glWidget->makeCurrent();
1093    return m_internal->isRenderbuffer(renderbuffer);
1094}
1095
1096GC3Dboolean GraphicsContext3D::isShader(Platform3DObject shader)
1097{
1098    if (!shader)
1099        return GL_FALSE;
1100
1101    m_internal->m_glWidget->makeCurrent();
1102    return m_internal->isShader(shader);
1103}
1104
1105GC3Dboolean GraphicsContext3D::isTexture(Platform3DObject texture)
1106{
1107    if (!texture)
1108        return GL_FALSE;
1109
1110    m_internal->m_glWidget->makeCurrent();
1111    return glIsTexture(texture);
1112}
1113
1114void GraphicsContext3D::lineWidth(GC3Dfloat width)
1115{
1116    m_internal->m_glWidget->makeCurrent();
1117    glLineWidth(static_cast<float>(width));
1118}
1119
1120void GraphicsContext3D::linkProgram(Platform3DObject program)
1121{
1122    ASSERT(program);
1123    m_internal->m_glWidget->makeCurrent();
1124    m_internal->linkProgram(program);
1125}
1126
1127void GraphicsContext3D::pixelStorei(GC3Denum paramName, GC3Dint param)
1128{
1129    m_internal->m_glWidget->makeCurrent();
1130    glPixelStorei(paramName, param);
1131}
1132
1133void GraphicsContext3D::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
1134{
1135    m_internal->m_glWidget->makeCurrent();
1136    glPolygonOffset(factor, units);
1137}
1138
1139void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
1140{
1141    m_internal->m_glWidget->makeCurrent();
1142
1143    if (type != GraphicsContext3D::UNSIGNED_BYTE || format != GraphicsContext3D::RGBA)
1144        return;
1145
1146    glReadPixels(x, y, width, height, format, type, data);
1147}
1148
1149void GraphicsContext3D::releaseShaderCompiler()
1150{
1151    m_internal->m_glWidget->makeCurrent();
1152    notImplemented();
1153}
1154
1155void GraphicsContext3D::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
1156{
1157    m_internal->m_glWidget->makeCurrent();
1158#if !defined(QT_OPENGL_ES_2)
1159    switch (internalformat) {
1160    case DEPTH_STENCIL:
1161        internalformat = GL_DEPTH24_STENCIL8;
1162        break;
1163    case DEPTH_COMPONENT16:
1164        internalformat = DEPTH_COMPONENT;
1165        break;
1166    case RGBA4:
1167    case RGB5_A1:
1168        internalformat = RGBA;
1169        break;
1170    case RGB565:
1171        internalformat = RGB;
1172        break;
1173    }
1174#endif
1175    m_internal->renderbufferStorage(target, internalformat, width, height);
1176}
1177
1178void GraphicsContext3D::sampleCoverage(GC3Dclampf value, GC3Dboolean invert)
1179{
1180    m_internal->m_glWidget->makeCurrent();
1181    m_internal->sampleCoverage(value, invert);
1182}
1183
1184void GraphicsContext3D::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
1185{
1186    m_internal->m_glWidget->makeCurrent();
1187    glScissor(x, y, width, height);
1188}
1189
1190void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& source)
1191{
1192    ASSERT(shader);
1193
1194    m_internal->m_glWidget->makeCurrent();
1195
1196    String prefixedSource;
1197
1198#if defined (QT_OPENGL_ES_2)
1199    prefixedSource.append("precision mediump float;\n");
1200#endif
1201
1202    prefixedSource.append(source);
1203
1204    CString sourceCS = prefixedSource.utf8();
1205    const char* data = sourceCS.data();
1206    int length = prefixedSource.length();
1207    m_internal->shaderSource((GLuint) shader, /* count */ 1, &data, &length);
1208}
1209
1210void GraphicsContext3D::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
1211{
1212    m_internal->m_glWidget->makeCurrent();
1213    glStencilFunc(func, ref, mask);
1214}
1215
1216void GraphicsContext3D::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
1217{
1218    m_internal->m_glWidget->makeCurrent();
1219    m_internal->stencilFuncSeparate(face, func, ref, mask);
1220}
1221
1222void GraphicsContext3D::stencilMask(GC3Duint mask)
1223{
1224    m_internal->m_glWidget->makeCurrent();
1225    glStencilMask(mask);
1226}
1227
1228void GraphicsContext3D::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
1229{
1230    m_internal->m_glWidget->makeCurrent();
1231    m_internal->stencilMaskSeparate(face, mask);
1232}
1233
1234void GraphicsContext3D::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
1235{
1236    m_internal->m_glWidget->makeCurrent();
1237    glStencilOp(fail, zfail, zpass);
1238}
1239
1240void GraphicsContext3D::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
1241{
1242    m_internal->m_glWidget->makeCurrent();
1243    m_internal->stencilOpSeparate(face, fail, zfail, zpass);
1244}
1245
1246void GraphicsContext3D::texParameterf(GC3Denum target, GC3Denum paramName, GC3Dfloat value)
1247{
1248    m_internal->m_glWidget->makeCurrent();
1249    glTexParameterf(target, paramName, value);
1250}
1251
1252void GraphicsContext3D::texParameteri(GC3Denum target, GC3Denum paramName, GC3Dint value)
1253{
1254    m_internal->m_glWidget->makeCurrent();
1255    glTexParameteri(target, paramName, value);
1256}
1257
1258void GraphicsContext3D::uniform1f(GC3Dint location, GC3Dfloat v0)
1259{
1260    m_internal->m_glWidget->makeCurrent();
1261    m_internal->uniform1f(location, v0);
1262}
1263
1264void GraphicsContext3D::uniform1fv(GC3Dint location, GC3Dfloat* array, GC3Dsizei size)
1265{
1266    m_internal->m_glWidget->makeCurrent();
1267    m_internal->uniform1fv(location, size, array);
1268}
1269
1270void GraphicsContext3D::uniform2f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1)
1271{
1272    m_internal->m_glWidget->makeCurrent();
1273    m_internal->uniform2f(location, v0, v1);
1274}
1275
1276void GraphicsContext3D::uniform2fv(GC3Dint location, GC3Dfloat* array, GC3Dsizei size)
1277{
1278    m_internal->m_glWidget->makeCurrent();
1279    m_internal->uniform2fv(location, size, array);
1280}
1281
1282void GraphicsContext3D::uniform3f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
1283{
1284    m_internal->m_glWidget->makeCurrent();
1285    m_internal->uniform3f(location, v0, v1, v2);
1286}
1287
1288void GraphicsContext3D::uniform3fv(GC3Dint location, GC3Dfloat* array, GC3Dsizei size)
1289{
1290    m_internal->m_glWidget->makeCurrent();
1291    m_internal->uniform3fv(location, size, array);
1292}
1293
1294void GraphicsContext3D::uniform4f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
1295{
1296    m_internal->m_glWidget->makeCurrent();
1297    m_internal->uniform4f(location, v0, v1, v2, v3);
1298}
1299
1300void GraphicsContext3D::uniform4fv(GC3Dint location, GC3Dfloat* array, GC3Dsizei size)
1301{
1302    m_internal->m_glWidget->makeCurrent();
1303    m_internal->uniform4fv(location, size, array);
1304}
1305
1306void GraphicsContext3D::uniform1i(GC3Dint location, GC3Dint v0)
1307{
1308    m_internal->m_glWidget->makeCurrent();
1309    m_internal->uniform1i(location, v0);
1310}
1311
1312void GraphicsContext3D::uniform1iv(GC3Dint location, GC3Dint* array, GC3Dsizei size)
1313{
1314    m_internal->m_glWidget->makeCurrent();
1315    m_internal->uniform1iv(location, size, array);
1316}
1317
1318void GraphicsContext3D::uniform2i(GC3Dint location, GC3Dint v0, GC3Dint v1)
1319{
1320    m_internal->m_glWidget->makeCurrent();
1321    m_internal->uniform2i(location, v0, v1);
1322}
1323
1324void GraphicsContext3D::uniform2iv(GC3Dint location, GC3Dint* array, GC3Dsizei size)
1325{
1326    m_internal->m_glWidget->makeCurrent();
1327    m_internal->uniform2iv(location, size, array);
1328}
1329
1330void GraphicsContext3D::uniform3i(GC3Dint location, GC3Dint v0, GC3Dint v1, GC3Dint v2)
1331{
1332    m_internal->m_glWidget->makeCurrent();
1333    m_internal->uniform3i(location, v0, v1, v2);
1334}
1335
1336void GraphicsContext3D::uniform3iv(GC3Dint location, GC3Dint* array, GC3Dsizei size)
1337{
1338    m_internal->m_glWidget->makeCurrent();
1339    m_internal->uniform3iv(location, size, array);
1340}
1341
1342void GraphicsContext3D::uniform4i(GC3Dint location, GC3Dint v0, GC3Dint v1, GC3Dint v2, GC3Dint v3)
1343{
1344    m_internal->m_glWidget->makeCurrent();
1345    m_internal->uniform4i(location, v0, v1, v2, v3);
1346}
1347
1348void GraphicsContext3D::uniform4iv(GC3Dint location, GC3Dint* array, GC3Dsizei size)
1349{
1350    m_internal->m_glWidget->makeCurrent();
1351    m_internal->uniform4iv(location, size, array);
1352}
1353
1354void GraphicsContext3D::uniformMatrix2fv(GC3Dint location, GC3Dboolean transpose, GC3Dfloat* array, GC3Dsizei size)
1355{
1356    m_internal->m_glWidget->makeCurrent();
1357    m_internal->uniformMatrix2fv(location, size, transpose, array);
1358}
1359
1360void GraphicsContext3D::uniformMatrix3fv(GC3Dint location, GC3Dboolean transpose, GC3Dfloat* array, GC3Dsizei size)
1361{
1362    m_internal->m_glWidget->makeCurrent();
1363    m_internal->uniformMatrix3fv(location, size, transpose, array);
1364}
1365
1366void GraphicsContext3D::uniformMatrix4fv(GC3Dint location, GC3Dboolean transpose, GC3Dfloat* array, GC3Dsizei size)
1367{
1368    m_internal->m_glWidget->makeCurrent();
1369    m_internal->uniformMatrix4fv(location, size, transpose, array);
1370}
1371
1372void GraphicsContext3D::useProgram(Platform3DObject program)
1373{
1374    ASSERT(program);
1375
1376    m_internal->m_glWidget->makeCurrent();
1377    m_internal->useProgram(program);
1378}
1379
1380void GraphicsContext3D::validateProgram(Platform3DObject program)
1381{
1382    ASSERT(program);
1383
1384    m_internal->m_glWidget->makeCurrent();
1385    m_internal->validateProgram(program);
1386}
1387
1388void GraphicsContext3D::vertexAttrib1f(GC3Duint index, GC3Dfloat v0)
1389{
1390    m_internal->m_glWidget->makeCurrent();
1391    m_internal->vertexAttrib1f(index, v0);
1392}
1393
1394void GraphicsContext3D::vertexAttrib1fv(GC3Duint index, GC3Dfloat* array)
1395{
1396    m_internal->m_glWidget->makeCurrent();
1397    m_internal->vertexAttrib1fv(index, array);
1398}
1399
1400void GraphicsContext3D::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1)
1401{
1402    m_internal->m_glWidget->makeCurrent();
1403    m_internal->vertexAttrib2f(index, v0, v1);
1404}
1405
1406void GraphicsContext3D::vertexAttrib2fv(GC3Duint index, GC3Dfloat* array)
1407{
1408    m_internal->m_glWidget->makeCurrent();
1409    m_internal->vertexAttrib2fv(index, array);
1410}
1411
1412void GraphicsContext3D::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
1413{
1414    m_internal->m_glWidget->makeCurrent();
1415    m_internal->vertexAttrib3f(index, v0, v1, v2);
1416}
1417
1418void GraphicsContext3D::vertexAttrib3fv(GC3Duint index, GC3Dfloat* array)
1419{
1420    m_internal->m_glWidget->makeCurrent();
1421    m_internal->vertexAttrib3fv(index, array);
1422}
1423
1424void GraphicsContext3D::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
1425{
1426    m_internal->m_glWidget->makeCurrent();
1427    m_internal->vertexAttrib4f(index, v0, v1, v2, v3);
1428}
1429
1430void GraphicsContext3D::vertexAttrib4fv(GC3Duint index, GC3Dfloat* array)
1431{
1432    m_internal->m_glWidget->makeCurrent();
1433    m_internal->vertexAttrib4fv(index, array);
1434}
1435
1436void GraphicsContext3D::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset)
1437{
1438    m_internal->m_glWidget->makeCurrent();
1439    m_internal->vertexAttribPointer(index, size, type, normalized, stride, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)));
1440}
1441
1442void GraphicsContext3D::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
1443{
1444    m_internal->m_glWidget->makeCurrent();
1445    glViewport(x, y, width, height);
1446}
1447
1448void GraphicsContext3D::getBooleanv(GC3Denum paramName, GC3Dboolean* value)
1449{
1450    m_internal->m_glWidget->makeCurrent();
1451    glGetBooleanv(paramName, value);
1452}
1453
1454void GraphicsContext3D::getBufferParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value)
1455{
1456    m_internal->m_glWidget->makeCurrent();
1457    m_internal->getBufferParameteriv(target, paramName, value);
1458}
1459
1460void GraphicsContext3D::getFloatv(GC3Denum paramName, GC3Dfloat* value)
1461{
1462    m_internal->m_glWidget->makeCurrent();
1463    glGetFloatv(paramName, value);
1464}
1465
1466void GraphicsContext3D::getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment, GC3Denum paramName, GC3Dint* value)
1467{
1468    m_internal->m_glWidget->makeCurrent();
1469    m_internal->getFramebufferAttachmentParameteriv(target, attachment, paramName, value);
1470}
1471
1472void GraphicsContext3D::getIntegerv(GC3Denum paramName, GC3Dint* value)
1473{
1474    m_internal->m_glWidget->makeCurrent();
1475    glGetIntegerv(paramName, value);
1476}
1477
1478void GraphicsContext3D::getProgramiv(Platform3DObject program, GC3Denum paramName, GC3Dint* value)
1479{
1480    m_internal->m_glWidget->makeCurrent();
1481    m_internal->getProgramiv(program, paramName, value);
1482}
1483
1484String GraphicsContext3D::getProgramInfoLog(Platform3DObject program)
1485{
1486    m_internal->m_glWidget->makeCurrent();
1487
1488    GLint length = 0;
1489    m_internal->getProgramiv(program, GraphicsContext3D::INFO_LOG_LENGTH, &length);
1490
1491    GLsizei size = 0;
1492
1493    GLchar* info = (GLchar*) fastMalloc(length);
1494    if (!info)
1495        return "";
1496
1497    m_internal->getProgramInfoLog(program, length, &size, info);
1498
1499    String result(info);
1500    fastFree(info);
1501
1502    return result;
1503}
1504
1505void GraphicsContext3D::getRenderbufferParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value)
1506{
1507    m_internal->m_glWidget->makeCurrent();
1508    m_internal->getRenderbufferParameteriv(target, paramName, value);
1509}
1510
1511void GraphicsContext3D::getShaderiv(Platform3DObject shader, GC3Denum paramName, GC3Dint* value)
1512{
1513    ASSERT(shader);
1514    m_internal->m_glWidget->makeCurrent();
1515    m_internal->getShaderiv(shader, paramName, value);
1516}
1517
1518String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader)
1519{
1520    m_internal->m_glWidget->makeCurrent();
1521
1522    GLint length = 0;
1523    m_internal->getShaderiv(shader, GraphicsContext3D::INFO_LOG_LENGTH, &length);
1524
1525    GLsizei size = 0;
1526    GLchar* info = (GLchar*) fastMalloc(length);
1527    if (!info)
1528        return "";
1529
1530    m_internal->getShaderInfoLog(shader, length, &size, info);
1531
1532    String result(info);
1533    fastFree(info);
1534
1535    return result;
1536}
1537
1538String GraphicsContext3D::getShaderSource(Platform3DObject shader)
1539{
1540    m_internal->m_glWidget->makeCurrent();
1541
1542    GLint length = 0;
1543    m_internal->getShaderiv(shader, GraphicsContext3D::SHADER_SOURCE_LENGTH, &length);
1544
1545    GLsizei size = 0;
1546    GLchar* info = (GLchar*) fastMalloc(length);
1547    if (!info)
1548        return "";
1549
1550    m_internal->getShaderSource(shader, length, &size, info);
1551
1552    String result(info);
1553    fastFree(info);
1554
1555    return result;
1556}
1557
1558void GraphicsContext3D::getTexParameterfv(GC3Denum target, GC3Denum paramName, GC3Dfloat* value)
1559{
1560    m_internal->m_glWidget->makeCurrent();
1561    glGetTexParameterfv(target, paramName, value);
1562}
1563
1564void GraphicsContext3D::getTexParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value)
1565{
1566    m_internal->m_glWidget->makeCurrent();
1567    glGetTexParameteriv(target, paramName, value);
1568}
1569
1570void GraphicsContext3D::getUniformfv(Platform3DObject program, GC3Dint location, GC3Dfloat* value)
1571{
1572    m_internal->m_glWidget->makeCurrent();
1573    m_internal->getUniformfv(program, location, value);
1574}
1575
1576void GraphicsContext3D::getUniformiv(Platform3DObject program, GC3Dint location, GC3Dint* value)
1577{
1578    m_internal->m_glWidget->makeCurrent();
1579    m_internal->getUniformiv(program, location, value);
1580}
1581
1582GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name)
1583{
1584    ASSERT(program);
1585
1586    m_internal->m_glWidget->makeCurrent();
1587    return m_internal->getUniformLocation(program, name.utf8().data());
1588}
1589
1590void GraphicsContext3D::getVertexAttribfv(GC3Duint index, GC3Denum paramName, GC3Dfloat* value)
1591{
1592    m_internal->m_glWidget->makeCurrent();
1593    m_internal->getVertexAttribfv(index, paramName, value);
1594}
1595
1596void GraphicsContext3D::getVertexAttribiv(GC3Duint index, GC3Denum paramName, GC3Dint* value)
1597{
1598    m_internal->m_glWidget->makeCurrent();
1599    m_internal->getVertexAttribiv(index, paramName, value);
1600}
1601
1602GC3Dsizeiptr GraphicsContext3D::getVertexAttribOffset(GC3Duint index, GC3Denum paramName)
1603{
1604    m_internal->m_glWidget->makeCurrent();
1605
1606    GLvoid* pointer = 0;
1607    m_internal->getVertexAttribPointerv(index, paramName, &pointer);
1608    return static_cast<GC3Dsizeiptr>(reinterpret_cast<intptr_t>(pointer));
1609}
1610
1611bool GraphicsContext3D::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
1612{
1613    m_internal->m_glWidget->makeCurrent();
1614    glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
1615    return true;
1616}
1617
1618void GraphicsContext3D::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoff, GC3Dint yoff, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels)
1619{
1620    m_internal->m_glWidget->makeCurrent();
1621    glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
1622}
1623
1624Platform3DObject GraphicsContext3D::createBuffer()
1625{
1626    m_internal->m_glWidget->makeCurrent();
1627    GLuint handle = 0;
1628    m_internal->genBuffers(/* count */ 1, &handle);
1629    return handle;
1630}
1631
1632Platform3DObject GraphicsContext3D::createFramebuffer()
1633{
1634    m_internal->m_glWidget->makeCurrent();
1635    GLuint handle = 0;
1636    m_internal->genFramebuffers(/* count */ 1, &handle);
1637    return handle;
1638}
1639
1640Platform3DObject GraphicsContext3D::createProgram()
1641{
1642    m_internal->m_glWidget->makeCurrent();
1643    return m_internal->createProgram();
1644}
1645
1646Platform3DObject GraphicsContext3D::createRenderbuffer()
1647{
1648    m_internal->m_glWidget->makeCurrent();
1649    GLuint handle = 0;
1650    m_internal->genRenderbuffers(/* count */ 1, &handle);
1651    return handle;
1652}
1653
1654Platform3DObject GraphicsContext3D::createShader(GC3Denum type)
1655{
1656    m_internal->m_glWidget->makeCurrent();
1657    return m_internal->createShader(type);
1658}
1659
1660Platform3DObject GraphicsContext3D::createTexture()
1661{
1662    m_internal->m_glWidget->makeCurrent();
1663    GLuint handle = 0;
1664    glGenTextures(1, &handle);
1665    return handle;
1666}
1667
1668void GraphicsContext3D::deleteBuffer(Platform3DObject buffer)
1669{
1670    m_internal->m_glWidget->makeCurrent();
1671    m_internal->deleteBuffers(1, &buffer);
1672}
1673
1674void GraphicsContext3D::deleteFramebuffer(Platform3DObject framebuffer)
1675{
1676    m_internal->m_glWidget->makeCurrent();
1677    m_internal->deleteFramebuffers(1, &framebuffer);
1678}
1679
1680void GraphicsContext3D::deleteProgram(Platform3DObject program)
1681{
1682    m_internal->m_glWidget->makeCurrent();
1683    m_internal->deleteProgram(program);
1684}
1685
1686void GraphicsContext3D::deleteRenderbuffer(Platform3DObject renderbuffer)
1687{
1688    m_internal->m_glWidget->makeCurrent();
1689    m_internal->deleteRenderbuffers(1, &renderbuffer);
1690}
1691
1692void GraphicsContext3D::deleteShader(Platform3DObject shader)
1693{
1694    m_internal->m_glWidget->makeCurrent();
1695    m_internal->deleteShader(shader);
1696}
1697
1698void GraphicsContext3D::deleteTexture(Platform3DObject texture)
1699{
1700    m_internal->m_glWidget->makeCurrent();
1701    glDeleteTextures(1, &texture);
1702}
1703
1704void GraphicsContext3D::synthesizeGLError(GC3Denum error)
1705{
1706    m_internal->m_syntheticErrors.add(error);
1707}
1708
1709void GraphicsContext3D::markLayerComposited()
1710{
1711    m_internal->m_layerComposited = true;
1712}
1713
1714void GraphicsContext3D::markContextChanged()
1715{
1716    // FIXME: Any accelerated compositor needs to be told to re-read from here.
1717    m_internal->m_layerComposited = false;
1718}
1719
1720bool GraphicsContext3D::layerComposited() const
1721{
1722    return m_internal->m_layerComposited;
1723}
1724
1725Extensions3D* GraphicsContext3D::getExtensions()
1726{
1727    if (!m_internal->m_extensions)
1728        m_internal->m_extensions = adoptPtr(new Extensions3DQt);
1729    return m_internal->m_extensions.get();
1730}
1731
1732bool GraphicsContext3D::getImageData(Image* image,
1733                                     GC3Denum format,
1734                                     GC3Denum type,
1735                                     bool premultiplyAlpha,
1736                                     bool ignoreGammaAndColorProfile,
1737                                     Vector<uint8_t>& outputVector)
1738{
1739    UNUSED_PARAM(ignoreGammaAndColorProfile);
1740    if (!image)
1741        return false;
1742    QPixmap* nativePixmap = image->nativeImageForCurrentFrame();
1743    if (!nativePixmap)
1744        return false;
1745
1746    AlphaOp neededAlphaOp = AlphaDoNothing;
1747    if (!premultiplyAlpha)
1748        // FIXME: must fetch the image data before the premultiplication step
1749        neededAlphaOp = AlphaDoUnmultiply;
1750    QImage nativeImage = nativePixmap->toImage().convertToFormat(QImage::Format_ARGB32);
1751    outputVector.resize(nativeImage.byteCount());
1752    return packPixels(nativeImage.rgbSwapped().bits(), SourceFormatRGBA8, image->width(), image->height(), 0,
1753                      format, type, neededAlphaOp, outputVector.data());
1754}
1755
1756void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>)
1757{
1758}
1759
1760}
1761
1762#endif // ENABLE(WEBGL)
1763