Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp

Issue 24096029: Moved the majority of WebGL functionality into WebGLRenderingContextBase (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "V8WebGLRenderingContext.h"
33
34 #include "V8ANGLEInstancedArrays.h"
35 #include "V8EXTFragDepth.h"
36 #include "V8EXTTextureFilterAnisotropic.h"
37 #include "V8HTMLCanvasElement.h"
38 #include "V8HTMLImageElement.h"
39 #include "V8HTMLVideoElement.h"
40 #include "V8ImageData.h"
41 #include "V8OESElementIndexUint.h"
42 #include "V8OESStandardDerivatives.h"
43 #include "V8OESTextureFloat.h"
44 #include "V8OESTextureFloatLinear.h"
45 #include "V8OESTextureHalfFloat.h"
46 #include "V8OESTextureHalfFloatLinear.h"
47 #include "V8OESVertexArrayObject.h"
48 #include "V8WebGLBuffer.h"
49 #include "V8WebGLCompressedTextureATC.h"
50 #include "V8WebGLCompressedTexturePVRTC.h"
51 #include "V8WebGLCompressedTextureS3TC.h"
52 #include "V8WebGLDebugRendererInfo.h"
53 #include "V8WebGLDebugShaders.h"
54 #include "V8WebGLDepthTexture.h"
55 #include "V8WebGLDrawBuffers.h"
56 #include "V8WebGLFramebuffer.h"
57 #include "V8WebGLLoseContext.h"
58 #include "V8WebGLProgram.h"
59 #include "V8WebGLRenderbuffer.h"
60 #include "V8WebGLShader.h"
61 #include "V8WebGLTexture.h"
62 #include "V8WebGLUniformLocation.h"
63 #include "V8WebGLVertexArrayObjectOES.h"
64 #include "bindings/v8/V8Binding.h"
65 #include "bindings/v8/V8HiddenPropertyName.h"
66 #include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
67 #include "bindings/v8/custom/V8Float32ArrayCustom.h"
68 #include "bindings/v8/custom/V8Int16ArrayCustom.h"
69 #include "bindings/v8/custom/V8Int32ArrayCustom.h"
70 #include "bindings/v8/custom/V8Int8ArrayCustom.h"
71 #include "bindings/v8/custom/V8Uint16ArrayCustom.h"
72 #include "bindings/v8/custom/V8Uint32ArrayCustom.h"
73 #include "bindings/v8/custom/V8Uint8ArrayCustom.h"
74 #include "core/dom/ExceptionCode.h"
75 #include "core/html/canvas/WebGLRenderingContext.h"
76 #include "core/platform/NotImplemented.h"
77 #include "wtf/FastMalloc.h"
78 #include <limits>
79
80 namespace WebCore {
81
82 // Allocates new storage via fastMalloc.
83 // Returns NULL if array failed to convert for any reason.
84 static float* jsArrayToFloatArray(v8::Handle<v8::Array> array, uint32_t len)
85 {
86 // Convert the data element-by-element.
87 if (len > std::numeric_limits<uint32_t>::max() / sizeof(float))
88 return 0;
89 float* data = static_cast<float*>(fastMalloc(len * sizeof(float)));
90
91 for (uint32_t i = 0; i < len; i++) {
92 v8::Local<v8::Value> val = array->Get(i);
93 if (!val->IsNumber()) {
94 fastFree(data);
95 return 0;
96 }
97 data[i] = toFloat(val);
98 }
99 return data;
100 }
101
102 // Allocates new storage via fastMalloc.
103 // Returns NULL if array failed to convert for any reason.
104 static int* jsArrayToIntArray(v8::Handle<v8::Array> array, uint32_t len)
105 {
106 // Convert the data element-by-element.
107 if (len > std::numeric_limits<uint32_t>::max() / sizeof(int))
108 return 0;
109 int* data = static_cast<int*>(fastMalloc(len * sizeof(int)));
110
111 for (uint32_t i = 0; i < len; i++) {
112 v8::Local<v8::Value> val = array->Get(i);
113 bool ok;
114 int ival = toInt32(val, ok);
115 if (!ok) {
116 fastFree(data);
117 return 0;
118 }
119 data[i] = ival;
120 }
121 return data;
122 }
123
124 static v8::Handle<v8::Value> toV8Object(const WebGLGetInfo& info, v8::Handle<v8: :Object> creationContext, v8::Isolate* isolate)
125 {
126 switch (info.getType()) {
127 case WebGLGetInfo::kTypeBool:
128 return v8::Boolean::New(info.getBool());
129 case WebGLGetInfo::kTypeBoolArray: {
130 const Vector<bool>& value = info.getBoolArray();
131 v8::Local<v8::Array> array = v8::Array::New(value.size());
132 for (size_t ii = 0; ii < value.size(); ++ii)
133 array->Set(v8::Integer::New(ii, isolate), v8::Boolean::New(value[ii] ));
134 return array;
135 }
136 case WebGLGetInfo::kTypeFloat:
137 return v8::Number::New(isolate, info.getFloat());
138 case WebGLGetInfo::kTypeInt:
139 return v8::Integer::New(info.getInt(), isolate);
140 case WebGLGetInfo::kTypeNull:
141 return v8::Null(isolate);
142 case WebGLGetInfo::kTypeString:
143 return v8String(info.getString(), isolate);
144 case WebGLGetInfo::kTypeUnsignedInt:
145 return v8::Integer::NewFromUnsigned(info.getUnsignedInt(), isolate);
146 case WebGLGetInfo::kTypeWebGLBuffer:
147 return toV8(info.getWebGLBuffer(), creationContext, isolate);
148 case WebGLGetInfo::kTypeWebGLFloatArray:
149 return toV8(info.getWebGLFloatArray(), creationContext, isolate);
150 case WebGLGetInfo::kTypeWebGLFramebuffer:
151 return toV8(info.getWebGLFramebuffer(), creationContext, isolate);
152 case WebGLGetInfo::kTypeWebGLIntArray:
153 return toV8(info.getWebGLIntArray(), creationContext, isolate);
154 // FIXME: implement WebGLObjectArray
155 // case WebGLGetInfo::kTypeWebGLObjectArray:
156 case WebGLGetInfo::kTypeWebGLProgram:
157 return toV8(info.getWebGLProgram(), creationContext, isolate);
158 case WebGLGetInfo::kTypeWebGLRenderbuffer:
159 return toV8(info.getWebGLRenderbuffer(), creationContext, isolate);
160 case WebGLGetInfo::kTypeWebGLTexture:
161 return toV8(info.getWebGLTexture(), creationContext, isolate);
162 case WebGLGetInfo::kTypeWebGLUnsignedByteArray:
163 return toV8(info.getWebGLUnsignedByteArray(), creationContext, isolate);
164 case WebGLGetInfo::kTypeWebGLUnsignedIntArray:
165 return toV8(info.getWebGLUnsignedIntArray(), creationContext, isolate);
166 case WebGLGetInfo::kTypeWebGLVertexArrayObjectOES:
167 return toV8(info.getWebGLVertexArrayObjectOES(), creationContext, isolat e);
168 default:
169 notImplemented();
170 return v8::Undefined(isolate);
171 }
172 }
173
174 static v8::Handle<v8::Value> toV8Object(WebGLExtension* extension, v8::Handle<v8 ::Object> contextObject, v8::Isolate* isolate)
175 {
176 if (!extension)
177 return v8::Null(isolate);
178 v8::Handle<v8::Value> extensionObject;
179 const char* referenceName = 0;
180 switch (extension->getName()) {
181 case WebGLExtension::ANGLEInstancedArraysName:
182 extensionObject = toV8(static_cast<ANGLEInstancedArrays*>(extension), co ntextObject, isolate);
183 referenceName = "angleInstancedArraysName";
184 break;
185 case WebGLExtension::EXTFragDepthName:
186 extensionObject = toV8(static_cast<EXTFragDepth*>(extension), contextObj ect, isolate);
187 referenceName = "extFragDepthName";
188 break;
189 case WebGLExtension::EXTTextureFilterAnisotropicName:
190 extensionObject = toV8(static_cast<EXTTextureFilterAnisotropic*>(extensi on), contextObject, isolate);
191 referenceName = "extTextureFilterAnisotropicName";
192 break;
193 case WebGLExtension::OESElementIndexUintName:
194 extensionObject = toV8(static_cast<OESElementIndexUint*>(extension), con textObject, isolate);
195 referenceName = "oesElementIndexUintName";
196 break;
197 case WebGLExtension::OESStandardDerivativesName:
198 extensionObject = toV8(static_cast<OESStandardDerivatives*>(extension), contextObject, isolate);
199 referenceName = "oesStandardDerivativesName";
200 break;
201 case WebGLExtension::OESTextureFloatName:
202 extensionObject = toV8(static_cast<OESTextureFloat*>(extension), context Object, isolate);
203 referenceName = "oesTextureFloatName";
204 break;
205 case WebGLExtension::OESTextureFloatLinearName:
206 extensionObject = toV8(static_cast<OESTextureFloatLinear*>(extension), c ontextObject, isolate);
207 referenceName = "oesTextureFloatLinearName";
208 break;
209 case WebGLExtension::OESTextureHalfFloatName:
210 extensionObject = toV8(static_cast<OESTextureHalfFloat*>(extension), con textObject, isolate);
211 referenceName = "oesTextureHalfFloatName";
212 break;
213 case WebGLExtension::OESTextureHalfFloatLinearName:
214 extensionObject = toV8(static_cast<OESTextureHalfFloatLinear*>(extension ), contextObject, isolate);
215 referenceName = "oesTextureHalfFloatLinearName";
216 break;
217 case WebGLExtension::OESVertexArrayObjectName:
218 extensionObject = toV8(static_cast<OESVertexArrayObject*>(extension), co ntextObject, isolate);
219 referenceName = "oesVertexArrayObjectName";
220 break;
221 case WebGLExtension::WebGLCompressedTextureATCName:
222 extensionObject = toV8(static_cast<WebGLCompressedTextureATC*>(extension ), contextObject, isolate);
223 referenceName = "webGLCompressedTextureATCName";
224 case WebGLExtension::WebGLCompressedTexturePVRTCName:
225 extensionObject = toV8(static_cast<WebGLCompressedTexturePVRTC*>(extensi on), contextObject, isolate);
226 referenceName = "webGLCompressedTexturePVRTCName";
227 break;
228 case WebGLExtension::WebGLCompressedTextureS3TCName:
229 extensionObject = toV8(static_cast<WebGLCompressedTextureS3TC*>(extensio n), contextObject, isolate);
230 referenceName = "webGLCompressedTextureS3TCName";
231 break;
232 case WebGLExtension::WebGLDebugRendererInfoName:
233 extensionObject = toV8(static_cast<WebGLDebugRendererInfo*>(extension), contextObject, isolate);
234 referenceName = "webGLDebugRendererInfoName";
235 break;
236 case WebGLExtension::WebGLDebugShadersName:
237 extensionObject = toV8(static_cast<WebGLDebugShaders*>(extension), conte xtObject, isolate);
238 referenceName = "webGLDebugShadersName";
239 break;
240 case WebGLExtension::WebGLDepthTextureName:
241 extensionObject = toV8(static_cast<WebGLDepthTexture*>(extension), conte xtObject, isolate);
242 referenceName = "webGLDepthTextureName";
243 break;
244 case WebGLExtension::WebGLDrawBuffersName:
245 extensionObject = toV8(static_cast<WebGLDrawBuffers*>(extension), contex tObject, isolate);
246 referenceName = "webGLDrawBuffersName";
247 break;
248 case WebGLExtension::WebGLLoseContextName:
249 extensionObject = toV8(static_cast<WebGLLoseContext*>(extension), contex tObject, isolate);
250 referenceName = "webGLLoseContextName";
251 break;
252 }
253 ASSERT(!extensionObject.IsEmpty());
254 V8HiddenPropertyName::setNamedHiddenReference(contextObject, referenceName, extensionObject);
255 return extensionObject;
256 }
257
258 enum ObjectType {
259 kBuffer, kRenderbuffer, kTexture, kVertexAttrib
260 };
261
262 static void getObjectParameter(const v8::FunctionCallbackInfo<v8::Value>& args, ObjectType objectType)
263 {
264 if (args.Length() != 2) {
265 throwNotEnoughArgumentsError(args.GetIsolate());
266 return;
267 }
268
269 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Hold er());
270 unsigned target = toInt32(args[0]);
271 unsigned pname = toInt32(args[1]);
272 WebGLGetInfo info;
273 switch (objectType) {
274 case kBuffer:
275 info = context->getBufferParameter(target, pname);
276 break;
277 case kRenderbuffer:
278 info = context->getRenderbufferParameter(target, pname);
279 break;
280 case kTexture:
281 info = context->getTexParameter(target, pname);
282 break;
283 case kVertexAttrib:
284 // target => index
285 info = context->getVertexAttrib(target, pname);
286 break;
287 default:
288 notImplemented();
289 break;
290 }
291 v8SetReturnValue(args, toV8Object(info, args.Holder(), args.GetIsolate()));
292 }
293
294 static WebGLUniformLocation* toWebGLUniformLocation(v8::Handle<v8::Value> value, bool& ok, v8::Isolate* isolate)
295 {
296 ok = false;
297 WebGLUniformLocation* location = 0;
298 if (V8WebGLUniformLocation::HasInstance(value, isolate, worldType(isolate))) {
299 location = V8WebGLUniformLocation::toNative(value->ToObject());
300 ok = true;
301 }
302 return location;
303 }
304
305 enum WhichProgramCall {
306 kProgramParameter, kUniform
307 };
308
309 void V8WebGLRenderingContext::getAttachedShadersMethodCustom(const v8::FunctionC allbackInfo<v8::Value>& args)
310 {
311 if (args.Length() < 1) {
312 throwNotEnoughArgumentsError(args.GetIsolate());
313 return;
314 }
315
316 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Hold er());
317 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::Has Instance(args[0], args.GetIsolate(), worldType(args.GetIsolate()))) {
318 throwTypeError(args.GetIsolate());
319 return;
320 }
321 WebGLProgram* program = V8WebGLProgram::HasInstance(args[0], args.GetIsolate (), worldType(args.GetIsolate())) ? V8WebGLProgram::toNative(v8::Handle<v8::Obje ct>::Cast(args[0])) : 0;
322 Vector<RefPtr<WebGLShader> > shaders;
323 bool succeed = context->getAttachedShaders(program, shaders);
324 if (!succeed) {
325 v8SetReturnValueNull(args);
326 return;
327 }
328 v8::Local<v8::Array> array = v8::Array::New(shaders.size());
329 for (size_t ii = 0; ii < shaders.size(); ++ii)
330 array->Set(v8::Integer::New(ii, args.GetIsolate()), toV8(shaders[ii].get (), args.Holder(), args.GetIsolate()));
331 v8SetReturnValue(args, array);
332 }
333
334 void V8WebGLRenderingContext::getBufferParameterMethodCustom(const v8::FunctionC allbackInfo<v8::Value>& args)
335 {
336 getObjectParameter(args, kBuffer);
337 }
338
339 void V8WebGLRenderingContext::getExtensionMethodCustom(const v8::FunctionCallbac kInfo<v8::Value>& args)
340 {
341 WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(args.Holder() );
342 if (args.Length() < 1) {
343 throwNotEnoughArgumentsError(args.GetIsolate());
344 return;
345 }
346 V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, name, args[0]);
347 RefPtr<WebGLExtension> extension(imp->getExtension(name));
348 v8SetReturnValue(args, toV8Object(extension.get(), args.Holder(), args.GetIs olate()));
349 }
350
351 void V8WebGLRenderingContext::getFramebufferAttachmentParameterMethodCustom(cons t v8::FunctionCallbackInfo<v8::Value>& args)
352 {
353 if (args.Length() != 3) {
354 throwNotEnoughArgumentsError(args.GetIsolate());
355 return;
356 }
357
358 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Hold er());
359 unsigned target = toInt32(args[0]);
360 unsigned attachment = toInt32(args[1]);
361 unsigned pname = toInt32(args[2]);
362 WebGLGetInfo info = context->getFramebufferAttachmentParameter(target, attac hment, pname);
363 v8SetReturnValue(args, toV8Object(info, args.Holder(), args.GetIsolate()));
364 }
365
366 void V8WebGLRenderingContext::getParameterMethodCustom(const v8::FunctionCallbac kInfo<v8::Value>& args)
367 {
368 if (args.Length() != 1) {
369 throwNotEnoughArgumentsError(args.GetIsolate());
370 return;
371 }
372
373 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Hold er());
374 unsigned pname = toInt32(args[0]);
375 WebGLGetInfo info = context->getParameter(pname);
376 v8SetReturnValue(args, toV8Object(info, args.Holder(), args.GetIsolate()));
377 }
378
379 void V8WebGLRenderingContext::getProgramParameterMethodCustom(const v8::Function CallbackInfo<v8::Value>& args)
380 {
381 if (args.Length() != 2) {
382 throwNotEnoughArgumentsError(args.GetIsolate());
383 return;
384 }
385
386 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Hold er());
387 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::Has Instance(args[0], args.GetIsolate(), worldType(args.GetIsolate()))) {
388 throwTypeError(args.GetIsolate());
389 return;
390 }
391 WebGLProgram* program = V8WebGLProgram::HasInstance(args[0], args.GetIsolate (), worldType(args.GetIsolate())) ? V8WebGLProgram::toNative(v8::Handle<v8::Obje ct>::Cast(args[0])) : 0;
392 unsigned pname = toInt32(args[1]);
393 WebGLGetInfo info = context->getProgramParameter(program, pname);
394 v8SetReturnValue(args, toV8Object(info, args.Holder(), args.GetIsolate()));
395 }
396
397 void V8WebGLRenderingContext::getRenderbufferParameterMethodCustom(const v8::Fun ctionCallbackInfo<v8::Value>& args)
398 {
399 getObjectParameter(args, kRenderbuffer);
400 }
401
402 void V8WebGLRenderingContext::getShaderParameterMethodCustom(const v8::FunctionC allbackInfo<v8::Value>& args)
403 {
404 if (args.Length() != 2) {
405 throwNotEnoughArgumentsError(args.GetIsolate());
406 return;
407 }
408
409 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Hold er());
410 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLShader::HasI nstance(args[0], args.GetIsolate(), worldType(args.GetIsolate()))) {
411 throwTypeError(args.GetIsolate());
412 return;
413 }
414 WebGLShader* shader = V8WebGLShader::HasInstance(args[0], args.GetIsolate(), worldType(args.GetIsolate())) ? V8WebGLShader::toNative(v8::Handle<v8::Object>: :Cast(args[0])) : 0;
415 unsigned pname = toInt32(args[1]);
416 WebGLGetInfo info = context->getShaderParameter(shader, pname);
417 v8SetReturnValue(args, toV8Object(info, args.Holder(), args.GetIsolate()));
418 }
419
420 void V8WebGLRenderingContext::getSupportedExtensionsMethodCustom(const v8::Funct ionCallbackInfo<v8::Value>& args)
421 {
422 WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(args.Holder() );
423 if (imp->isContextLost()) {
424 v8SetReturnValueNull(args);
425 return;
426 }
427
428 Vector<String> value = imp->getSupportedExtensions();
429 v8::Local<v8::Array> array = v8::Array::New(value.size());
430 for (size_t ii = 0; ii < value.size(); ++ii)
431 array->Set(v8::Integer::New(ii, args.GetIsolate()), v8String(value[ii], args.GetIsolate()));
432 v8SetReturnValue(args, array);
433 }
434
435 void V8WebGLRenderingContext::getTexParameterMethodCustom(const v8::FunctionCall backInfo<v8::Value>& args)
436 {
437 getObjectParameter(args, kTexture);
438 }
439
440 void V8WebGLRenderingContext::getUniformMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& args)
441 {
442 if (args.Length() != 2) {
443 throwNotEnoughArgumentsError(args.GetIsolate());
444 return;
445 }
446
447 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Hold er());
448 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::Has Instance(args[0], args.GetIsolate(), worldType(args.GetIsolate()))) {
449 throwTypeError(args.GetIsolate());
450 return;
451 }
452 WebGLProgram* program = V8WebGLProgram::HasInstance(args[0], args.GetIsolate (), worldType(args.GetIsolate())) ? V8WebGLProgram::toNative(v8::Handle<v8::Obje ct>::Cast(args[0])) : 0;
453
454 if (args.Length() > 1 && !isUndefinedOrNull(args[1]) && !V8WebGLUniformLocat ion::HasInstance(args[1], args.GetIsolate(), worldType(args.GetIsolate()))) {
455 throwTypeError(args.GetIsolate());
456 return;
457 }
458 bool ok = false;
459 WebGLUniformLocation* location = toWebGLUniformLocation(args[1], ok, args.Ge tIsolate());
460
461 WebGLGetInfo info = context->getUniform(program, location);
462 v8SetReturnValue(args, toV8Object(info, args.Holder(), args.GetIsolate()));
463 }
464
465 void V8WebGLRenderingContext::getVertexAttribMethodCustom(const v8::FunctionCall backInfo<v8::Value>& args)
466 {
467 getObjectParameter(args, kVertexAttrib);
468 }
469
470 enum FunctionToCall {
471 kUniform1v, kUniform2v, kUniform3v, kUniform4v,
472 kVertexAttrib1v, kVertexAttrib2v, kVertexAttrib3v, kVertexAttrib4v
473 };
474
475 bool isFunctionToCallForAttribute(FunctionToCall functionToCall)
476 {
477 switch (functionToCall) {
478 case kVertexAttrib1v:
479 case kVertexAttrib2v:
480 case kVertexAttrib3v:
481 case kVertexAttrib4v:
482 return true;
483 default:
484 break;
485 }
486 return false;
487 }
488
489 static void vertexAttribAndUniformHelperf(const v8::FunctionCallbackInfo<v8::Val ue>& args, FunctionToCall functionToCall)
490 {
491 // Forms:
492 // * glUniform1fv(WebGLUniformLocation location, Array data);
493 // * glUniform1fv(WebGLUniformLocation location, Float32Array data);
494 // * glUniform2fv(WebGLUniformLocation location, Array data);
495 // * glUniform2fv(WebGLUniformLocation location, Float32Array data);
496 // * glUniform3fv(WebGLUniformLocation location, Array data);
497 // * glUniform3fv(WebGLUniformLocation location, Float32Array data);
498 // * glUniform4fv(WebGLUniformLocation location, Array data);
499 // * glUniform4fv(WebGLUniformLocation location, Float32Array data);
500 // * glVertexAttrib1fv(GLint index, Array data);
501 // * glVertexAttrib1fv(GLint index, Float32Array data);
502 // * glVertexAttrib2fv(GLint index, Array data);
503 // * glVertexAttrib2fv(GLint index, Float32Array data);
504 // * glVertexAttrib3fv(GLint index, Array data);
505 // * glVertexAttrib3fv(GLint index, Float32Array data);
506 // * glVertexAttrib4fv(GLint index, Array data);
507 // * glVertexAttrib4fv(GLint index, Float32Array data);
508
509 if (args.Length() != 2) {
510 throwNotEnoughArgumentsError(args.GetIsolate());
511 return;
512 }
513
514 bool ok = false;
515 int index = -1;
516 WebGLUniformLocation* location = 0;
517
518 if (isFunctionToCallForAttribute(functionToCall))
519 index = toInt32(args[0]);
520 else {
521 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformL ocation::HasInstance(args[0], args.GetIsolate(), worldType(args.GetIsolate()))) {
522 throwTypeError(args.GetIsolate());
523 return;
524 }
525 location = toWebGLUniformLocation(args[0], ok, args.GetIsolate());
526 }
527
528 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Hold er());
529
530 if (V8Float32Array::HasInstance(args[1], args.GetIsolate(), worldType(args.G etIsolate()))) {
531 Float32Array* array = V8Float32Array::toNative(args[1]->ToObject());
532 ASSERT(array != NULL);
533 switch (functionToCall) {
534 case kUniform1v: context->uniform1fv(location, array); break;
535 case kUniform2v: context->uniform2fv(location, array); break;
536 case kUniform3v: context->uniform3fv(location, array); break;
537 case kUniform4v: context->uniform4fv(location, array); break;
538 case kVertexAttrib1v: context->vertexAttrib1fv(index, array); break;
539 case kVertexAttrib2v: context->vertexAttrib2fv(index, array); break;
540 case kVertexAttrib3v: context->vertexAttrib3fv(index, array); break;
541 case kVertexAttrib4v: context->vertexAttrib4fv(index, array); break;
542 default: ASSERT_NOT_REACHED(); break;
543 }
544 return;
545 }
546
547 if (args[1].IsEmpty() || !args[1]->IsArray()) {
548 throwTypeError(args.GetIsolate());
549 return;
550 }
551 v8::Handle<v8::Array> array =
552 v8::Local<v8::Array>::Cast(args[1]);
553 uint32_t len = array->Length();
554 float* data = jsArrayToFloatArray(array, len);
555 if (!data) {
556 // FIXME: consider different / better exception type.
557 setDOMException(SyntaxError, args.GetIsolate());
558 return;
559 }
560 switch (functionToCall) {
561 case kUniform1v: context->uniform1fv(location, data, len); break;
562 case kUniform2v: context->uniform2fv(location, data, len); break;
563 case kUniform3v: context->uniform3fv(location, data, len); break;
564 case kUniform4v: context->uniform4fv(location, data, len); break;
565 case kVertexAttrib1v: context->vertexAttrib1fv(index, data, len); break;
566 case kVertexAttrib2v: context->vertexAttrib2fv(index, data, len); break;
567 case kVertexAttrib3v: context->vertexAttrib3fv(index, data, len); break;
568 case kVertexAttrib4v: context->vertexAttrib4fv(index, data, len); break;
569 default: ASSERT_NOT_REACHED(); break;
570 }
571 fastFree(data);
572 }
573
574 static void uniformHelperi(const v8::FunctionCallbackInfo<v8::Value>& args, Func tionToCall functionToCall)
575 {
576 // Forms:
577 // * glUniform1iv(GLUniformLocation location, Array data);
578 // * glUniform1iv(GLUniformLocation location, Int32Array data);
579 // * glUniform2iv(GLUniformLocation location, Array data);
580 // * glUniform2iv(GLUniformLocation location, Int32Array data);
581 // * glUniform3iv(GLUniformLocation location, Array data);
582 // * glUniform3iv(GLUniformLocation location, Int32Array data);
583 // * glUniform4iv(GLUniformLocation location, Array data);
584 // * glUniform4iv(GLUniformLocation location, Int32Array data);
585
586 if (args.Length() != 2) {
587 throwNotEnoughArgumentsError(args.GetIsolate());
588 return;
589 }
590
591 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Hold er());
592 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocat ion::HasInstance(args[0], args.GetIsolate(), worldType(args.GetIsolate()))) {
593 throwTypeError(args.GetIsolate());
594 return;
595 }
596 bool ok = false;
597 WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok, args.Ge tIsolate());
598
599 if (V8Int32Array::HasInstance(args[1], args.GetIsolate(), worldType(args.Get Isolate()))) {
600 Int32Array* array = V8Int32Array::toNative(args[1]->ToObject());
601 ASSERT(array != NULL);
602 switch (functionToCall) {
603 case kUniform1v: context->uniform1iv(location, array); break;
604 case kUniform2v: context->uniform2iv(location, array); break;
605 case kUniform3v: context->uniform3iv(location, array); break;
606 case kUniform4v: context->uniform4iv(location, array); break;
607 default: ASSERT_NOT_REACHED(); break;
608 }
609 return;
610 }
611
612 if (args[1].IsEmpty() || !args[1]->IsArray()) {
613 throwTypeError(args.GetIsolate());
614 return;
615 }
616 v8::Handle<v8::Array> array =
617 v8::Local<v8::Array>::Cast(args[1]);
618 uint32_t len = array->Length();
619 int* data = jsArrayToIntArray(array, len);
620 if (!data) {
621 // FIXME: consider different / better exception type.
622 setDOMException(SyntaxError, args.GetIsolate());
623 return;
624 }
625 switch (functionToCall) {
626 case kUniform1v: context->uniform1iv(location, data, len); break;
627 case kUniform2v: context->uniform2iv(location, data, len); break;
628 case kUniform3v: context->uniform3iv(location, data, len); break;
629 case kUniform4v: context->uniform4iv(location, data, len); break;
630 default: ASSERT_NOT_REACHED(); break;
631 }
632 fastFree(data);
633 }
634
635 void V8WebGLRenderingContext::uniform1fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& args)
636 {
637 vertexAttribAndUniformHelperf(args, kUniform1v);
638 }
639
640 void V8WebGLRenderingContext::uniform1ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& args)
641 {
642 uniformHelperi(args, kUniform1v);
643 }
644
645 void V8WebGLRenderingContext::uniform2fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& args)
646 {
647 vertexAttribAndUniformHelperf(args, kUniform2v);
648 }
649
650 void V8WebGLRenderingContext::uniform2ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& args)
651 {
652 uniformHelperi(args, kUniform2v);
653 }
654
655 void V8WebGLRenderingContext::uniform3fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& args)
656 {
657 vertexAttribAndUniformHelperf(args, kUniform3v);
658 }
659
660 void V8WebGLRenderingContext::uniform3ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& args)
661 {
662 uniformHelperi(args, kUniform3v);
663 }
664
665 void V8WebGLRenderingContext::uniform4fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& args)
666 {
667 vertexAttribAndUniformHelperf(args, kUniform4v);
668 }
669
670 void V8WebGLRenderingContext::uniform4ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& args)
671 {
672 uniformHelperi(args, kUniform4v);
673 }
674
675 static void uniformMatrixHelper(const v8::FunctionCallbackInfo<v8::Value>& args, int matrixSize)
676 {
677 // Forms:
678 // * glUniformMatrix2fv(GLint location, GLboolean transpose, Array data);
679 // * glUniformMatrix2fv(GLint location, GLboolean transpose, Float32Array da ta);
680 // * glUniformMatrix3fv(GLint location, GLboolean transpose, Array data);
681 // * glUniformMatrix3fv(GLint location, GLboolean transpose, Float32Array da ta);
682 // * glUniformMatrix4fv(GLint location, GLboolean transpose, Array data);
683 // * glUniformMatrix4fv(GLint location, GLboolean transpose, Float32Array da ta);
684 //
685 // FIXME: need to change to accept Float32Array as well.
686 if (args.Length() != 3) {
687 throwNotEnoughArgumentsError(args.GetIsolate());
688 return;
689 }
690
691 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Hold er());
692
693 if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocat ion::HasInstance(args[0], args.GetIsolate(), worldType(args.GetIsolate()))) {
694 throwTypeError(args.GetIsolate());
695 return;
696 }
697 bool ok = false;
698 WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok, args.Ge tIsolate());
699
700 bool transpose = args[1]->BooleanValue();
701 if (V8Float32Array::HasInstance(args[2], args.GetIsolate(), worldType(args.G etIsolate()))) {
702 Float32Array* array = V8Float32Array::toNative(args[2]->ToObject());
703 ASSERT(array != NULL);
704 switch (matrixSize) {
705 case 2: context->uniformMatrix2fv(location, transpose, array); break;
706 case 3: context->uniformMatrix3fv(location, transpose, array); break;
707 case 4: context->uniformMatrix4fv(location, transpose, array); break;
708 default: ASSERT_NOT_REACHED(); break;
709 }
710 return;
711 }
712
713 if (args[2].IsEmpty() || !args[2]->IsArray()) {
714 throwTypeError(args.GetIsolate());
715 return;
716 }
717 v8::Handle<v8::Array> array =
718 v8::Local<v8::Array>::Cast(args[2]);
719 uint32_t len = array->Length();
720 float* data = jsArrayToFloatArray(array, len);
721 if (!data) {
722 // FIXME: consider different / better exception type.
723 setDOMException(SyntaxError, args.GetIsolate());
724 return;
725 }
726 switch (matrixSize) {
727 case 2: context->uniformMatrix2fv(location, transpose, data, len); break;
728 case 3: context->uniformMatrix3fv(location, transpose, data, len); break;
729 case 4: context->uniformMatrix4fv(location, transpose, data, len); break;
730 default: ASSERT_NOT_REACHED(); break;
731 }
732 fastFree(data);
733 }
734
735 void V8WebGLRenderingContext::uniformMatrix2fvMethodCustom(const v8::FunctionCal lbackInfo<v8::Value>& args)
736 {
737 uniformMatrixHelper(args, 2);
738 }
739
740 void V8WebGLRenderingContext::uniformMatrix3fvMethodCustom(const v8::FunctionCal lbackInfo<v8::Value>& args)
741 {
742 uniformMatrixHelper(args, 3);
743 }
744
745 void V8WebGLRenderingContext::uniformMatrix4fvMethodCustom(const v8::FunctionCal lbackInfo<v8::Value>& args)
746 {
747 uniformMatrixHelper(args, 4);
748 }
749
750 void V8WebGLRenderingContext::vertexAttrib1fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& args)
751 {
752 vertexAttribAndUniformHelperf(args, kVertexAttrib1v);
753 }
754
755 void V8WebGLRenderingContext::vertexAttrib2fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& args)
756 {
757 vertexAttribAndUniformHelperf(args, kVertexAttrib2v);
758 }
759
760 void V8WebGLRenderingContext::vertexAttrib3fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& args)
761 {
762 vertexAttribAndUniformHelperf(args, kVertexAttrib3v);
763 }
764
765 void V8WebGLRenderingContext::vertexAttrib4fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& args)
766 {
767 vertexAttribAndUniformHelperf(args, kVertexAttrib4v);
768 }
769
770 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698