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