b=520920, update WebGL arrays to support views, r=vlad

This commit is contained in:
Mark Steele
2009-10-29 23:01:06 -07:00
parent 30871f519f
commit 8a49c0aa1b
9 changed files with 1509 additions and 197 deletions

View File

@@ -38,6 +38,7 @@
#ifndef WEBGLARRAY_H_ #ifndef WEBGLARRAY_H_
#define WEBGLARRAY_H_ #define WEBGLARRAY_H_
nsresult NS_NewCanvasArrayBuffer(nsISupports **aNewObject);
nsresult NS_NewCanvasFloatArray(nsISupports **aNewObject); nsresult NS_NewCanvasFloatArray(nsISupports **aNewObject);
nsresult NS_NewCanvasByteArray(nsISupports **aNewObject); nsresult NS_NewCanvasByteArray(nsISupports **aNewObject);
nsresult NS_NewCanvasUnsignedByteArray(nsISupports **aNewObject); nsresult NS_NewCanvasUnsignedByteArray(nsISupports **aNewObject);

View File

@@ -85,7 +85,7 @@ public:
if (type == LOCAL_GL_INT) return sizeof(int); if (type == LOCAL_GL_INT) return sizeof(int);
if (type == LOCAL_GL_UNSIGNED_INT) return sizeof(unsigned int); if (type == LOCAL_GL_UNSIGNED_INT) return sizeof(unsigned int);
if (type == LOCAL_GL_DOUBLE) return sizeof(double); if (type == LOCAL_GL_DOUBLE) return sizeof(double);
return 0; return 1;
} }
void Clear() { void Clear() {

File diff suppressed because it is too large Load Diff

View File

@@ -356,6 +356,10 @@ public:
mCount = na->NativeCount(); mCount = na->NativeCount();
} }
void SetCount(GLuint count) {
mCount = count;
}
GLenum GLType() { return mGLType; } GLenum GLType() { return mGLType; }
PRUint32 ByteCount() { return mElementSize * mCount; } PRUint32 ByteCount() { return mElementSize * mCount; }
PRUint32 Count() { return mCount; } PRUint32 Count() { return mCount; }
@@ -497,28 +501,54 @@ protected:
// array wrapper classes // array wrapper classes
// //
// XXX refactor buffer stuff
class WebGLArrayBuffer :
public nsICanvasArrayBuffer,
public nsIJSNativeInitializer,
public SimpleBuffer
{
public:
WebGLArrayBuffer() { }
WebGLArrayBuffer(PRUint32 length);
NS_DECL_ISUPPORTS
NS_DECL_NSICANVASARRAYBUFFER
NS_IMETHOD Initialize(nsISupports* aOwner,
JSContext* aCx,
JSObject* aObj,
PRUint32 aArgc,
jsval* aArgv);
};
class WebGLFloatArray : class WebGLFloatArray :
public nsICanvasFloatArray, public nsICanvasFloatArray,
public nsIJSNativeInitializer public nsIJSNativeInitializer
{ {
public: public:
WebGLFloatArray(); WebGLFloatArray() :
mOffset(0), mLength(0) { }
WebGLFloatArray(PRUint32 length);
WebGLFloatArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
WebGLFloatArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen); WebGLFloatArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSICANVASARRAY NS_DECL_NSICANVASARRAY
NS_DECL_NSICANVASFLOATARRAY NS_DECL_NSICANVASFLOATARRAY
static nsresult NewCanvasFloatArray(nsISupports **aNewObject);
NS_IMETHOD Initialize(nsISupports* aOwner, NS_IMETHOD Initialize(nsISupports* aOwner,
JSContext* aCx, JSContext* aCx,
JSObject* aObj, JSObject* aObj,
PRUint32 aArgc, PRUint32 aArgc,
jsval* aArgv); jsval* aArgv);
void Set(PRUint32 index, float value);
protected: protected:
SimpleBuffer mBuffer; nsRefPtr<WebGLArrayBuffer> mBuffer;
PRUint32 mOffset;
PRUint32 mLength; PRUint32 mLength;
PRUint32 mSize; PRUint32 mSize;
PRUint32 mElementSize; PRUint32 mElementSize;
@@ -530,7 +560,11 @@ class WebGLByteArray :
public nsIJSNativeInitializer public nsIJSNativeInitializer
{ {
public: public:
WebGLByteArray(); WebGLByteArray() :
mOffset(0), mLength(0) { }
WebGLByteArray(PRUint32 length);
WebGLByteArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
WebGLByteArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen); WebGLByteArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -542,8 +576,12 @@ public:
JSObject* aObj, JSObject* aObj,
PRUint32 aArgc, PRUint32 aArgc,
jsval* aArgv); jsval* aArgv);
void Set(PRUint32 index, char value);
protected: protected:
SimpleBuffer mBuffer; nsRefPtr<WebGLArrayBuffer> mBuffer;
PRUint32 mOffset;
PRUint32 mLength; PRUint32 mLength;
PRUint32 mSize; PRUint32 mSize;
PRUint32 mElementSize; PRUint32 mElementSize;
@@ -555,7 +593,11 @@ class WebGLUnsignedByteArray :
public nsIJSNativeInitializer public nsIJSNativeInitializer
{ {
public: public:
WebGLUnsignedByteArray(); WebGLUnsignedByteArray() :
mOffset(0), mLength(0) { }
WebGLUnsignedByteArray(PRUint32 length);
WebGLUnsignedByteArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
WebGLUnsignedByteArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen); WebGLUnsignedByteArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -567,8 +609,12 @@ public:
JSObject* aObj, JSObject* aObj,
PRUint32 aArgc, PRUint32 aArgc,
jsval* aArgv); jsval* aArgv);
void Set(PRUint32 index, unsigned char value);
protected: protected:
SimpleBuffer mBuffer; nsRefPtr<WebGLArrayBuffer> mBuffer;
PRUint32 mOffset;
PRUint32 mLength; PRUint32 mLength;
PRUint32 mSize; PRUint32 mSize;
PRUint32 mElementSize; PRUint32 mElementSize;
@@ -580,7 +626,11 @@ class WebGLShortArray :
public nsIJSNativeInitializer public nsIJSNativeInitializer
{ {
public: public:
WebGLShortArray(); WebGLShortArray() :
mOffset(0), mLength(0) { }
WebGLShortArray(PRUint32 length);
WebGLShortArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
WebGLShortArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen); WebGLShortArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -592,8 +642,12 @@ public:
JSObject* aObj, JSObject* aObj,
PRUint32 aArgc, PRUint32 aArgc,
jsval* aArgv); jsval* aArgv);
void Set(PRUint32 index, short value);
protected: protected:
SimpleBuffer mBuffer; nsRefPtr<WebGLArrayBuffer> mBuffer;
PRUint32 mOffset;
PRUint32 mLength; PRUint32 mLength;
PRUint32 mSize; PRUint32 mSize;
PRUint32 mElementSize; PRUint32 mElementSize;
@@ -605,7 +659,11 @@ class WebGLUnsignedShortArray :
public nsIJSNativeInitializer public nsIJSNativeInitializer
{ {
public: public:
WebGLUnsignedShortArray(); WebGLUnsignedShortArray() :
mOffset(0), mLength(0) { }
WebGLUnsignedShortArray(PRUint32 length);
WebGLUnsignedShortArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
WebGLUnsignedShortArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen); WebGLUnsignedShortArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -617,8 +675,12 @@ public:
JSObject* aObj, JSObject* aObj,
PRUint32 aArgc, PRUint32 aArgc,
jsval* aArgv); jsval* aArgv);
void Set(PRUint32 index, unsigned short value);
protected: protected:
SimpleBuffer mBuffer; nsRefPtr<WebGLArrayBuffer> mBuffer;
PRUint32 mOffset;
PRUint32 mLength; PRUint32 mLength;
PRUint32 mSize; PRUint32 mSize;
PRUint32 mElementSize; PRUint32 mElementSize;
@@ -630,7 +692,11 @@ class WebGLIntArray :
public nsIJSNativeInitializer public nsIJSNativeInitializer
{ {
public: public:
WebGLIntArray(); WebGLIntArray() :
mOffset(0), mLength(0) { }
WebGLIntArray(PRUint32 length);
WebGLIntArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
WebGLIntArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen); WebGLIntArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -642,8 +708,12 @@ public:
JSObject* aObj, JSObject* aObj,
PRUint32 aArgc, PRUint32 aArgc,
jsval* aArgv); jsval* aArgv);
void Set(PRUint32 index, int value);
protected: protected:
SimpleBuffer mBuffer; nsRefPtr<WebGLArrayBuffer> mBuffer;
PRUint32 mOffset;
PRUint32 mLength; PRUint32 mLength;
PRUint32 mSize; PRUint32 mSize;
PRUint32 mElementSize; PRUint32 mElementSize;
@@ -655,7 +725,11 @@ class WebGLUnsignedIntArray :
public nsIJSNativeInitializer public nsIJSNativeInitializer
{ {
public: public:
WebGLUnsignedIntArray(); WebGLUnsignedIntArray() :
mOffset(0), mLength(0) { }
WebGLUnsignedIntArray(PRUint32 length);
WebGLUnsignedIntArray(WebGLArrayBuffer *buffer, PRUint32 offset, PRUint32 length);
WebGLUnsignedIntArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen); WebGLUnsignedIntArray(JSContext *cx, JSObject *arrayObj, jsuint arrayLen);
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -667,8 +741,12 @@ public:
JSObject* aObj, JSObject* aObj,
PRUint32 aArgc, PRUint32 aArgc,
jsval* aArgv); jsval* aArgv);
void Set(PRUint32 index, unsigned int value);
protected: protected:
SimpleBuffer mBuffer; nsRefPtr<WebGLArrayBuffer> mBuffer;
PRUint32 mOffset;
PRUint32 mLength; PRUint32 mLength;
PRUint32 mSize; PRUint32 mSize;
PRUint32 mElementSize; PRUint32 mElementSize;

