b=571027; implement new TexImage2D signatures; r=vladimir

This commit is contained in:
Benoit Jacob 2010-06-15 11:54:03 -04:00
Родитель 5d0602a31e
Коммит 5a63875239
3 изменённых файлов: 163 добавлений и 135 удалений

Просмотреть файл

@ -42,6 +42,29 @@
#include "jstypedarray.h"
#define GET_INT32_ARG(var, index) \
int32 var; \
do { \
if (!JS_ValueToECMAInt32(cx, argv[index], &(var))) \
return JS_FALSE; \
} while (0)
#define GET_UINT32_ARG(var, index) \
uint32 var; \
do { \
if (!JS_ValueToECMAUint32(cx, argv[index], &(var))) \
return JS_FALSE; \
} while (0)
#define GET_OPTIONAL_UINT32_ARG(var, index) \
uint32 var = 0; \
do { \
if (argc > index) \
if (!JS_ValueToECMAUint32(cx, argv[index], &(var))) \
return JS_FALSE; \
} while (0)
static inline bool
helper_isInt32Array(JSObject *obj) {
return obj->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_INT32];
@ -102,7 +125,7 @@ nsICanvasRenderingContextWebGL_BufferData(JSContext *cx, uintN argc, jsval *vp)
{
return JS_FALSE;
}
nsresult rv;
if (wa)
@ -188,9 +211,8 @@ nsICanvasRenderingContextWebGL_BufferSubData(JSContext *cx, uintN argc, jsval *v
/*
* TexImage2D takes:
* TexImage2D(int, int, int, int, int, int, int, int, WebGLArray)
* TexImage2D(int, int, int, int, int, int, int, int, WebGLArrayBuffer)
* TexImage2D(int, int, nsIDOMElement, [bool[, bool]])
* TexImage2D(uint, int, uint, int, int, int, uint, uint, ArrayBufferView)\
* TexImage2D(uint, int, uint, uint, uint, nsIDOMElement)
*/
static JSBool
nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
@ -208,71 +230,74 @@ nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
return JS_FALSE;
// XXX we currently allow passing only 3 args to support the API. Eventually drop that.
// if (argc < 6 || argc == 7 || argc == 8)
if (argc < 3)
return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
jsval *argv = JS_ARGV(cx, vp);
int32 intargs[8];
JSObject *arg9 = nsnull;
// arguments common to all cases
GET_UINT32_ARG(argv0, 0);
GET_INT32_ARG(argv1, 1);
// convert the first two args, they must be ints
for (jsuint i = 0; i < 2; ++i) {
if (!JS_ValueToECMAInt32(cx, argv[i], &intargs[i]))
return JS_FALSE;
}
if (argc > 2 && JSVAL_IS_OBJECT(argv[2])) {
// the old API. Eventually drop that.
if (JSVAL_IS_OBJECT(argv[2])) {
// try to make this a nsIDOMElement
nsIDOMElement *elt;
xpc_qsSelfRef eltRef;
rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[2], &elt, &eltRef.ptr, &argv[2]);
if (NS_SUCCEEDED(rv)) {
intargs[3] = 0;
intargs[4] = 0;
if (NS_FAILED(rv)) return JS_FALSE;
// convert args 4 and 5 if present, default to 0
for (jsuint i = 3; i < 5 && i < argc; ++i) {
if (!JS_ValueToECMAInt32(cx, argv[i], &intargs[i]))
return JS_FALSE;
}
GET_OPTIONAL_UINT32_ARG(argv3, 3);
GET_OPTIONAL_UINT32_ARG(argv4, 4);
rv = self->TexImage2D_dom(intargs[0], intargs[1], elt, (WebGLboolean) intargs[3], (WebGLboolean) intargs[4]);
goto check_rv_and_return;
}
}
rv = self->TexImage2D_dom_old_API_deprecated(argv0, argv1, elt, argv3, argv4);
} else if (argc > 5 && JSVAL_IS_OBJECT(argv[5])) {
// implement the variants taking a DOMElement as argv[5]
GET_UINT32_ARG(argv2, 2);
GET_UINT32_ARG(argv3, 3);
GET_UINT32_ARG(argv4, 4);
// didn't succeed? convert the rest of the int args
for (jsuint i = 2; i < 8; ++i) {
if (!JS_ValueToECMAInt32(cx, argv[i], &intargs[i]))
nsIDOMElement *elt;
xpc_qsSelfRef eltRef;
rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[5], &elt, &eltRef.ptr, &argv[5]);
if (NS_FAILED(rv)) return JS_FALSE;
rv = self->TexImage2D_dom(argv0, argv1, argv2, argv3, argv4, elt);
} else if (argc > 8 && JSVAL_IS_OBJECT(argv[8])) {
// implement the variants taking a buffer/array as argv[8]
GET_UINT32_ARG(argv2, 2);
GET_INT32_ARG(argv3, 3);
GET_INT32_ARG(argv4, 4);
GET_INT32_ARG(argv5, 5);
GET_UINT32_ARG(argv6, 6);
GET_UINT32_ARG(argv7, 7);
JSObject *argv8 = JSVAL_TO_OBJECT(argv[8]);
// then try to grab either a js::ArrayBuffer, js::TypedArray, or null
if (argv8 == nsnull) {
rv = self->TexImage2D_buf(argv0, argv1, argv2, argv3,
argv4, argv5, argv6, argv7,
nsnull);
} else if (js_IsArrayBuffer(argv8)) {
rv = self->TexImage2D_buf(argv0, argv1, argv2, argv3,
argv4, argv5, argv6, argv7,
js::ArrayBuffer::fromJSObject(argv8));
} else if (js_IsTypedArray(argv8)) {
rv = self->TexImage2D_array(argv0, argv1, argv2, argv3,
argv4, argv5, argv6, argv7,
js::TypedArray::fromJSObject(argv8));
} else {
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
return JS_FALSE;
}
if (!JSVAL_IS_OBJECT(argv[8])) {
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
return JS_FALSE;
}
// then try to grab either a js::ArrayBuffer, js::TypedArray, or null
arg9 = JSVAL_TO_OBJECT(argv[8]);
if (arg9 == nsnull) {
rv = self->TexImage2D_buf(intargs[0], intargs[1], intargs[2], intargs[3],
intargs[4], intargs[5], intargs[6], intargs[7],
nsnull);
} else if (js_IsArrayBuffer(arg9)) {
rv = self->TexImage2D_buf(intargs[0], intargs[1], intargs[2], intargs[3],
intargs[4], intargs[5], intargs[6], intargs[7],
js::ArrayBuffer::fromJSObject(arg9));
} else if (js_IsTypedArray(arg9)) {
rv = self->TexImage2D_array(intargs[0], intargs[1], intargs[2], intargs[3],
intargs[4], intargs[5], intargs[6], intargs[7],
js::TypedArray::fromJSObject(arg9));
}
} else {
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
return JS_FALSE;
}
check_rv_and_return:
if (NS_FAILED(rv))
return xpc_qsThrowMethodFailed(cx, rv, vp);
@ -280,11 +305,9 @@ check_rv_and_return:
return JS_TRUE;
}
/*
* TexSubImage2D takes:
* TexSubImage2D(int, int, int, int, int, int, int, int, WebGLArray)
* TexSubImage2D(int, int, int, int, int, int, int, int, WebGLArrayBuffer)
* TexSubImage2D(int, int, int, int, int, int, nsIDOMElement, [bool[, bool]])
/* TexSubImage2D takes:
* TexSubImage2D(uint, int, int, int, int, int, uint, uint, ArrayBufferView)
* TexSubImage2D(uint, int, int, int, uint, uint, nsIDOMElement)
*/
static JSBool
nsICanvasRenderingContextWebGL_TexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
@ -302,80 +325,51 @@ nsICanvasRenderingContextWebGL_TexSubImage2D(JSContext *cx, uintN argc, jsval *v
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
return JS_FALSE;
if (argc < 7)
if (argc < 7 || argc == 8)
return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
jsval *argv = JS_ARGV(cx, vp);
int32 intargs[9];
// arguments common to all cases
GET_UINT32_ARG(argv0, 0);
GET_INT32_ARG(argv1, 1);
GET_INT32_ARG(argv2, 2);
GET_INT32_ARG(argv3, 3);
// convert the first six args, they must be ints
for (jsuint i = 0; i < 6; ++i) {
if (!JS_ValueToECMAInt32(cx, argv[i], &intargs[i]))
return JS_FALSE;
}
if (argc > 6 && JSVAL_IS_OBJECT(argv[6])) {
// implement the variants taking a DOMElement as argv[6]
GET_UINT32_ARG(argv4, 4);
GET_UINT32_ARG(argv5, 5);
if (JSVAL_IS_OBJECT(argv[6])) {
// try to make this a nsIDOMElement
nsIDOMElement *elt;
xpc_qsSelfRef eltRef;
rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[6], &elt, &eltRef.ptr, &argv[6]);
if (NS_FAILED(rv)) return JS_FALSE;
// these are two optinal args, default to 0
intargs[7] = 0;
intargs[8] = 0;
rv = self->TexSubImage2D_dom(argv0, argv1, argv2, argv3, argv4, argv5, elt);
} else if (argc > 8 && JSVAL_IS_OBJECT(argv[8])) {
// implement the variants taking a buffer/array as argv[8]
GET_INT32_ARG(argv4, 4);
GET_INT32_ARG(argv5, 5);
GET_UINT32_ARG(argv6, 6);
GET_UINT32_ARG(argv7, 7);
// convert args 7 and 8 if present
for (jsuint i = 7; i < 9 && i < argc; ++i) {
if (!JS_ValueToECMAInt32(cx, argv[i], &intargs[i]))
return JS_FALSE;
}
rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[2], &elt, &eltRef.ptr, &argv[2]);
if (NS_SUCCEEDED(rv)) {
rv = self->TexSubImage2D_dom(intargs[0], intargs[1], intargs[2],
intargs[2], intargs[4], intargs[5],
elt, (WebGLboolean) intargs[7], (WebGLboolean) intargs[8]);
if (NS_FAILED(rv))
return xpc_qsThrowMethodFailed(cx, rv, vp);
return JS_TRUE;
}
}
// didn't succeed? convert the rest of the int args
for (jsuint i = 6; i < 8; ++i) {
if (!JS_ValueToECMAInt32(cx, argv[i], &intargs[i]))
JSObject *argv8 = JSVAL_TO_OBJECT(argv[8]);
// try to grab either a js::ArrayBuffer or js::TypedArray
if (js_IsArrayBuffer(argv8)) {
rv = self->TexSubImage2D_buf(argv0, argv1, argv2, argv3,
argv4, argv5, argv6, argv7,
js::ArrayBuffer::fromJSObject(argv8));
} else if (js_IsTypedArray(argv8)) {
rv = self->TexSubImage2D_array(argv0, argv1, argv2, argv3,
argv4, argv5, argv6, argv7,
js::TypedArray::fromJSObject(argv8));
} else {
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
return JS_FALSE;
}
if (JSVAL_IS_PRIMITIVE(argv[8])) {
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
return JS_FALSE;
}
// then try to grab either a js::ArrayBuffer or js::TypedArray
js::TypedArray *wa = 0;
js::ArrayBuffer *wb = 0;
JSObject *arg9 = JSVAL_TO_OBJECT(argv[8]);
if (js_IsArrayBuffer(arg9)) {
wb = js::ArrayBuffer::fromJSObject(arg9);
} else if (js_IsTypedArray(arg9)) {
wa = js::TypedArray::fromJSObject(arg9);
}
} else {
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
return JS_FALSE;
}
if (wa) {
rv = self->TexSubImage2D_array(intargs[0], intargs[1], intargs[2], intargs[3],
intargs[4], intargs[5], intargs[6], intargs[7],
wa);
} else if (wb) {
rv = self->TexSubImage2D_buf(intargs[0], intargs[1], intargs[2], intargs[3],
intargs[4], intargs[5], intargs[6], intargs[7],
wb);
} else {
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
return JS_FALSE;
}
@ -563,7 +557,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv(JSContext *cx, uintN ar
xpc_qsThrowBadArg(cx, rv, vp, 0);
return JS_FALSE;
}
int32 transpose;
if (!JS_ValueToECMAInt32(cx, argv[1], &transpose))
return JS_FALSE;

