2 * Copyright (C) 2009 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
35 #include "V8WebGLRenderingContext.h"
37 #include "ExceptionCode.h"
38 #include "NotImplemented.h"
39 #include "V8ArrayBufferView.h"
40 #include "V8Binding.h"
41 #include "V8BindingMacros.h"
42 #include "V8WebKitLoseContext.h"
43 #include "V8Float32Array.h"
44 #include "V8HTMLCanvasElement.h"
45 #include "V8HTMLImageElement.h"
46 #include "V8HTMLVideoElement.h"
47 #include "V8ImageData.h"
48 #include "V8Int16Array.h"
49 #include "V8Int32Array.h"
50 #include "V8Int8Array.h"
51 #include "V8OESStandardDerivatives.h"
52 #include "V8OESTextureFloat.h"
53 #include "V8OESVertexArrayObject.h"
55 #include "V8Uint16Array.h"
56 #include "V8Uint32Array.h"
57 #include "V8Uint8Array.h"
58 #include "V8WebGLBuffer.h"
59 #include "V8WebGLFramebuffer.h"
60 #include "V8WebGLProgram.h"
61 #include "V8WebGLRenderbuffer.h"
62 #include "V8WebGLShader.h"
63 #include "V8WebGLTexture.h"
64 #include "V8WebGLUniformLocation.h"
65 #include "V8WebGLVertexArrayObjectOES.h"
66 #include "WebGLRenderingContext.h"
68 #include <wtf/FastMalloc.h>
72 // Allocates new storage via tryFastMalloc.
73 // Returns NULL if array failed to convert for any reason.
74 static float* jsArrayToFloatArray(v8::Handle<v8::Array> array, uint32_t len)
76 // Convert the data element-by-element.
78 if (len > std::numeric_limits<uint32_t>::max() / sizeof(float)
79 || !tryFastMalloc(len * sizeof(float)).getValue(data))
81 for (uint32_t i = 0; i < len; i++) {
82 v8::Local<v8::Value> val = array->Get(i);
83 if (!val->IsNumber()) {
87 data[i] = toFloat(val);
92 // Allocates new storage via tryFastMalloc.
93 // Returns NULL if array failed to convert for any reason.
94 static int* jsArrayToIntArray(v8::Handle<v8::Array> array, uint32_t len)
96 // Convert the data element-by-element.
98 if (len > std::numeric_limits<uint32_t>::max() / sizeof(int)
99 || !tryFastMalloc(len * sizeof(int)).getValue(data))
101 for (uint32_t i = 0; i < len; i++) {
102 v8::Local<v8::Value> val = array->Get(i);
104 int ival = toInt32(val, ok);
114 static v8::Handle<v8::Value> toV8Object(const WebGLGetInfo& info)
116 switch (info.getType()) {
117 case WebGLGetInfo::kTypeBool:
118 return v8::Boolean::New(info.getBool());
119 case WebGLGetInfo::kTypeBoolArray: {
120 const Vector<bool>& value = info.getBoolArray();
121 v8::Local<v8::Array> array = v8::Array::New(value.size());
122 for (size_t ii = 0; ii < value.size(); ++ii)
123 array->Set(v8::Integer::New(ii), v8::Boolean::New(value[ii]));
126 case WebGLGetInfo::kTypeFloat:
127 return v8::Number::New(info.getFloat());
128 case WebGLGetInfo::kTypeInt:
129 return v8::Integer::New(info.getInt());
130 case WebGLGetInfo::kTypeNull:
132 case WebGLGetInfo::kTypeString:
133 return v8::String::New(fromWebCoreString(info.getString()), info.getString().length());
134 case WebGLGetInfo::kTypeUnsignedInt:
135 return v8::Integer::NewFromUnsigned(info.getUnsignedInt());
136 case WebGLGetInfo::kTypeWebGLBuffer:
137 return toV8(info.getWebGLBuffer());
138 case WebGLGetInfo::kTypeWebGLFloatArray:
139 return toV8(info.getWebGLFloatArray());
140 case WebGLGetInfo::kTypeWebGLFramebuffer:
141 return toV8(info.getWebGLFramebuffer());
142 case WebGLGetInfo::kTypeWebGLIntArray:
143 return toV8(info.getWebGLIntArray());
144 // FIXME: implement WebGLObjectArray
145 // case WebGLGetInfo::kTypeWebGLObjectArray:
146 case WebGLGetInfo::kTypeWebGLProgram:
147 return toV8(info.getWebGLProgram());
148 case WebGLGetInfo::kTypeWebGLRenderbuffer:
149 return toV8(info.getWebGLRenderbuffer());
150 case WebGLGetInfo::kTypeWebGLTexture:
151 return toV8(info.getWebGLTexture());
152 case WebGLGetInfo::kTypeWebGLUnsignedByteArray:
153 return toV8(info.getWebGLUnsignedByteArray());
154 case WebGLGetInfo::kTypeWebGLVertexArrayObjectOES:
155 return toV8(info.getWebGLVertexArrayObjectOES());
158 return v8::Undefined();
162 static v8::Handle<v8::Value> toV8Object(WebGLExtension* extension, v8::Handle<v8::Object> contextObject)
166 v8::Handle<v8::Value> extensionObject;
167 const char* referenceName = 0;
168 switch (extension->getName()) {
169 case WebGLExtension::WebKitLoseContextName:
170 extensionObject = toV8(static_cast<WebKitLoseContext*>(extension));
171 referenceName = "webKitLoseContextName";
173 case WebGLExtension::OESStandardDerivativesName:
174 extensionObject = toV8(static_cast<OESStandardDerivatives*>(extension));
175 referenceName = "oesStandardDerivativesName";
177 case WebGLExtension::OESTextureFloatName:
178 extensionObject = toV8(static_cast<OESTextureFloat*>(extension));
179 referenceName = "oesTextureFloatName";
181 case WebGLExtension::OESVertexArrayObjectName:
182 extensionObject = toV8(static_cast<OESVertexArrayObject*>(extension));
183 referenceName = "oesVertexArrayObjectName";
186 ASSERT(!extensionObject.IsEmpty());
187 V8DOMWrapper::setNamedHiddenReference(contextObject, referenceName, extensionObject);
188 return extensionObject;
192 kBuffer, kRenderbuffer, kTexture, kVertexAttrib
195 static v8::Handle<v8::Value> getObjectParameter(const v8::Arguments& args, ObjectType objectType)
197 if (args.Length() != 2) {
198 V8Proxy::setDOMException(SYNTAX_ERR);
199 return notHandledByInterceptor();
202 ExceptionCode ec = 0;
203 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
204 unsigned target = toInt32(args[0]);
205 unsigned pname = toInt32(args[1]);
207 switch (objectType) {
209 info = context->getBufferParameter(target, pname, ec);
212 info = context->getRenderbufferParameter(target, pname, ec);
215 info = context->getTexParameter(target, pname, ec);
219 info = context->getVertexAttrib(target, pname, ec);
226 V8Proxy::setDOMException(ec);
227 return v8::Undefined();
229 return toV8Object(info);
232 static WebGLUniformLocation* toWebGLUniformLocation(v8::Handle<v8::Value> value, bool& ok)
235 WebGLUniformLocation* location = 0;
236 if (V8WebGLUniformLocation::HasInstance(value)) {
237 location = V8WebGLUniformLocation::toNative(value->ToObject());
243 enum WhichProgramCall {
244 kProgramParameter, kUniform
247 v8::Handle<v8::Value> V8WebGLRenderingContext::getAttachedShadersCallback(const v8::Arguments& args)
249 INC_STATS("DOM.WebGLRenderingContext.getAttachedShaders()");
251 if (args.Length() < 1) {
252 V8Proxy::setDOMException(SYNTAX_ERR);
253 return notHandledByInterceptor();
256 ExceptionCode ec = 0;
257 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
258 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) {
259 V8Proxy::throwTypeError();
260 return notHandledByInterceptor();
262 WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
263 Vector<WebGLShader*> shaders;
264 bool succeed = context->getAttachedShaders(program, shaders, ec);
266 V8Proxy::setDOMException(ec);
271 v8::Local<v8::Array> array = v8::Array::New(shaders.size());
272 for (size_t ii = 0; ii < shaders.size(); ++ii)
273 array->Set(v8::Integer::New(ii), toV8(shaders[ii]));
277 v8::Handle<v8::Value> V8WebGLRenderingContext::getBufferParameterCallback(const v8::Arguments& args)
279 INC_STATS("DOM.WebGLRenderingContext.getBufferParameter()");
280 return getObjectParameter(args, kBuffer);
283 v8::Handle<v8::Value> V8WebGLRenderingContext::getExtensionCallback(const v8::Arguments& args)
285 INC_STATS("DOM.WebGLRenderingContext.getExtensionCallback()");
286 WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(args.Holder());
287 if (args.Length() < 1) {
288 V8Proxy::setDOMException(SYNTAX_ERR);
289 return notHandledByInterceptor();
291 STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, name, args[0]);
292 WebGLExtension* extension = imp->getExtension(name);
293 return toV8Object(extension, args.Holder());
296 v8::Handle<v8::Value> V8WebGLRenderingContext::getFramebufferAttachmentParameterCallback(const v8::Arguments& args)
298 INC_STATS("DOM.WebGLRenderingContext.getFramebufferAttachmentParameter()");
300 if (args.Length() != 3) {
301 V8Proxy::setDOMException(SYNTAX_ERR);
302 return notHandledByInterceptor();
305 ExceptionCode ec = 0;
306 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
307 unsigned target = toInt32(args[0]);
308 unsigned attachment = toInt32(args[1]);
309 unsigned pname = toInt32(args[2]);
310 WebGLGetInfo info = context->getFramebufferAttachmentParameter(target, attachment, pname, ec);
312 V8Proxy::setDOMException(ec);
313 return v8::Undefined();
315 return toV8Object(info);
318 v8::Handle<v8::Value> V8WebGLRenderingContext::getParameterCallback(const v8::Arguments& args)
320 INC_STATS("DOM.WebGLRenderingContext.getParameter()");
322 if (args.Length() != 1) {
323 V8Proxy::setDOMException(SYNTAX_ERR);
324 return notHandledByInterceptor();
327 ExceptionCode ec = 0;
328 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
329 unsigned pname = toInt32(args[0]);
330 WebGLGetInfo info = context->getParameter(pname, ec);
332 V8Proxy::setDOMException(ec);
333 return v8::Undefined();
335 return toV8Object(info);
338 v8::Handle<v8::Value> V8WebGLRenderingContext::getProgramParameterCallback(const v8::Arguments& args)
340 INC_STATS("DOM.WebGLRenderingContext.getProgramParameter()");
342 if (args.Length() != 2) {
343 V8Proxy::setDOMException(SYNTAX_ERR);
344 return notHandledByInterceptor();
347 ExceptionCode ec = 0;
348 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
349 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) {
350 V8Proxy::throwTypeError();
351 return notHandledByInterceptor();
353 WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
354 unsigned pname = toInt32(args[1]);
355 WebGLGetInfo info = context->getProgramParameter(program, pname, ec);
357 V8Proxy::setDOMException(ec);
358 return v8::Undefined();
360 return toV8Object(info);
363 v8::Handle<v8::Value> V8WebGLRenderingContext::getRenderbufferParameterCallback(const v8::Arguments& args)
365 INC_STATS("DOM.WebGLRenderingContext.getRenderbufferParameter()");
366 return getObjectParameter(args, kRenderbuffer);
369 v8::Handle<v8::Value> V8WebGLRenderingContext::getShaderParameterCallback(const v8::Arguments& args)
371 INC_STATS("DOM.WebGLRenderingContext.getShaderParameter()");
373 if (args.Length() != 2) {
374 V8Proxy::setDOMException(SYNTAX_ERR);
375 return notHandledByInterceptor();
378 ExceptionCode ec = 0;
379 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
380 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLShader::HasInstance(args[0])) {
381 V8Proxy::throwTypeError();
382 return notHandledByInterceptor();
384 WebGLShader* shader = V8WebGLShader::HasInstance(args[0]) ? V8WebGLShader::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
385 unsigned pname = toInt32(args[1]);
386 WebGLGetInfo info = context->getShaderParameter(shader, pname, ec);
388 V8Proxy::setDOMException(ec);
389 return v8::Undefined();
391 return toV8Object(info);
394 v8::Handle<v8::Value> V8WebGLRenderingContext::getSupportedExtensionsCallback(const v8::Arguments& args)
396 INC_STATS("DOM.WebGLRenderingContext.getSupportedExtensionsCallback()");
397 WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(args.Holder());
398 if (imp->isContextLost())
401 Vector<String> value = imp->getSupportedExtensions();
402 v8::Local<v8::Array> array = v8::Array::New(value.size());
403 for (size_t ii = 0; ii < value.size(); ++ii)
404 array->Set(v8::Integer::New(ii), v8::String::New(fromWebCoreString(value[ii]), value[ii].length()));
408 v8::Handle<v8::Value> V8WebGLRenderingContext::getTexParameterCallback(const v8::Arguments& args)
410 INC_STATS("DOM.WebGLRenderingContext.getTexParameter()");
411 return getObjectParameter(args, kTexture);
414 v8::Handle<v8::Value> V8WebGLRenderingContext::getUniformCallback(const v8::Arguments& args)
416 INC_STATS("DOM.WebGLRenderingContext.getUniform()");
418 if (args.Length() != 2) {
419 V8Proxy::setDOMException(SYNTAX_ERR);
420 return notHandledByInterceptor();
423 ExceptionCode ec = 0;
424 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
425 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) {
426 V8Proxy::throwTypeError();
427 return notHandledByInterceptor();
429 WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
431 if (args.Length() > 1 && !isUndefinedOrNull(args[1]) && !V8WebGLUniformLocation::HasInstance(args[1])) {
432 V8Proxy::throwTypeError();
433 return notHandledByInterceptor();
436 WebGLUniformLocation* location = toWebGLUniformLocation(args[1], ok);
438 WebGLGetInfo info = context->getUniform(program, location, ec);
440 V8Proxy::setDOMException(ec);
441 return v8::Undefined();
443 return toV8Object(info);
446 v8::Handle<v8::Value> V8WebGLRenderingContext::getVertexAttribCallback(const v8::Arguments& args)
448 INC_STATS("DOM.WebGLRenderingContext.getVertexAttrib()");
449 return getObjectParameter(args, kVertexAttrib);
452 enum FunctionToCall {
453 kUniform1v, kUniform2v, kUniform3v, kUniform4v,
454 kVertexAttrib1v, kVertexAttrib2v, kVertexAttrib3v, kVertexAttrib4v
457 bool isFunctionToCallForAttribute(FunctionToCall functionToCall)
459 switch (functionToCall) {
460 case kVertexAttrib1v:
461 case kVertexAttrib2v:
462 case kVertexAttrib3v:
463 case kVertexAttrib4v:
471 static v8::Handle<v8::Value> vertexAttribAndUniformHelperf(const v8::Arguments& args,
472 FunctionToCall functionToCall) {
474 // * glUniform1fv(WebGLUniformLocation location, Array data);
475 // * glUniform1fv(WebGLUniformLocation location, Float32Array data);
476 // * glUniform2fv(WebGLUniformLocation location, Array data);
477 // * glUniform2fv(WebGLUniformLocation location, Float32Array data);
478 // * glUniform3fv(WebGLUniformLocation location, Array data);
479 // * glUniform3fv(WebGLUniformLocation location, Float32Array data);
480 // * glUniform4fv(WebGLUniformLocation location, Array data);
481 // * glUniform4fv(WebGLUniformLocation location, Float32Array data);
482 // * glVertexAttrib1fv(GLint index, Array data);
483 // * glVertexAttrib1fv(GLint index, Float32Array data);
484 // * glVertexAttrib2fv(GLint index, Array data);
485 // * glVertexAttrib2fv(GLint index, Float32Array data);
486 // * glVertexAttrib3fv(GLint index, Array data);
487 // * glVertexAttrib3fv(GLint index, Float32Array data);
488 // * glVertexAttrib4fv(GLint index, Array data);
489 // * glVertexAttrib4fv(GLint index, Float32Array data);
491 if (args.Length() != 2) {
492 V8Proxy::setDOMException(SYNTAX_ERR);
493 return notHandledByInterceptor();
498 WebGLUniformLocation* location = 0;
500 if (isFunctionToCallForAttribute(functionToCall))
501 index = toInt32(args[0]);
503 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) {
504 V8Proxy::throwTypeError();
505 return notHandledByInterceptor();
507 location = toWebGLUniformLocation(args[0], ok);
510 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
512 if (V8Float32Array::HasInstance(args[1])) {
513 Float32Array* array = V8Float32Array::toNative(args[1]->ToObject());
514 ASSERT(array != NULL);
515 ExceptionCode ec = 0;
516 switch (functionToCall) {
517 case kUniform1v: context->uniform1fv(location, array, ec); break;
518 case kUniform2v: context->uniform2fv(location, array, ec); break;
519 case kUniform3v: context->uniform3fv(location, array, ec); break;
520 case kUniform4v: context->uniform4fv(location, array, ec); break;
521 case kVertexAttrib1v: context->vertexAttrib1fv(index, array); break;
522 case kVertexAttrib2v: context->vertexAttrib2fv(index, array); break;
523 case kVertexAttrib3v: context->vertexAttrib3fv(index, array); break;
524 case kVertexAttrib4v: context->vertexAttrib4fv(index, array); break;
525 default: ASSERT_NOT_REACHED(); break;
528 V8Proxy::setDOMException(ec);
529 return v8::Undefined();
532 if (args[1].IsEmpty() || !args[1]->IsArray()) {
533 V8Proxy::throwTypeError();
534 return notHandledByInterceptor();
536 v8::Handle<v8::Array> array =
537 v8::Local<v8::Array>::Cast(args[1]);
538 uint32_t len = array->Length();
539 float* data = jsArrayToFloatArray(array, len);
541 // FIXME: consider different / better exception type.
542 V8Proxy::setDOMException(SYNTAX_ERR);
543 return notHandledByInterceptor();
545 ExceptionCode ec = 0;
546 switch (functionToCall) {
547 case kUniform1v: context->uniform1fv(location, data, len, ec); break;
548 case kUniform2v: context->uniform2fv(location, data, len, ec); break;
549 case kUniform3v: context->uniform3fv(location, data, len, ec); break;
550 case kUniform4v: context->uniform4fv(location, data, len, ec); break;
551 case kVertexAttrib1v: context->vertexAttrib1fv(index, data, len); break;
552 case kVertexAttrib2v: context->vertexAttrib2fv(index, data, len); break;
553 case kVertexAttrib3v: context->vertexAttrib3fv(index, data, len); break;
554 case kVertexAttrib4v: context->vertexAttrib4fv(index, data, len); break;
555 default: ASSERT_NOT_REACHED(); break;
559 V8Proxy::setDOMException(ec);
560 return v8::Undefined();
563 static v8::Handle<v8::Value> uniformHelperi(const v8::Arguments& args,
564 FunctionToCall functionToCall) {
566 // * glUniform1iv(GLUniformLocation location, Array data);
567 // * glUniform1iv(GLUniformLocation location, Int32Array data);
568 // * glUniform2iv(GLUniformLocation location, Array data);
569 // * glUniform2iv(GLUniformLocation location, Int32Array data);
570 // * glUniform3iv(GLUniformLocation location, Array data);
571 // * glUniform3iv(GLUniformLocation location, Int32Array data);
572 // * glUniform4iv(GLUniformLocation location, Array data);
573 // * glUniform4iv(GLUniformLocation location, Int32Array data);
575 if (args.Length() != 2) {
576 V8Proxy::setDOMException(SYNTAX_ERR);
577 return notHandledByInterceptor();
580 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
581 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) {
582 V8Proxy::throwTypeError();
583 return notHandledByInterceptor();
586 WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
588 if (V8Int32Array::HasInstance(args[1])) {
589 Int32Array* array = V8Int32Array::toNative(args[1]->ToObject());
590 ASSERT(array != NULL);
591 ExceptionCode ec = 0;
592 switch (functionToCall) {
593 case kUniform1v: context->uniform1iv(location, array, ec); break;
594 case kUniform2v: context->uniform2iv(location, array, ec); break;
595 case kUniform3v: context->uniform3iv(location, array, ec); break;
596 case kUniform4v: context->uniform4iv(location, array, ec); break;
597 default: ASSERT_NOT_REACHED(); break;
600 V8Proxy::setDOMException(ec);
601 return v8::Undefined();
604 if (args[1].IsEmpty() || !args[1]->IsArray()) {
605 V8Proxy::throwTypeError();
606 return notHandledByInterceptor();
608 v8::Handle<v8::Array> array =
609 v8::Local<v8::Array>::Cast(args[1]);
610 uint32_t len = array->Length();
611 int* data = jsArrayToIntArray(array, len);
613 // FIXME: consider different / better exception type.
614 V8Proxy::setDOMException(SYNTAX_ERR);
615 return notHandledByInterceptor();
617 ExceptionCode ec = 0;
618 switch (functionToCall) {
619 case kUniform1v: context->uniform1iv(location, data, len, ec); break;
620 case kUniform2v: context->uniform2iv(location, data, len, ec); break;
621 case kUniform3v: context->uniform3iv(location, data, len, ec); break;
622 case kUniform4v: context->uniform4iv(location, data, len, ec); break;
623 default: ASSERT_NOT_REACHED(); break;
627 V8Proxy::setDOMException(ec);
628 return v8::Undefined();
631 v8::Handle<v8::Value> V8WebGLRenderingContext::uniform1fvCallback(const v8::Arguments& args)
633 INC_STATS("DOM.WebGLRenderingContext.uniform1fv()");
634 return vertexAttribAndUniformHelperf(args, kUniform1v);
637 v8::Handle<v8::Value> V8WebGLRenderingContext::uniform1ivCallback(const v8::Arguments& args)
639 INC_STATS("DOM.WebGLRenderingContext.uniform1iv()");
640 return uniformHelperi(args, kUniform1v);
643 v8::Handle<v8::Value> V8WebGLRenderingContext::uniform2fvCallback(const v8::Arguments& args)
645 INC_STATS("DOM.WebGLRenderingContext.uniform2fv()");
646 return vertexAttribAndUniformHelperf(args, kUniform2v);
649 v8::Handle<v8::Value> V8WebGLRenderingContext::uniform2ivCallback(const v8::Arguments& args)
651 INC_STATS("DOM.WebGLRenderingContext.uniform2iv()");
652 return uniformHelperi(args, kUniform2v);
655 v8::Handle<v8::Value> V8WebGLRenderingContext::uniform3fvCallback(const v8::Arguments& args)
657 INC_STATS("DOM.WebGLRenderingContext.uniform3fv()");
658 return vertexAttribAndUniformHelperf(args, kUniform3v);
661 v8::Handle<v8::Value> V8WebGLRenderingContext::uniform3ivCallback(const v8::Arguments& args)
663 INC_STATS("DOM.WebGLRenderingContext.uniform3iv()");
664 return uniformHelperi(args, kUniform3v);
667 v8::Handle<v8::Value> V8WebGLRenderingContext::uniform4fvCallback(const v8::Arguments& args)
669 INC_STATS("DOM.WebGLRenderingContext.uniform4fv()");
670 return vertexAttribAndUniformHelperf(args, kUniform4v);
673 v8::Handle<v8::Value> V8WebGLRenderingContext::uniform4ivCallback(const v8::Arguments& args)
675 INC_STATS("DOM.WebGLRenderingContext.uniform4iv()");
676 return uniformHelperi(args, kUniform4v);
679 static v8::Handle<v8::Value> uniformMatrixHelper(const v8::Arguments& args,
683 // * glUniformMatrix2fv(GLint location, GLboolean transpose, Array data);
684 // * glUniformMatrix2fv(GLint location, GLboolean transpose, Float32Array data);
685 // * glUniformMatrix3fv(GLint location, GLboolean transpose, Array data);
686 // * glUniformMatrix3fv(GLint location, GLboolean transpose, Float32Array data);
687 // * glUniformMatrix4fv(GLint location, GLboolean transpose, Array data);
688 // * glUniformMatrix4fv(GLint location, GLboolean transpose, Float32Array data);
690 // FIXME: need to change to accept Float32Array as well.
691 if (args.Length() != 3) {
692 V8Proxy::setDOMException(SYNTAX_ERR);
693 return notHandledByInterceptor();
696 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
698 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) {
699 V8Proxy::throwTypeError();
700 return notHandledByInterceptor();
703 WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
705 bool transpose = args[1]->BooleanValue();
706 if (V8Float32Array::HasInstance(args[2])) {
707 Float32Array* array = V8Float32Array::toNative(args[2]->ToObject());
708 ASSERT(array != NULL);
709 ExceptionCode ec = 0;
710 switch (matrixSize) {
711 case 2: context->uniformMatrix2fv(location, transpose, array, ec); break;
712 case 3: context->uniformMatrix3fv(location, transpose, array, ec); break;
713 case 4: context->uniformMatrix4fv(location, transpose, array, ec); break;
714 default: ASSERT_NOT_REACHED(); break;
717 V8Proxy::setDOMException(ec);
718 return v8::Undefined();
721 if (args[2].IsEmpty() || !args[2]->IsArray()) {
722 V8Proxy::throwTypeError();
723 return notHandledByInterceptor();
725 v8::Handle<v8::Array> array =
726 v8::Local<v8::Array>::Cast(args[2]);
727 uint32_t len = array->Length();
728 float* data = jsArrayToFloatArray(array, len);
730 // FIXME: consider different / better exception type.
731 V8Proxy::setDOMException(SYNTAX_ERR);
732 return notHandledByInterceptor();
734 ExceptionCode ec = 0;
735 switch (matrixSize) {
736 case 2: context->uniformMatrix2fv(location, transpose, data, len, ec); break;
737 case 3: context->uniformMatrix3fv(location, transpose, data, len, ec); break;
738 case 4: context->uniformMatrix4fv(location, transpose, data, len, ec); break;
739 default: ASSERT_NOT_REACHED(); break;
743 V8Proxy::setDOMException(ec);
744 return v8::Undefined();
747 v8::Handle<v8::Value> V8WebGLRenderingContext::uniformMatrix2fvCallback(const v8::Arguments& args)
749 INC_STATS("DOM.WebGLRenderingContext.uniformMatrix2fv()");
750 return uniformMatrixHelper(args, 2);
753 v8::Handle<v8::Value> V8WebGLRenderingContext::uniformMatrix3fvCallback(const v8::Arguments& args)
755 INC_STATS("DOM.WebGLRenderingContext.uniformMatrix3fv()");
756 return uniformMatrixHelper(args, 3);
759 v8::Handle<v8::Value> V8WebGLRenderingContext::uniformMatrix4fvCallback(const v8::Arguments& args)
761 INC_STATS("DOM.WebGLRenderingContext.uniformMatrix4fv()");
762 return uniformMatrixHelper(args, 4);
765 v8::Handle<v8::Value> V8WebGLRenderingContext::vertexAttrib1fvCallback(const v8::Arguments& args)
767 INC_STATS("DOM.WebGLRenderingContext.vertexAttrib1fv()");
768 return vertexAttribAndUniformHelperf(args, kVertexAttrib1v);
771 v8::Handle<v8::Value> V8WebGLRenderingContext::vertexAttrib2fvCallback(const v8::Arguments& args)
773 INC_STATS("DOM.WebGLRenderingContext.vertexAttrib2fv()");
774 return vertexAttribAndUniformHelperf(args, kVertexAttrib2v);
777 v8::Handle<v8::Value> V8WebGLRenderingContext::vertexAttrib3fvCallback(const v8::Arguments& args)
779 INC_STATS("DOM.WebGLRenderingContext.vertexAttrib3fv()");
780 return vertexAttribAndUniformHelperf(args, kVertexAttrib3v);
783 v8::Handle<v8::Value> V8WebGLRenderingContext::vertexAttrib4fvCallback(const v8::Arguments& args)
785 INC_STATS("DOM.WebGLRenderingContext.vertexAttrib4fv()");
786 return vertexAttribAndUniformHelperf(args, kVertexAttrib4v);
789 } // namespace WebCore
791 #endif // ENABLE(WEBGL)