/* [implicit_jscontext] dpoIData allocateData (in jsval templ, [optional] in uint32_t length); */ NS_IMETHODIMP dpoCContext::AllocateData(const jsval & templ, uint32_t length, JSContext *cx, dpoIData **_retval) { cl_int err_code; nsresult result; JSObject *tArray; size_t bytePerElements; nsCOMPtr<dpoCData> data; result = ExtractArray( templ, &tArray, cx); if (NS_FAILED(result)) { return result; } data = new dpoCData( this); if (data == NULL) { DEBUG_LOG_STATUS("AllocateData", "Cannot create new dpoCData object"); return NS_ERROR_OUT_OF_MEMORY; } if (length == 0) { DEBUG_LOG_STATUS("AllocateData", "size not provided, assuming template's size"); length = JS_GetTypedArrayLength(tArray); } bytePerElements = JS_GetTypedArrayByteLength(tArray) / JS_GetTypedArrayLength(tArray); DEBUG_LOG_STATUS("AllocateData", "length " << length << " bytePerElements " << bytePerElements); #ifdef PREALLOCATE_IN_JS_HEAP JSObject *jsArray; if (NS_FAILED(CreateAlignedTA(JS_GetTypedArrayType(tArray, cx), length, &jsArray, cx))) { return NS_ERROR_NOT_AVAILABLE; } if (!jsArray) { DEBUG_LOG_STATUS("AllocateData", "Cannot create typed array"); return NS_ERROR_OUT_OF_MEMORY; } cl_mem memObj = CreateBuffer( CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, JS_GetTypedArrayByteLength(jsArray, cx), GetPointerFromTA(jsArray, cx), &err_code); #else /* PREALLOCATE_IN_JS_HEAP */ JSObject *jsArray = nullptr; cl_mem memObj = CreateBuffer(cx, CL_MEM_READ_WRITE, length * bytePerElements, NULL, &err_code); #endif /* PREALLOCATE_IN_JS_HEAP */ if (err_code != CL_SUCCESS) { DEBUG_LOG_ERROR("AllocateData", err_code); return NS_ERROR_NOT_AVAILABLE; } result = data->InitCData(cx, cmdQueue, memObj, JS_GetArrayBufferViewType(tArray), length, length * bytePerElements, jsArray); if (NS_SUCCEEDED(result)) { data.forget((dpoCData **) _retval); } return result; }
/* [implicit_jscontext] void writeToContext2D (in nsIDOMCanvasRenderingContext2D ctx, in jsval source, in long width, in long height); */ NS_IMETHODIMP dpoCContext::WriteToContext2D(nsIDOMCanvasRenderingContext2D *ctx, const JS::Value & source, PRInt32 width, PRInt32 height, JSContext* cx) { JSObject *srcArray; nsresult result; result = ExtractArray(source, &srcArray, cx); if (NS_FAILED(result)) { return result; } uint32_t size = JS_GetTypedArrayLength(srcArray, cx); uint32_t type = JS_GetTypedArrayType(srcArray, cx); if (size != width*height*4) return NS_ERROR_INVALID_ARG; if (JS_IsFloat32Array(srcArray, cx)) { unsigned char *data = (unsigned char *) nsMemory::Alloc(size); float *src = JS_GetFloat32ArrayData(srcArray, cx); for (int i = 0; i < size; i++) { float val = src[i]; data[i] = val > 0 ? (val < 255 ? ((int) val) : 255) : 0; } ctx->PutImageData_explicit(0, 0, width, height, data, size, false, 0, 0, 0, 0); nsMemory::Free(data); } else if (JS_IsFloat64Array(srcArray, cx)) { unsigned char *data = (unsigned char *) nsMemory::Alloc(size); double *src = JS_GetFloat64ArrayData(srcArray, cx); for (int i = 0; i < size; i++) { double val = src[i]; data[i] = val > 0 ? (val < 255 ? ((int) val) : 255) : 0; } ctx->PutImageData_explicit(0, 0, width, height, data, size, false, 0, 0, 0, 0); nsMemory::Free(data); } else if(JS_IsUint8ClampedArray(srcArray, cx)) { uint8_t *src = JS_GetUint8ClampedArrayData(srcArray, cx); ctx->PutImageData_explicit(0, 0, width, height, src, size, false, 0, 0, 0, 0); } else if(JS_IsUint8Array(srcArray, cx)) { return NS_ERROR_INVALID_ARG; } else { return NS_ERROR_NOT_IMPLEMENTED; } return NS_OK; }
/* [implicit_jscontext] dpoIData mapData (in jsval source); */ NS_IMETHODIMP dpoCContext::MapData(const jsval & source, JSContext *cx, dpoIData **_retval) { cl_int err_code; nsresult result; JSObject *tArray; nsCOMPtr<dpoCData> data; result = ExtractArray( source, &tArray, cx); if (NS_SUCCEEDED(result)) { // we have a typed array data = new dpoCData( this); if (data == NULL) { DEBUG_LOG_STATUS("MapData", "Cannot create new dpoCData object"); return NS_ERROR_OUT_OF_MEMORY; } // USE_HOST_PTR is save as the CData object will keep the associated typed array alive as long as the // memory buffer lives cl_mem_flags flags = CL_MEM_READ_ONLY; void *tArrayBuffer = NULL; size_t arrayByteLength = JS_GetTypedArrayByteLength(tArray, cx); if(arrayByteLength == 0) { arrayByteLength = 1; } else { tArrayBuffer = GetPointerFromTA(tArray, cx); flags |= CL_MEM_USE_HOST_PTR; } cl_mem memObj = CreateBuffer(flags, arrayByteLength, tArrayBuffer , &err_code); if (err_code != CL_SUCCESS) { DEBUG_LOG_ERROR("MapData", err_code); return NS_ERROR_NOT_AVAILABLE; } result = data->InitCData(cx, cmdQueue, memObj, JS_GetTypedArrayType(tArray, cx), JS_GetTypedArrayLength(tArray, cx), JS_GetTypedArrayByteLength(tArray, cx), tArray); #ifdef SUPPORT_MAPPING_ARRAYS } else if (JSVAL_IS_OBJECT(source)) { // maybe it is a regular array. // // WARNING: We map a pointer to the actual array here. All this works on CPU only // and only of the OpenCL compiler knows what to do! For the current Intel OpenCL SDK // this works but your milage may vary. const jsval *elems = UnsafeDenseArrayElements(cx, JSVAL_TO_OBJECT(source)); if (elems != NULL) { data = new dpoCData( this); if (data == NULL) { DEBUG_LOG_STATUS("MapData", "Cannot create new dpoCData object"); return NS_ERROR_OUT_OF_MEMORY; } cl_mem memObj = CreateBuffer(CL_MEM_COPY_HOST_PTR | CL_MEM_READ_ONLY, sizeof(double *), &elems, &err_code); if (err_code != CL_SUCCESS) { DEBUG_LOG_ERROR("MapData", err_code); return NS_ERROR_NOT_AVAILABLE; } result = data->InitCData(cx, cmdQueue, memObj, 0 /* bogus type */, 1, sizeof(double *), JSVAL_TO_OBJECT(source)); #ifndef DEBUG_OFF } else { DEBUG_LOG_STATUS("MapData", "No elements returned!"); #endif /* DEBUG_OFF */ } #endif /* SUPPORT_MAPPING_ARRAYS */ } if (NS_SUCCEEDED(result)) { data.forget((dpoCData **)_retval); } return result; }