Просмотреть файл

@ -2806,21 +2806,53 @@ WebGLContext::TexImage2D_array(WebGLenum target, WebGLint level, WebGLenum inter
}
NS_IMETHODIMP
WebGLContext::TexImage2D_dom(WebGLenum target, WebGLint level,
nsIDOMElement *elt,
WebGLboolean flipY, WebGLboolean premultiplyAlpha)
WebGLContext::TexImage2D_dom(WebGLenum target, WebGLint level, WebGLenum internalformat,
WebGLenum format, GLenum type, nsIDOMElement *elt)
{
nsRefPtr<gfxImageSurface> isurf;
nsresult rv = DOMElementToImageSurface(elt, getter_AddRefs(isurf),
PR_FALSE/*flipY*/, PR_FALSE/*premultiplyAlpha*/);
if (NS_FAILED(rv))
return rv;
NS_ASSERTION(isurf->Stride() == isurf->Width() * 4, "Bad stride!");
PRUint32 byteLength = isurf->Stride() * isurf->Height();
return TexImage2D_base(target, level, internalformat,
isurf->Width(), isurf->Height(), 0,
format, type,
isurf->Data(), byteLength);
}
NS_IMETHODIMP
WebGLContext::TexImage2D_dom_old_API_deprecated(WebGLenum target, WebGLint level, nsIDOMElement *elt,
PRBool flipY, PRBool premultiplyAlpha)
{
static PRBool firsttime = PR_TRUE;
if (firsttime) {
LogMessage("The WebGL spec changed, TexImage2D is now taking at least 6 parameters, please "
"adapt your JavaScript code as support for the old API will soon be dropped!");
firsttime = PR_FALSE;
}
nsRefPtr<gfxImageSurface> isurf;
nsresult rv = DOMElementToImageSurface(elt, getter_AddRefs(isurf),
flipY, premultiplyAlpha);
if (NS_FAILED(rv))
return rv;
NS_ASSERTION(isurf->Stride() == isurf->Width() * 4, "Bad stride!");
PRUint32 byteLength = isurf->Stride() * isurf->Height();
return TexImage2D_base(target, level, LOCAL_GL_RGBA,
isurf->Width(), isurf->Height(), 0,
LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE,
isurf->Data(), isurf->Stride() * isurf->Height());
isurf->Data(), byteLength);
}
NS_IMETHODIMP
@ -2948,22 +2980,23 @@ WebGLContext::TexSubImage2D_array(WebGLenum target, WebGLint level,
NS_IMETHODIMP
WebGLContext::TexSubImage2D_dom(WebGLenum target, WebGLint level,
WebGLint xoffset, WebGLint yoffset,
WebGLsizei width, WebGLsizei height,
nsIDOMElement *elt,
WebGLboolean flipY, WebGLboolean premultiplyAlpha)
WebGLenum format, WebGLenum type,
nsIDOMElement *elt)
{
nsRefPtr<gfxImageSurface> isurf;
nsresult rv = DOMElementToImageSurface(elt, getter_AddRefs(isurf),
flipY, premultiplyAlpha);
PR_FALSE/*flipY*/, PR_FALSE/*premultiplyAlpha*/);
if (NS_FAILED(rv))
return rv;
PRUint32 byteLength = isurf->Stride() * isurf->Height();
return TexSubImage2D_base(target, level,
xoffset, yoffset,
width, height,
isurf->Width(), isurf->Height(),
LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE,
isurf->Data(), isurf->Stride() * isurf->Height());
isurf->Data(), byteLength);
}
#if 0

