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

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: Re-wrote patch by hand (too much to rebase) Created 6 years, 10 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/ExceptionMessages.h"
65 #include "bindings/v8/V8Binding.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 "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, Exc eptionState& exceptionState)
85 {
86 // Convert the data element-by-element.
87 if (len > std::numeric_limits<uint32_t>::max() / sizeof(float)) {
88 exceptionState.throwTypeError("Array length exceeds supported limit.");
89 return 0;
90 }
91 float* data = static_cast<float*>(fastMalloc(len * sizeof(float)));
92
93 for (uint32_t i = 0; i < len; i++) {
94 v8::Local<v8::Value> val = array->Get(i);
95 float value = toFloat(val, exceptionState);
96 if (exceptionState.hadException()) {
97 fastFree(data);
98 return 0;
99 }
100 data[i] = value;
101 }
102 return data;
103 }
104
105 // Allocates new storage via fastMalloc.
106 // Returns NULL if array failed to convert for any reason.
107 static int* jsArrayToIntArray(v8::Handle<v8::Array> array, uint32_t len, Excepti onState& exceptionState)
108 {
109 // Convert the data element-by-element.
110 if (len > std::numeric_limits<uint32_t>::max() / sizeof(int)) {
111 exceptionState.throwTypeError("Array length exceeds supported limit.");
112 return 0;
113 }
114 int* data = static_cast<int*>(fastMalloc(len * sizeof(int)));
115
116 for (uint32_t i = 0; i < len; i++) {
117 v8::Local<v8::Value> val = array->Get(i);
118 int ival = toInt32(val, exceptionState);
119 if (exceptionState.hadException()) {
120 fastFree(data);
121 return 0;
122 }
123 data[i] = ival;
124 }
125 return data;
126 }
127
128 static v8::Handle<v8::Value> toV8Object(const WebGLGetInfo& args, v8::Handle<v8: :Object> creationContext, v8::Isolate* isolate)
129 {
130 switch (args.getType()) {
131 case WebGLGetInfo::kTypeBool:
132 return v8Boolean(args.getBool(), isolate);
133 case WebGLGetInfo::kTypeBoolArray: {
134 const Vector<bool>& value = args.getBoolArray();
135 v8::Local<v8::Array> array = v8::Array::New(isolate, value.size());
136 for (size_t ii = 0; ii < value.size(); ++ii)
137 array->Set(v8::Integer::New(isolate, ii), v8Boolean(value[ii], isola te));
138 return array;
139 }
140 case WebGLGetInfo::kTypeFloat:
141 return v8::Number::New(isolate, args.getFloat());
142 case WebGLGetInfo::kTypeInt:
143 return v8::Integer::New(isolate, args.getInt());
144 case WebGLGetInfo::kTypeNull:
145 return v8::Null(isolate);
146 case WebGLGetInfo::kTypeString:
147 return v8String(isolate, args.getString());
148 case WebGLGetInfo::kTypeUnsignedInt:
149 return v8::Integer::NewFromUnsigned(isolate, args.getUnsignedInt());
150 case WebGLGetInfo::kTypeWebGLBuffer:
151 return toV8(args.getWebGLBuffer(), creationContext, isolate);
152 case WebGLGetInfo::kTypeWebGLFloatArray:
153 return toV8(args.getWebGLFloatArray(), creationContext, isolate);
154 case WebGLGetInfo::kTypeWebGLFramebuffer:
155 return toV8(args.getWebGLFramebuffer(), creationContext, isolate);
156 case WebGLGetInfo::kTypeWebGLIntArray:
157 return toV8(args.getWebGLIntArray(), creationContext, isolate);
158 // FIXME: implement WebGLObjectArray
159 // case WebGLGetInfo::kTypeWebGLObjectArray:
160 case WebGLGetInfo::kTypeWebGLProgram:
161 return toV8(args.getWebGLProgram(), creationContext, isolate);
162 case WebGLGetInfo::kTypeWebGLRenderbuffer:
163 return toV8(args.getWebGLRenderbuffer(), creationContext, isolate);
164 case WebGLGetInfo::kTypeWebGLTexture:
165 return toV8(args.getWebGLTexture(), creationContext, isolate);
166 case WebGLGetInfo::kTypeWebGLUnsignedByteArray:
167 return toV8(args.getWebGLUnsignedByteArray(), creationContext, isolate);
168 case WebGLGetInfo::kTypeWebGLUnsignedIntArray:
169 return toV8(args.getWebGLUnsignedIntArray(), creationContext, isolate);
170 case WebGLGetInfo::kTypeWebGLVertexArrayObjectOES:
171 return toV8(args.getWebGLVertexArrayObjectOES(), creationContext, isolat e);
172 default:
173 notImplemented();
174 return v8::Undefined(isolate);
175 }
176 }
177
178 static v8::Handle<v8::Value> toV8Object(WebGLExtension* extension, v8::Handle<v8 ::Object> contextObject, v8::Isolate* isolate)
179 {
180 if (!extension)
181 return v8::Null(isolate);
182 v8::Handle<v8::Value> extensionObject;
183 const char* referenceName = 0;
184 switch (extension->name()) {
185 case WebGLExtension::ANGLEInstancedArraysName:
186 extensionObject = toV8(static_cast<ANGLEInstancedArrays*>(extension), co ntextObject, isolate);
187 referenceName = "angleInstancedArraysName";
188 break;
189 case WebGLExtension::EXTFragDepthName:
190 extensionObject = toV8(static_cast<EXTFragDepth*>(extension), contextObj ect, isolate);
191 referenceName = "extFragDepthName";
192 break;
193 case WebGLExtension::EXTTextureFilterAnisotropicName:
194 extensionObject = toV8(static_cast<EXTTextureFilterAnisotropic*>(extensi on), contextObject, isolate);
195 referenceName = "extTextureFilterAnisotropicName";
196 break;
197 case WebGLExtension::OESElementIndexUintName:
198 extensionObject = toV8(static_cast<OESElementIndexUint*>(extension), con textObject, isolate);
199 referenceName = "oesElementIndexUintName";
200 break;
201 case WebGLExtension::OESStandardDerivativesName:
202 extensionObject = toV8(static_cast<OESStandardDerivatives*>(extension), contextObject, isolate);
203 referenceName = "oesStandardDerivativesName";
204 break;
205 case WebGLExtension::OESTextureFloatName:
206 extensionObject = toV8(static_cast<OESTextureFloat*>(extension), context Object, isolate);
207 referenceName = "oesTextureFloatName";
208 break;
209 case WebGLExtension::OESTextureFloatLinearName:
210 extensionObject = toV8(static_cast<OESTextureFloatLinear*>(extension), c ontextObject, isolate);
211 referenceName = "oesTextureFloatLinearName";
212 break;
213 case WebGLExtension::OESTextureHalfFloatName:
214 extensionObject = toV8(static_cast<OESTextureHalfFloat*>(extension), con textObject, isolate);
215 referenceName = "oesTextureHalfFloatName";
216 break;
217 case WebGLExtension::OESTextureHalfFloatLinearName:
218 extensionObject = toV8(static_cast<OESTextureHalfFloatLinear*>(extension ), contextObject, isolate);
219 referenceName = "oesTextureHalfFloatLinearName";
220 break;
221 case WebGLExtension::OESVertexArrayObjectName:
222 extensionObject = toV8(static_cast<OESVertexArrayObject*>(extension), co ntextObject, isolate);
223 referenceName = "oesVertexArrayObjectName";
224 break;
225 case WebGLExtension::WebGLCompressedTextureATCName:
226 extensionObject = toV8(static_cast<WebGLCompressedTextureATC*>(extension ), contextObject, isolate);
227 referenceName = "webGLCompressedTextureATCName";
228 break;
229 case WebGLExtension::WebGLCompressedTexturePVRTCName:
230 extensionObject = toV8(static_cast<WebGLCompressedTexturePVRTC*>(extensi on), contextObject, isolate);
231 referenceName = "webGLCompressedTexturePVRTCName";
232 break;
233 case WebGLExtension::WebGLCompressedTextureS3TCName:
234 extensionObject = toV8(static_cast<WebGLCompressedTextureS3TC*>(extensio n), contextObject, isolate);
235 referenceName = "webGLCompressedTextureS3TCName";
236 break;
237 case WebGLExtension::WebGLDebugRendererInfoName:
238 extensionObject = toV8(static_cast<WebGLDebugRendererInfo*>(extension), contextObject, isolate);
239 referenceName = "webGLDebugRendererInfoName";
240 break;
241 case WebGLExtension::WebGLDebugShadersName:
242 extensionObject = toV8(static_cast<WebGLDebugShaders*>(extension), conte xtObject, isolate);
243 referenceName = "webGLDebugShadersName";
244 break;
245 case WebGLExtension::WebGLDepthTextureName:
246 extensionObject = toV8(static_cast<WebGLDepthTexture*>(extension), conte xtObject, isolate);
247 referenceName = "webGLDepthTextureName";
248 break;
249 case WebGLExtension::WebGLDrawBuffersName:
250 extensionObject = toV8(static_cast<WebGLDrawBuffers*>(extension), contex tObject, isolate);
251 referenceName = "webGLDrawBuffersName";
252 break;
253 case WebGLExtension::WebGLLoseContextName:
254 extensionObject = toV8(static_cast<WebGLLoseContext*>(extension), contex tObject, isolate);
255 referenceName = "webGLLoseContextName";
256 break;
257 }
258 ASSERT(!extensionObject.IsEmpty());
259 setHiddenValue(isolate, contextObject, referenceName, extensionObject);
260 return extensionObject;
261 }
262
263 enum ObjectType {
264 kBuffer, kRenderbuffer, kTexture, kVertexAttrib
265 };
266
267 static void getObjectParameter(const v8::FunctionCallbackInfo<v8::Value>& info, ObjectType objectType, ExceptionState& exceptionState)
268 {
269 if (info.Length() != 2) {
270 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, i nfo.Length()));
271 exceptionState.throwIfNeeded();
272 return;
273 }
274
275 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
276 unsigned target = toInt32(info[0], exceptionState);
277 if (exceptionState.throwIfNeeded())
278 return;
279 unsigned pname = toInt32(info[1], exceptionState);
280 if (exceptionState.throwIfNeeded())
281 return;
282 WebGLGetInfo args;
283 switch (objectType) {
284 case kBuffer:
285 args = context->getBufferParameter(target, pname);
286 break;
287 case kRenderbuffer:
288 args = context->getRenderbufferParameter(target, pname);
289 break;
290 case kTexture:
291 args = context->getTexParameter(target, pname);
292 break;
293 case kVertexAttrib:
294 // target => index
295 args = context->getVertexAttrib(target, pname);
296 break;
297 default:
298 notImplemented();
299 break;
300 }
301 v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
302 }
303
304 static WebGLUniformLocation* toWebGLUniformLocation(v8::Handle<v8::Value> value, v8::Isolate* isolate)
305 {
306 if (!V8WebGLUniformLocation::hasInstance(value, isolate))
307 return 0;
308 return V8WebGLUniformLocation::toNative(value->ToObject());
309 }
310
311 enum WhichProgramCall {
312 kProgramParameter, kUniform
313 };
314
315 void V8WebGLRenderingContext::getAttachedShadersMethodCustom(const v8::FunctionC allbackInfo<v8::Value>& info)
316 {
317 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getAttached Shaders", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
318 if (info.Length() < 1) {
319 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, i nfo.Length()));
320 exceptionState.throwIfNeeded();
321 return;
322 }
323
324 const int programArgumentIndex = 0;
325 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
326 if (info.Length() > 0 && !isUndefinedOrNull(info[programArgumentIndex]) && ! V8WebGLProgram::hasInstance(info[programArgumentIndex], info.GetIsolate())) {
327 exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentType(p rogramArgumentIndex + 1, "is not a WebGLProgram object."));
328 exceptionState.throwIfNeeded();
329 return;
330 }
331 WebGLProgram* program = V8WebGLProgram::hasInstance(info[0], info.GetIsolate ()) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0;
332 Vector<RefPtr<WebGLShader> > shaders;
333 bool succeed = context->getAttachedShaders(program, shaders);
334 if (!succeed) {
335 v8SetReturnValueNull(info);
336 return;
337 }
338 v8::Local<v8::Array> array = v8::Array::New(info.GetIsolate(), shaders.size( ));
339 for (size_t ii = 0; ii < shaders.size(); ++ii)
340 array->Set(v8::Integer::New(info.GetIsolate(), ii), toV8(shaders[ii].get (), info.Holder(), info.GetIsolate()));
341 v8SetReturnValue(info, array);
342 }
343
344 void V8WebGLRenderingContext::getBufferParameterMethodCustom(const v8::FunctionC allbackInfo<v8::Value>& info)
345 {
346 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getBufferPa rameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
347 getObjectParameter(info, kBuffer, exceptionState);
348 }
349
350 void V8WebGLRenderingContext::getExtensionMethodCustom(const v8::FunctionCallbac kInfo<v8::Value>& info)
351 {
352 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getExtensio n", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
353 WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(info.Holder() );
354 if (info.Length() < 1) {
355 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, i nfo.Length()));
356 exceptionState.throwIfNeeded();
357 return;
358 }
359 V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, name, info[0]);
360 RefPtr<WebGLExtension> extension(imp->getExtension(name));
361 v8SetReturnValue(info, toV8Object(extension.get(), info.Holder(), info.GetIs olate()));
362 }
363
364 void V8WebGLRenderingContext::getFramebufferAttachmentParameterMethodCustom(cons t v8::FunctionCallbackInfo<v8::Value>& info)
365 {
366 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getFramebuf ferAttachmentParameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate ());
367 if (info.Length() != 3) {
368 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(3, i nfo.Length()));
369 exceptionState.throwIfNeeded();
370 return;
371 }
372
373 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
374 unsigned target = toInt32(info[0]);
375 unsigned attachment = toInt32(info[1], exceptionState);
376 if (exceptionState.throwIfNeeded())
377 return;
378 unsigned pname = toInt32(info[2], exceptionState);
379 if (exceptionState.throwIfNeeded())
380 return;
381 WebGLGetInfo args = context->getFramebufferAttachmentParameter(target, attac hment, pname);
382 v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
383 }
384
385 void V8WebGLRenderingContext::getParameterMethodCustom(const v8::FunctionCallbac kInfo<v8::Value>& info)
386 {
387 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getParamete r", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
388 if (info.Length() != 1) {
389 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, i nfo.Length()));
390 exceptionState.throwIfNeeded();
391 return;
392 }
393
394 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
395 unsigned pname = toInt32(info[0], exceptionState);
396 if (exceptionState.throwIfNeeded())
397 return;
398 WebGLGetInfo args = context->getParameter(pname);
399 v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
400 }
401
402 void V8WebGLRenderingContext::getProgramParameterMethodCustom(const v8::Function CallbackInfo<v8::Value>& info)
403 {
404 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getProgramP arameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
405 if (info.Length() != 2) {
406 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, i nfo.Length()));
407 exceptionState.throwIfNeeded();
408 return;
409 }
410
411 const int programArgumentIndex = 0;
412 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
413 if (info.Length() > 0 && !isUndefinedOrNull(info[programArgumentIndex]) && ! V8WebGLProgram::hasInstance(info[programArgumentIndex], info.GetIsolate())) {
414 exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentType(p rogramArgumentIndex + 1, "is not a WebGLProgram object."));
415 exceptionState.throwIfNeeded();
416 return;
417 }
418 WebGLProgram* program = V8WebGLProgram::hasInstance(info[0], info.GetIsolate ()) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0;
419 unsigned pname = toInt32(info[1], exceptionState);
420 if (exceptionState.throwIfNeeded())
421 return;
422 WebGLGetInfo args = context->getProgramParameter(program, pname);
423 v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
424 }
425
426 void V8WebGLRenderingContext::getRenderbufferParameterMethodCustom(const v8::Fun ctionCallbackInfo<v8::Value>& info)
427 {
428 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getRenderbu fferParameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
429 getObjectParameter(info, kRenderbuffer, exceptionState);
430 }
431
432 void V8WebGLRenderingContext::getShaderParameterMethodCustom(const v8::FunctionC allbackInfo<v8::Value>& info)
433 {
434 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getShaderPa rameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
435 if (info.Length() != 2) {
436 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, i nfo.Length()));
437 exceptionState.throwIfNeeded();
438 return;
439 }
440
441 const int shaderArgumentIndex = 0;
442 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
443 if (info.Length() > 0 && !isUndefinedOrNull(info[shaderArgumentIndex]) && !V 8WebGLShader::hasInstance(info[shaderArgumentIndex], info.GetIsolate())) {
444 exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentType(s haderArgumentIndex + 1, "is not a WebGLShader object."));
445 exceptionState.throwIfNeeded();
446 return;
447 }
448 WebGLShader* shader = V8WebGLShader::hasInstance(info[shaderArgumentIndex], info.GetIsolate()) ? V8WebGLShader::toNative(v8::Handle<v8::Object>::Cast(info[0 ])) : 0;
449 unsigned pname = toInt32(info[1], exceptionState);
450 if (exceptionState.throwIfNeeded())
451 return;
452 WebGLGetInfo args = context->getShaderParameter(shader, pname);
453 v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
454 }
455
456 void V8WebGLRenderingContext::getSupportedExtensionsMethodCustom(const v8::Funct ionCallbackInfo<v8::Value>& info)
457 {
458 WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(info.Holder() );
459 if (imp->isContextLost()) {
460 v8SetReturnValueNull(info);
461 return;
462 }
463
464 Vector<String> value = imp->getSupportedExtensions();
465 v8::Local<v8::Array> array = v8::Array::New(info.GetIsolate(), value.size()) ;
466 for (size_t ii = 0; ii < value.size(); ++ii)
467 array->Set(v8::Integer::New(info.GetIsolate(), ii), v8String(info.GetIso late(), value[ii]));
468 v8SetReturnValue(info, array);
469 }
470
471 void V8WebGLRenderingContext::getTexParameterMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
472 {
473 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getTexParam eter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
474 getObjectParameter(info, kTexture, exceptionState);
475 }
476
477 void V8WebGLRenderingContext::getUniformMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
478 {
479 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getUniform" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
480 if (info.Length() != 2) {
481 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, i nfo.Length()));
482 exceptionState.throwIfNeeded();
483 return;
484 }
485
486 const int programArgumentIndex = 0;
487 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
488 if (info.Length() > 0 && !isUndefinedOrNull(info[programArgumentIndex]) && ! V8WebGLProgram::hasInstance(info[programArgumentIndex], info.GetIsolate())) {
489 exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentType(p rogramArgumentIndex + 1, "is not a WebGLProgram object."));
490 exceptionState.throwIfNeeded();
491 return;
492 }
493 WebGLProgram* program = V8WebGLProgram::hasInstance(info[programArgumentInde x], info.GetIsolate()) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(i nfo[0])) : 0;
494
495 const int uniformArgumentIndex = 1;
496 if (info.Length() > 1 && !isUndefinedOrNull(info[uniformArgumentIndex]) && ! V8WebGLUniformLocation::hasInstance(info[uniformArgumentIndex], info.GetIsolate( ))) {
497 exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentType(u niformArgumentIndex + 1, "is not a WebGLUniformLocation object."));
498 exceptionState.throwIfNeeded();
499 return;
500 }
501 const int uniformLocationArgumentIndex = 1;
502 WebGLUniformLocation* location = toWebGLUniformLocation(info[uniformLocation ArgumentIndex], info.GetIsolate());
503
504 WebGLGetInfo args = context->getUniform(program, location);
505 v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
506 }
507
508 void V8WebGLRenderingContext::getVertexAttribMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
509 {
510 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getVertexAt trib", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
511 getObjectParameter(info, kVertexAttrib, exceptionState);
512 }
513
514 enum FunctionToCall {
515 kUniform1v, kUniform2v, kUniform3v, kUniform4v,
516 kVertexAttrib1v, kVertexAttrib2v, kVertexAttrib3v, kVertexAttrib4v
517 };
518
519 bool isFunctionToCallForAttribute(FunctionToCall functionToCall)
520 {
521 switch (functionToCall) {
522 case kVertexAttrib1v:
523 case kVertexAttrib2v:
524 case kVertexAttrib3v:
525 case kVertexAttrib4v:
526 return true;
527 default:
528 break;
529 }
530 return false;
531 }
532
533 static void vertexAttribAndUniformHelperf(const v8::FunctionCallbackInfo<v8::Val ue>& info, FunctionToCall functionToCall, ExceptionState& exceptionState)
534 {
535 // Forms:
536 // * glUniform1fv(WebGLUniformLocation location, Array data);
537 // * glUniform1fv(WebGLUniformLocation location, Float32Array data);
538 // * glUniform2fv(WebGLUniformLocation location, Array data);
539 // * glUniform2fv(WebGLUniformLocation location, Float32Array data);
540 // * glUniform3fv(WebGLUniformLocation location, Array data);
541 // * glUniform3fv(WebGLUniformLocation location, Float32Array data);
542 // * glUniform4fv(WebGLUniformLocation location, Array data);
543 // * glUniform4fv(WebGLUniformLocation location, Float32Array data);
544 // * glVertexAttrib1fv(GLint index, Array data);
545 // * glVertexAttrib1fv(GLint index, Float32Array data);
546 // * glVertexAttrib2fv(GLint index, Array data);
547 // * glVertexAttrib2fv(GLint index, Float32Array data);
548 // * glVertexAttrib3fv(GLint index, Array data);
549 // * glVertexAttrib3fv(GLint index, Float32Array data);
550 // * glVertexAttrib4fv(GLint index, Array data);
551 // * glVertexAttrib4fv(GLint index, Float32Array data);
552
553 if (info.Length() != 2) {
554 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, i nfo.Length()));
555 exceptionState.throwIfNeeded();
556 return;
557 }
558
559 int index = -1;
560 WebGLUniformLocation* location = 0;
561
562 if (isFunctionToCallForAttribute(functionToCall)) {
563 index = toInt32(info[0], exceptionState);
564 if (exceptionState.throwIfNeeded())
565 return;
566 } else {
567 const int uniformLocationArgumentIndex = 0;
568 if (info.Length() > 0 && !isUndefinedOrNull(info[uniformLocationArgument Index]) && !V8WebGLUniformLocation::hasInstance(info[uniformLocationArgumentInde x], info.GetIsolate())) {
569 exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentTy pe(uniformLocationArgumentIndex + 1, "is not a WebGLUniformLocation object."));
570 exceptionState.throwIfNeeded();
571 return;
572 }
573 location = toWebGLUniformLocation(info[uniformLocationArgumentIndex], in fo.GetIsolate());
574 }
575
576 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
577
578 const int indexArrayArgument = 1;
579 if (V8Float32Array::hasInstance(info[indexArrayArgument], info.GetIsolate()) ) {
580 Float32Array* array = V8Float32Array::toNative(info[indexArrayArgument]- >ToObject());
581 ASSERT(array != NULL);
582 switch (functionToCall) {
583 case kUniform1v: context->uniform1fv(location, array); break;
584 case kUniform2v: context->uniform2fv(location, array); break;
585 case kUniform3v: context->uniform3fv(location, array); break;
586 case kUniform4v: context->uniform4fv(location, array); break;
587 case kVertexAttrib1v: context->vertexAttrib1fv(index, array); break;
588 case kVertexAttrib2v: context->vertexAttrib2fv(index, array); break;
589 case kVertexAttrib3v: context->vertexAttrib3fv(index, array); break;
590 case kVertexAttrib4v: context->vertexAttrib4fv(index, array); break;
591 default: ASSERT_NOT_REACHED(); break;
592 }
593 return;
594 }
595
596 if (info[indexArrayArgument].IsEmpty() || !info[indexArrayArgument]->IsArray ()) {
597 exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentType(i ndexArrayArgument + 1, "is not an Array."));
598 exceptionState.throwIfNeeded();
599 return;
600 }
601 v8::Handle<v8::Array> array = v8::Local<v8::Array>::Cast(info[1]);
602 uint32_t len = array->Length();
603 float* data = jsArrayToFloatArray(array, len, exceptionState);
604 if (exceptionState.throwIfNeeded())
605 return;
606 if (!data) {
607 // FIXME: consider different / better exception type.
608 exceptionState.throwDOMException(SyntaxError, "Failed to convert array a rgument");
609 exceptionState.throwIfNeeded();
610 return;
611 }
612 switch (functionToCall) {
613 case kUniform1v: context->uniform1fv(location, data, len); break;
614 case kUniform2v: context->uniform2fv(location, data, len); break;
615 case kUniform3v: context->uniform3fv(location, data, len); break;
616 case kUniform4v: context->uniform4fv(location, data, len); break;
617 case kVertexAttrib1v: context->vertexAttrib1fv(index, data, len); break;
618 case kVertexAttrib2v: context->vertexAttrib2fv(index, data, len); break;
619 case kVertexAttrib3v: context->vertexAttrib3fv(index, data, len); break;
620 case kVertexAttrib4v: context->vertexAttrib4fv(index, data, len); break;
621 default: ASSERT_NOT_REACHED(); break;
622 }
623 fastFree(data);
624 }
625
626 static void uniformHelperi(const v8::FunctionCallbackInfo<v8::Value>& info, Func tionToCall functionToCall, ExceptionState& exceptionState)
627 {
628 // Forms:
629 // * glUniform1iv(GLUniformLocation location, Array data);
630 // * glUniform1iv(GLUniformLocation location, Int32Array data);
631 // * glUniform2iv(GLUniformLocation location, Array data);
632 // * glUniform2iv(GLUniformLocation location, Int32Array data);
633 // * glUniform3iv(GLUniformLocation location, Array data);
634 // * glUniform3iv(GLUniformLocation location, Int32Array data);
635 // * glUniform4iv(GLUniformLocation location, Array data);
636 // * glUniform4iv(GLUniformLocation location, Int32Array data);
637
638 if (info.Length() != 2) {
639 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, i nfo.Length()));
640 exceptionState.throwIfNeeded();
641 return;
642 }
643
644 const int uniformLocationArgumentIndex = 0;
645 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
646 if (info.Length() > 0 && !isUndefinedOrNull(info[uniformLocationArgumentInde x]) && !V8WebGLUniformLocation::hasInstance(info[uniformLocationArgumentIndex], info.GetIsolate())) {
647 exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentType(u niformLocationArgumentIndex + 1, "is not a WebGLUniformLocation object."));
648 exceptionState.throwIfNeeded();
649 return;
650 }
651 WebGLUniformLocation* location = toWebGLUniformLocation(info[uniformLocation ArgumentIndex], info.GetIsolate());
652
653 const int indexArrayArgumentIndex = 1;
654 if (V8Int32Array::hasInstance(info[indexArrayArgumentIndex], info.GetIsolate ())) {
655 Int32Array* array = V8Int32Array::toNative(info[indexArrayArgumentIndex] ->ToObject());
656 ASSERT(array != NULL);
657 switch (functionToCall) {
658 case kUniform1v: context->uniform1iv(location, array); break;
659 case kUniform2v: context->uniform2iv(location, array); break;
660 case kUniform3v: context->uniform3iv(location, array); break;
661 case kUniform4v: context->uniform4iv(location, array); break;
662 default: ASSERT_NOT_REACHED(); break;
663 }
664 return;
665 }
666
667 if (info[indexArrayArgumentIndex].IsEmpty() || !info[indexArrayArgumentIndex ]->IsArray()) {
668 exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentType(i ndexArrayArgumentIndex + 1, "is not an Array."));
669 exceptionState.throwIfNeeded();
670 return;
671 }
672 v8::Handle<v8::Array> array = v8::Local<v8::Array>::Cast(info[indexArrayArgu mentIndex]);
673 uint32_t len = array->Length();
674 int* data = jsArrayToIntArray(array, len, exceptionState);
675 if (exceptionState.throwIfNeeded())
676 return;
677 if (!data) {
678 // FIXME: consider different / better exception type.
679 exceptionState.throwDOMException(SyntaxError, "Failed to convert array a rgument");
680 exceptionState.throwIfNeeded();
681 return;
682 }
683 switch (functionToCall) {
684 case kUniform1v: context->uniform1iv(location, data, len); break;
685 case kUniform2v: context->uniform2iv(location, data, len); break;
686 case kUniform3v: context->uniform3iv(location, data, len); break;
687 case kUniform4v: context->uniform4iv(location, data, len); break;
688 default: ASSERT_NOT_REACHED(); break;
689 }
690 fastFree(data);
691 }
692
693 void V8WebGLRenderingContext::uniform1fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
694 {
695 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform1fv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
696 vertexAttribAndUniformHelperf(info, kUniform1v, exceptionState);
697 }
698
699 void V8WebGLRenderingContext::uniform1ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
700 {
701 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform1iv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
702 uniformHelperi(info, kUniform1v, exceptionState);
703 }
704
705 void V8WebGLRenderingContext::uniform2fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
706 {
707 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform2fv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
708 vertexAttribAndUniformHelperf(info, kUniform2v, exceptionState);
709 }
710
711 void V8WebGLRenderingContext::uniform2ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
712 {
713 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform2iv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
714 uniformHelperi(info, kUniform2v, exceptionState);
715 }
716
717 void V8WebGLRenderingContext::uniform3fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
718 {
719 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform3fv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
720 vertexAttribAndUniformHelperf(info, kUniform3v, exceptionState);
721 }
722
723 void V8WebGLRenderingContext::uniform3ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
724 {
725 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform3iv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
726 uniformHelperi(info, kUniform3v, exceptionState);
727 }
728
729 void V8WebGLRenderingContext::uniform4fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
730 {
731 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform4fv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
732 vertexAttribAndUniformHelperf(info, kUniform4v, exceptionState);
733 }
734
735 void V8WebGLRenderingContext::uniform4ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
736 {
737 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform4iv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
738 uniformHelperi(info, kUniform4v, exceptionState);
739 }
740
741 static void uniformMatrixHelper(const v8::FunctionCallbackInfo<v8::Value>& info, int matrixSize, ExceptionState& exceptionState)
742 {
743 // Forms:
744 // * glUniformMatrix2fv(GLint location, GLboolean transpose, Array data);
745 // * glUniformMatrix2fv(GLint location, GLboolean transpose, Float32Array da ta);
746 // * glUniformMatrix3fv(GLint location, GLboolean transpose, Array data);
747 // * glUniformMatrix3fv(GLint location, GLboolean transpose, Float32Array da ta);
748 // * glUniformMatrix4fv(GLint location, GLboolean transpose, Array data);
749 // * glUniformMatrix4fv(GLint location, GLboolean transpose, Float32Array da ta);
750 //
751 // FIXME: need to change to accept Float32Array as well.
752 if (info.Length() != 3) {
753 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(3, i nfo.Length()));
754 exceptionState.throwIfNeeded();
755 return;
756 }
757
758 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
759
760 const int uniformLocationArgumentIndex = 0;
761 if (info.Length() > 0 && !isUndefinedOrNull(info[uniformLocationArgumentInde x]) && !V8WebGLUniformLocation::hasInstance(info[uniformLocationArgumentIndex], info.GetIsolate())) {
762 exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentType(u niformLocationArgumentIndex + 1, "is not a WebGLUniformLocation object."));
763 exceptionState.throwIfNeeded();
764 return;
765 }
766 WebGLUniformLocation* location = toWebGLUniformLocation(info[uniformLocation ArgumentIndex], info.GetIsolate());
767
768 bool transpose = info[1]->BooleanValue();
769 const int arrayArgumentIndex = 2;
770 if (V8Float32Array::hasInstance(info[arrayArgumentIndex], info.GetIsolate()) ) {
771 Float32Array* array = V8Float32Array::toNative(info[arrayArgumentIndex]- >ToObject());
772 ASSERT(array != NULL);
773 switch (matrixSize) {
774 case 2: context->uniformMatrix2fv(location, transpose, array); break;
775 case 3: context->uniformMatrix3fv(location, transpose, array); break;
776 case 4: context->uniformMatrix4fv(location, transpose, array); break;
777 default: ASSERT_NOT_REACHED(); break;
778 }
779 return;
780 }
781
782 if (info[arrayArgumentIndex].IsEmpty() || !info[arrayArgumentIndex]->IsArray ()) {
783 exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentType(a rrayArgumentIndex + 1, "is not an Array."));
784 exceptionState.throwIfNeeded();
785 return;
786 }
787 v8::Handle<v8::Array> array = v8::Local<v8::Array>::Cast(info[2]);
788 uint32_t len = array->Length();
789 float* data = jsArrayToFloatArray(array, len, exceptionState);
790 if (exceptionState.throwIfNeeded())
791 return;
792 if (!data) {
793 // FIXME: consider different / better exception type.
794 exceptionState.throwDOMException(SyntaxError, "failed to convert Array v alue");
795 exceptionState.throwIfNeeded();
796 return;
797 }
798 switch (matrixSize) {
799 case 2: context->uniformMatrix2fv(location, transpose, data, len); break;
800 case 3: context->uniformMatrix3fv(location, transpose, data, len); break;
801 case 4: context->uniformMatrix4fv(location, transpose, data, len); break;
802 default: ASSERT_NOT_REACHED(); break;
803 }
804 fastFree(data);
805 }
806
807 void V8WebGLRenderingContext::uniformMatrix2fvMethodCustom(const v8::FunctionCal lbackInfo<v8::Value>& info)
808 {
809 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniformMatr ix2fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
810 uniformMatrixHelper(info, 2, exceptionState);
811 }
812
813 void V8WebGLRenderingContext::uniformMatrix3fvMethodCustom(const v8::FunctionCal lbackInfo<v8::Value>& info)
814 {
815 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniformMatr ix3fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
816 uniformMatrixHelper(info, 3, exceptionState);
817 }
818
819 void V8WebGLRenderingContext::uniformMatrix4fvMethodCustom(const v8::FunctionCal lbackInfo<v8::Value>& info)
820 {
821 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniformMatr ix4fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
822 uniformMatrixHelper(info, 4, exceptionState);
823 }
824
825 void V8WebGLRenderingContext::vertexAttrib1fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
826 {
827 ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttri b1fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
828 vertexAttribAndUniformHelperf(info, kVertexAttrib1v, exceptionState);
829 }
830
831 void V8WebGLRenderingContext::vertexAttrib2fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
832 {
833 ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttri b2fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
834 vertexAttribAndUniformHelperf(info, kVertexAttrib2v, exceptionState);
835 }
836
837 void V8WebGLRenderingContext::vertexAttrib3fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
838 {
839 ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttri b3fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
840 vertexAttribAndUniformHelperf(info, kVertexAttrib3v, exceptionState);
841 }
842
843 void V8WebGLRenderingContext::vertexAttrib4fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
844 {
845 ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttri b4fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
846 vertexAttribAndUniformHelperf(info, kVertexAttrib4v, exceptionState);
847 }
848
849 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698