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

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: Fixed typo in gypi, was only causing issues on Windows (?!?) 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 return V8WebGLUniformLocation::toNativeWithTypeCheck(isolate, value);
307 }
308
309 enum WhichProgramCall {
310 kProgramParameter, kUniform
311 };
312
313 void V8WebGLRenderingContext::getAttachedShadersMethodCustom(const v8::FunctionC allbackInfo<v8::Value>& info)
314 {
315 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getAttached Shaders", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
316 if (info.Length() < 1) {
317 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, i nfo.Length()));
318 exceptionState.throwIfNeeded();
319 return;
320 }
321
322 const int programArgumentIndex = 0;
323 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
324 if (info.Length() > 0 && !isUndefinedOrNull(info[programArgumentIndex]) && ! V8WebGLProgram::hasInstance(info[programArgumentIndex], info.GetIsolate())) {
325 exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrect Type(programArgumentIndex + 1, "WebGLProgram"));
326 exceptionState.throwIfNeeded();
327 return;
328 }
329 WebGLProgram* program = V8WebGLProgram::toNativeWithTypeCheck(info.GetIsolat e(), info[programArgumentIndex]);
330 Vector<RefPtr<WebGLShader> > shaders;
331 bool succeed = context->getAttachedShaders(program, shaders);
332 if (!succeed) {
333 v8SetReturnValueNull(info);
334 return;
335 }
336 v8::Local<v8::Array> array = v8::Array::New(info.GetIsolate(), shaders.size( ));
337 for (size_t ii = 0; ii < shaders.size(); ++ii)
338 array->Set(v8::Integer::New(info.GetIsolate(), ii), toV8(shaders[ii].get (), info.Holder(), info.GetIsolate()));
339 v8SetReturnValue(info, array);
340 }
341
342 void V8WebGLRenderingContext::getBufferParameterMethodCustom(const v8::FunctionC allbackInfo<v8::Value>& info)
343 {
344 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getBufferPa rameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
345 getObjectParameter(info, kBuffer, exceptionState);
346 }
347
348 void V8WebGLRenderingContext::getExtensionMethodCustom(const v8::FunctionCallbac kInfo<v8::Value>& info)
349 {
350 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getExtensio n", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
351 WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(info.Holder() );
352 if (info.Length() < 1) {
353 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, i nfo.Length()));
354 exceptionState.throwIfNeeded();
355 return;
356 }
357 V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, name, info[0]);
358 RefPtr<WebGLExtension> extension(imp->getExtension(name));
359 v8SetReturnValue(info, toV8Object(extension.get(), info.Holder(), info.GetIs olate()));
360 }
361
362 void V8WebGLRenderingContext::getFramebufferAttachmentParameterMethodCustom(cons t v8::FunctionCallbackInfo<v8::Value>& info)
363 {
364 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getFramebuf ferAttachmentParameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate ());
365 if (info.Length() != 3) {
366 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(3, i nfo.Length()));
367 exceptionState.throwIfNeeded();
368 return;
369 }
370
371 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
372 unsigned target = toInt32(info[0]);
373 unsigned attachment = toInt32(info[1], exceptionState);
374 if (exceptionState.throwIfNeeded())
375 return;
376 unsigned pname = toInt32(info[2], exceptionState);
377 if (exceptionState.throwIfNeeded())
378 return;
379 WebGLGetInfo args = context->getFramebufferAttachmentParameter(target, attac hment, pname);
380 v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
381 }
382
383 void V8WebGLRenderingContext::getParameterMethodCustom(const v8::FunctionCallbac kInfo<v8::Value>& info)
384 {
385 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getParamete r", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
386 if (info.Length() != 1) {
387 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, i nfo.Length()));
388 exceptionState.throwIfNeeded();
389 return;
390 }
391
392 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
393 unsigned pname = toInt32(info[0], exceptionState);
394 if (exceptionState.throwIfNeeded())
395 return;
396 WebGLGetInfo args = context->getParameter(pname);
397 v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
398 }
399
400 void V8WebGLRenderingContext::getProgramParameterMethodCustom(const v8::Function CallbackInfo<v8::Value>& info)
401 {
402 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getProgramP arameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
403 if (info.Length() != 2) {
404 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, i nfo.Length()));
405 exceptionState.throwIfNeeded();
406 return;
407 }
408
409 const int programArgumentIndex = 0;
410 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
411 if (info.Length() > 0 && !isUndefinedOrNull(info[programArgumentIndex]) && ! V8WebGLProgram::hasInstance(info[programArgumentIndex], info.GetIsolate())) {
412 exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrect Type(programArgumentIndex + 1, "WebGLProgram"));
413 exceptionState.throwIfNeeded();
414 return;
415 }
416 WebGLProgram* program = V8WebGLProgram::toNativeWithTypeCheck(info.GetIsolat e(), info[programArgumentIndex]);
417 unsigned pname = toInt32(info[1], exceptionState);
418 if (exceptionState.throwIfNeeded())
419 return;
420 WebGLGetInfo args = context->getProgramParameter(program, pname);
421 v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
422 }
423
424 void V8WebGLRenderingContext::getRenderbufferParameterMethodCustom(const v8::Fun ctionCallbackInfo<v8::Value>& info)
425 {
426 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getRenderbu fferParameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
427 getObjectParameter(info, kRenderbuffer, exceptionState);
428 }
429
430 void V8WebGLRenderingContext::getShaderParameterMethodCustom(const v8::FunctionC allbackInfo<v8::Value>& info)
431 {
432 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getShaderPa rameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
433 if (info.Length() != 2) {
434 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, i nfo.Length()));
435 exceptionState.throwIfNeeded();
436 return;
437 }
438
439 const int shaderArgumentIndex = 0;
440 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
441 if (info.Length() > 0 && !isUndefinedOrNull(info[shaderArgumentIndex]) && !V 8WebGLShader::hasInstance(info[shaderArgumentIndex], info.GetIsolate())) {
442 exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrect Type(shaderArgumentIndex + 1, "WebGLShader"));
443 exceptionState.throwIfNeeded();
444 return;
445 }
446 WebGLShader* shader = V8WebGLShader::toNativeWithTypeCheck(info.GetIsolate() , info[shaderArgumentIndex]);
447 unsigned pname = toInt32(info[1], exceptionState);
448 if (exceptionState.throwIfNeeded())
449 return;
450 WebGLGetInfo args = context->getShaderParameter(shader, pname);
451 v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
452 }
453
454 void V8WebGLRenderingContext::getSupportedExtensionsMethodCustom(const v8::Funct ionCallbackInfo<v8::Value>& info)
455 {
456 WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(info.Holder() );
457 if (imp->isContextLost()) {
458 v8SetReturnValueNull(info);
459 return;
460 }
461
462 Vector<String> value = imp->getSupportedExtensions();
463 v8::Local<v8::Array> array = v8::Array::New(info.GetIsolate(), value.size()) ;
464 for (size_t ii = 0; ii < value.size(); ++ii)
465 array->Set(v8::Integer::New(info.GetIsolate(), ii), v8String(info.GetIso late(), value[ii]));
466 v8SetReturnValue(info, array);
467 }
468
469 void V8WebGLRenderingContext::getTexParameterMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
470 {
471 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getTexParam eter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
472 getObjectParameter(info, kTexture, exceptionState);
473 }
474
475 void V8WebGLRenderingContext::getUniformMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
476 {
477 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getUniform" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
478 if (info.Length() != 2) {
479 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, i nfo.Length()));
480 exceptionState.throwIfNeeded();
481 return;
482 }
483
484 const int programArgumentIndex = 0;
485 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
486 if (info.Length() > 0 && !isUndefinedOrNull(info[programArgumentIndex]) && ! V8WebGLProgram::hasInstance(info[programArgumentIndex], info.GetIsolate())) {
487 exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrect Type(programArgumentIndex + 1, "WebGLProgram"));
488 exceptionState.throwIfNeeded();
489 return;
490 }
491 WebGLProgram* program = V8WebGLProgram::toNativeWithTypeCheck(info.GetIsolat e(), info[programArgumentIndex]);
492
493 const int uniformArgumentIndex = 1;
494 if (info.Length() > 1 && !isUndefinedOrNull(info[uniformArgumentIndex]) && ! V8WebGLUniformLocation::hasInstance(info[uniformArgumentIndex], info.GetIsolate( ))) {
495 exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrect Type(uniformArgumentIndex + 1, "WebGLUniformLocation"));
496 exceptionState.throwIfNeeded();
497 return;
498 }
499 const int uniformLocationArgumentIndex = 1;
500 WebGLUniformLocation* location = toWebGLUniformLocation(info[uniformLocation ArgumentIndex], info.GetIsolate());
501
502 WebGLGetInfo args = context->getUniform(program, location);
503 v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
504 }
505
506 void V8WebGLRenderingContext::getVertexAttribMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
507 {
508 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getVertexAt trib", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
509 getObjectParameter(info, kVertexAttrib, exceptionState);
510 }
511
512 enum FunctionToCall {
513 kUniform1v, kUniform2v, kUniform3v, kUniform4v,
514 kVertexAttrib1v, kVertexAttrib2v, kVertexAttrib3v, kVertexAttrib4v
515 };
516
517 bool isFunctionToCallForAttribute(FunctionToCall functionToCall)
518 {
519 switch (functionToCall) {
520 case kVertexAttrib1v:
521 case kVertexAttrib2v:
522 case kVertexAttrib3v:
523 case kVertexAttrib4v:
524 return true;
525 default:
526 break;
527 }
528 return false;
529 }
530
531 static void vertexAttribAndUniformHelperf(const v8::FunctionCallbackInfo<v8::Val ue>& info, FunctionToCall functionToCall, ExceptionState& exceptionState)
532 {
533 // Forms:
534 // * glUniform1fv(WebGLUniformLocation location, Array data);
535 // * glUniform1fv(WebGLUniformLocation location, Float32Array data);
536 // * glUniform2fv(WebGLUniformLocation location, Array data);
537 // * glUniform2fv(WebGLUniformLocation location, Float32Array data);
538 // * glUniform3fv(WebGLUniformLocation location, Array data);
539 // * glUniform3fv(WebGLUniformLocation location, Float32Array data);
540 // * glUniform4fv(WebGLUniformLocation location, Array data);
541 // * glUniform4fv(WebGLUniformLocation location, Float32Array data);
542 // * glVertexAttrib1fv(GLint index, Array data);
543 // * glVertexAttrib1fv(GLint index, Float32Array data);
544 // * glVertexAttrib2fv(GLint index, Array data);
545 // * glVertexAttrib2fv(GLint index, Float32Array data);
546 // * glVertexAttrib3fv(GLint index, Array data);
547 // * glVertexAttrib3fv(GLint index, Float32Array data);
548 // * glVertexAttrib4fv(GLint index, Array data);
549 // * glVertexAttrib4fv(GLint index, Float32Array data);
550
551 if (info.Length() != 2) {
552 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, i nfo.Length()));
553 exceptionState.throwIfNeeded();
554 return;
555 }
556
557 int index = -1;
558 WebGLUniformLocation* location = 0;
559
560 if (isFunctionToCallForAttribute(functionToCall)) {
561 index = toInt32(info[0], exceptionState);
562 if (exceptionState.throwIfNeeded())
563 return;
564 } else {
565 const int uniformLocationArgumentIndex = 0;
566 if (info.Length() > 0 && !isUndefinedOrNull(info[uniformLocationArgument Index]) && !V8WebGLUniformLocation::hasInstance(info[uniformLocationArgumentInde x], info.GetIsolate())) {
567 exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncor rectType(uniformLocationArgumentIndex + 1, "WebGLUniformLocation"));
568 exceptionState.throwIfNeeded();
569 return;
570 }
571 location = toWebGLUniformLocation(info[uniformLocationArgumentIndex], in fo.GetIsolate());
572 }
573
574 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
575
576 const int indexArrayArgument = 1;
577 if (V8Float32Array::hasInstance(info[indexArrayArgument], info.GetIsolate()) ) {
578 Float32Array* array = V8Float32Array::toNative(info[indexArrayArgument]- >ToObject());
579 ASSERT(array != NULL);
580 switch (functionToCall) {
581 case kUniform1v: context->uniform1fv(location, array); break;
582 case kUniform2v: context->uniform2fv(location, array); break;
583 case kUniform3v: context->uniform3fv(location, array); break;
584 case kUniform4v: context->uniform4fv(location, array); break;
585 case kVertexAttrib1v: context->vertexAttrib1fv(index, array); break;
586 case kVertexAttrib2v: context->vertexAttrib2fv(index, array); break;
587 case kVertexAttrib3v: context->vertexAttrib3fv(index, array); break;
588 case kVertexAttrib4v: context->vertexAttrib4fv(index, array); break;
589 default: ASSERT_NOT_REACHED(); break;
590 }
591 return;
592 }
593
594 if (info[indexArrayArgument].IsEmpty() || !info[indexArrayArgument]->IsArray ()) {
595 exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrect Type(indexArrayArgument + 1, "Array"));
596 exceptionState.throwIfNeeded();
597 return;
598 }
599 v8::Handle<v8::Array> array = v8::Local<v8::Array>::Cast(info[1]);
600 uint32_t len = array->Length();
601 float* data = jsArrayToFloatArray(array, len, exceptionState);
602 if (exceptionState.throwIfNeeded())
603 return;
604 if (!data) {
605 // FIXME: consider different / better exception type.
606 exceptionState.throwDOMException(SyntaxError, "Failed to convert array a rgument");
607 exceptionState.throwIfNeeded();
608 return;
609 }
610 switch (functionToCall) {
611 case kUniform1v: context->uniform1fv(location, data, len); break;
612 case kUniform2v: context->uniform2fv(location, data, len); break;
613 case kUniform3v: context->uniform3fv(location, data, len); break;
614 case kUniform4v: context->uniform4fv(location, data, len); break;
615 case kVertexAttrib1v: context->vertexAttrib1fv(index, data, len); break;
616 case kVertexAttrib2v: context->vertexAttrib2fv(index, data, len); break;
617 case kVertexAttrib3v: context->vertexAttrib3fv(index, data, len); break;
618 case kVertexAttrib4v: context->vertexAttrib4fv(index, data, len); break;
619 default: ASSERT_NOT_REACHED(); break;
620 }
621 fastFree(data);
622 }
623
624 static void uniformHelperi(const v8::FunctionCallbackInfo<v8::Value>& info, Func tionToCall functionToCall, ExceptionState& exceptionState)
625 {
626 // Forms:
627 // * glUniform1iv(GLUniformLocation location, Array data);
628 // * glUniform1iv(GLUniformLocation location, Int32Array data);
629 // * glUniform2iv(GLUniformLocation location, Array data);
630 // * glUniform2iv(GLUniformLocation location, Int32Array data);
631 // * glUniform3iv(GLUniformLocation location, Array data);
632 // * glUniform3iv(GLUniformLocation location, Int32Array data);
633 // * glUniform4iv(GLUniformLocation location, Array data);
634 // * glUniform4iv(GLUniformLocation location, Int32Array data);
635
636 if (info.Length() != 2) {
637 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, i nfo.Length()));
638 exceptionState.throwIfNeeded();
639 return;
640 }
641
642 const int uniformLocationArgumentIndex = 0;
643 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
644 if (info.Length() > 0 && !isUndefinedOrNull(info[uniformLocationArgumentInde x]) && !V8WebGLUniformLocation::hasInstance(info[uniformLocationArgumentIndex], info.GetIsolate())) {
645 exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrect Type(uniformLocationArgumentIndex + 1, "WebGLUniformLocation"));
646 exceptionState.throwIfNeeded();
647 return;
648 }
649 WebGLUniformLocation* location = toWebGLUniformLocation(info[uniformLocation ArgumentIndex], info.GetIsolate());
650
651 const int indexArrayArgumentIndex = 1;
652 if (V8Int32Array::hasInstance(info[indexArrayArgumentIndex], info.GetIsolate ())) {
653 Int32Array* array = V8Int32Array::toNative(info[indexArrayArgumentIndex] ->ToObject());
654 ASSERT(array != NULL);
655 switch (functionToCall) {
656 case kUniform1v: context->uniform1iv(location, array); break;
657 case kUniform2v: context->uniform2iv(location, array); break;
658 case kUniform3v: context->uniform3iv(location, array); break;
659 case kUniform4v: context->uniform4iv(location, array); break;
660 default: ASSERT_NOT_REACHED(); break;
661 }
662 return;
663 }
664
665 if (info[indexArrayArgumentIndex].IsEmpty() || !info[indexArrayArgumentIndex ]->IsArray()) {
666 exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrect Type(indexArrayArgumentIndex + 1, "Array"));
667 exceptionState.throwIfNeeded();
668 return;
669 }
670 v8::Handle<v8::Array> array = v8::Local<v8::Array>::Cast(info[indexArrayArgu mentIndex]);
671 uint32_t len = array->Length();
672 int* data = jsArrayToIntArray(array, len, exceptionState);
673 if (exceptionState.throwIfNeeded())
674 return;
675 if (!data) {
676 // FIXME: consider different / better exception type.
677 exceptionState.throwDOMException(SyntaxError, "Failed to convert array a rgument");
678 exceptionState.throwIfNeeded();
679 return;
680 }
681 switch (functionToCall) {
682 case kUniform1v: context->uniform1iv(location, data, len); break;
683 case kUniform2v: context->uniform2iv(location, data, len); break;
684 case kUniform3v: context->uniform3iv(location, data, len); break;
685 case kUniform4v: context->uniform4iv(location, data, len); break;
686 default: ASSERT_NOT_REACHED(); break;
687 }
688 fastFree(data);
689 }
690
691 void V8WebGLRenderingContext::uniform1fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
692 {
693 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform1fv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
694 vertexAttribAndUniformHelperf(info, kUniform1v, exceptionState);
695 }
696
697 void V8WebGLRenderingContext::uniform1ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
698 {
699 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform1iv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
700 uniformHelperi(info, kUniform1v, exceptionState);
701 }
702
703 void V8WebGLRenderingContext::uniform2fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
704 {
705 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform2fv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
706 vertexAttribAndUniformHelperf(info, kUniform2v, exceptionState);
707 }
708
709 void V8WebGLRenderingContext::uniform2ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
710 {
711 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform2iv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
712 uniformHelperi(info, kUniform2v, exceptionState);
713 }
714
715 void V8WebGLRenderingContext::uniform3fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
716 {
717 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform3fv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
718 vertexAttribAndUniformHelperf(info, kUniform3v, exceptionState);
719 }
720
721 void V8WebGLRenderingContext::uniform3ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
722 {
723 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform3iv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
724 uniformHelperi(info, kUniform3v, exceptionState);
725 }
726
727 void V8WebGLRenderingContext::uniform4fvMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
728 {
729 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform4fv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
730 vertexAttribAndUniformHelperf(info, kUniform4v, exceptionState);
731 }
732
733 void V8WebGLRenderingContext::uniform4ivMethodCustom(const v8::FunctionCallbackI nfo<v8::Value>& info)
734 {
735 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform4iv" , "WebGLRenderingContext", info.Holder(), info.GetIsolate());
736 uniformHelperi(info, kUniform4v, exceptionState);
737 }
738
739 static void uniformMatrixHelper(const v8::FunctionCallbackInfo<v8::Value>& info, int matrixSize, ExceptionState& exceptionState)
740 {
741 // Forms:
742 // * glUniformMatrix2fv(GLint location, GLboolean transpose, Array data);
743 // * glUniformMatrix2fv(GLint location, GLboolean transpose, Float32Array da ta);
744 // * glUniformMatrix3fv(GLint location, GLboolean transpose, Array data);
745 // * glUniformMatrix3fv(GLint location, GLboolean transpose, Float32Array da ta);
746 // * glUniformMatrix4fv(GLint location, GLboolean transpose, Array data);
747 // * glUniformMatrix4fv(GLint location, GLboolean transpose, Float32Array da ta);
748 //
749 // FIXME: need to change to accept Float32Array as well.
750 if (info.Length() != 3) {
751 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(3, i nfo.Length()));
752 exceptionState.throwIfNeeded();
753 return;
754 }
755
756 WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Hold er());
757
758 const int uniformLocationArgumentIndex = 0;
759 if (info.Length() > 0 && !isUndefinedOrNull(info[uniformLocationArgumentInde x]) && !V8WebGLUniformLocation::hasInstance(info[uniformLocationArgumentIndex], info.GetIsolate())) {
760 exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrect Type(uniformLocationArgumentIndex + 1, "WebGLUniformLocation"));
761 exceptionState.throwIfNeeded();
762 return;
763 }
764 WebGLUniformLocation* location = toWebGLUniformLocation(info[uniformLocation ArgumentIndex], info.GetIsolate());
765
766 bool transpose = info[1]->BooleanValue();
767 const int arrayArgumentIndex = 2;
768 if (V8Float32Array::hasInstance(info[arrayArgumentIndex], info.GetIsolate()) ) {
769 Float32Array* array = V8Float32Array::toNative(info[arrayArgumentIndex]- >ToObject());
770 ASSERT(array != NULL);
771 switch (matrixSize) {
772 case 2: context->uniformMatrix2fv(location, transpose, array); break;
773 case 3: context->uniformMatrix3fv(location, transpose, array); break;
774 case 4: context->uniformMatrix4fv(location, transpose, array); break;
775 default: ASSERT_NOT_REACHED(); break;
776 }
777 return;
778 }
779
780 if (info[arrayArgumentIndex].IsEmpty() || !info[arrayArgumentIndex]->IsArray ()) {
781 exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrect Type(arrayArgumentIndex + 1, "Array"));
782 exceptionState.throwIfNeeded();
783 return;
784 }
785 v8::Handle<v8::Array> array = v8::Local<v8::Array>::Cast(info[2]);
786 uint32_t len = array->Length();
787 float* data = jsArrayToFloatArray(array, len, exceptionState);
788 if (exceptionState.throwIfNeeded())
789 return;
790 if (!data) {
791 // FIXME: consider different / better exception type.
792 exceptionState.throwDOMException(SyntaxError, "failed to convert Array v alue");
793 exceptionState.throwIfNeeded();
794 return;
795 }
796 switch (matrixSize) {
797 case 2: context->uniformMatrix2fv(location, transpose, data, len); break;
798 case 3: context->uniformMatrix3fv(location, transpose, data, len); break;
799 case 4: context->uniformMatrix4fv(location, transpose, data, len); break;
800 default: ASSERT_NOT_REACHED(); break;
801 }
802 fastFree(data);
803 }
804
805 void V8WebGLRenderingContext::uniformMatrix2fvMethodCustom(const v8::FunctionCal lbackInfo<v8::Value>& info)
806 {
807 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniformMatr ix2fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
808 uniformMatrixHelper(info, 2, exceptionState);
809 }
810
811 void V8WebGLRenderingContext::uniformMatrix3fvMethodCustom(const v8::FunctionCal lbackInfo<v8::Value>& info)
812 {
813 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniformMatr ix3fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
814 uniformMatrixHelper(info, 3, exceptionState);
815 }
816
817 void V8WebGLRenderingContext::uniformMatrix4fvMethodCustom(const v8::FunctionCal lbackInfo<v8::Value>& info)
818 {
819 ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniformMatr ix4fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
820 uniformMatrixHelper(info, 4, exceptionState);
821 }
822
823 void V8WebGLRenderingContext::vertexAttrib1fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
824 {
825 ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttri b1fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
826 vertexAttribAndUniformHelperf(info, kVertexAttrib1v, exceptionState);
827 }
828
829 void V8WebGLRenderingContext::vertexAttrib2fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
830 {
831 ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttri b2fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
832 vertexAttribAndUniformHelperf(info, kVertexAttrib2v, exceptionState);
833 }
834
835 void V8WebGLRenderingContext::vertexAttrib3fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
836 {
837 ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttri b3fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
838 vertexAttribAndUniformHelperf(info, kVertexAttrib3v, exceptionState);
839 }
840
841 void V8WebGLRenderingContext::vertexAttrib4fvMethodCustom(const v8::FunctionCall backInfo<v8::Value>& info)
842 {
843 ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttri b4fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
844 vertexAttribAndUniformHelperf(info, kVertexAttrib4v, exceptionState);
845 }
846
847 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698