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