mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 495499. Speed up PutImageData for cases when the array contains doubles. r=brendan,vlad,jorendorff
This commit is contained in:
parent
9927adf1d1
commit
7b0ee90b96
@ -3740,8 +3740,38 @@ nsCanvasRenderingContext2D::GetImageData()
|
||||
extern "C" {
|
||||
#include "jstypes.h"
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSUint8Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint8 *dest);
|
||||
js_CoerceArrayToCanvasImageData(JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint8 *dest);
|
||||
}
|
||||
|
||||
static inline PRUint8 ToUint8(PRInt32 aInput)
|
||||
{
|
||||
if (PRUint32(aInput) > 255)
|
||||
return (aInput < 0) ? 0 : 255;
|
||||
return PRUint8(aInput);
|
||||
}
|
||||
|
||||
static inline PRUint8 ToUint8(double aInput)
|
||||
{
|
||||
if (!(aInput >= 0)) /* Not < so that NaN coerces to 0 */
|
||||
return 0;
|
||||
if (aInput > 255)
|
||||
return 255;
|
||||
double toTruncate = aInput + 0.5;
|
||||
PRUint8 retval = PRUint8(toTruncate);
|
||||
|
||||
// now retval is rounded to nearest, ties rounded up. We want
|
||||
// rounded to nearest ties to even, so check whether we had a tie.
|
||||
if (retval == toTruncate) {
|
||||
// It was a tie (since adding 0.5 gave us the exact integer we want).
|
||||
// Since we rounded up, we either already have an even number or we
|
||||
// have an odd number but the number we want is one less. So just
|
||||
// unconditionally masking out the ones bit should do the trick to get
|
||||
// us the value we want.
|
||||
return (retval & ~1);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// void putImageData (in ImageData d, in float x, in float y);
|
||||
@ -3815,34 +3845,42 @@ nsCanvasRenderingContext2D::PutImageData()
|
||||
|
||||
PRUint8 *imgPtr = imageBuffer.get();
|
||||
|
||||
JSBool ok = js_ArrayToJSUint8Buffer(ctx, dataArray, 0, w*h*4, imageBuffer);
|
||||
JSBool canFastPath =
|
||||
js_CoerceArrayToCanvasImageData(dataArray, 0, w*h*4, imageBuffer);
|
||||
|
||||
// no fast path? go slow.
|
||||
if (!ok) {
|
||||
// no fast path? go slow. We sadly need this for now, instead of just
|
||||
// throwing, because dataArray might not be dense in case someone stuck
|
||||
// their own array on the imageData.
|
||||
// FIXME: it'd be awfully nice if we could prevent such modification of
|
||||
// imageData objects, since it's likely the spec won't allow it anyway.
|
||||
// Bug 497110 covers this.
|
||||
if (!canFastPath) {
|
||||
jsval vr, vg, vb, va;
|
||||
PRUint8 ir, ig, ib, ia;
|
||||
for (int32 j = 0; j < h; j++) {
|
||||
int32 lineOffset = (j*w*4);
|
||||
for (int32 i = 0; i < w; i++) {
|
||||
if (!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 0, &vr) ||
|
||||
!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 1, &vg) ||
|
||||
!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 2, &vb) ||
|
||||
!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 3, &va))
|
||||
int32 pixelOffset = lineOffset + i*4;
|
||||
if (!JS_GetElement(ctx, dataArray, pixelOffset + 0, &vr) ||
|
||||
!JS_GetElement(ctx, dataArray, pixelOffset + 1, &vg) ||
|
||||
!JS_GetElement(ctx, dataArray, pixelOffset + 2, &vb) ||
|
||||
!JS_GetElement(ctx, dataArray, pixelOffset + 3, &va))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
if (JSVAL_IS_INT(vr)) ir = (PRUint8) JSVAL_TO_INT(vr);
|
||||
else if (JSVAL_IS_DOUBLE(vr)) ir = (PRUint8) (*JSVAL_TO_DOUBLE(vr));
|
||||
if (JSVAL_IS_INT(vr)) ir = ToUint8(JSVAL_TO_INT(vr));
|
||||
else if (JSVAL_IS_DOUBLE(vr)) ir = ToUint8(*JSVAL_TO_DOUBLE(vr));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
if (JSVAL_IS_INT(vg)) ig = (PRUint8) JSVAL_TO_INT(vg);
|
||||
else if (JSVAL_IS_DOUBLE(vg)) ig = (PRUint8) (*JSVAL_TO_DOUBLE(vg));
|
||||
if (JSVAL_IS_INT(vg)) ig = ToUint8(JSVAL_TO_INT(vg));
|
||||
else if (JSVAL_IS_DOUBLE(vg)) ig = ToUint8(*JSVAL_TO_DOUBLE(vg));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
if (JSVAL_IS_INT(vb)) ib = (PRUint8) JSVAL_TO_INT(vb);
|
||||
else if (JSVAL_IS_DOUBLE(vb)) ib = (PRUint8) (*JSVAL_TO_DOUBLE(vb));
|
||||
if (JSVAL_IS_INT(vb)) ib = ToUint8(JSVAL_TO_INT(vb));
|
||||
else if (JSVAL_IS_DOUBLE(vb)) ib = ToUint8(*JSVAL_TO_DOUBLE(vb));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
if (JSVAL_IS_INT(va)) ia = (PRUint8) JSVAL_TO_INT(va);
|
||||
else if (JSVAL_IS_DOUBLE(va)) ia = (PRUint8) (*JSVAL_TO_DOUBLE(va));
|
||||
if (JSVAL_IS_INT(va)) ia = ToUint8(JSVAL_TO_INT(va));
|
||||
else if (JSVAL_IS_DOUBLE(va)) ia = ToUint8(*JSVAL_TO_DOUBLE(va));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
// Convert to premultiplied color (losslessly if the input came from getImageData)
|
||||
|
@ -714,6 +714,7 @@ _TEST_FILES_6 = \
|
||||
image_green.png \
|
||||
image_green-redirect \
|
||||
image_green-redirect^headers^ \
|
||||
test_2d.imagedata_coercion.html \
|
||||
$(NULL)
|
||||
|
||||
# xor and lighter aren't well handled by cairo; they mostly work, but we don't want
|
||||
|
110
content/canvas/test/test_2d.imagedata_coercion.html
Normal file
110
content/canvas/test/test_2d.imagedata_coercion.html
Normal file
@ -0,0 +1,110 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>Canvas test: 2d.imagedata_coercion</title>
|
||||
<!-- Testing: imagedata coerced correctly on set -->
|
||||
<script src="/MochiKit/packed.js"></script>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<body>
|
||||
<canvas id="c" width="100" height="1"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<script>
|
||||
|
||||
/* NOTE: Due to round-tripping through premultiplied values and the rounding
|
||||
that ensues, values of alpha < 255 will tend to do weird things. In
|
||||
particular, the premultiplied color values are computed by multiplying by a,
|
||||
dividing by 255, then always rounding up. The conversion the other way is done
|
||||
by multiplying by 255/a and rounding down. So if
|
||||
|
||||
255/a * (amount added when rounding) > 1
|
||||
|
||||
we will get a change in value when we go through a putImageData/getImageData cycle. Therefore, to make sure we don't have to worry about our color
|
||||
channels, our alpha channel should never be < 250, unless it's 0. And when it's 0, all our color channels will come back as 0 too. */
|
||||
|
||||
/* Our tests. Each test has two arrays: the array of values to set and the
|
||||
array of values that should read back as a result. */
|
||||
var tests = [
|
||||
[
|
||||
[ 0, 1, 3, 250 ], [ 0, 1, 3, 250 ]
|
||||
],
|
||||
[
|
||||
[ 0, 1, 2, 250, 4, 5, 6, 250 ], [ 0, 1, 2, 250, 4, 5, 6, 250 ]
|
||||
],
|
||||
[
|
||||
[ 0, 1000, 2, 300, 400, 5, 600, 250 ], [ 0, 255, 2, 255, 255, 5, 255, 250 ]
|
||||
],
|
||||
[
|
||||
[ -10, -5, NaN, 250, 4, 5, 6, -250 ], [ 0, 0, 0, 250, 0, 0, 0, 0 ]
|
||||
],
|
||||
[
|
||||
[ 0.5, 12.2, 12.8, 251.5, 12.5, 13.5, 13.2, 250.5 ],
|
||||
[ 0, 12, 13, 252, 12, 14, 13, 250 ]
|
||||
],
|
||||
];
|
||||
|
||||
function doTest(type, idx) {
|
||||
var testPair = tests[idx];
|
||||
var test = testPair[0];
|
||||
var ref = testPair[1];
|
||||
var descSuffix = " for " + type + " test #" + (idx+1);
|
||||
function myIs(a, b, str) {
|
||||
is(a, b, str + descSuffix);
|
||||
}
|
||||
|
||||
myIs(test.length, ref.length, "Length mismatch");
|
||||
myIs(test.length % 4, 0, "Length not a multiple of 4");
|
||||
var pixels = test.length / 4;
|
||||
var imageData = ctx.createImageData(pixels, 1);
|
||||
myIs(imageData.width, pixels, "Incorrect created data width");
|
||||
myIs(imageData.height, 1, "Incorrect created data height");
|
||||
myIs(imageData.data.length, test.length,
|
||||
"Incorrect length in created image data");
|
||||
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
var testImageData = ctx.getImageData(0, 0, pixels, 1);
|
||||
myIs(testImageData.data.length, test.length,
|
||||
"Incorrect length in test image data after clearing pixels");
|
||||
var j;
|
||||
for (j = 0; j < testImageData.data.length; ++j) {
|
||||
myIs(testImageData.data[j], 0,
|
||||
"Nonzero value at position " + j + " in test image data " +
|
||||
"after clearing pixels");
|
||||
}
|
||||
for (j = 0; j < imageData.data.length; ++j) {
|
||||
imageData.data[j] = test[j];
|
||||
}
|
||||
if (type == "slow") {
|
||||
// convert to a non-dense array so we can test that codepath
|
||||
imageData.data.makeMeSlow = 1;
|
||||
}
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
testImageData = ctx.getImageData(0, 0, pixels, 1);
|
||||
myIs(testImageData.data.length, test.length,
|
||||
"Incorrect length in test image data after putting our imagedata");
|
||||
for (j = 0; j < testImageData.data.length; ++j) {
|
||||
myIs(testImageData.data[j], ref[j],
|
||||
"Incorrect value at position " + j + " in test image data " +
|
||||
"after putting our imagedata");
|
||||
}
|
||||
}
|
||||
|
||||
function doTests(type) {
|
||||
for (var i = 0; i < tests.length; ++i) {
|
||||
doTest(type, i);
|
||||
}
|
||||
}
|
||||
|
||||
var canvas;
|
||||
var ctx;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(function () {
|
||||
|
||||
canvas = document.getElementById('c');
|
||||
ctx = canvas.getContext('2d');
|
||||
|
||||
doTests("fast");
|
||||
doTests("slow")
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
});
|
||||
</script>
|
@ -1171,7 +1171,7 @@ array_trace(JSTracer *trc, JSObject *obj)
|
||||
size_t i;
|
||||
jsval v;
|
||||
|
||||
JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
|
||||
JS_ASSERT(js_IsDenseArray(obj));
|
||||
|
||||
capacity = js_DenseArrayCapacity(obj);
|
||||
for (i = 0; i < capacity; i++) {
|
||||
@ -3465,192 +3465,59 @@ js_ArrayInfo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSUint8Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint8 *dest)
|
||||
js_CoerceArrayToCanvasImageData(JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint8 *dest)
|
||||
{
|
||||
uint32 length;
|
||||
|
||||
if (!obj || !OBJ_IS_DENSE_ARRAY(cx, obj))
|
||||
if (!obj || !js_IsDenseArray(obj))
|
||||
return JS_FALSE;
|
||||
|
||||
length = obj->fslots[JSSLOT_ARRAY_LENGTH];
|
||||
if (length < offset + count)
|
||||
return JS_FALSE;
|
||||
|
||||
jsval v;
|
||||
jsint vi;
|
||||
|
||||
JSUint8 *dp = dest;
|
||||
for (uintN i = offset; i < offset+count; i++) {
|
||||
v = obj->dslots[i];
|
||||
if (!JSVAL_IS_INT(v) || (vi = JSVAL_TO_INT(v)) < 0)
|
||||
return JS_FALSE;
|
||||
jsval v = obj->dslots[i];
|
||||
if (JSVAL_IS_INT(v)) {
|
||||
jsint vi = JSVAL_TO_INT(v);
|
||||
if (jsuint(vi) > 255)
|
||||
vi = (vi < 0) ? 0 : 255;
|
||||
*dp++ = JSUint8(vi);
|
||||
} else if (JSVAL_IS_DOUBLE(v)) {
|
||||
jsdouble vd = *JSVAL_TO_DOUBLE(v);
|
||||
if (!(vd >= 0)) /* Not < so that NaN coerces to 0 */
|
||||
*dp++ = 0;
|
||||
else if (vd > 255)
|
||||
*dp++ = 255;
|
||||
else {
|
||||
jsdouble toTruncate = vd + 0.5;
|
||||
JSUint8 val = JSUint8(toTruncate);
|
||||
|
||||
*dp++ = (JSUint8) vi;
|
||||
/*
|
||||
* now val is rounded to nearest, ties rounded up. We want
|
||||
* rounded to nearest ties to even, so check whether we had a
|
||||
* tie.
|
||||
*/
|
||||
if (val == toTruncate) {
|
||||
/*
|
||||
* It was a tie (since adding 0.5 gave us the exact integer
|
||||
* we want). Since we rounded up, we either already have an
|
||||
* even number or we have an odd number but the number we
|
||||
* want is one less. So just unconditionally masking out the
|
||||
* ones bit should do the trick to get us the value we
|
||||
* want.
|
||||
*/
|
||||
*dp++ = (val & ~1);
|
||||
} else {
|
||||
*dp++ = val;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSUint16Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint16 *dest)
|
||||
{
|
||||
uint32 length;
|
||||
|
||||
if (!obj || !OBJ_IS_DENSE_ARRAY(cx, obj))
|
||||
return JS_FALSE;
|
||||
|
||||
length = obj->fslots[JSSLOT_ARRAY_LENGTH];
|
||||
if (length < offset + count)
|
||||
return JS_FALSE;
|
||||
|
||||
jsval v;
|
||||
jsint vi;
|
||||
|
||||
JSUint16 *dp = dest;
|
||||
for (uintN i = offset; i < offset+count; i++) {
|
||||
v = obj->dslots[i];
|
||||
if (!JSVAL_IS_INT(v) || (vi = JSVAL_TO_INT(v)) < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
*dp++ = (JSUint16) vi;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSUint32Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint32 *dest)
|
||||
{
|
||||
uint32 length;
|
||||
|
||||
if (!obj || !OBJ_IS_DENSE_ARRAY(cx, obj))
|
||||
return JS_FALSE;
|
||||
|
||||
length = obj->fslots[JSSLOT_ARRAY_LENGTH];
|
||||
if (length < offset + count)
|
||||
return JS_FALSE;
|
||||
|
||||
jsval v;
|
||||
jsint vi;
|
||||
|
||||
JSUint32 *dp = dest;
|
||||
for (uintN i = offset; i < offset+count; i++) {
|
||||
v = obj->dslots[i];
|
||||
if (!JSVAL_IS_INT(v) || (vi = JSVAL_TO_INT(v)) < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
*dp++ = (JSUint32) vi;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSInt8Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSInt8 *dest)
|
||||
{
|
||||
uint32 length;
|
||||
|
||||
if (!obj || !OBJ_IS_DENSE_ARRAY(cx, obj))
|
||||
return JS_FALSE;
|
||||
|
||||
length = obj->fslots[JSSLOT_ARRAY_LENGTH];
|
||||
if (length < offset + count)
|
||||
return JS_FALSE;
|
||||
|
||||
jsval v;
|
||||
JSInt8 *dp = dest;
|
||||
for (uintN i = offset; i < offset+count; i++) {
|
||||
v = obj->dslots[i];
|
||||
if (!JSVAL_IS_INT(v))
|
||||
return JS_FALSE;
|
||||
|
||||
*dp++ = (JSInt8) JSVAL_TO_INT(v);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSInt16Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSInt16 *dest)
|
||||
{
|
||||
uint32 length;
|
||||
|
||||
if (!obj || !OBJ_IS_DENSE_ARRAY(cx, obj))
|
||||
return JS_FALSE;
|
||||
|
||||
length = obj->fslots[JSSLOT_ARRAY_LENGTH];
|
||||
if (length < offset + count)
|
||||
return JS_FALSE;
|
||||
|
||||
jsval v;
|
||||
JSInt16 *dp = dest;
|
||||
for (uintN i = offset; i < offset+count; i++) {
|
||||
v = obj->dslots[i];
|
||||
if (!JSVAL_IS_INT(v))
|
||||
return JS_FALSE;
|
||||
|
||||
*dp++ = (JSInt16) JSVAL_TO_INT(v);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSInt32Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSInt32 *dest)
|
||||
{
|
||||
uint32 length;
|
||||
|
||||
if (!obj || !OBJ_IS_DENSE_ARRAY(cx, obj))
|
||||
return JS_FALSE;
|
||||
|
||||
length = obj->fslots[JSSLOT_ARRAY_LENGTH];
|
||||
if (length < offset + count)
|
||||
return JS_FALSE;
|
||||
|
||||
jsval v;
|
||||
JSInt32 *dp = dest;
|
||||
for (uintN i = offset; i < offset+count; i++) {
|
||||
v = obj->dslots[i];
|
||||
if (!JSVAL_IS_INT(v))
|
||||
return JS_FALSE;
|
||||
|
||||
*dp++ = (JSInt32) JSVAL_TO_INT(v);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSDoubleBuffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
jsdouble *dest)
|
||||
{
|
||||
uint32 length;
|
||||
|
||||
if (!obj || !OBJ_IS_DENSE_ARRAY(cx, obj))
|
||||
return JS_FALSE;
|
||||
|
||||
length = obj->fslots[JSSLOT_ARRAY_LENGTH];
|
||||
if (length < offset + count)
|
||||
return JS_FALSE;
|
||||
|
||||
jsval v;
|
||||
jsdouble *dp = dest;
|
||||
for (uintN i = offset; i < offset+count; i++) {
|
||||
v = obj->dslots[i];
|
||||
if (JSVAL_IS_INT(v))
|
||||
*dp++ = (jsdouble) JSVAL_TO_INT(v);
|
||||
else if (JSVAL_IS_DOUBLE(v))
|
||||
*dp++ = *(JSVAL_TO_DOUBLE(v));
|
||||
else
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,13 @@ js_IdIsIndex(jsval id, jsuint *indexp);
|
||||
|
||||
extern JSClass js_ArrayClass, js_SlowArrayClass;
|
||||
|
||||
#define OBJ_IS_DENSE_ARRAY(cx,obj) (OBJ_GET_CLASS(cx, obj) == &js_ArrayClass)
|
||||
static JS_INLINE JSBool
|
||||
js_IsDenseArray(JSObject *obj)
|
||||
{
|
||||
return STOBJ_GET_CLASS(obj) == &js_ArrayClass;
|
||||
}
|
||||
|
||||
#define OBJ_IS_DENSE_ARRAY(cx, obj) js_IsDenseArray(obj)
|
||||
|
||||
#define OBJ_IS_ARRAY(cx,obj) (OBJ_IS_DENSE_ARRAY(cx, obj) || \
|
||||
OBJ_GET_CLASS(cx, obj) == &js_SlowArrayClass)
|
||||
@ -109,14 +115,14 @@ js_MakeArraySlow(JSContext *cx, JSObject *obj);
|
||||
static JS_INLINE uint32
|
||||
js_DenseArrayCapacity(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(OBJ_IS_DENSE_ARRAY(BOGUS_CX, obj));
|
||||
JS_ASSERT(js_IsDenseArray(obj));
|
||||
return obj->dslots ? (uint32) obj->dslots[-1] : 0;
|
||||
}
|
||||
|
||||
static JS_INLINE void
|
||||
js_SetDenseArrayCapacity(JSObject *obj, uint32 capacity)
|
||||
{
|
||||
JS_ASSERT(OBJ_IS_DENSE_ARRAY(BOGUS_CX, obj));
|
||||
JS_ASSERT(js_IsDenseArray(obj));
|
||||
JS_ASSERT(obj->dslots);
|
||||
obj->dslots[-1] = (jsval) capacity;
|
||||
}
|
||||
@ -169,59 +175,24 @@ extern JSBool JS_FASTCALL
|
||||
js_ArrayCompPush(JSContext *cx, JSObject *obj, jsval v);
|
||||
|
||||
/*
|
||||
* Fast dense-array-to-buffer conversions.
|
||||
* Fast dense-array-to-buffer conversion for use by canvas.
|
||||
*
|
||||
* If the array is a dense array, fill [offset..offset+count] values
|
||||
* into destination, assuming that types are consistent. Return
|
||||
* JS_TRUE if successful, otherwise JS_FALSE -- note that the
|
||||
* destination buffer may be modified even if JS_FALSE is returned
|
||||
* (e.g. due to finding an inappropriate type later on in the array).
|
||||
* If JS_FALSE is returned, no error conditions or exceptions are set
|
||||
* on the context.
|
||||
* If the array is a dense array, fill [offset..offset+count] values into
|
||||
* destination, assuming that types are consistent. Return JS_TRUE if
|
||||
* successful, otherwise JS_FALSE -- note that the destination buffer may be
|
||||
* modified even if JS_FALSE is returned (e.g. due to finding an inappropriate
|
||||
* type later on in the array). If JS_FALSE is returned, no error conditions
|
||||
* or exceptions are set on the context.
|
||||
*
|
||||
* For ArrayToJSUint8, ArrayToJSUint16, and ArrayToJSUint32, each element
|
||||
* in the array a) must be an integer; b) must be >= 0. Integers
|
||||
* are clamped to fit in the destination size. Only JSVAL_IS_INT values
|
||||
* are considered to be valid, so for JSUint32, the maximum value that
|
||||
* can be fast-converted is less than the full unsigned 32-bit range.
|
||||
*
|
||||
* For ArrayToJSInt8, ArrayToJSInt16, ArrayToJSInt32, each element in
|
||||
* the array must be an integer. Integers are clamped to fit in the
|
||||
* destination size. Only JSVAL_IS_INT values are considered to be
|
||||
* valid, so for JSInt32, the maximum value that can be
|
||||
* fast-converted is less than the full signed 32-bit range.
|
||||
*
|
||||
* For ArrayToJSDouble, each element in the array must be an
|
||||
* integer -or- a double (JSVAL_IS_NUMBER).
|
||||
* This method succeeds if each element of the array is an integer or a double.
|
||||
* Values outside the 0-255 range are clamped to that range. Double values are
|
||||
* converted to integers in this range by clamping and then rounding to
|
||||
* nearest, ties to even.
|
||||
*/
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSUint8Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint8 *dest);
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSUint16Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint16 *dest);
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSUint32Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint32 *dest);
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSInt8Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSInt8 *dest);
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSInt16Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSInt16 *dest);
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSInt32Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSInt32 *dest);
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSDoubleBuffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
jsdouble *dest);
|
||||
js_CoerceArrayToCanvasImageData(JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint8 *dest);
|
||||
|
||||
JSBool
|
||||
js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj);
|
||||
|
Loading…
Reference in New Issue
Block a user