1/*
2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32
33#if ENABLE(WEBGL)
34
35#include "GraphicsContext3D.h"
36
37#include "CachedImage.h"
38#include "WebGLLayerChromium.h"
39#include "CanvasRenderingContext.h"
40#include "Chrome.h"
41#include "ChromeClientImpl.h"
42#include "Extensions3DChromium.h"
43#include "GraphicsContext3DInternal.h"
44#include "HTMLCanvasElement.h"
45#include "HTMLImageElement.h"
46#include "ImageBuffer.h"
47#include "ImageData.h"
48#include "WebGraphicsContext3D.h"
49#include "WebKit.h"
50#include "WebKitClient.h"
51#include "WebViewImpl.h"
52
53#include <stdio.h>
54#include <wtf/FastMalloc.h>
55#include <wtf/text/CString.h>
56
57#if USE(CG)
58#include "GraphicsContext.h"
59#include "WebGLRenderingContext.h"
60#include <CoreGraphics/CGContext.h>
61#include <CoreGraphics/CGImage.h>
62#endif
63
64// There are two levels of delegation in this file:
65//
66//   1. GraphicsContext3D delegates to GraphicsContext3DInternal. This is done
67//      so that we have some place to store data members common among
68//      implementations; GraphicsContext3D only provides us the m_internal
69//      pointer. We always delegate to the GraphicsContext3DInternal. While we
70//      could sidestep it and go directly to the WebGraphicsContext3D in some
71//      cases, it is better for consistency to always delegate through it.
72//
73//   2. GraphicsContext3DInternal delegates to an implementation of
74//      WebGraphicsContext3D. This is done so we have a place to inject an
75//      implementation which remotes the OpenGL calls across processes.
76
77namespace WebCore {
78
79//----------------------------------------------------------------------
80// GraphicsContext3DInternal
81
82GraphicsContext3DInternal::GraphicsContext3DInternal()
83    : m_webViewImpl(0)
84    , m_initializedAvailableExtensions(false)
85    , m_layerComposited(false)
86#if USE(SKIA)
87#elif USE(CG)
88    , m_renderOutput(0)
89#else
90#error Must port to your platform
91#endif
92{
93}
94
95GraphicsContext3DInternal::~GraphicsContext3DInternal()
96{
97#if USE(CG)
98    if (m_renderOutput)
99        delete[] m_renderOutput;
100#endif
101}
102
103bool GraphicsContext3DInternal::initialize(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, bool renderDirectlyToHostWindow)
104{
105    WebKit::WebGraphicsContext3D::Attributes webAttributes;
106    webAttributes.alpha = attrs.alpha;
107    webAttributes.depth = attrs.depth;
108    webAttributes.stencil = attrs.stencil;
109    webAttributes.antialias = attrs.antialias;
110    webAttributes.premultipliedAlpha = attrs.premultipliedAlpha;
111    webAttributes.canRecoverFromContextLoss = attrs.canRecoverFromContextLoss;
112    WebKit::WebGraphicsContext3D* webContext = WebKit::webKitClient()->createGraphicsContext3D();
113    if (!webContext)
114        return false;
115
116    Chrome* chrome = static_cast<Chrome*>(hostWindow);
117    m_webViewImpl = static_cast<WebKit::WebViewImpl*>(chrome->client()->webView());
118
119    if (!m_webViewImpl)
120        return false;
121    if (!webContext->initialize(webAttributes, m_webViewImpl, renderDirectlyToHostWindow)) {
122        delete webContext;
123        return false;
124    }
125    m_impl.set(webContext);
126
127#if USE(ACCELERATED_COMPOSITING)
128    m_compositingLayer = WebGLLayerChromium::create(0);
129#endif
130    return true;
131}
132
133WebKit::WebGraphicsContext3D* GraphicsContext3DInternal::extractWebGraphicsContext3D(GraphicsContext3D* context)
134{
135    if (!context)
136        return 0;
137    return context->m_internal->m_impl.get();
138}
139
140PlatformGraphicsContext3D GraphicsContext3DInternal::platformGraphicsContext3D() const
141{
142    return m_impl.get();
143}
144
145Platform3DObject GraphicsContext3DInternal::platformTexture() const
146{
147    return m_impl->getPlatformTextureId();
148}
149
150void GraphicsContext3DInternal::prepareTexture()
151{
152    m_impl->prepareTexture();
153}
154
155#if USE(ACCELERATED_COMPOSITING)
156WebGLLayerChromium* GraphicsContext3DInternal::platformLayer() const
157{
158    return m_compositingLayer.get();
159}
160#endif
161
162void GraphicsContext3DInternal::markContextChanged()
163{
164#if USE(ACCELERATED_COMPOSITING)
165    platformLayer()->setTextureUpdated();
166#endif
167    m_layerComposited = false;
168}
169
170void GraphicsContext3DInternal::markLayerComposited()
171{
172    m_layerComposited = true;
173}
174
175bool GraphicsContext3DInternal::layerComposited() const
176{
177    return m_layerComposited;
178}
179
180void GraphicsContext3DInternal::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
181{
182    HTMLCanvasElement* canvas = context->canvas();
183    ImageBuffer* imageBuffer = canvas->buffer();
184    unsigned char* pixels = 0;
185#if USE(SKIA)
186    const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bitmap();
187    const SkBitmap* readbackBitmap = 0;
188    ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config);
189    if (canvasBitmap->width() == m_impl->width() && canvasBitmap->height() == m_impl->height()) {
190        // This is the fastest and most common case. We read back
191        // directly into the canvas's backing store.
192        readbackBitmap = canvasBitmap;
193        m_resizingBitmap.reset();
194    } else {
195        // We need to allocate a temporary bitmap for reading back the
196        // pixel data. We will then use Skia to rescale this bitmap to
197        // the size of the canvas's backing store.
198        if (m_resizingBitmap.width() != m_impl->width() || m_resizingBitmap.height() != m_impl->height()) {
199            m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config,
200                                       m_impl->width(),
201                                       m_impl->height());
202            if (!m_resizingBitmap.allocPixels())
203                return;
204        }
205        readbackBitmap = &m_resizingBitmap;
206    }
207
208    // Read back the frame buffer.
209    SkAutoLockPixels bitmapLock(*readbackBitmap);
210    pixels = static_cast<unsigned char*>(readbackBitmap->getPixels());
211#elif USE(CG)
212    if (m_renderOutput)
213        pixels = m_renderOutput;
214#else
215#error Must port to your platform
216#endif
217
218    m_impl->readBackFramebuffer(pixels, 4 * m_impl->width() * m_impl->height());
219
220    if (!m_impl->getContextAttributes().premultipliedAlpha) {
221        size_t bufferSize = 4 * m_impl->width() * m_impl->height();
222
223        for (size_t i = 0; i < bufferSize; i += 4) {
224            pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255);
225            pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255);
226            pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255);
227        }
228    }
229
230#if USE(SKIA)
231    readbackBitmap->notifyPixelsChanged();
232    if (m_resizingBitmap.readyToDraw()) {
233        // We need to draw the resizing bitmap into the canvas's backing store.
234        SkCanvas canvas(*canvasBitmap);
235        SkRect dst;
236        dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->width()), SkIntToScalar(canvasBitmap->height()));
237        canvas.drawBitmapRect(m_resizingBitmap, 0, dst);
238    }
239#elif USE(CG)
240    if (m_renderOutput && context->is3d()) {
241        WebGLRenderingContext* webGLContext = static_cast<WebGLRenderingContext*>(context);
242        webGLContext->graphicsContext3D()->paintToCanvas(m_renderOutput, m_impl->width(), m_impl->height(), canvas->width(), canvas->height(), imageBuffer->context()->platformContext());
243    }
244#else
245#error Must port to your platform
246#endif
247}
248
249PassRefPtr<ImageData> GraphicsContext3DInternal::paintRenderingResultsToImageData()
250{
251    if (m_impl->getContextAttributes().premultipliedAlpha)
252        return 0;
253
254    RefPtr<ImageData> imageData = ImageData::create(IntSize(m_impl->width(), m_impl->height()));
255    unsigned char* pixels = imageData->data()->data()->data();
256    size_t bufferSize = 4 * m_impl->width() * m_impl->height();
257
258    m_impl->readBackFramebuffer(pixels, bufferSize);
259
260    for (size_t i = 0; i < bufferSize; i += 4)
261        std::swap(pixels[i], pixels[i + 2]);
262
263    return imageData.release();
264}
265
266bool GraphicsContext3DInternal::paintsIntoCanvasBuffer() const
267{
268    // If the gpu compositor is on then skip the readback and software rendering path.
269    return !m_webViewImpl->isAcceleratedCompositingActive();
270}
271
272void GraphicsContext3DInternal::reshape(int width, int height)
273{
274    if (width == m_impl->width() && height == m_impl->height())
275        return;
276
277    m_impl->reshape(width, height);
278
279#if USE(CG)
280    // Need to reallocate the client-side backing store.
281    // FIXME: make this more efficient.
282    if (m_renderOutput) {
283        delete[] m_renderOutput;
284        m_renderOutput = 0;
285    }
286    int rowBytes = width * 4;
287    m_renderOutput = new unsigned char[height * rowBytes];
288#endif // USE(CG)
289}
290
291IntSize GraphicsContext3DInternal::getInternalFramebufferSize()
292{
293    return IntSize(m_impl->width(), m_impl->height());
294}
295
296bool GraphicsContext3DInternal::isContextLost()
297{
298    return m_impl->isContextLost();
299}
300
301// Macros to assist in delegating from GraphicsContext3DInternal to
302// WebGraphicsContext3D.
303
304#define DELEGATE_TO_IMPL(name) \
305void GraphicsContext3DInternal::name() \
306{ \
307    m_impl->name(); \
308}
309
310#define DELEGATE_TO_IMPL_R(name, rt)           \
311rt GraphicsContext3DInternal::name() \
312{ \
313    return m_impl->name(); \
314}
315
316#define DELEGATE_TO_IMPL_1(name, t1) \
317void GraphicsContext3DInternal::name(t1 a1) \
318{ \
319    m_impl->name(a1); \
320}
321
322#define DELEGATE_TO_IMPL_1R(name, t1, rt)    \
323rt GraphicsContext3DInternal::name(t1 a1) \
324{ \
325    return m_impl->name(a1); \
326}
327
328#define DELEGATE_TO_IMPL_2(name, t1, t2) \
329void GraphicsContext3DInternal::name(t1 a1, t2 a2) \
330{ \
331    m_impl->name(a1, a2); \
332}
333
334#define DELEGATE_TO_IMPL_2R(name, t1, t2, rt)  \
335rt GraphicsContext3DInternal::name(t1 a1, t2 a2) \
336{ \
337    return m_impl->name(a1, a2); \
338}
339
340#define DELEGATE_TO_IMPL_3(name, t1, t2, t3)   \
341void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3)    \
342{ \
343    m_impl->name(a1, a2, a3);                  \
344}
345
346#define DELEGATE_TO_IMPL_3R(name, t1, t2, t3, rt)   \
347rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3)    \
348{ \
349    return m_impl->name(a1, a2, a3);                  \
350}
351
352#define DELEGATE_TO_IMPL_4(name, t1, t2, t3, t4)    \
353void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4)  \
354{ \
355    m_impl->name(a1, a2, a3, a4);              \
356}
357
358#define DELEGATE_TO_IMPL_4R(name, t1, t2, t3, t4, rt)       \
359rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4)        \
360{ \
361    return m_impl->name(a1, a2, a3, a4);           \
362}
363
364#define DELEGATE_TO_IMPL_5(name, t1, t2, t3, t4, t5)      \
365void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5)        \
366{ \
367    m_impl->name(a1, a2, a3, a4, a5);   \
368}
369
370#define DELEGATE_TO_IMPL_5R(name, t1, t2, t3, t4, t5, rt)      \
371rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5)        \
372{ \
373    return m_impl->name(a1, a2, a3, a4, a5);   \
374}
375
376#define DELEGATE_TO_IMPL_6(name, t1, t2, t3, t4, t5, t6)  \
377void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
378{ \
379    m_impl->name(a1, a2, a3, a4, a5, a6);       \
380}
381
382#define DELEGATE_TO_IMPL_6R(name, t1, t2, t3, t4, t5, t6, rt)  \
383rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
384{ \
385    return m_impl->name(a1, a2, a3, a4, a5, a6);       \
386}
387
388#define DELEGATE_TO_IMPL_7(name, t1, t2, t3, t4, t5, t6, t7) \
389void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \
390{ \
391    m_impl->name(a1, a2, a3, a4, a5, a6, a7);   \
392}
393
394#define DELEGATE_TO_IMPL_7R(name, t1, t2, t3, t4, t5, t6, t7, rt) \
395rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \
396{ \
397    return m_impl->name(a1, a2, a3, a4, a5, a6, a7);   \
398}
399
400#define DELEGATE_TO_IMPL_8(name, t1, t2, t3, t4, t5, t6, t7, t8)       \
401void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \
402{ \
403    m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8);      \
404}
405
406#define DELEGATE_TO_IMPL_9R(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, rt) \
407rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) \
408{ \
409    return m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8, a9);   \
410}
411
412#define DELEGATE_TO_IMPL_10(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) \
413void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9, t10 a10) \
414{ \
415    m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); \
416}
417
418DELEGATE_TO_IMPL_R(makeContextCurrent, bool)
419
420bool GraphicsContext3DInternal::isGLES2Compliant() const
421{
422    return m_impl->isGLES2Compliant();
423}
424
425DELEGATE_TO_IMPL_1(activeTexture, GC3Denum)
426DELEGATE_TO_IMPL_2(attachShader, Platform3DObject, Platform3DObject)
427
428void GraphicsContext3DInternal::bindAttribLocation(Platform3DObject program, GC3Duint index, const String& name)
429{
430    m_impl->bindAttribLocation(program, index, name.utf8().data());
431}
432
433DELEGATE_TO_IMPL_2(bindBuffer, GC3Denum, Platform3DObject)
434DELEGATE_TO_IMPL_2(bindFramebuffer, GC3Denum, Platform3DObject)
435DELEGATE_TO_IMPL_2(bindRenderbuffer, GC3Denum, Platform3DObject)
436DELEGATE_TO_IMPL_2(bindTexture, GC3Denum, Platform3DObject)
437DELEGATE_TO_IMPL_4(blendColor, GC3Dclampf, GC3Dclampf, GC3Dclampf, GC3Dclampf)
438DELEGATE_TO_IMPL_1(blendEquation, GC3Denum)
439DELEGATE_TO_IMPL_2(blendEquationSeparate, GC3Denum, GC3Denum)
440DELEGATE_TO_IMPL_2(blendFunc, GC3Denum, GC3Denum)
441DELEGATE_TO_IMPL_4(blendFuncSeparate, GC3Denum, GC3Denum, GC3Denum, GC3Denum)
442
443void GraphicsContext3DInternal::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage)
444{
445    m_impl->bufferData(target, size, 0, usage);
446}
447
448void GraphicsContext3DInternal::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage)
449{
450    m_impl->bufferData(target, size, data, usage);
451}
452
453void GraphicsContext3DInternal::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data)
454{
455    m_impl->bufferSubData(target, offset, size, data);
456}
457
458DELEGATE_TO_IMPL_1R(checkFramebufferStatus, GC3Denum, GC3Denum)
459DELEGATE_TO_IMPL_1(clear, GC3Dbitfield)
460DELEGATE_TO_IMPL_4(clearColor, GC3Dclampf, GC3Dclampf, GC3Dclampf, GC3Dclampf)
461DELEGATE_TO_IMPL_1(clearDepth, GC3Dclampf)
462DELEGATE_TO_IMPL_1(clearStencil, GC3Dint)
463DELEGATE_TO_IMPL_4(colorMask, GC3Dboolean, GC3Dboolean, GC3Dboolean, GC3Dboolean)
464DELEGATE_TO_IMPL_1(compileShader, Platform3DObject)
465
466DELEGATE_TO_IMPL_8(copyTexImage2D, GC3Denum, GC3Dint, GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dint)
467DELEGATE_TO_IMPL_8(copyTexSubImage2D, GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei)
468DELEGATE_TO_IMPL_1(cullFace, GC3Denum)
469DELEGATE_TO_IMPL_1(depthFunc, GC3Denum)
470DELEGATE_TO_IMPL_1(depthMask, GC3Dboolean)
471DELEGATE_TO_IMPL_2(depthRange, GC3Dclampf, GC3Dclampf)
472DELEGATE_TO_IMPL_2(detachShader, Platform3DObject, Platform3DObject)
473DELEGATE_TO_IMPL_1(disable, GC3Denum)
474DELEGATE_TO_IMPL_1(disableVertexAttribArray, GC3Duint)
475DELEGATE_TO_IMPL_3(drawArrays, GC3Denum, GC3Dint, GC3Dsizei)
476DELEGATE_TO_IMPL_4(drawElements, GC3Denum, GC3Dsizei, GC3Denum, GC3Dsizeiptr)
477
478DELEGATE_TO_IMPL_1(enable, GC3Denum)
479DELEGATE_TO_IMPL_1(enableVertexAttribArray, GC3Duint)
480DELEGATE_TO_IMPL(finish)
481DELEGATE_TO_IMPL(flush)
482DELEGATE_TO_IMPL_4(framebufferRenderbuffer, GC3Denum, GC3Denum, GC3Denum, Platform3DObject)
483DELEGATE_TO_IMPL_5(framebufferTexture2D, GC3Denum, GC3Denum, GC3Denum, Platform3DObject, GC3Dint)
484DELEGATE_TO_IMPL_1(frontFace, GC3Denum)
485DELEGATE_TO_IMPL_1(generateMipmap, GC3Denum)
486
487bool GraphicsContext3DInternal::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info)
488{
489    WebKit::WebGraphicsContext3D::ActiveInfo webInfo;
490    if (!m_impl->getActiveAttrib(program, index, webInfo))
491        return false;
492    info.name = webInfo.name;
493    info.type = webInfo.type;
494    info.size = webInfo.size;
495    return true;
496}
497
498bool GraphicsContext3DInternal::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
499{
500    WebKit::WebGraphicsContext3D::ActiveInfo webInfo;
501    if (!m_impl->getActiveUniform(program, index, webInfo))
502        return false;
503    info.name = webInfo.name;
504    info.type = webInfo.type;
505    info.size = webInfo.size;
506    return true;
507}
508
509DELEGATE_TO_IMPL_4(getAttachedShaders, Platform3DObject, GC3Dsizei, GC3Dsizei*, Platform3DObject*)
510
511GC3Dint GraphicsContext3DInternal::getAttribLocation(Platform3DObject program, const String& name)
512{
513    return m_impl->getAttribLocation(program, name.utf8().data());
514}
515
516DELEGATE_TO_IMPL_2(getBooleanv, GC3Denum, GC3Dboolean*)
517
518DELEGATE_TO_IMPL_3(getBufferParameteriv, GC3Denum, GC3Denum, GC3Dint*)
519
520GraphicsContext3D::Attributes GraphicsContext3DInternal::getContextAttributes()
521{
522    WebKit::WebGraphicsContext3D::Attributes webAttributes = m_impl->getContextAttributes();
523    GraphicsContext3D::Attributes attributes;
524    attributes.alpha = webAttributes.alpha;
525    attributes.depth = webAttributes.depth;
526    attributes.stencil = webAttributes.stencil;
527    attributes.antialias = webAttributes.antialias;
528    attributes.premultipliedAlpha = webAttributes.premultipliedAlpha;
529    return attributes;
530}
531
532DELEGATE_TO_IMPL_R(getError, GC3Denum)
533
534DELEGATE_TO_IMPL_2(getFloatv, GC3Denum, GC3Dfloat*)
535
536DELEGATE_TO_IMPL_4(getFramebufferAttachmentParameteriv, GC3Denum, GC3Denum, GC3Denum, GC3Dint*)
537
538DELEGATE_TO_IMPL_2(getIntegerv, GC3Denum, GC3Dint*)
539
540DELEGATE_TO_IMPL_3(getProgramiv, Platform3DObject, GC3Denum, GC3Dint*)
541
542String GraphicsContext3DInternal::getProgramInfoLog(Platform3DObject program)
543{
544    return m_impl->getProgramInfoLog(program);
545}
546
547DELEGATE_TO_IMPL_3(getRenderbufferParameteriv, GC3Denum, GC3Denum, GC3Dint*)
548
549DELEGATE_TO_IMPL_3(getShaderiv, Platform3DObject, GC3Denum, GC3Dint*)
550
551String GraphicsContext3DInternal::getShaderInfoLog(Platform3DObject shader)
552{
553    return m_impl->getShaderInfoLog(shader);
554}
555
556String GraphicsContext3DInternal::getShaderSource(Platform3DObject shader)
557{
558    return m_impl->getShaderSource(shader);
559}
560
561String GraphicsContext3DInternal::getString(GC3Denum name)
562{
563    return m_impl->getString(name);
564}
565
566DELEGATE_TO_IMPL_3(getTexParameterfv, GC3Denum, GC3Denum, GC3Dfloat*)
567DELEGATE_TO_IMPL_3(getTexParameteriv, GC3Denum, GC3Denum, GC3Dint*)
568
569DELEGATE_TO_IMPL_3(getUniformfv, Platform3DObject, GC3Dint, GC3Dfloat*)
570DELEGATE_TO_IMPL_3(getUniformiv, Platform3DObject, GC3Dint, GC3Dint*)
571
572GC3Dint GraphicsContext3DInternal::getUniformLocation(Platform3DObject program, const String& name)
573{
574    return m_impl->getUniformLocation(program, name.utf8().data());
575}
576
577DELEGATE_TO_IMPL_3(getVertexAttribfv, GC3Duint, GC3Denum, GC3Dfloat*)
578DELEGATE_TO_IMPL_3(getVertexAttribiv, GC3Duint, GC3Denum, GC3Dint*)
579
580DELEGATE_TO_IMPL_2R(getVertexAttribOffset, GC3Duint, GC3Denum, GC3Dsizeiptr)
581
582DELEGATE_TO_IMPL_2(hint, GC3Denum, GC3Denum)
583DELEGATE_TO_IMPL_1R(isBuffer, Platform3DObject, GC3Dboolean)
584DELEGATE_TO_IMPL_1R(isEnabled, GC3Denum, GC3Dboolean)
585DELEGATE_TO_IMPL_1R(isFramebuffer, Platform3DObject, GC3Dboolean)
586DELEGATE_TO_IMPL_1R(isProgram, Platform3DObject, GC3Dboolean)
587DELEGATE_TO_IMPL_1R(isRenderbuffer, Platform3DObject, GC3Dboolean)
588DELEGATE_TO_IMPL_1R(isShader, Platform3DObject, GC3Dboolean)
589DELEGATE_TO_IMPL_1R(isTexture, Platform3DObject, GC3Dboolean)
590DELEGATE_TO_IMPL_1(lineWidth, GC3Dfloat)
591DELEGATE_TO_IMPL_1(linkProgram, Platform3DObject)
592DELEGATE_TO_IMPL_2(pixelStorei, GC3Denum, GC3Dint)
593DELEGATE_TO_IMPL_2(polygonOffset, GC3Dfloat, GC3Dfloat)
594DELEGATE_TO_IMPL_7(readPixels, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, void*)
595DELEGATE_TO_IMPL(releaseShaderCompiler)
596DELEGATE_TO_IMPL_4(renderbufferStorage, GC3Denum, GC3Denum, GC3Dsizei, GC3Dsizei)
597DELEGATE_TO_IMPL_2(sampleCoverage, GC3Dclampf, GC3Dboolean)
598DELEGATE_TO_IMPL_4(scissor, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei)
599
600void GraphicsContext3DInternal::shaderSource(Platform3DObject shader, const String& string)
601{
602    m_impl->shaderSource(shader, string.utf8().data());
603}
604
605DELEGATE_TO_IMPL_3(stencilFunc, GC3Denum, GC3Dint, GC3Duint)
606DELEGATE_TO_IMPL_4(stencilFuncSeparate, GC3Denum, GC3Denum, GC3Dint, GC3Duint)
607DELEGATE_TO_IMPL_1(stencilMask, GC3Duint)
608DELEGATE_TO_IMPL_2(stencilMaskSeparate, GC3Denum, GC3Duint)
609DELEGATE_TO_IMPL_3(stencilOp, GC3Denum, GC3Denum, GC3Denum)
610DELEGATE_TO_IMPL_4(stencilOpSeparate, GC3Denum, GC3Denum, GC3Denum, GC3Denum)
611
612bool GraphicsContext3DInternal::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
613{
614    m_impl->texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
615    return true;
616}
617
618DELEGATE_TO_IMPL_3(texParameterf, GC3Denum, GC3Denum, GC3Dfloat)
619DELEGATE_TO_IMPL_3(texParameteri, GC3Denum, GC3Denum, GC3Dint)
620
621void GraphicsContext3DInternal::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels)
622{
623    m_impl->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
624}
625
626DELEGATE_TO_IMPL_2(uniform1f, GC3Dint, GC3Dfloat)
627
628void GraphicsContext3DInternal::uniform1fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
629{
630    m_impl->uniform1fv(location, size, v);
631}
632
633DELEGATE_TO_IMPL_2(uniform1i, GC3Dint, GC3Dint)
634
635void GraphicsContext3DInternal::uniform1iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
636{
637    m_impl->uniform1iv(location, size, v);
638}
639
640DELEGATE_TO_IMPL_3(uniform2f, GC3Dint, GC3Dfloat, GC3Dfloat)
641
642void GraphicsContext3DInternal::uniform2fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
643{
644    m_impl->uniform2fv(location, size, v);
645}
646
647DELEGATE_TO_IMPL_3(uniform2i, GC3Dint, GC3Dint, GC3Dint)
648
649void GraphicsContext3DInternal::uniform2iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
650{
651    m_impl->uniform2iv(location, size, v);
652}
653
654DELEGATE_TO_IMPL_4(uniform3f, GC3Dint, GC3Dfloat, GC3Dfloat, GC3Dfloat)
655
656void GraphicsContext3DInternal::uniform3fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
657{
658    m_impl->uniform3fv(location, size, v);
659}
660
661DELEGATE_TO_IMPL_4(uniform3i, GC3Dint, GC3Dint, GC3Dint, GC3Dint)
662
663void GraphicsContext3DInternal::uniform3iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
664{
665    m_impl->uniform3iv(location, size, v);
666}
667
668DELEGATE_TO_IMPL_5(uniform4f, GC3Dint, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat)
669
670void GraphicsContext3DInternal::uniform4fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
671{
672    m_impl->uniform4fv(location, size, v);
673}
674
675DELEGATE_TO_IMPL_5(uniform4i, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint)
676
677void GraphicsContext3DInternal::uniform4iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
678{
679    m_impl->uniform4iv(location, size, v);
680}
681
682void GraphicsContext3DInternal::uniformMatrix2fv(GC3Dint location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size)
683{
684    m_impl->uniformMatrix2fv(location, size, transpose, value);
685}
686
687void GraphicsContext3DInternal::uniformMatrix3fv(GC3Dint location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size)
688{
689    m_impl->uniformMatrix3fv(location, size, transpose, value);
690}
691
692void GraphicsContext3DInternal::uniformMatrix4fv(GC3Dint location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size)
693{
694    m_impl->uniformMatrix4fv(location, size, transpose, value);
695}
696
697DELEGATE_TO_IMPL_1(useProgram, Platform3DObject)
698DELEGATE_TO_IMPL_1(validateProgram, Platform3DObject)
699
700DELEGATE_TO_IMPL_2(vertexAttrib1f, GC3Duint, GC3Dfloat)
701DELEGATE_TO_IMPL_2(vertexAttrib1fv, GC3Duint, GC3Dfloat*)
702DELEGATE_TO_IMPL_3(vertexAttrib2f, GC3Duint, GC3Dfloat, GC3Dfloat)
703DELEGATE_TO_IMPL_2(vertexAttrib2fv, GC3Duint, GC3Dfloat*)
704DELEGATE_TO_IMPL_4(vertexAttrib3f, GC3Duint, GC3Dfloat, GC3Dfloat, GC3Dfloat)
705DELEGATE_TO_IMPL_2(vertexAttrib3fv, GC3Duint, GC3Dfloat*)
706DELEGATE_TO_IMPL_5(vertexAttrib4f, GC3Duint, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat)
707DELEGATE_TO_IMPL_2(vertexAttrib4fv, GC3Duint, GC3Dfloat*)
708DELEGATE_TO_IMPL_6(vertexAttribPointer, GC3Duint, GC3Dint, GC3Denum, GC3Dboolean, GC3Dsizei, GC3Dsizeiptr)
709
710DELEGATE_TO_IMPL_4(viewport, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei)
711
712DELEGATE_TO_IMPL_R(createBuffer, Platform3DObject)
713DELEGATE_TO_IMPL_R(createFramebuffer, Platform3DObject)
714DELEGATE_TO_IMPL_R(createProgram, Platform3DObject)
715DELEGATE_TO_IMPL_R(createRenderbuffer, Platform3DObject)
716DELEGATE_TO_IMPL_1R(createShader, GC3Denum, Platform3DObject)
717DELEGATE_TO_IMPL_R(createTexture, Platform3DObject)
718
719DELEGATE_TO_IMPL_1(deleteBuffer, Platform3DObject)
720DELEGATE_TO_IMPL_1(deleteFramebuffer, Platform3DObject)
721DELEGATE_TO_IMPL_1(deleteProgram, Platform3DObject)
722DELEGATE_TO_IMPL_1(deleteRenderbuffer, Platform3DObject)
723DELEGATE_TO_IMPL_1(deleteShader, Platform3DObject)
724DELEGATE_TO_IMPL_1(deleteTexture, Platform3DObject)
725
726DELEGATE_TO_IMPL_1(synthesizeGLError, GC3Denum)
727
728Extensions3D* GraphicsContext3DInternal::getExtensions()
729{
730    if (!m_extensions)
731        m_extensions = adoptPtr(new Extensions3DChromium(this));
732    return m_extensions.get();
733}
734
735namespace {
736
737void splitStringHelper(const String& str, HashSet<String>& set)
738{
739    Vector<String> substrings;
740    str.split(" ", substrings);
741    for (size_t i = 0; i < substrings.size(); ++i)
742        set.add(substrings[i]);
743}
744
745String mapExtensionName(const String& name)
746{
747    if (name == "GL_ANGLE_framebuffer_blit"
748        || name == "GL_ANGLE_framebuffer_multisample")
749        return "GL_CHROMIUM_framebuffer_multisample";
750    return name;
751}
752
753} // anonymous namespace
754
755void GraphicsContext3DInternal::initializeExtensions()
756{
757    if (!m_initializedAvailableExtensions) {
758        String extensionsString = getString(GraphicsContext3D::EXTENSIONS);
759        splitStringHelper(extensionsString, m_enabledExtensions);
760
761        String requestableExtensionsString = m_impl->getRequestableExtensionsCHROMIUM();
762        splitStringHelper(requestableExtensionsString, m_requestableExtensions);
763
764        m_initializedAvailableExtensions = true;
765    }
766}
767
768
769bool GraphicsContext3DInternal::supportsExtension(const String& name)
770{
771    initializeExtensions();
772    String mappedName = mapExtensionName(name);
773    return m_enabledExtensions.contains(mappedName) || m_requestableExtensions.contains(mappedName);
774}
775
776bool GraphicsContext3DInternal::ensureExtensionEnabled(const String& name)
777{
778    initializeExtensions();
779
780    String mappedName = mapExtensionName(name);
781    if (m_enabledExtensions.contains(mappedName))
782        return true;
783
784    if (m_requestableExtensions.contains(mappedName)) {
785        m_impl->requestExtensionCHROMIUM(mappedName.ascii().data());
786        m_enabledExtensions.clear();
787        m_requestableExtensions.clear();
788        m_initializedAvailableExtensions = false;
789    }
790
791    initializeExtensions();
792    return m_enabledExtensions.contains(mappedName);
793}
794
795bool GraphicsContext3DInternal::isExtensionEnabled(const String& name)
796{
797    initializeExtensions();
798    String mappedName = mapExtensionName(name);
799    return m_enabledExtensions.contains(mappedName);
800}
801
802DELEGATE_TO_IMPL_4R(mapBufferSubDataCHROMIUM, GC3Denum, GC3Dsizeiptr, GC3Dsizei, GC3Denum, void*)
803DELEGATE_TO_IMPL_1(unmapBufferSubDataCHROMIUM, const void*)
804DELEGATE_TO_IMPL_9R(mapTexSubImage2DCHROMIUM, GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, GC3Denum, void*)
805DELEGATE_TO_IMPL_1(unmapTexSubImage2DCHROMIUM, const void*)
806DELEGATE_TO_IMPL_2(copyTextureToParentTextureCHROMIUM, Platform3DObject, Platform3DObject)
807DELEGATE_TO_IMPL_10(blitFramebufferCHROMIUM, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dbitfield, GC3Denum)
808DELEGATE_TO_IMPL_5(renderbufferStorageMultisampleCHROMIUM, GC3Denum, GC3Dsizei, GC3Denum, GC3Dsizei, GC3Dsizei)
809DELEGATE_TO_IMPL_1(getParentToChildLatchCHROMIUM, GC3Duint*)
810DELEGATE_TO_IMPL_1(getChildToParentLatchCHROMIUM, GC3Duint*)
811DELEGATE_TO_IMPL_1(waitLatchCHROMIUM, GC3Duint)
812DELEGATE_TO_IMPL_1(setLatchCHROMIUM, GC3Duint)
813
814//----------------------------------------------------------------------
815// GraphicsContext3D
816//
817
818// Macros to assist in delegating from GraphicsContext3D to
819// GraphicsContext3DInternal.
820
821#define DELEGATE_TO_INTERNAL(name) \
822void GraphicsContext3D::name() \
823{ \
824    m_internal->name(); \
825}
826
827#define DELEGATE_TO_INTERNAL_R(name, rt)           \
828rt GraphicsContext3D::name() \
829{ \
830    return m_internal->name(); \
831}
832
833#define DELEGATE_TO_INTERNAL_1(name, t1) \
834void GraphicsContext3D::name(t1 a1) \
835{ \
836    m_internal->name(a1); \
837}
838
839#define DELEGATE_TO_INTERNAL_1R(name, t1, rt)    \
840rt GraphicsContext3D::name(t1 a1) \
841{ \
842    return m_internal->name(a1); \
843}
844
845#define DELEGATE_TO_INTERNAL_2(name, t1, t2) \
846void GraphicsContext3D::name(t1 a1, t2 a2) \
847{ \
848    m_internal->name(a1, a2); \
849}
850
851#define DELEGATE_TO_INTERNAL_2R(name, t1, t2, rt)  \
852rt GraphicsContext3D::name(t1 a1, t2 a2) \
853{ \
854    return m_internal->name(a1, a2); \
855}
856
857#define DELEGATE_TO_INTERNAL_3(name, t1, t2, t3)   \
858void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3)    \
859{ \
860    m_internal->name(a1, a2, a3);                  \
861}
862
863#define DELEGATE_TO_INTERNAL_3R(name, t1, t2, t3, rt)   \
864rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3)    \
865{ \
866    return m_internal->name(a1, a2, a3);                  \
867}
868
869#define DELEGATE_TO_INTERNAL_4(name, t1, t2, t3, t4)    \
870void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4)  \
871{ \
872    m_internal->name(a1, a2, a3, a4);              \
873}
874
875#define DELEGATE_TO_INTERNAL_4R(name, t1, t2, t3, t4, rt)    \
876rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4)  \
877{ \
878    return m_internal->name(a1, a2, a3, a4);           \
879}
880
881#define DELEGATE_TO_INTERNAL_5(name, t1, t2, t3, t4, t5)      \
882void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5)        \
883{ \
884    m_internal->name(a1, a2, a3, a4, a5);   \
885}
886
887#define DELEGATE_TO_INTERNAL_6(name, t1, t2, t3, t4, t5, t6)  \
888void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
889{ \
890    m_internal->name(a1, a2, a3, a4, a5, a6);   \
891}
892
893#define DELEGATE_TO_INTERNAL_6R(name, t1, t2, t3, t4, t5, t6, rt)  \
894rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
895{ \
896    return m_internal->name(a1, a2, a3, a4, a5, a6);       \
897}
898
899#define DELEGATE_TO_INTERNAL_7(name, t1, t2, t3, t4, t5, t6, t7) \
900void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \
901{ \
902    m_internal->name(a1, a2, a3, a4, a5, a6, a7);   \
903}
904
905#define DELEGATE_TO_INTERNAL_7R(name, t1, t2, t3, t4, t5, t6, t7, rt) \
906rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \
907{ \
908    return m_internal->name(a1, a2, a3, a4, a5, a6, a7);   \
909}
910
911#define DELEGATE_TO_INTERNAL_8(name, t1, t2, t3, t4, t5, t6, t7, t8)       \
912void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \
913{ \
914    m_internal->name(a1, a2, a3, a4, a5, a6, a7, a8);      \
915}
916
917#define DELEGATE_TO_INTERNAL_9(name, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
918void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) \
919{ \
920    m_internal->name(a1, a2, a3, a4, a5, a6, a7, a8, a9);   \
921}
922
923#define DELEGATE_TO_INTERNAL_9R(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, rt) \
924rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) \
925{ \
926    return m_internal->name(a1, a2, a3, a4, a5, a6, a7, a8, a9);   \
927}
928
929GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes, HostWindow*, bool)
930{
931}
932
933GraphicsContext3D::~GraphicsContext3D()
934{
935}
936
937PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
938{
939    OwnPtr<GraphicsContext3DInternal> internal = adoptPtr(new GraphicsContext3DInternal());
940    if (!internal->initialize(attrs, hostWindow, renderStyle == RenderDirectlyToHostWindow)) {
941        return 0;
942    }
943    RefPtr<GraphicsContext3D> result = adoptRef(new GraphicsContext3D(attrs, hostWindow, renderStyle == RenderDirectlyToHostWindow));
944    result->m_internal = internal.release();
945    return result.release();
946}
947
948PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D() const
949{
950    return m_internal->platformGraphicsContext3D();
951}
952
953Platform3DObject GraphicsContext3D::platformTexture() const
954{
955    return m_internal->platformTexture();
956}
957
958void GraphicsContext3D::prepareTexture()
959{
960    return m_internal->prepareTexture();
961}
962
963#if USE(ACCELERATED_COMPOSITING)
964PlatformLayer* GraphicsContext3D::platformLayer() const
965{
966    WebGLLayerChromium* canvasLayer = m_internal->platformLayer();
967    canvasLayer->setContext(this);
968    return canvasLayer;
969}
970#endif
971
972DELEGATE_TO_INTERNAL(makeContextCurrent)
973DELEGATE_TO_INTERNAL_2(reshape, int, int)
974DELEGATE_TO_INTERNAL_R(getInternalFramebufferSize, IntSize)
975
976DELEGATE_TO_INTERNAL_1(activeTexture, GC3Denum)
977DELEGATE_TO_INTERNAL_2(attachShader, Platform3DObject, Platform3DObject)
978DELEGATE_TO_INTERNAL_3(bindAttribLocation, Platform3DObject, GC3Duint, const String&)
979
980DELEGATE_TO_INTERNAL_2(bindBuffer, GC3Denum, Platform3DObject)
981DELEGATE_TO_INTERNAL_2(bindFramebuffer, GC3Denum, Platform3DObject)
982DELEGATE_TO_INTERNAL_2(bindRenderbuffer, GC3Denum, Platform3DObject)
983DELEGATE_TO_INTERNAL_2(bindTexture, GC3Denum, Platform3DObject)
984DELEGATE_TO_INTERNAL_4(blendColor, GC3Dclampf, GC3Dclampf, GC3Dclampf, GC3Dclampf)
985DELEGATE_TO_INTERNAL_1(blendEquation, GC3Denum)
986DELEGATE_TO_INTERNAL_2(blendEquationSeparate, GC3Denum, GC3Denum)
987DELEGATE_TO_INTERNAL_2(blendFunc, GC3Denum, GC3Denum)
988DELEGATE_TO_INTERNAL_4(blendFuncSeparate, GC3Denum, GC3Denum, GC3Denum, GC3Denum)
989
990DELEGATE_TO_INTERNAL_3(bufferData, GC3Denum, GC3Dsizeiptr, GC3Denum)
991DELEGATE_TO_INTERNAL_4(bufferData, GC3Denum, GC3Dsizeiptr, const void*, GC3Denum)
992DELEGATE_TO_INTERNAL_4(bufferSubData, GC3Denum, GC3Dintptr, GC3Dsizeiptr, const void*)
993
994DELEGATE_TO_INTERNAL_1R(checkFramebufferStatus, GC3Denum, GC3Denum)
995DELEGATE_TO_INTERNAL_1(clear, GC3Dbitfield)
996DELEGATE_TO_INTERNAL_4(clearColor, GC3Dclampf, GC3Dclampf, GC3Dclampf, GC3Dclampf)
997DELEGATE_TO_INTERNAL_1(clearDepth, GC3Dclampf)
998DELEGATE_TO_INTERNAL_1(clearStencil, GC3Dint)
999DELEGATE_TO_INTERNAL_4(colorMask, GC3Dboolean, GC3Dboolean, GC3Dboolean, GC3Dboolean)
1000DELEGATE_TO_INTERNAL_1(compileShader, Platform3DObject)
1001
1002DELEGATE_TO_INTERNAL_8(copyTexImage2D, GC3Denum, GC3Dint, GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dint)
1003DELEGATE_TO_INTERNAL_8(copyTexSubImage2D, GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei)
1004DELEGATE_TO_INTERNAL_1(cullFace, GC3Denum)
1005DELEGATE_TO_INTERNAL_1(depthFunc, GC3Denum)
1006DELEGATE_TO_INTERNAL_1(depthMask, GC3Dboolean)
1007DELEGATE_TO_INTERNAL_2(depthRange, GC3Dclampf, GC3Dclampf)
1008DELEGATE_TO_INTERNAL_2(detachShader, Platform3DObject, Platform3DObject)
1009DELEGATE_TO_INTERNAL_1(disable, GC3Denum)
1010DELEGATE_TO_INTERNAL_1(disableVertexAttribArray, GC3Duint)
1011DELEGATE_TO_INTERNAL_3(drawArrays, GC3Denum, GC3Dint, GC3Dsizei)
1012DELEGATE_TO_INTERNAL_4(drawElements, GC3Denum, GC3Dsizei, GC3Denum, GC3Dintptr)
1013
1014DELEGATE_TO_INTERNAL_1(enable, GC3Denum)
1015DELEGATE_TO_INTERNAL_1(enableVertexAttribArray, GC3Duint)
1016DELEGATE_TO_INTERNAL(finish)
1017DELEGATE_TO_INTERNAL(flush)
1018DELEGATE_TO_INTERNAL_4(framebufferRenderbuffer, GC3Denum, GC3Denum, GC3Denum, Platform3DObject)
1019DELEGATE_TO_INTERNAL_5(framebufferTexture2D, GC3Denum, GC3Denum, GC3Denum, Platform3DObject, GC3Dint)
1020DELEGATE_TO_INTERNAL_1(frontFace, GC3Denum)
1021DELEGATE_TO_INTERNAL_1(generateMipmap, GC3Denum)
1022
1023DELEGATE_TO_INTERNAL_3R(getActiveAttrib, Platform3DObject, GC3Duint, ActiveInfo&, bool)
1024DELEGATE_TO_INTERNAL_3R(getActiveUniform, Platform3DObject, GC3Duint, ActiveInfo&, bool)
1025DELEGATE_TO_INTERNAL_4(getAttachedShaders, Platform3DObject, GC3Dsizei, GC3Dsizei*, Platform3DObject*)
1026DELEGATE_TO_INTERNAL_2R(getAttribLocation, Platform3DObject, const String&, GC3Dint)
1027DELEGATE_TO_INTERNAL_2(getBooleanv, GC3Denum, GC3Dboolean*)
1028DELEGATE_TO_INTERNAL_3(getBufferParameteriv, GC3Denum, GC3Denum, GC3Dint*)
1029DELEGATE_TO_INTERNAL_R(getContextAttributes, GraphicsContext3D::Attributes)
1030DELEGATE_TO_INTERNAL_R(getError, GC3Denum)
1031DELEGATE_TO_INTERNAL_2(getFloatv, GC3Denum, GC3Dfloat*)
1032DELEGATE_TO_INTERNAL_4(getFramebufferAttachmentParameteriv, GC3Denum, GC3Denum, GC3Denum, GC3Dint*)
1033DELEGATE_TO_INTERNAL_2(getIntegerv, GC3Denum, GC3Dint*)
1034DELEGATE_TO_INTERNAL_3(getProgramiv, Platform3DObject, GC3Denum, GC3Dint*)
1035DELEGATE_TO_INTERNAL_1R(getProgramInfoLog, Platform3DObject, String)
1036DELEGATE_TO_INTERNAL_3(getRenderbufferParameteriv, GC3Denum, GC3Denum, GC3Dint*)
1037DELEGATE_TO_INTERNAL_3(getShaderiv, Platform3DObject, GC3Denum, GC3Dint*)
1038DELEGATE_TO_INTERNAL_1R(getShaderInfoLog, Platform3DObject, String)
1039DELEGATE_TO_INTERNAL_1R(getShaderSource, Platform3DObject, String)
1040DELEGATE_TO_INTERNAL_1R(getString, GC3Denum, String)
1041DELEGATE_TO_INTERNAL_3(getTexParameterfv, GC3Denum, GC3Denum, GC3Dfloat*)
1042DELEGATE_TO_INTERNAL_3(getTexParameteriv, GC3Denum, GC3Denum, GC3Dint*)
1043DELEGATE_TO_INTERNAL_3(getUniformfv, Platform3DObject, GC3Dint, GC3Dfloat*)
1044DELEGATE_TO_INTERNAL_3(getUniformiv, Platform3DObject, GC3Dint, GC3Dint*)
1045DELEGATE_TO_INTERNAL_2R(getUniformLocation, Platform3DObject, const String&, GC3Dint)
1046DELEGATE_TO_INTERNAL_3(getVertexAttribfv, GC3Duint, GC3Denum, GC3Dfloat*)
1047DELEGATE_TO_INTERNAL_3(getVertexAttribiv, GC3Duint, GC3Denum, GC3Dint*)
1048DELEGATE_TO_INTERNAL_2R(getVertexAttribOffset, GC3Duint, GC3Denum, GC3Dsizeiptr)
1049
1050DELEGATE_TO_INTERNAL_2(hint, GC3Denum, GC3Denum)
1051DELEGATE_TO_INTERNAL_1R(isBuffer, Platform3DObject, GC3Dboolean)
1052DELEGATE_TO_INTERNAL_1R(isEnabled, GC3Denum, GC3Dboolean)
1053DELEGATE_TO_INTERNAL_1R(isFramebuffer, Platform3DObject, GC3Dboolean)
1054DELEGATE_TO_INTERNAL_1R(isProgram, Platform3DObject, GC3Dboolean)
1055DELEGATE_TO_INTERNAL_1R(isRenderbuffer, Platform3DObject, GC3Dboolean)
1056DELEGATE_TO_INTERNAL_1R(isShader, Platform3DObject, GC3Dboolean)
1057DELEGATE_TO_INTERNAL_1R(isTexture, Platform3DObject, GC3Dboolean)
1058DELEGATE_TO_INTERNAL_1(lineWidth, GC3Dfloat)
1059DELEGATE_TO_INTERNAL_1(linkProgram, Platform3DObject)
1060DELEGATE_TO_INTERNAL_2(pixelStorei, GC3Denum, GC3Dint)
1061DELEGATE_TO_INTERNAL_2(polygonOffset, GC3Dfloat, GC3Dfloat)
1062
1063DELEGATE_TO_INTERNAL_7(readPixels, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, void*)
1064
1065DELEGATE_TO_INTERNAL(releaseShaderCompiler)
1066DELEGATE_TO_INTERNAL_4(renderbufferStorage, GC3Denum, GC3Denum, GC3Dsizei, GC3Dsizei)
1067DELEGATE_TO_INTERNAL_2(sampleCoverage, GC3Dclampf, GC3Dboolean)
1068DELEGATE_TO_INTERNAL_4(scissor, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei)
1069DELEGATE_TO_INTERNAL_2(shaderSource, Platform3DObject, const String&)
1070DELEGATE_TO_INTERNAL_3(stencilFunc, GC3Denum, GC3Dint, GC3Duint)
1071DELEGATE_TO_INTERNAL_4(stencilFuncSeparate, GC3Denum, GC3Denum, GC3Dint, GC3Duint)
1072DELEGATE_TO_INTERNAL_1(stencilMask, GC3Duint)
1073DELEGATE_TO_INTERNAL_2(stencilMaskSeparate, GC3Denum, GC3Duint)
1074DELEGATE_TO_INTERNAL_3(stencilOp, GC3Denum, GC3Denum, GC3Denum)
1075DELEGATE_TO_INTERNAL_4(stencilOpSeparate, GC3Denum, GC3Denum, GC3Denum, GC3Denum)
1076
1077DELEGATE_TO_INTERNAL_9R(texImage2D, GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, const void*, bool)
1078DELEGATE_TO_INTERNAL_3(texParameterf, GC3Denum, GC3Denum, GC3Dfloat)
1079DELEGATE_TO_INTERNAL_3(texParameteri, GC3Denum, GC3Denum, GC3Dint)
1080DELEGATE_TO_INTERNAL_9(texSubImage2D, GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, const void*)
1081
1082DELEGATE_TO_INTERNAL_2(uniform1f, GC3Dint, GC3Dfloat)
1083DELEGATE_TO_INTERNAL_3(uniform1fv, GC3Dint, GC3Dfloat*, GC3Dsizei)
1084DELEGATE_TO_INTERNAL_2(uniform1i, GC3Dint, GC3Dint)
1085DELEGATE_TO_INTERNAL_3(uniform1iv, GC3Dint, GC3Dint*, GC3Dsizei)
1086DELEGATE_TO_INTERNAL_3(uniform2f, GC3Dint, GC3Dfloat, GC3Dfloat)
1087DELEGATE_TO_INTERNAL_3(uniform2fv, GC3Dint, GC3Dfloat*, GC3Dsizei)
1088DELEGATE_TO_INTERNAL_3(uniform2i, GC3Dint, GC3Dint, GC3Dint)
1089DELEGATE_TO_INTERNAL_3(uniform2iv, GC3Dint, GC3Dint*, GC3Dsizei)
1090DELEGATE_TO_INTERNAL_4(uniform3f, GC3Dint, GC3Dfloat, GC3Dfloat, GC3Dfloat)
1091DELEGATE_TO_INTERNAL_3(uniform3fv, GC3Dint, GC3Dfloat*, GC3Dsizei)
1092DELEGATE_TO_INTERNAL_4(uniform3i, GC3Dint, GC3Dint, GC3Dint, GC3Dint)
1093DELEGATE_TO_INTERNAL_3(uniform3iv, GC3Dint, GC3Dint*, GC3Dsizei)
1094DELEGATE_TO_INTERNAL_5(uniform4f, GC3Dint, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat)
1095DELEGATE_TO_INTERNAL_3(uniform4fv, GC3Dint, GC3Dfloat*, GC3Dsizei)
1096DELEGATE_TO_INTERNAL_5(uniform4i, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint)
1097DELEGATE_TO_INTERNAL_3(uniform4iv, GC3Dint, GC3Dint*, GC3Dsizei)
1098DELEGATE_TO_INTERNAL_4(uniformMatrix2fv, GC3Dint, GC3Dboolean, GC3Dfloat*, GC3Dsizei)
1099DELEGATE_TO_INTERNAL_4(uniformMatrix3fv, GC3Dint, GC3Dboolean, GC3Dfloat*, GC3Dsizei)
1100DELEGATE_TO_INTERNAL_4(uniformMatrix4fv, GC3Dint, GC3Dboolean, GC3Dfloat*, GC3Dsizei)
1101
1102DELEGATE_TO_INTERNAL_1(useProgram, Platform3DObject)
1103DELEGATE_TO_INTERNAL_1(validateProgram, Platform3DObject)
1104
1105DELEGATE_TO_INTERNAL_2(vertexAttrib1f, GC3Duint, GC3Dfloat)
1106DELEGATE_TO_INTERNAL_2(vertexAttrib1fv, GC3Duint, GC3Dfloat*)
1107DELEGATE_TO_INTERNAL_3(vertexAttrib2f, GC3Duint, GC3Dfloat, GC3Dfloat)
1108DELEGATE_TO_INTERNAL_2(vertexAttrib2fv, GC3Duint, GC3Dfloat*)
1109DELEGATE_TO_INTERNAL_4(vertexAttrib3f, GC3Duint, GC3Dfloat, GC3Dfloat, GC3Dfloat)
1110DELEGATE_TO_INTERNAL_2(vertexAttrib3fv, GC3Duint, GC3Dfloat*)
1111DELEGATE_TO_INTERNAL_5(vertexAttrib4f, GC3Duint, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat)
1112DELEGATE_TO_INTERNAL_2(vertexAttrib4fv, GC3Duint, GC3Dfloat*)
1113DELEGATE_TO_INTERNAL_6(vertexAttribPointer, GC3Duint, GC3Dint, GC3Denum, GC3Dboolean, GC3Dsizei, GC3Dintptr)
1114
1115DELEGATE_TO_INTERNAL_4(viewport, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei)
1116
1117DELEGATE_TO_INTERNAL(markLayerComposited)
1118DELEGATE_TO_INTERNAL(markContextChanged)
1119
1120bool GraphicsContext3D::layerComposited() const
1121{
1122    return m_internal->layerComposited();
1123}
1124
1125DELEGATE_TO_INTERNAL_1(paintRenderingResultsToCanvas, CanvasRenderingContext*)
1126DELEGATE_TO_INTERNAL_R(paintRenderingResultsToImageData, PassRefPtr<ImageData>)
1127
1128bool GraphicsContext3D::paintsIntoCanvasBuffer() const
1129{
1130    return m_internal->paintsIntoCanvasBuffer();
1131}
1132
1133DELEGATE_TO_INTERNAL_R(createBuffer, Platform3DObject)
1134DELEGATE_TO_INTERNAL_R(createFramebuffer, Platform3DObject)
1135DELEGATE_TO_INTERNAL_R(createProgram, Platform3DObject)
1136DELEGATE_TO_INTERNAL_R(createRenderbuffer, Platform3DObject)
1137DELEGATE_TO_INTERNAL_1R(createShader, GC3Denum, Platform3DObject)
1138DELEGATE_TO_INTERNAL_R(createTexture, Platform3DObject)
1139
1140DELEGATE_TO_INTERNAL_1(deleteBuffer, Platform3DObject)
1141DELEGATE_TO_INTERNAL_1(deleteFramebuffer, Platform3DObject)
1142DELEGATE_TO_INTERNAL_1(deleteProgram, Platform3DObject)
1143DELEGATE_TO_INTERNAL_1(deleteRenderbuffer, Platform3DObject)
1144DELEGATE_TO_INTERNAL_1(deleteShader, Platform3DObject)
1145DELEGATE_TO_INTERNAL_1(deleteTexture, Platform3DObject)
1146
1147DELEGATE_TO_INTERNAL_1(synthesizeGLError, GC3Denum)
1148DELEGATE_TO_INTERNAL_R(getExtensions, Extensions3D*)
1149
1150DELEGATE_TO_INTERNAL_1(setContextLostCallback, PassOwnPtr<GraphicsContext3D::ContextLostCallback>)
1151
1152class GraphicsContextLostCallbackAdapter : public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback {
1153public:
1154    virtual void onContextLost();
1155    static PassOwnPtr<GraphicsContextLostCallbackAdapter> create(PassOwnPtr<GraphicsContext3D::ContextLostCallback>);
1156    virtual ~GraphicsContextLostCallbackAdapter() {}
1157private:
1158    GraphicsContextLostCallbackAdapter(PassOwnPtr<GraphicsContext3D::ContextLostCallback> cb) : m_contextLostCallback(cb) {}
1159    OwnPtr<GraphicsContext3D::ContextLostCallback> m_contextLostCallback;
1160};
1161
1162void GraphicsContextLostCallbackAdapter::onContextLost()
1163{
1164    if (m_contextLostCallback)
1165        m_contextLostCallback->onContextLost();
1166}
1167
1168PassOwnPtr<GraphicsContextLostCallbackAdapter> GraphicsContextLostCallbackAdapter::create(PassOwnPtr<GraphicsContext3D::ContextLostCallback> cb)
1169{
1170    return adoptPtr(new GraphicsContextLostCallbackAdapter(cb));
1171}
1172
1173void GraphicsContext3DInternal::setContextLostCallback(PassOwnPtr<GraphicsContext3D::ContextLostCallback> cb)
1174{
1175    m_contextLostCallbackAdapter = GraphicsContextLostCallbackAdapter::create(cb);
1176    m_impl->setContextLostCallback(m_contextLostCallbackAdapter.get());
1177}
1178
1179bool GraphicsContext3D::isGLES2Compliant() const
1180{
1181    return m_internal->isGLES2Compliant();
1182}
1183
1184} // namespace WebCore
1185
1186#endif // ENABLE(WEBGL)
1187