1643ca7872b450ea4efacab6188849e5aac2ba161Steve Block/*
2643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Copyright (C) 2009 Google Inc. All rights reserved.
3643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
4643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Redistribution and use in source and binary forms, with or without
5dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * modification, are permitted provided that the following conditions are
6643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * met:
7643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
8643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Redistributions of source code must retain the above copyright
9643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * notice, this list of conditions and the following disclaimer.
10643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Redistributions in binary form must reproduce the above
11643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * copyright notice, this list of conditions and the following disclaimer
12643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * in the documentation and/or other materials provided with the
13643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * distribution.
14643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Neither the name of Google Inc. nor the names of its
15643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * contributors may be used to endorse or promote products derived from
16643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * this software without specific prior written permission.
17643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
18643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29643ca7872b450ea4efacab6188849e5aac2ba161Steve Block */
30643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
31643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "config.h"
32643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if ENABLE(WEBGL)
34643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
35d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "V8WebGLRenderingContext.h"
36643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
37643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "ExceptionCode.h"
38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "NotImplemented.h"
39cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8ArrayBufferView.h"
40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "V8Binding.h"
41f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "V8BindingMacros.h"
42cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8WebKitLoseContext.h"
43545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "V8Float32Array.h"
44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "V8HTMLCanvasElement.h"
45643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "V8HTMLImageElement.h"
46d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "V8HTMLVideoElement.h"
47d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "V8ImageData.h"
48cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8Int16Array.h"
49cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8Int32Array.h"
50cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8Int8Array.h"
51ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "V8OESStandardDerivatives.h"
52f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "V8OESTextureFloat.h"
5381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "V8OESVertexArrayObject.h"
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "V8Proxy.h"
55cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8Uint16Array.h"
56cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8Uint32Array.h"
57cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8Uint8Array.h"
58cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8WebGLBuffer.h"
59cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8WebGLFramebuffer.h"
60cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8WebGLProgram.h"
61cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8WebGLRenderbuffer.h"
62cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8WebGLShader.h"
63cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8WebGLTexture.h"
64cad810f21b803229eb11403f9209855525a25d57Steve Block#include "V8WebGLUniformLocation.h"
6581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "V8WebGLVertexArrayObjectOES.h"
66d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "WebGLRenderingContext.h"
67cad810f21b803229eb11403f9209855525a25d57Steve Block#include <wtf/FastMalloc.h>
68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
69643ca7872b450ea4efacab6188849e5aac2ba161Steve Blocknamespace WebCore {
70643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Allocates new storage via tryFastMalloc.
72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Returns NULL if array failed to convert for any reason.
73643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic float* jsArrayToFloatArray(v8::Handle<v8::Array> array, uint32_t len)
74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Convert the data element-by-element.
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    float* data;
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!tryFastMalloc(len * sizeof(float)).getValue(data))
78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return 0;
79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (uint32_t i = 0; i < len; i++) {
80643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        v8::Local<v8::Value> val = array->Get(v8::Integer::New(i));
81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!val->IsNumber()) {
82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            fastFree(data);
83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return 0;
84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        data[i] = toFloat(val);
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return data;
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Allocates new storage via tryFastMalloc.
91643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Returns NULL if array failed to convert for any reason.
92643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic int* jsArrayToIntArray(v8::Handle<v8::Array> array, uint32_t len)
93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Convert the data element-by-element.
95643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    int* data;
96643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!tryFastMalloc(len * sizeof(int)).getValue(data))
97643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return 0;
98643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (uint32_t i = 0; i < len; i++) {
99643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        v8::Local<v8::Value> val = array->Get(v8::Integer::New(i));
100643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        bool ok;
101643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        int ival = toInt32(val, ok);
102643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!ok) {
103643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            fastFree(data);
104643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return 0;
105643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
106643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        data[i] = ival;
107643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
108643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return data;
109643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
110643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1115e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockstatic v8::Handle<v8::Value> toV8Object(const WebGLGetInfo& info)
112643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
113643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    switch (info.getType()) {
114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeBool:
115643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Boolean::New(info.getBool());
116ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case WebGLGetInfo::kTypeBoolArray: {
117ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        const Vector<bool>& value = info.getBoolArray();
118ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        v8::Local<v8::Array> array = v8::Array::New(value.size());
119ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        for (size_t ii = 0; ii < value.size(); ++ii)
120ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            array->Set(v8::Integer::New(ii), v8::Boolean::New(value[ii]));
121ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return array;
122ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
123643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeFloat:
124643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Number::New(info.getFloat());
1252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case WebGLGetInfo::kTypeInt:
1262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return v8::Integer::New(info.getInt());
127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeNull:
128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Null();
129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeString:
130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::String::New(fromWebCoreString(info.getString()), info.getString().length());
1312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case WebGLGetInfo::kTypeUnsignedInt:
1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return v8::Integer::NewFromUnsigned(info.getUnsignedInt());
133643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeWebGLBuffer:
1345e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        return toV8(info.getWebGLBuffer());
135643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeWebGLFloatArray:
1365e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        return toV8(info.getWebGLFloatArray());
137643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeWebGLFramebuffer:
1385e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        return toV8(info.getWebGLFramebuffer());
139643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeWebGLIntArray:
1405e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        return toV8(info.getWebGLIntArray());
141643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // FIXME: implement WebGLObjectArray
142643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // case WebGLGetInfo::kTypeWebGLObjectArray:
143643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeWebGLProgram:
1445e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        return toV8(info.getWebGLProgram());
145643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeWebGLRenderbuffer:
1465e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        return toV8(info.getWebGLRenderbuffer());
147643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeWebGLTexture:
1485e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        return toV8(info.getWebGLTexture());
149643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WebGLGetInfo::kTypeWebGLUnsignedByteArray:
1505e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        return toV8(info.getWebGLUnsignedByteArray());
15181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case WebGLGetInfo::kTypeWebGLVertexArrayObjectOES:
15281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return toV8(info.getWebGLVertexArrayObjectOES());
153643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    default:
154643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        notImplemented();
155643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Undefined();
156643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
157643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
159f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic v8::Handle<v8::Value> toV8Object(WebGLExtension* extension, v8::Handle<v8::Object> contextObject)
160f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
161f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!extension)
162f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return v8::Null();
163f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    v8::Handle<v8::Value> extensionObject;
1645319190a069ce6657577718a72e645dad45be0afxqian    const char* referenceName;
165f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    switch (extension->getName()) {
166cad810f21b803229eb11403f9209855525a25d57Steve Block    case WebGLExtension::WebKitLoseContextName:
167cad810f21b803229eb11403f9209855525a25d57Steve Block        extensionObject = toV8(static_cast<WebKitLoseContext*>(extension));
1685319190a069ce6657577718a72e645dad45be0afxqian        referenceName = "webKitLoseContextName";
169cad810f21b803229eb11403f9209855525a25d57Steve Block        break;
170ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    case WebGLExtension::OESStandardDerivativesName:
171ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        extensionObject = toV8(static_cast<OESStandardDerivatives*>(extension));
1725319190a069ce6657577718a72e645dad45be0afxqian        referenceName = "oesStandardDerivativesName";
173ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        break;
174f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    case WebGLExtension::OESTextureFloatName:
175f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        extensionObject = toV8(static_cast<OESTextureFloat*>(extension));
1765319190a069ce6657577718a72e645dad45be0afxqian        referenceName = "oesTextureFloatName";
177f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        break;
17881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case WebGLExtension::OESVertexArrayObjectName:
17981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        extensionObject = toV8(static_cast<OESVertexArrayObject*>(extension));
1805319190a069ce6657577718a72e645dad45be0afxqian        referenceName = "oesVertexArrayObjectName";
18181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        break;
182f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
183f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    ASSERT(!extensionObject.IsEmpty());
1845319190a069ce6657577718a72e645dad45be0afxqian    V8DOMWrapper::setNamedHiddenReference(contextObject, referenceName, extensionObject);
185f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return extensionObject;
186f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
187f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
188643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockenum ObjectType {
189643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    kBuffer, kRenderbuffer, kTexture, kVertexAttrib
190643ca7872b450ea4efacab6188849e5aac2ba161Steve Block};
191643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
192643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic v8::Handle<v8::Value> getObjectParameter(const v8::Arguments& args, ObjectType objectType)
193643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
194643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (args.Length() != 2) {
195643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
196643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
197643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
198643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
199643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ExceptionCode ec = 0;
200d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
2016b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    unsigned target = toInt32(args[0]);
2026b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    unsigned pname = toInt32(args[1]);
203643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebGLGetInfo info;
204643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    switch (objectType) {
205643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case kBuffer:
206643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        info = context->getBufferParameter(target, pname, ec);
207643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
208643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case kRenderbuffer:
209643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        info = context->getRenderbufferParameter(target, pname, ec);
210643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
211643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case kTexture:
212643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        info = context->getTexParameter(target, pname, ec);
213643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
214643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case kVertexAttrib:
215643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // target => index
216643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        info = context->getVertexAttrib(target, pname, ec);
217643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
218643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    default:
219643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        notImplemented();
220643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
221643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
222643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (ec) {
223643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(ec);
224643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Undefined();
225643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
2265e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    return toV8Object(info);
227643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
228643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
229643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic WebGLUniformLocation* toWebGLUniformLocation(v8::Handle<v8::Value> value, bool& ok)
230643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
231643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ok = false;
232643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebGLUniformLocation* location = 0;
233643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (V8WebGLUniformLocation::HasInstance(value)) {
234d0825bca7fe65beaee391d30da42e937db621564Steve Block        location = V8WebGLUniformLocation::toNative(value->ToObject());
235643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ok = true;
236643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
237643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return location;
238643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
239643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
240643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockenum WhichProgramCall {
241643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    kProgramParameter, kUniform
242643ca7872b450ea4efacab6188849e5aac2ba161Steve Block};
243643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
244ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::getAttachedShadersCallback(const v8::Arguments& args)
245ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
246ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    INC_STATS("DOM.WebGLRenderingContext.getAttachedShaders()");
247ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
248ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (args.Length() < 1) {
249ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
250ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return notHandledByInterceptor();
251ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
252ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
253ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    ExceptionCode ec = 0;
254ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
255e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) {
256e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        V8Proxy::throwTypeError();
257e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return notHandledByInterceptor();
258e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
259ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
260ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    Vector<WebGLShader*> shaders;
261ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    bool succeed = context->getAttachedShaders(program, shaders, ec);
262ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (ec) {
263ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        V8Proxy::setDOMException(ec);
26428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return v8::Null();
265ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
266ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (!succeed)
26728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return v8::Null();
268ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    v8::Local<v8::Array> array = v8::Array::New(shaders.size());
269ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    for (size_t ii = 0; ii < shaders.size(); ++ii)
270ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        array->Set(v8::Integer::New(ii), toV8(shaders[ii]));
271ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return array;
272ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
273ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
274d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::getBufferParameterCallback(const v8::Arguments& args)
275643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
276643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.getBufferParameter()");
277643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return getObjectParameter(args, kBuffer);
278643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
279643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
280f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochv8::Handle<v8::Value> V8WebGLRenderingContext::getExtensionCallback(const v8::Arguments& args)
281f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
282f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    INC_STATS("DOM.WebGLRenderingContext.getExtensionCallback()");
283f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(args.Holder());
284f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (args.Length() < 1) {
285f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        V8Proxy::setDOMException(SYNTAX_ERR);
286f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return notHandledByInterceptor();
287f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
288f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, name, args[0]);
289f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    WebGLExtension* extension = imp->getExtension(name);
290f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return toV8Object(extension, args.Holder());
291f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
292f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
293d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::getFramebufferAttachmentParameterCallback(const v8::Arguments& args)
294643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
295643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.getFramebufferAttachmentParameter()");
296643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
297643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (args.Length() != 3) {
298643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
299643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
300643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
301643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
302643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ExceptionCode ec = 0;
303d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
3046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    unsigned target = toInt32(args[0]);
3056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    unsigned attachment = toInt32(args[1]);
3066b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    unsigned pname = toInt32(args[2]);
307643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebGLGetInfo info = context->getFramebufferAttachmentParameter(target, attachment, pname, ec);
308643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (ec) {
309643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(ec);
310643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Undefined();
311643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
3125e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    return toV8Object(info);
313643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
314643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
315d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::getParameterCallback(const v8::Arguments& args)
316643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
317643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.getParameter()");
318643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
319643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (args.Length() != 1) {
320643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
321643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
322643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
323643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
324643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ExceptionCode ec = 0;
325d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
3266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    unsigned pname = toInt32(args[0]);
327643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebGLGetInfo info = context->getParameter(pname, ec);
328643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (ec) {
329643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(ec);
330643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Undefined();
331643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
3325e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    return toV8Object(info);
333643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
334643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
335d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::getProgramParameterCallback(const v8::Arguments& args)
336643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
337643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.getProgramParameter()");
338643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
339643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (args.Length() != 2) {
340643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
341643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
342643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
343643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
344643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ExceptionCode ec = 0;
345d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
346e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) {
347e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        V8Proxy::throwTypeError();
348e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return notHandledByInterceptor();
349e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
350d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
3516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    unsigned pname = toInt32(args[1]);
352643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebGLGetInfo info = context->getProgramParameter(program, pname, ec);
353643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (ec) {
354643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(ec);
355643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Undefined();
356643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
3575e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    return toV8Object(info);
358643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
359643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
360d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::getRenderbufferParameterCallback(const v8::Arguments& args)
361643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
362643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.getRenderbufferParameter()");
363643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return getObjectParameter(args, kRenderbuffer);
364643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
365643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
366d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::getShaderParameterCallback(const v8::Arguments& args)
367643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
368643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.getShaderParameter()");
369643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
370643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (args.Length() != 2) {
371643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
372643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
373643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
374643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
375643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ExceptionCode ec = 0;
376d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
377e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLShader::HasInstance(args[0])) {
378e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        V8Proxy::throwTypeError();
379e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return notHandledByInterceptor();
380e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
381d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLShader* shader = V8WebGLShader::HasInstance(args[0]) ? V8WebGLShader::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
3826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    unsigned pname = toInt32(args[1]);
383643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebGLGetInfo info = context->getShaderParameter(shader, pname, ec);
384643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (ec) {
385643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(ec);
386643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Undefined();
387643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
3885e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    return toV8Object(info);
389643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
390643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
391f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochv8::Handle<v8::Value> V8WebGLRenderingContext::getSupportedExtensionsCallback(const v8::Arguments& args)
392f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
393f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    INC_STATS("DOM.WebGLRenderingContext.getSupportedExtensionsCallback()");
394f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(args.Holder());
395cad810f21b803229eb11403f9209855525a25d57Steve Block    if (imp->isContextLost())
396cad810f21b803229eb11403f9209855525a25d57Steve Block        return v8::Null();
397cad810f21b803229eb11403f9209855525a25d57Steve Block
398f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    Vector<String> value = imp->getSupportedExtensions();
399f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    v8::Local<v8::Array> array = v8::Array::New(value.size());
400f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (size_t ii = 0; ii < value.size(); ++ii)
401f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        array->Set(v8::Integer::New(ii), v8::String::New(fromWebCoreString(value[ii]), value[ii].length()));
402f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return array;
403f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
404f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
405d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::getTexParameterCallback(const v8::Arguments& args)
406643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
407643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.getTexParameter()");
408643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return getObjectParameter(args, kTexture);
409643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
410643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
411d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::getUniformCallback(const v8::Arguments& args)
412643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
413643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.getUniform()");
414643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
415643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (args.Length() != 2) {
416643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
417643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
418643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
419643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
420643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ExceptionCode ec = 0;
421d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
422e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) {
423e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        V8Proxy::throwTypeError();
424e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return notHandledByInterceptor();
425e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
426d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
427643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
428e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (args.Length() > 1 && !isUndefinedOrNull(args[1]) && !V8WebGLUniformLocation::HasInstance(args[1])) {
429e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        V8Proxy::throwTypeError();
430e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return notHandledByInterceptor();
431e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
432643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    bool ok = false;
433643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebGLUniformLocation* location = toWebGLUniformLocation(args[1], ok);
434643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
435643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebGLGetInfo info = context->getUniform(program, location, ec);
436643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (ec) {
437643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(ec);
438643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Undefined();
439643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
4405e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    return toV8Object(info);
441643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
442643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
443d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::getVertexAttribCallback(const v8::Arguments& args)
444643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
445643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.getVertexAttrib()");
446643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return getObjectParameter(args, kVertexAttrib);
447643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
448643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
449643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockenum FunctionToCall {
450643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    kUniform1v, kUniform2v, kUniform3v, kUniform4v,
451643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    kVertexAttrib1v, kVertexAttrib2v, kVertexAttrib3v, kVertexAttrib4v
452643ca7872b450ea4efacab6188849e5aac2ba161Steve Block};
453643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
454643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool isFunctionToCallForAttribute(FunctionToCall functionToCall)
455643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
456643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    switch (functionToCall) {
457643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case kVertexAttrib1v:
458643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case kVertexAttrib2v:
459643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case kVertexAttrib3v:
460643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case kVertexAttrib4v:
461643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return true;
462643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    default:
463643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
464643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
465643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return false;
466643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
467643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
468643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic v8::Handle<v8::Value> vertexAttribAndUniformHelperf(const v8::Arguments& args,
469643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                                           FunctionToCall functionToCall) {
470643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Forms:
471643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glUniform1fv(WebGLUniformLocation location, Array data);
472545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // * glUniform1fv(WebGLUniformLocation location, Float32Array data);
473643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glUniform2fv(WebGLUniformLocation location, Array data);
474545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // * glUniform2fv(WebGLUniformLocation location, Float32Array data);
475643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glUniform3fv(WebGLUniformLocation location, Array data);
476545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // * glUniform3fv(WebGLUniformLocation location, Float32Array data);
477643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glUniform4fv(WebGLUniformLocation location, Array data);
478545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // * glUniform4fv(WebGLUniformLocation location, Float32Array data);
479643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glVertexAttrib1fv(GLint index, Array data);
480545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // * glVertexAttrib1fv(GLint index, Float32Array data);
481643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glVertexAttrib2fv(GLint index, Array data);
482545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // * glVertexAttrib2fv(GLint index, Float32Array data);
483643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glVertexAttrib3fv(GLint index, Array data);
484545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // * glVertexAttrib3fv(GLint index, Float32Array data);
485643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glVertexAttrib4fv(GLint index, Array data);
486545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // * glVertexAttrib4fv(GLint index, Float32Array data);
487643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
488643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (args.Length() != 2) {
489643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
490643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
491643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
492643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
493643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    bool ok = false;
494643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    int index = -1;
495643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebGLUniformLocation* location = 0;
496643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
497643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (isFunctionToCallForAttribute(functionToCall))
4986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        index = toInt32(args[0]);
499e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    else {
500e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) {
501e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            V8Proxy::throwTypeError();
502e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            return notHandledByInterceptor();
503e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        }
504643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        location = toWebGLUniformLocation(args[0], ok);
505e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
506643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
507d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
508643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
509545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (V8Float32Array::HasInstance(args[1])) {
510545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        Float32Array* array = V8Float32Array::toNative(args[1]->ToObject());
511643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ASSERT(array != NULL);
512643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ExceptionCode ec = 0;
513643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        switch (functionToCall) {
514643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kUniform1v: context->uniform1fv(location, array, ec); break;
515643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kUniform2v: context->uniform2fv(location, array, ec); break;
516643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kUniform3v: context->uniform3fv(location, array, ec); break;
517643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kUniform4v: context->uniform4fv(location, array, ec); break;
518643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kVertexAttrib1v: context->vertexAttrib1fv(index, array); break;
519643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kVertexAttrib2v: context->vertexAttrib2fv(index, array); break;
520643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kVertexAttrib3v: context->vertexAttrib3fv(index, array); break;
521643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kVertexAttrib4v: context->vertexAttrib4fv(index, array); break;
522643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            default: ASSERT_NOT_REACHED(); break;
523643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
524643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (ec)
525643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            V8Proxy::setDOMException(ec);
526643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Undefined();
527643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
528643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
529e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (args[1].IsEmpty() || !args[1]->IsArray()) {
530e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        V8Proxy::throwTypeError();
531643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
532643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
533e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    v8::Handle<v8::Array> array =
534e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke      v8::Local<v8::Array>::Cast(args[1]);
535643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    uint32_t len = array->Length();
536643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    float* data = jsArrayToFloatArray(array, len);
537643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!data) {
538643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // FIXME: consider different / better exception type.
539643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
540643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
541643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
542643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ExceptionCode ec = 0;
543643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    switch (functionToCall) {
544643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kUniform1v: context->uniform1fv(location, data, len, ec); break;
545643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kUniform2v: context->uniform2fv(location, data, len, ec); break;
546643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kUniform3v: context->uniform3fv(location, data, len, ec); break;
547643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kUniform4v: context->uniform4fv(location, data, len, ec); break;
548643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kVertexAttrib1v: context->vertexAttrib1fv(index, data, len); break;
549643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kVertexAttrib2v: context->vertexAttrib2fv(index, data, len); break;
550643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kVertexAttrib3v: context->vertexAttrib3fv(index, data, len); break;
551643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kVertexAttrib4v: context->vertexAttrib4fv(index, data, len); break;
552643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        default: ASSERT_NOT_REACHED(); break;
553643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
554643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    fastFree(data);
555643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (ec)
556643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(ec);
557643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return v8::Undefined();
558643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
559643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
560643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic v8::Handle<v8::Value> uniformHelperi(const v8::Arguments& args,
561643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                            FunctionToCall functionToCall) {
562643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Forms:
563643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glUniform1iv(GLUniformLocation location, Array data);
5646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    // * glUniform1iv(GLUniformLocation location, Int32Array data);
565643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glUniform2iv(GLUniformLocation location, Array data);
5666c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    // * glUniform2iv(GLUniformLocation location, Int32Array data);
567643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glUniform3iv(GLUniformLocation location, Array data);
5686c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    // * glUniform3iv(GLUniformLocation location, Int32Array data);
569643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glUniform4iv(GLUniformLocation location, Array data);
5706c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    // * glUniform4iv(GLUniformLocation location, Int32Array data);
571643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
572643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (args.Length() != 2) {
573643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
574643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
575643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
576643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
577d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
578e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) {
579e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        V8Proxy::throwTypeError();
580e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return notHandledByInterceptor();
581e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
582643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    bool ok = false;
583643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
584643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
5856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (V8Int32Array::HasInstance(args[1])) {
5866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        Int32Array* array = V8Int32Array::toNative(args[1]->ToObject());
587643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ASSERT(array != NULL);
588643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ExceptionCode ec = 0;
589643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        switch (functionToCall) {
590643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kUniform1v: context->uniform1iv(location, array, ec); break;
591643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kUniform2v: context->uniform2iv(location, array, ec); break;
592643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kUniform3v: context->uniform3iv(location, array, ec); break;
593643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case kUniform4v: context->uniform4iv(location, array, ec); break;
594643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            default: ASSERT_NOT_REACHED(); break;
595643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
596643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (ec)
597643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            V8Proxy::setDOMException(ec);
598643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Undefined();
599643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
600643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
601e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (args[1].IsEmpty() || !args[1]->IsArray()) {
602e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        V8Proxy::throwTypeError();
603643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
604643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
605e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    v8::Handle<v8::Array> array =
606e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke      v8::Local<v8::Array>::Cast(args[1]);
607643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    uint32_t len = array->Length();
608643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    int* data = jsArrayToIntArray(array, len);
609643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!data) {
610643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // FIXME: consider different / better exception type.
611643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
612643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
613643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
614643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ExceptionCode ec = 0;
615643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    switch (functionToCall) {
616643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kUniform1v: context->uniform1iv(location, data, len, ec); break;
617643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kUniform2v: context->uniform2iv(location, data, len, ec); break;
618643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kUniform3v: context->uniform3iv(location, data, len, ec); break;
619643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case kUniform4v: context->uniform4iv(location, data, len, ec); break;
620643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        default: ASSERT_NOT_REACHED(); break;
621643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
622643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    fastFree(data);
623643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (ec)
624643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(ec);
625643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return v8::Undefined();
626643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
627643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
628d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::uniform1fvCallback(const v8::Arguments& args)
629643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
630643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.uniform1fv()");
631643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return vertexAttribAndUniformHelperf(args, kUniform1v);
632643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
633643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
634d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::uniform1ivCallback(const v8::Arguments& args)
635643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
636643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.uniform1iv()");
637643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return uniformHelperi(args, kUniform1v);
638643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
639643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
640d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::uniform2fvCallback(const v8::Arguments& args)
641643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
642643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.uniform2fv()");
643643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return vertexAttribAndUniformHelperf(args, kUniform2v);
644643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
645643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
646d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::uniform2ivCallback(const v8::Arguments& args)
647643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
648643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.uniform2iv()");
649643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return uniformHelperi(args, kUniform2v);
650643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
651643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
652d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::uniform3fvCallback(const v8::Arguments& args)
653643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
654643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.uniform3fv()");
655643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return vertexAttribAndUniformHelperf(args, kUniform3v);
656643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
657643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
658d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::uniform3ivCallback(const v8::Arguments& args)
659643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
660643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.uniform3iv()");
661643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return uniformHelperi(args, kUniform3v);
662643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
663643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
664d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::uniform4fvCallback(const v8::Arguments& args)
665643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
666643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.uniform4fv()");
667643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return vertexAttribAndUniformHelperf(args, kUniform4v);
668643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
669643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
670d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::uniform4ivCallback(const v8::Arguments& args)
671643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
672643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.uniform4iv()");
673643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return uniformHelperi(args, kUniform4v);
674643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
675643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
676643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic v8::Handle<v8::Value> uniformMatrixHelper(const v8::Arguments& args,
677643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                                 int matrixSize)
678643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
679643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Forms:
680643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glUniformMatrix2fv(GLint location, GLboolean transpose, Array data);
681545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // * glUniformMatrix2fv(GLint location, GLboolean transpose, Float32Array data);
682643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glUniformMatrix3fv(GLint location, GLboolean transpose, Array data);
683545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // * glUniformMatrix3fv(GLint location, GLboolean transpose, Float32Array data);
684643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // * glUniformMatrix4fv(GLint location, GLboolean transpose, Array data);
685545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // * glUniformMatrix4fv(GLint location, GLboolean transpose, Float32Array data);
686643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    //
687545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // FIXME: need to change to accept Float32Array as well.
688643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (args.Length() != 3) {
689643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
690643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
691643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
692643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
693d0825bca7fe65beaee391d30da42e937db621564Steve Block    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
694643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
695e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) {
696e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        V8Proxy::throwTypeError();
697e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return notHandledByInterceptor();
698e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
699643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    bool ok = false;
700643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
701643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
702643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    bool transpose = args[1]->BooleanValue();
703545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (V8Float32Array::HasInstance(args[2])) {
704545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        Float32Array* array = V8Float32Array::toNative(args[2]->ToObject());
705643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ASSERT(array != NULL);
706643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ExceptionCode ec = 0;
707643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        switch (matrixSize) {
708643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case 2: context->uniformMatrix2fv(location, transpose, array, ec); break;
709643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case 3: context->uniformMatrix3fv(location, transpose, array, ec); break;
710643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            case 4: context->uniformMatrix4fv(location, transpose, array, ec); break;
711643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            default: ASSERT_NOT_REACHED(); break;
712643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
713643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (ec)
714643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            V8Proxy::setDOMException(ec);
715643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8::Undefined();
716643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
717643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
718e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (args[2].IsEmpty() || !args[2]->IsArray()) {
719e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        V8Proxy::throwTypeError();
720643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
721643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
722e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    v8::Handle<v8::Array> array =
723e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke      v8::Local<v8::Array>::Cast(args[2]);
724643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    uint32_t len = array->Length();
725643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    float* data = jsArrayToFloatArray(array, len);
726643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!data) {
727643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // FIXME: consider different / better exception type.
728643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(SYNTAX_ERR);
729643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return notHandledByInterceptor();
730643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
731643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ExceptionCode ec = 0;
732643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    switch (matrixSize) {
733643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case 2: context->uniformMatrix2fv(location, transpose, data, len, ec); break;
734643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case 3: context->uniformMatrix3fv(location, transpose, data, len, ec); break;
735643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case 4: context->uniformMatrix4fv(location, transpose, data, len, ec); break;
736643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        default: ASSERT_NOT_REACHED(); break;
737643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
738643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    fastFree(data);
739643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (ec)
740643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        V8Proxy::setDOMException(ec);
741643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return v8::Undefined();
742643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
743643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
744d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::uniformMatrix2fvCallback(const v8::Arguments& args)
745643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
746643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.uniformMatrix2fv()");
747643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return uniformMatrixHelper(args, 2);
748643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
749643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
750d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::uniformMatrix3fvCallback(const v8::Arguments& args)
751643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
752643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.uniformMatrix3fv()");
753643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return uniformMatrixHelper(args, 3);
754643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
755643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
756d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::uniformMatrix4fvCallback(const v8::Arguments& args)
757643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
758643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.uniformMatrix4fv()");
759643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return uniformMatrixHelper(args, 4);
760643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
761643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
762d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::vertexAttrib1fvCallback(const v8::Arguments& args)
763643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
764643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.vertexAttrib1fv()");
765643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return vertexAttribAndUniformHelperf(args, kVertexAttrib1v);
766643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
767643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
768d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::vertexAttrib2fvCallback(const v8::Arguments& args)
769643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
770643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.vertexAttrib2fv()");
771643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return vertexAttribAndUniformHelperf(args, kVertexAttrib2v);
772643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
773643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
774d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::vertexAttrib3fvCallback(const v8::Arguments& args)
775643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
776643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.vertexAttrib3fv()");
777643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return vertexAttribAndUniformHelperf(args, kVertexAttrib3v);
778643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
779643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
780d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8WebGLRenderingContext::vertexAttrib4fvCallback(const v8::Arguments& args)
781643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
782643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    INC_STATS("DOM.WebGLRenderingContext.vertexAttrib4fv()");
783643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return vertexAttribAndUniformHelperf(args, kVertexAttrib4v);
784643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
785643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
786643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} // namespace WebCore
787643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
7882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif // ENABLE(WEBGL)
789