View File

@@ -354,6 +354,20 @@ WebGLContext::Present()
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
} }
/* long sizeInBytes (in GLenum type); */
NS_IMETHODIMP
WebGLContext::SizeInBytes(GLenum type, PRInt32 *retval)
{
if (type == LOCAL_GL_FLOAT) *retval = sizeof(float);
if (type == LOCAL_GL_SHORT) *retval = sizeof(short);
if (type == LOCAL_GL_UNSIGNED_SHORT) *retval = sizeof(unsigned short);
if (type == LOCAL_GL_BYTE) *retval = 1;
if (type == LOCAL_GL_UNSIGNED_BYTE) *retval = 1;
if (type == LOCAL_GL_INT) *retval = sizeof(int);
if (type == LOCAL_GL_UNSIGNED_INT) *retval = sizeof(unsigned int);
if (type == LOCAL_GL_DOUBLE) *retval = sizeof(double);
return NS_OK;
}
/* void GlActiveTexture (in PRUint32 texture); */ /* void GlActiveTexture (in PRUint32 texture); */
NS_IMETHODIMP NS_IMETHODIMP
@@ -508,15 +522,28 @@ GL_SAME_METHOD_2(BlendFunc, BlendFunc, PRUint32, PRUint32)
GL_SAME_METHOD_4(BlendFuncSeparate, BlendFuncSeparate, PRUint32, PRUint32, PRUint32, PRUint32) GL_SAME_METHOD_4(BlendFuncSeparate, BlendFuncSeparate, PRUint32, PRUint32, PRUint32, PRUint32)
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::BufferData(GLenum target, nsICanvasArray *na, GLenum usage) WebGLContext::BufferData(GLenum target)
{ {
// overloaded:
// void bufferData (in GLenum target, in GLsizei size, in GLenum usage);
// void bufferData (in GLenum target, in nsICanvasArray data, in GLenum usage);
// void bufferData (in GLenum target, in nsICanvasArrayBuffer data, in GLenum usage)
NativeJSContext js;
if (NS_FAILED(js.error))
return js.error;
if (js.argc != 3)
return NS_ERROR_DOM_SYNTAX_ERR;
WebGLBuffer *boundBuffer = NULL; WebGLBuffer *boundBuffer = NULL;
if (target == LOCAL_GL_ARRAY_BUFFER) { if (target == LOCAL_GL_ARRAY_BUFFER) {
boundBuffer = mBoundArrayBuffer; boundBuffer = mBoundArrayBuffer;
} else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
if (na->NativeType() != LOCAL_GL_UNSIGNED_SHORT) // XXX fix type check
return ErrorMessage("glBufferData: %x - GL_ELEMENT_ARRAY_BUFFER target must be used with UnsignedShortBuffer", na->NativeType()); //if (na->NativeType() != LOCAL_GL_UNSIGNED_SHORT)
// return ErrorMessage("glBufferData: %x - GL_ELEMENT_ARRAY_BUFFER target must be used with UnsignedShortBuffer", na->NativeType());
boundBuffer = mBoundElementArrayBuffer; boundBuffer = mBoundElementArrayBuffer;
} else { } else {
@@ -527,18 +554,62 @@ WebGLContext::BufferData(GLenum target, nsICanvasArray *na, GLenum usage)
return ErrorMessage("glBufferData: no buffer bound!"); return ErrorMessage("glBufferData: no buffer bound!");
} }
MakeContextCurrent(); MakeContextCurrent();
boundBuffer->Set(na); GLenum usage;
gl->fBufferData(target, na->NativeSize(), na->NativePointer(), usage); if (!::JS_ValueToECMAUint32(js.ctx, js.argv[2], &usage)) {
return ErrorMessage("bufferData: invalid usage parameter");
}
if (JSVAL_IS_NUMBER(js.argv[1])) {
GLsizei size;
if (!::JS_ValueToECMAInt32(js.ctx, js.argv[1], &size)) {
return ErrorMessage("bufferData: invalid size parameter");
}
boundBuffer->SetCount(size);
gl->fBufferData(target, size, 0, usage);
} else if (JSVAL_IS_OBJECT(js.argv[1])) {
nsCOMPtr<nsICanvasArray> canvasArrayObj;
nsresult rv;
rv = nsContentUtils::XPConnect()->WrapJS(js.ctx, JSVAL_TO_OBJECT(js.argv[1]),
NS_GET_IID(nsICanvasArray), getter_AddRefs(canvasArrayObj));
if (NS_FAILED(rv) || !canvasArrayObj) {
nsCOMPtr<nsICanvasArrayBuffer> arrayBuf;
rv = nsContentUtils::XPConnect()->WrapJS(js.ctx, JSVAL_TO_OBJECT(js.argv[1]),
NS_GET_IID(nsICanvasArrayBuffer), getter_AddRefs(arrayBuf));
if (NS_FAILED(rv) || !arrayBuf)
return ErrorMessage("bufferData: need CanvasArray or CanvasArrayBuffer");
boundBuffer->SetCount(arrayBuf->NativeSize());
gl->fBufferData(target, arrayBuf->NativeSize(), arrayBuf->NativePointer(), usage);
} else {
boundBuffer->Set(canvasArrayObj);
gl->fBufferData(target, canvasArrayObj->NativeSize(), canvasArrayObj->NativePointer(), usage);
}
} else {
return ErrorMessage("bufferData: invalid data");
}
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::BufferSubData(GLenum target, GLuint offset, nsICanvasArray *na) WebGLContext::BufferSubData(GLenum target, GLsizeiptr offset)
{ {
// overloaded:
// void bufferSubData(in GLenum target, in GLsizeiptr offset, in CanvasArray data)
// void bufferSubData(in GLenum target, in GLsizeiptr offset, in CanvasArrayBuffer data)
NativeJSContext js;
if (NS_FAILED(js.error))
return js.error;
if (js.argc != 3)
return NS_ERROR_DOM_SYNTAX_ERR;
WebGLBuffer *boundBuffer = NULL; WebGLBuffer *boundBuffer = NULL;
if (target == LOCAL_GL_ARRAY_BUFFER) { if (target == LOCAL_GL_ARRAY_BUFFER) {
@@ -553,24 +624,63 @@ WebGLContext::BufferSubData(GLenum target, GLuint offset, nsICanvasArray *na)
return ErrorMessage("glBufferSubData: no buffer bound!"); return ErrorMessage("glBufferSubData: no buffer bound!");
} }
/* XXX FIXME
// check type // check type
if (na->NativeType() != boundBuffer->GLType()) { if (na->NativeType() != boundBuffer->GLType()) {
return ErrorMessage("glBufferSubData: existing buffer has different base type (0x%04x) the sub data (0x%04x)!", boundBuffer->GLType(), na->NativeType()); return ErrorMessage("glBufferSubData: existing buffer has different base type (0x%04x) the sub data (0x%04x)!", boundBuffer->GLType(), na->NativeType());
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
*/
// check size if (JSVAL_IS_OBJECT(js.argv[2])) {
if ((offset + na->NativeCount()) > boundBuffer->Count()) { nsCOMPtr<nsICanvasArray> canvasArrayObj;
return ErrorMessage("glBufferSubData: existing buffer is too small for additional data"); nsresult rv;
return NS_ERROR_FAILURE;
rv = nsContentUtils::XPConnect()->WrapJS(js.ctx, JSVAL_TO_OBJECT(js.argv[2]),
NS_GET_IID(nsICanvasArray), getter_AddRefs(canvasArrayObj));
if (NS_FAILED(rv) || !canvasArrayObj) {
nsCOMPtr<nsICanvasArrayBuffer> arrayBuf;
rv = nsContentUtils::XPConnect()->WrapJS(js.ctx, JSVAL_TO_OBJECT(js.argv[2]),
NS_GET_IID(nsICanvasArrayBuffer), getter_AddRefs(arrayBuf));
if (NS_FAILED(rv) || !arrayBuf)
return ErrorMessage("bufferData: need CanvasArray or CanvasArrayBuffer");
// check size
// XXX should be bytes
if ((offset + arrayBuf->NativeSize()) > boundBuffer->Count()) {
return ErrorMessage("glBufferSubData: existing buffer is too small (%d) for data at offset (%d+%d)",
boundBuffer->Count(), offset, arrayBuf->NativeSize());
return NS_ERROR_FAILURE;
}
#ifdef DEBUG
LogMessage("bufferSubData: buffer (%d) for data at offset (%d+%d)", boundBuffer->Count(), offset, arrayBuf->NativeSize());
#endif
// all good
MakeContextCurrent();
gl->fBufferSubData(target, offset, arrayBuf->NativeSize(), arrayBuf->NativePointer());
} else {
// check size
// XXX should be bytes
if ((offset + canvasArrayObj->NativeCount()) > boundBuffer->Count()) {
return ErrorMessage("glBufferSubData: existing buffer is too small (%d) for data at offset (%d+%d)",
boundBuffer->Count(), offset, canvasArrayObj->NativeCount());
return NS_ERROR_FAILURE;
}
#ifdef DEBUG
LogMessage("bufferSubData: buffer (%d) for data at offset (%d+%d)", boundBuffer->Count(), offset, canvasArrayObj->NativeSize());
#endif
// all good
MakeContextCurrent();
gl->fBufferSubData(target, offset, canvasArrayObj->NativeSize(), canvasArrayObj->NativePointer());
}
} else {
return ErrorMessage("bufferData: invalid data");
} }
// all good
MakeContextCurrent();
gl->fBufferSubData(target, offset * na->NativeElementSize(), na->NativeSize(), na->NativePointer());
return NS_OK; return NS_OK;
} }
@@ -970,7 +1080,7 @@ WebGLContext::DrawElements(GLenum mode, GLuint count, GLenum type, GLuint offset
return ErrorMessage("glDrawElements: ValidateBuffers failed"); return ErrorMessage("glDrawElements: ValidateBuffers failed");
#endif #endif
// XXX uh, is this offset, or offset * elementsize? // XXX uh, is this offset, or offset * elementsize?
gl->fDrawElements(mode, count, type, (GLvoid*) (offset * mBoundElementArrayBuffer->ElementSize())); gl->fDrawElements(mode, count, type, (GLvoid*) (offset));
Invalidate(); Invalidate();
@@ -2400,7 +2510,7 @@ GL_SAME_METHOD_5(Uniform4f, Uniform4f, GLint, GLfloat, GLfloat, GLfloat, GLfloat
// one uint arg followed by an array of c elements of glTypeConst. // one uint arg followed by an array of c elements of glTypeConst.
#define GL_SIMPLE_ARRAY_METHOD(glname, name, c, glTypeConst, ptrType) \ #define GL_SIMPLE_ARRAY_METHOD(glname, name, c, glTypeConst, ptrType) \
NS_IMETHODIMP \ NS_IMETHODIMP \
WebGLContext::name(GLint idx, nsICanvasArray *v) \ WebGLContext::name(GLint idx, nsICanvasArray *v) \
{ \ { \
NativeJSContext js; \ NativeJSContext js; \
if (NS_FAILED(js.error)) \ if (NS_FAILED(js.error)) \
@@ -2423,22 +2533,20 @@ WebGLContext::name(GLint idx, nsICanvasArray *v)
if (v->NativeType() != LOCAL_GL_INT) { \ if (v->NativeType() != LOCAL_GL_INT) { \
return ErrorMessage(#name ": arg not an array"); \ return ErrorMessage(#name ": arg not an array"); \
} \ } \
WebGLIntArray *wga = static_cast<WebGLIntArray*>(v); \ if (v->NativeCount() % c != 0) { \
if (wga->NativeCount() % c != 0) { \
return ErrorMessage(#name ": array length not divisible by " #c); \ return ErrorMessage(#name ": array length not divisible by " #c); \
} \ } \
MakeContextCurrent(); \ MakeContextCurrent(); \
gl->f##glname(idx, wga->NativeCount() / c, ( ptrType *)wga->NativePointer()); \ gl->f##glname(idx, v->NativeCount() / c, ( ptrType *)v->NativePointer()); \
} else if (glTypeConst == LOCAL_GL_FLOAT) { \ } else if (glTypeConst == LOCAL_GL_FLOAT) { \
if (v->NativeType() != LOCAL_GL_FLOAT) { \ if (v->NativeType() != LOCAL_GL_FLOAT) { \
return ErrorMessage(#name ": arg not an array"); \ return ErrorMessage(#name ": arg not an array"); \
} \ } \
WebGLFloatArray *wga = static_cast<WebGLFloatArray*>(v); \ if (v->NativeCount() % c != 0) { \
if (wga->NativeCount() % c != 0) { \
return ErrorMessage(#name ": array length not divisible by " #c); \ return ErrorMessage(#name ": array length not divisible by " #c); \
} \ } \
MakeContextCurrent(); \ MakeContextCurrent(); \
gl->f##glname(idx, wga->NativeCount() / c, ( ptrType *)wga->NativePointer()); \ gl->f##glname(idx, v->NativeCount() / c, ( ptrType *)v->NativePointer()); \
} else { \ } else { \
return ErrorMessage("Unhandled glTypeConst"); /* need compiler fail */\ return ErrorMessage("Unhandled glTypeConst"); /* need compiler fail */\
} \ } \
@@ -2448,7 +2556,7 @@ WebGLContext::name(GLint idx, nsICanvasArray *v)
#define GL_SIMPLE_ARRAY_METHOD_NO_COUNT(glname, name, c, glTypeConst, ptrType) \ #define GL_SIMPLE_ARRAY_METHOD_NO_COUNT(glname, name, c, glTypeConst, ptrType) \
NS_IMETHODIMP \ NS_IMETHODIMP \
WebGLContext::name(GLuint idx, nsICanvasArray *v) \ WebGLContext::name(GLuint idx, nsICanvasArray *v) \
{ \ { \
NativeJSContext js; \ NativeJSContext js; \
if (NS_FAILED(js.error)) \ if (NS_FAILED(js.error)) \
@@ -2471,22 +2579,20 @@ WebGLContext::name(GLuint idx, nsICanvasArray *v)
if (v->NativeType() != LOCAL_GL_INT) { \ if (v->NativeType() != LOCAL_GL_INT) { \
return ErrorMessage(#name ": arg not an array"); \ return ErrorMessage(#name ": arg not an array"); \
} \ } \
WebGLIntArray *wga = static_cast<WebGLIntArray*>(v); \ if (v->NativeCount() % c != 0) { \
if (wga->NativeCount() % c != 0) { \ return ErrorMessage(#name ": array wrong size %d, expected " #c, v->NativeCount()); \
return ErrorMessage(#name ": array wrong size %d, expected " #c, wga->NativeCount()); \
} \ } \
MakeContextCurrent(); \ MakeContextCurrent(); \
gl->f##glname(idx, ( ptrType *)wga->NativePointer()); \ gl->f##glname(idx, ( ptrType *)v->NativePointer()); \
} else if (glTypeConst == LOCAL_GL_FLOAT) { \ } else if (glTypeConst == LOCAL_GL_FLOAT) { \
if (v->NativeType() != LOCAL_GL_FLOAT) { \ if (v->NativeType() != LOCAL_GL_FLOAT) { \
return ErrorMessage(#name ": arg not an array"); \ return ErrorMessage(#name ": arg not an array"); \
} \ } \
WebGLFloatArray *wga = static_cast<WebGLFloatArray*>(v); \ if (v->NativeCount() % c != 0) { \
if (wga->NativeCount() % c != 0) { \ return ErrorMessage(#name ": array wrong size %d, expected " #c, v->NativeCount()); \
return ErrorMessage(#name ": array wrong size %d, expected " #c, wga->NativeCount()); \
} \ } \
MakeContextCurrent(); \ MakeContextCurrent(); \
gl->f##glname(idx, ( ptrType *)wga->NativePointer()); \ gl->f##glname(idx, ( ptrType *)v->NativePointer()); \
} else { \ } else { \
return ErrorMessage("Unhandled glTypeConst"); /* need compiler fail */\ return ErrorMessage("Unhandled glTypeConst"); /* need compiler fail */\
} \ } \
@@ -2496,7 +2602,7 @@ WebGLContext::name(GLuint idx, nsICanvasArray *v)
#define GL_SIMPLE_MATRIX_METHOD(glname, name, c, glTypeConst, ptrType) \ #define GL_SIMPLE_MATRIX_METHOD(glname, name, c, glTypeConst, ptrType) \
NS_IMETHODIMP \ NS_IMETHODIMP \
WebGLContext::name(GLint location, GLboolean transpose, nsICanvasArray *value) \ WebGLContext::name(GLint location, GLboolean transpose, nsICanvasArray *value) \
{ \ { \
NativeJSContext js; \ NativeJSContext js; \
if (NS_FAILED(js.error)) \ if (NS_FAILED(js.error)) \
@@ -2519,12 +2625,11 @@ WebGLContext::name(GLint location, GLboolean transpose, nsICanvasArray *value)
if (value->NativeType() != LOCAL_GL_FLOAT) { \ if (value->NativeType() != LOCAL_GL_FLOAT) { \
return ErrorMessage(#name ": arg not an array"); \ return ErrorMessage(#name ": arg not an array"); \
} \ } \
WebGLFloatArray *wga = static_cast<WebGLFloatArray*>(value); \ if (value->NativeCount() % c != 0) { \
if (wga->NativeCount() % c != 0) { \ return ErrorMessage(#name ": array wrong size %d, expected " #c, value->NativeCount()); \
return ErrorMessage(#name ": array wrong size %d, expected " #c, wga->NativeCount()); \
} \ } \
MakeContextCurrent(); \ MakeContextCurrent(); \
gl->f##glname(location, wga->NativeCount() / c, transpose, ( ptrType *)wga->NativePointer()); \ gl->f##glname(location, value->NativeCount() / c, transpose, ( ptrType *)value->NativePointer()); \
} else { \ } else { \
return ErrorMessage("Unhandled glTypeConst"); /* need compiler fail */\ return ErrorMessage("Unhandled glTypeConst"); /* need compiler fail */\
} \ } \
@@ -2780,8 +2885,10 @@ WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type,
if (size < 1 || size > 4) if (size < 1 || size > 4)
return ErrorMessage("glVertexAttribPointer: invalid element size"); return ErrorMessage("glVertexAttribPointer: invalid element size");
/* XXX make work with bufferSubData & heterogeneous types
if (type != mBoundArrayBuffer->GLType()) if (type != mBoundArrayBuffer->GLType())
return ErrorMessage("glVertexAttribPointer: type must match bound VBO type: %d != %d", type, mBoundArrayBuffer->GLType()); return ErrorMessage("glVertexAttribPointer: type must match bound VBO type: %d != %d", type, mBoundArrayBuffer->GLType());
*/
// XXX 0 stride? // XXX 0 stride?
//if (stride < (GLuint) size) //if (stride < (GLuint) size)
@@ -2797,8 +2904,8 @@ WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type,
MakeContextCurrent(); MakeContextCurrent();
gl->fVertexAttribPointer(index, size, type, normalized, gl->fVertexAttribPointer(index, size, type, normalized,
stride * mBoundArrayBuffer->ElementSize(), stride,
(void*) (offset * mBoundArrayBuffer->ElementSize())); (void*) (offset));
return NS_OK; return NS_OK;
} }

View File

@@ -1335,6 +1335,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLRenderbuffer, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(WebGLRenderbuffer, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CanvasArrayBuffer, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CanvasFloatArray, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(CanvasFloatArray, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CanvasByteArray, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(CanvasByteArray, nsDOMGenericSH,
@@ -1396,6 +1398,7 @@ static const nsConstructorFuncMapData kConstructorFuncMap[] =
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(Worker, nsDOMWorker::NewWorker) NS_DEFINE_CONSTRUCTOR_FUNC_DATA(Worker, nsDOMWorker::NewWorker)
// WebGL Array Types // WebGL Array Types
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(CanvasArrayBuffer, NS_NewCanvasArrayBuffer)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(CanvasFloatArray, NS_NewCanvasFloatArray) NS_DEFINE_CONSTRUCTOR_FUNC_DATA(CanvasFloatArray, NS_NewCanvasFloatArray)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(CanvasByteArray, NS_NewCanvasByteArray) NS_DEFINE_CONSTRUCTOR_FUNC_DATA(CanvasByteArray, NS_NewCanvasByteArray)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(CanvasUnsignedByteArray, NS_NewCanvasUnsignedByteArray) NS_DEFINE_CONSTRUCTOR_FUNC_DATA(CanvasUnsignedByteArray, NS_NewCanvasUnsignedByteArray)
@@ -3722,6 +3725,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLRenderbuffer) DOM_CLASSINFO_MAP_ENTRY(nsIWebGLRenderbuffer)
DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(CanvasArrayBuffer, nsICanvasArrayBuffer)
DOM_CLASSINFO_MAP_ENTRY(nsICanvasArrayBuffer)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(CanvasFloatArray, nsICanvasFloatArray) DOM_CLASSINFO_MAP_BEGIN(CanvasFloatArray, nsICanvasFloatArray)
DOM_CLASSINFO_MAP_ENTRY(nsICanvasFloatArray) DOM_CLASSINFO_MAP_ENTRY(nsICanvasFloatArray)
DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_END

View File

@@ -473,6 +473,7 @@ enum nsDOMClassInfoID {
eDOMClassInfo_WebGLRenderbuffer_id, eDOMClassInfo_WebGLRenderbuffer_id,
// WebGL Buffers // WebGL Buffers
eDOMClassInfo_CanvasArrayBuffer_id,
eDOMClassInfo_CanvasFloatArray_id, eDOMClassInfo_CanvasFloatArray_id,
eDOMClassInfo_CanvasByteArray_id, eDOMClassInfo_CanvasByteArray_id,
eDOMClassInfo_CanvasUnsignedByteArray_id, eDOMClassInfo_CanvasUnsignedByteArray_id,

View File

@@ -59,16 +59,39 @@ typedef long GLfixed;
//typedef signed octet GLbyte; //typedef signed octet GLbyte;
//typedef unsigned long GLintptr; //typedef unsigned long GLintptr;
//typedef unsigned long GLsizeiptr; typedef long GLsizeiptr;
%{C++
namespace mozilla {
class WebGLArrayBuffer;
}
%}
[ptr] native WebGLArrayBufferPtr (mozilla::WebGLArrayBuffer);
// //
// Array types // Array types
// //
[scriptable, uuid(34b6cf8e-47da-458e-ab42-0451a3533ee5)]
interface nsICanvasArrayBuffer : nsISupports
{
readonly attribute unsigned long byteLength;
[noscript, notxpcom] WebGLArrayBufferPtr GetNativeArrayBuffer();
[noscript, notxpcom] voidPtr nativePointer();
[noscript, notxpcom] unsigned long nativeSize();
};
[scriptable, uuid(84ba4e98-8173-7c10-dca0-b5ba7809fcf3)] [scriptable, uuid(84ba4e98-8173-7c10-dca0-b5ba7809fcf3)]
interface nsICanvasArray : nsISupports interface nsICanvasArray : nsISupports
{ {
attribute unsigned long length; readonly attribute nsICanvasArrayBuffer buffer;
readonly attribute unsigned long byteOffset;
readonly attribute unsigned long byteLength;
readonly attribute unsigned long length;
// XXX kill this.
unsigned long alignedSizeInBytes();
nsICanvasArray slice(in unsigned long offset, in unsigned long length);
[noscript, notxpcom] unsigned long nativeType(); [noscript, notxpcom] unsigned long nativeType();
[noscript, notxpcom] voidPtr nativePointer(); [noscript, notxpcom] voidPtr nativePointer();
@@ -80,36 +103,71 @@ interface nsICanvasArray : nsISupports
[scriptable, Uuid(0f6d0e7b-bcfc-9305-6a1d-a9653b5e8c80)] [scriptable, Uuid(0f6d0e7b-bcfc-9305-6a1d-a9653b5e8c80)]
interface nsICanvasFloatArray : nsICanvasArray interface nsICanvasFloatArray : nsICanvasArray
{ {
[IndexGetter] float get(in unsigned long index);
//[IndexSetter] void set(in unsigned long index, in float value);
//void set(in CanvasFloatArray array, [Optional] in unsigned long offset);
//void set(in sequence<float> array, [Optional] in unsigned long offset);
void set();
}; };
[scriptable, uuid(b29db7cf-fa58-435f-8d45-611cc50979ad)] [scriptable, uuid(b29db7cf-fa58-435f-8d45-611cc50979ad)]
interface nsICanvasByteArray : nsICanvasArray interface nsICanvasByteArray : nsICanvasArray
{ {
[IndexGetter] long get(in unsigned long index);
//[IndexSetter] void set(in unsigned long index, in long value);
//void set(in nsICanvasByteArray array, [Optional] in unsigned long offset);
//void set(in sequence<long> array, [Optional] in unsigned long offset);
void set();
}; };
[scriptable, uuid(3daa67fa-e743-2cbd-a212-805c2fc520cc)] [scriptable, uuid(3daa67fa-e743-2cbd-a212-805c2fc520cc)]
interface nsICanvasUnsignedByteArray : nsICanvasArray interface nsICanvasUnsignedByteArray : nsICanvasArray
{ {
[IndexGetter] unsigned long get(in unsigned long index);
//[IndexSetter] void set(in unsigned long index, in unsigned long value);
//void set(in CanvasUnsignedByteArray array, [Optional] in unsigned long offset);
//void set(in sequence<unsigned long> array, [Optional] in unsigned long offset);
void set();
}; };
[scriptable, uuid(a8a982e3-3977-7364-f012-c497a5ab7681)] [scriptable, uuid(a8a982e3-3977-7364-f012-c497a5ab7681)]
interface nsICanvasShortArray : nsICanvasArray interface nsICanvasShortArray : nsICanvasArray
{ {
[IndexGetter] long get(in unsigned long index);
//[IndexSetter] void set(in unsigned long index, in long value);
//void set(in CanvasShortArray array, [Optional] in unsigned long offset);
//void set(in sequence<long> array, [Optional] in unsigned long offset);
void set();
}; };
[scriptable, uuid(8b9c67cc-c7be-a062-84b0-76a910a5c1e6)] [scriptable, uuid(8b9c67cc-c7be-a062-84b0-76a910a5c1e6)]
interface nsICanvasUnsignedShortArray : nsICanvasArray interface nsICanvasUnsignedShortArray : nsICanvasArray
{ {
[IndexGetter] unsigned long get(in unsigned long index);
//[IndexSetter] void set(in unsigned long index, in unsigned long value);
//void set(in CanvasUnsignedShortArray array, [Optional] in unsigned long offset);
//void set(in sequence<unsigned long> array, [Optional] in unsigned long offset);
void set();
}; };
[scriptable, uuid(b9b2e861-3a28-4311-993c-799e4f77dcba)] [scriptable, uuid(b9b2e861-3a28-4311-993c-799e4f77dcba)]
interface nsICanvasIntArray : nsICanvasArray interface nsICanvasIntArray : nsICanvasArray
{ {
[IndexGetter] long get(in unsigned long index);
//[IndexSetter] void set(in unsigned long index, in long value);
//void set(in CanvasIntArray array, [Optional] in unsigned long offset);
//void set(in sequence<long> array, [Optional] in unsigned long offset);
void set();
}; };
[scriptable, uuid(0d6ee3f8-71b6-460d-b05a-d579cc55edbe)] [scriptable, uuid(0d6ee3f8-71b6-460d-b05a-d579cc55edbe)]
interface nsICanvasUnsignedIntArray : nsICanvasArray interface nsICanvasUnsignedIntArray : nsICanvasArray
{ {
[IndexGetter] unsigned long get(in unsigned long index);
//[IndexSetter] void set(in unsigned long index, in unsigned long value);
//void set(in CanvasUnsignedIntArray array, [Optional] in unsigned long offset);
//void set(in sequence<unsigned long> array, [Optional] in unsigned long offset);
void set();
}; };
// //
@@ -624,6 +682,7 @@ interface nsICanvasRenderingContextWebGL : nsISupports
// METHODS // METHODS
// //
void present(); void present();
long sizeInBytes(in GLenum type);
void activeTexture (in GLenum texture); void activeTexture (in GLenum texture);
void attachShader (in nsIWebGLProgram program, in nsIWebGLShader shader); void attachShader (in nsIWebGLProgram program, in nsIWebGLShader shader);
@@ -640,10 +699,14 @@ interface nsICanvasRenderingContextWebGL : nsISupports
// Modified: void glBufferData (GLenum target, GLsizeiptr size, const void* data, GLenum usage); // Modified: void glBufferData (GLenum target, GLsizeiptr size, const void* data, GLenum usage);
// void bufferData (in GLenum target, in GLsizei size, in GLenum usage); // void bufferData (in GLenum target, in GLsizei size, in GLenum usage);
void bufferData (in GLenum target, in nsICanvasArray data, in GLenum usage); // void bufferData (in GLenum target, in nsICanvasArray data, in GLenum usage);
// void bufferData (in GLenum target, in nsICanvasArrayBuffer data, in GLenum usage);
void bufferData (in GLenum target);
// Modified: void glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void* data); // Modified: void glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
void bufferSubData (in GLenum target, in GLuint offset, in nsICanvasArray data); // void bufferSubData (in GLenum target, in GLsizeiptr offset, in nsICanvasArray data);
// void bufferSubData (in GLenum target, in GLsizeiptr offset, in CanvasArrayBuffer data);
void bufferSubData (in GLenum target, in GLsizeiptr offset);
GLenum checkFramebufferStatus (in GLenum target); GLenum checkFramebufferStatus (in GLenum target);
void clear (in GLbitfield mask); void clear (in GLbitfield mask);

View File

@@ -1077,6 +1077,11 @@ static const nsModuleComponentInfo gComponents[] = {
NS_CANVASRENDERINGCONTEXTWEBGL_CID, NS_CANVASRENDERINGCONTEXTWEBGL_CID,
"@mozilla.org/content/canvas-rendering-context;1?id=moz-webgl", "@mozilla.org/content/canvas-rendering-context;1?id=moz-webgl",
CreateCanvasRenderingContextWebGL }, CreateCanvasRenderingContextWebGL },
{ "Canvas WebGL Rendering Context",
NS_CANVASRENDERINGCONTEXTWEBGL_CID,
"@mozilla.org/content/canvas-rendering-context;1?id=experimental-webgl",
CreateCanvasRenderingContextWebGL },
{ "XML document encoder", { "XML document encoder",
NS_TEXT_ENCODER_CID, NS_TEXT_ENCODER_CID,