/platform/external/webkit/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h

https://github.com/aharish/totoro-gb-opensource-update2 · C Header · 219 lines · 142 code · 25 blank · 52 comment · 40 complexity · 44c6abb2301712e64198b2164d665f95 MD5 · raw file

  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. #include "config.h"
  31. #if ENABLE(3D_CANVAS)
  32. #include "WebGLArrayBuffer.h"
  33. #include "V8Binding.h"
  34. #include "V8WebGLArrayBuffer.h"
  35. #include "V8Proxy.h"
  36. namespace WebCore {
  37. // Template function used by the WebGLArray*Constructor callbacks.
  38. template<class ArrayClass>
  39. v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args,
  40. int classIndex)
  41. {
  42. if (!args.IsConstructCall())
  43. return throwError("DOM object constructor cannot be called as a function.");
  44. int argLen = args.Length();
  45. if (argLen == 0) {
  46. // This happens when we return a previously constructed
  47. // WebGLArray, e.g. from the call to WebGL<T>Array.slice().
  48. // The V8DOMWrapper will set the internal pointer in the
  49. // created object. Unfortunately it doesn't look like it's
  50. // possible to distinguish between this case and that where
  51. // the user calls "new WebGL<T>Array()" from JavaScript.
  52. return args.Holder();
  53. }
  54. // Supported constructors:
  55. // WebGL<T>Array(n) where n is an integer:
  56. // -- create an empty array of n elements
  57. // WebGL<T>Array(arr) where arr is an array:
  58. // -- create a WebGL<T>Array containing the contents of "arr"
  59. // WebGL<T>Array(buf, offset, length)
  60. // -- create a WebGL<T>Array pointing to the WebGLArrayBuffer
  61. // "buf", starting at the specified offset, for the given
  62. // length
  63. // See whether the first argument is a WebGLArrayBuffer.
  64. if (V8WebGLArrayBuffer::HasInstance(args[0])) {
  65. if (argLen > 3)
  66. return throwError("Wrong number of arguments to new WebGL<T>Array(WebGLArrayBuffer, int, int)");
  67. WebGLArrayBuffer* buf = V8WebGLArrayBuffer::toNative(args[0]->ToObject());
  68. if (buf == NULL)
  69. return throwError("Could not convert argument 0 to a WebGLArrayBuffer");
  70. bool ok;
  71. int offset = 0;
  72. if (argLen > 1) {
  73. offset = toInt32(args[1], ok);
  74. if (!ok)
  75. return throwError("Could not convert argument 1 to an integer");
  76. }
  77. int length = buf->byteLength() - offset;
  78. if (argLen > 2) {
  79. length = toInt32(args[2], ok);
  80. if (!ok)
  81. return throwError("Could not convert argument 2 to an integer");
  82. }
  83. if (length < 0)
  84. return throwError("Length / offset out of range");
  85. RefPtr<ArrayClass> array = ArrayClass::create(buf, offset, length);
  86. if (array == NULL)
  87. return throwError("Invalid arguments to new WebGL<T>Array(WebGLArrayBuffer, int, int)");
  88. // Transform the holder into a wrapper object for the array.
  89. V8DOMWrapper::setDOMWrapper(args.Holder(), classIndex, array.get());
  90. V8DOMWrapper::setIndexedPropertiesToExternalArray(args.Holder(),
  91. classIndex,
  92. array.get()->baseAddress(),
  93. array.get()->length());
  94. return toV8(array.release(), args.Holder());
  95. }
  96. int len = 0;
  97. v8::Handle<v8::Object> srcArray;
  98. if (argLen != 1)
  99. return throwError("Wrong number of arguments to new WebGL<T>Array(int / array)");
  100. if (args[0]->IsInt32()) {
  101. len = toInt32(args[0]);
  102. } else if (args[0]->IsObject()) {
  103. srcArray = args[0]->ToObject();
  104. if (srcArray.IsEmpty())
  105. return throwError("Could not convert argument 0 to an object");
  106. len = toInt32(srcArray->Get(v8::String::New("length")));
  107. } else
  108. return throwError("Could not convert argument 0 to either an int32 or an object");
  109. RefPtr<ArrayClass> array = ArrayClass::create(len);
  110. if (!srcArray.IsEmpty()) {
  111. // Need to copy the incoming array into the newly created WebGLArray.
  112. for (int i = 0; i < len; i++) {
  113. v8::Local<v8::Value> val = srcArray->Get(v8::Integer::New(i));
  114. array->set(i, val->NumberValue());
  115. }
  116. }
  117. // Transform the holder into a wrapper object for the array.
  118. V8DOMWrapper::setDOMWrapper(args.Holder(), classIndex, array.get());
  119. V8DOMWrapper::setIndexedPropertiesToExternalArray(args.Holder(),
  120. classIndex,
  121. array.get()->baseAddress(),
  122. array.get()->length());
  123. return toV8(array.release(), args.Holder());
  124. }
  125. template <class T, typename ElementType>
  126. v8::Handle<v8::Value> getWebGLArrayElement(const v8::Arguments& args,
  127. V8ClassIndex::V8WrapperType wrapperType)
  128. {
  129. if (args.Length() != 1) {
  130. V8Proxy::setDOMException(SYNTAX_ERR);
  131. return notHandledByInterceptor();
  132. }
  133. bool ok;
  134. uint32_t index = toInt32(args[0], ok);
  135. if (!ok) {
  136. V8Proxy::setDOMException(SYNTAX_ERR);
  137. return notHandledByInterceptor();
  138. }
  139. T* array = reinterpret_cast<T*>(args.Holder()->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
  140. if (index >= array->length())
  141. return v8::Undefined();
  142. ElementType result;
  143. if (!array->get(index, result))
  144. return v8::Undefined();
  145. return v8::Number::New(result);
  146. }
  147. template <class T>
  148. v8::Handle<v8::Value> setWebGLArrayFromArray(T* webGLArray, const v8::Arguments& args)
  149. {
  150. if (args[0]->IsObject()) {
  151. // void set(in sequence<long> array, [Optional] in unsigned long offset);
  152. v8::Local<v8::Object> array = args[0]->ToObject();
  153. uint32_t offset = 0;
  154. if (args.Length() == 2)
  155. offset = toInt32(args[1]);
  156. uint32_t length = toInt32(array->Get(v8::String::New("length")));
  157. if (offset + length > webGLArray->length())
  158. V8Proxy::setDOMException(INDEX_SIZE_ERR);
  159. else
  160. for (uint32_t i = 0; i < length; i++)
  161. webGLArray->set(offset + i, array->Get(v8::Integer::New(i))->NumberValue());
  162. }
  163. return v8::Undefined();
  164. }
  165. template <class CPlusPlusArrayType, class JavaScriptWrapperArrayType>
  166. v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args,
  167. V8ClassIndex::V8WrapperType wrapperType)
  168. {
  169. if (args.Length() < 1 || args.Length() > 2) {
  170. V8Proxy::setDOMException(SYNTAX_ERR);
  171. return notHandledByInterceptor();
  172. }
  173. CPlusPlusArrayType* array = JavaScriptWrapperArrayType::toNative(args.Holder());
  174. if (args.Length() == 2 && args[0]->IsInt32()) {
  175. // void set(in unsigned long index, in {long|float} value);
  176. uint32_t index = toInt32(args[0]);
  177. array->set(index, args[1]->NumberValue());
  178. return v8::Undefined();
  179. }
  180. if (JavaScriptWrapperArrayType::HasInstance(args[0])) {
  181. // void set(in WebGL<T>Array array, [Optional] in unsigned long offset);
  182. CPlusPlusArrayType* src = JavaScriptWrapperArrayType::toNative(args[0]->ToObject());
  183. uint32_t offset = 0;
  184. if (args.Length() == 2)
  185. offset = toInt32(args[1]);
  186. ExceptionCode ec = 0;
  187. array->set(src, offset, ec);
  188. V8Proxy::setDOMException(ec);
  189. return v8::Undefined();
  190. }
  191. return setWebGLArrayFromArray(array, args);
  192. }
  193. }
  194. #endif // ENABLE(3D_CANVAS)