Просмотреть файл

@ -745,9 +745,11 @@ interface nsICanvasRenderingContextWebGL : nsISupports
in WebGLsizei width, in WebGLsizei height,
in WebGLint border, in WebGLenum format, in WebGLenum type, in WebGLArrayPtr pixels);
// HTMLImageElement, HTMLCanvasElement, HTMLVideoElement
[noscript] void texImage2D_dom(in WebGLenum target, in WebGLint level, in nsIDOMElement element,
[optional] in WebGLboolean premultiply, [optional] in WebGLboolean asPremultipliedAlpha);
[noscript] void texImage2D_dom(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
in WebGLenum format, in WebGLenum type, in nsIDOMElement element);
// XXX the old API. Eventually drop that.
[noscript] void TexImage2D_dom_old_API_deprecated(in WebGLenum target, in WebGLint level,
in nsIDOMElement element, in PRBool flipY, in PRBool premultiplyAlpha);
void texSubImage2D([optional] in long dummy);
[noscript] void texSubImage2D_buf(in WebGLenum target, in WebGLint level,
@ -758,9 +760,8 @@ interface nsICanvasRenderingContextWebGL : nsISupports
in WebGLenum format, in WebGLenum type, in WebGLArrayPtr pixels);
// HTMLImageElement, HTMLCanvasElement, HTMLVideoElement
[noscript] void texSubImage2D_dom(in WebGLenum target, in WebGLint level,
in WebGLint xoffset, in WebGLint yoffset, in WebGLsizei width, in WebGLsizei height,
in nsIDOMElement element,
[optional] in WebGLboolean premultiply, [optional] in WebGLboolean asPremultipliedAlpha);
in WebGLint xoffset, in WebGLint yoffset, in WebGLenum format, in WebGLenum type,
in nsIDOMElement element);
// Modified: This replaces glTexParameterf, glTexParameterfv, glTexParameteri and glTexParameteriv
void texParameterf(in WebGLenum target, in WebGLenum pname, in WebGLfloat param);