зеркало из https://github.com/mozilla/gecko-dev.git
b=524042, [webgl] texImage & texSubImage need to support flipY, r=vlad
This commit is contained in:
Родитель
88afa1cc2e
Коммит
8b8423f08c
|
@ -265,7 +265,8 @@ protected:
|
|||
void MakeContextCurrent() { mGLPbuffer->MakeContextCurrent(); }
|
||||
|
||||
nsresult TexImageElementBase(nsIDOMHTMLElement *imageOrCanvas,
|
||||
gfxImageSurface **imageOut);
|
||||
gfxImageSurface **imageOut,
|
||||
bool flipY, bool premultiplyAlpha);
|
||||
|
||||
GLuint mActiveTexture;
|
||||
|
||||
|
|
|
@ -2334,7 +2334,8 @@ GL_SAME_METHOD_4(StencilOpSeparate, StencilOpSeparate, GLenum, GLenum, GLenum, G
|
|||
|
||||
nsresult
|
||||
WebGLContext::TexImageElementBase(nsIDOMHTMLElement *imageOrCanvas,
|
||||
gfxImageSurface **imageOut)
|
||||
gfxImageSurface **imageOut,
|
||||
bool flipY, bool premultiplyAlpha)
|
||||
{
|
||||
gfxImageSurface *surf = nsnull;
|
||||
|
||||
|
@ -2426,86 +2427,37 @@ WebGLContext::TexImageElementBase(nsIDOMHTMLElement *imageOrCanvas,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (flipY) {
|
||||
nsRefPtr<gfxImageSurface> tmpsurf = new gfxImageSurface(res.mSize,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
if (!tmpsurf || tmpsurf->CairoStatus())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsRefPtr<gfxContext> tmpctx = new gfxContext(tmpsurf);
|
||||
|
||||
if (!tmpctx || tmpctx->HasError())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
tmpctx->Translate(gfxPoint(0, res.mSize.height));
|
||||
tmpctx->Scale(1.0, -1.0);
|
||||
|
||||
tmpctx->NewPath();
|
||||
tmpctx->Rectangle(gfxRect(0, 0, res.mSize.width, res.mSize.height));
|
||||
|
||||
tmpctx->SetSource(res.mSurface);
|
||||
tmpctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpctx->Fill();
|
||||
|
||||
NS_ADDREF(surf = tmpsurf);
|
||||
tmpctx = nsnull;
|
||||
}
|
||||
|
||||
res.mSurface.forget();
|
||||
*imageOut = surf;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::TexSubImage2DHTML(PRUint32 target, PRUint32 level, PRInt32 x, PRInt32 y, nsIDOMHTMLElement *imageOrCanvas)
|
||||
{
|
||||
|
||||
NativeJSContext js;
|
||||
if (NS_FAILED(js.error))
|
||||
return js.error;
|
||||
|
||||
switch (target) {
|
||||
case LOCAL_GL_TEXTURE_2D:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
break;
|
||||
default:
|
||||
return ErrorMessage("texImage2DHTML: unsupported target");
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> isurf;
|
||||
nsresult rv;
|
||||
|
||||
rv = TexImageElementBase(imageOrCanvas,
|
||||
getter_AddRefs(isurf));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
gl->fTexSubImage2D(target, level, x, y, isurf->Width(), isurf->Height(), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, isurf->Data());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::TexImage2DHTML(PRUint32 target, PRUint32 level, nsIDOMHTMLElement *imageOrCanvas)
|
||||
{
|
||||
NativeJSContext js;
|
||||
if (NS_FAILED(js.error))
|
||||
return js.error;
|
||||
|
||||
switch (target) {
|
||||
case LOCAL_GL_TEXTURE_2D:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
break;
|
||||
default:
|
||||
return ErrorMessage("texImage2DHTML: unsupported target");
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> isurf;
|
||||
nsresult rv;
|
||||
|
||||
rv = TexImageElementBase(imageOrCanvas,
|
||||
getter_AddRefs(isurf));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
gl->fTexImage2D(target, level, LOCAL_GL_RGBA, isurf->Width(), isurf->Height(), 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, isurf->Data());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif /* XXX todo */
|
||||
|
||||
GL_SAME_METHOD_2(Uniform1i, Uniform1i, GLint, GLint)
|
||||
GL_SAME_METHOD_3(Uniform2i, Uniform2i, GLint, GLint, GLint)
|
||||
GL_SAME_METHOD_4(Uniform3i, Uniform3i, GLint, GLint, GLint, GLint)
|
||||
|
@ -2946,142 +2898,196 @@ WebGLContext::ValidateGL()
|
|||
NS_IMETHODIMP
|
||||
WebGLContext::TexSubImage2D()
|
||||
{
|
||||
// XXX TODO
|
||||
return NS_ERROR_FAILURE;
|
||||
// void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset,
|
||||
// in GLsizei width, in GLsizei height,
|
||||
// in GLenum format, in GLenum type, in CanvasArray pixels)
|
||||
// void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset,
|
||||
// in ImageData pixels,
|
||||
// [Optional] GLboolean flipY, [Optional] in asPremultipliedAlpha)
|
||||
// void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset,
|
||||
// in HTMLImageElement image,
|
||||
// [Optional] GLboolean flipY, [Optional] in asPremultipliedAlpha)
|
||||
// void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset,
|
||||
// in HTMLCanvasElement image,
|
||||
// [Optional] GLboolean flipY, [Optional] in asPremultipliedAlpha)
|
||||
// void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset,
|
||||
// in HTMLVideoElement image,
|
||||
// [Optional] GLboolean flipY, [Optional] in asPremultipliedAlpha)
|
||||
|
||||
#if 0
|
||||
// XXX TODO
|
||||
NativeJSContext js;
|
||||
if (NS_FAILED(js.error))
|
||||
return js.error;
|
||||
|
||||
if (js.argc != 9) {
|
||||
return ErrorMessage("texSubImage2D: expected 9 arguments");
|
||||
if (js.argc < 5 || js.argc > 9) {
|
||||
return ErrorMessage("texSubImage2D: expected 5 to 9 arguments");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
jsuint argTarget, argLevel, argX, argY, argWidth, argHeight, argFormat, argType;
|
||||
JSObject *argPixelsObj;
|
||||
jsuint argPixelsLen;
|
||||
if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uuuuuuuuo",
|
||||
&argTarget, &argLevel, &argX, &argY,
|
||||
&argWidth, &argHeight, &argFormat, &argType,
|
||||
&argPixelsObj) ||
|
||||
!argPixelsObj ||
|
||||
!::JS_IsArrayObject(js.ctx, argPixelsObj) ||
|
||||
!::JS_GetArrayLength(js.ctx, argPixelsObj, &argPixelsLen))
|
||||
{
|
||||
return ErrorMessage("texSubImage2D: argument error");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
if (js.argc < 8) {
|
||||
jsuint argTarget, argLevel, argX, argY;
|
||||
JSObject *argPixelsObj;
|
||||
JSBool flipY = JS_FALSE;
|
||||
JSBool premultiplyAlpha = JS_TRUE;
|
||||
|
||||
switch (argTarget) {
|
||||
case LOCAL_GL_TEXTURE_2D:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
break;
|
||||
default:
|
||||
return ErrorMessage("texSubImage2D: unsupported target");
|
||||
if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uuuuo/bb",
|
||||
&argTarget, &argLevel, &argX, &argY,
|
||||
&argPixelsObj, &flipY, &premultiplyAlpha) ||
|
||||
!argPixelsObj)
|
||||
{
|
||||
return ErrorMessage("texSubImage2D: argument error");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
nsCOMPtr<nsIDOMHTMLElement> imgElt;
|
||||
nsresult rv;
|
||||
rv = nsContentUtils::XPConnect()->WrapJS(js.ctx, argPixelsObj, NS_GET_IID(nsIDOMHTMLElement), getter_AddRefs(imgElt));
|
||||
|
||||
nsRefPtr<gfxImageSurface> isurf;
|
||||
|
||||
rv = TexImageElementBase(imgElt, getter_AddRefs(isurf), flipY, premultiplyAlpha);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return ErrorMessage("texImage2D: failed to get image for element");
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
gl->fTexSubImage2D (argTarget, argLevel, argX, argY, isurf->Width(), isurf->Height(), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, isurf->Data());
|
||||
} else {
|
||||
jsuint argTarget, argLevel, argX, argY, argWidth, argHeight, argFormat, argType;
|
||||
JSObject *argPixelsObj;
|
||||
jsuint argPixelsLen;
|
||||
if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uuuuuuuuo",
|
||||
&argTarget, &argLevel, &argX, &argY,
|
||||
&argWidth, &argHeight, &argFormat, &argType,
|
||||
&argPixelsObj) ||
|
||||
!argPixelsObj ||
|
||||
!::JS_IsArrayObject(js.ctx, argPixelsObj) ||
|
||||
!::JS_GetArrayLength(js.ctx, argPixelsObj, &argPixelsLen))
|
||||
{
|
||||
return ErrorMessage("texSubImage2D: argument error");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
switch (argTarget) {
|
||||
case LOCAL_GL_TEXTURE_2D:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
break;
|
||||
default:
|
||||
return ErrorMessage("texSubImage2D: unsupported target");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
PRUint32 bufferType, bufferSize;
|
||||
switch (argFormat) {
|
||||
case LOCAL_GL_RED:
|
||||
case LOCAL_GL_GREEN:
|
||||
case LOCAL_GL_BLUE:
|
||||
case LOCAL_GL_ALPHA:
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
bufferSize = 1;
|
||||
break;
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
bufferSize = 2;
|
||||
break;
|
||||
case LOCAL_GL_RGB:
|
||||
bufferSize = 3;
|
||||
break;
|
||||
case LOCAL_GL_RGBA:
|
||||
bufferSize = 4;
|
||||
break;
|
||||
default:
|
||||
return ErrorMessage("texSubImage2D: pixel format not supported");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
switch (argType) {
|
||||
case LOCAL_GL_SHORT:
|
||||
case LOCAL_GL_UNSIGNED_SHORT:
|
||||
case LOCAL_GL_BYTE:
|
||||
case LOCAL_GL_UNSIGNED_BYTE:
|
||||
case LOCAL_GL_INT:
|
||||
case LOCAL_GL_UNSIGNED_INT:
|
||||
case LOCAL_GL_FLOAT:
|
||||
bufferType = argType;
|
||||
break;
|
||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
|
||||
bufferType = LOCAL_GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
default:
|
||||
return ErrorMessage("texSubImage2D: pixel packing not supported");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
// make sure the size is valid
|
||||
PRInt32 tmp = argWidth * argHeight;
|
||||
if (tmp && tmp / argHeight != argWidth) {
|
||||
return ErrorMessage("texSubImage2D: too large width or height");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32 bufferType, bufferSize;
|
||||
switch (argFormat) {
|
||||
case LOCAL_GL_RED:
|
||||
case LOCAL_GL_GREEN:
|
||||
case LOCAL_GL_BLUE:
|
||||
case LOCAL_GL_ALPHA:
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
bufferSize = 1;
|
||||
break;
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
bufferSize = 2;
|
||||
break;
|
||||
case LOCAL_GL_RGB:
|
||||
bufferSize = 3;
|
||||
break;
|
||||
case LOCAL_GL_RGBA:
|
||||
bufferSize = 4;
|
||||
break;
|
||||
default:
|
||||
return ErrorMessage("texSubImage2D: pixel format not supported");
|
||||
tmp = tmp * bufferSize;
|
||||
if (tmp && tmp / bufferSize != (argWidth * argHeight)) {
|
||||
return ErrorMessage("texSubImage2D: too large width or height (after multiplying with pixel size)");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
switch (argType) {
|
||||
case LOCAL_GL_SHORT:
|
||||
case LOCAL_GL_UNSIGNED_SHORT:
|
||||
case LOCAL_GL_BYTE:
|
||||
case LOCAL_GL_UNSIGNED_BYTE:
|
||||
case LOCAL_GL_INT:
|
||||
case LOCAL_GL_UNSIGNED_INT:
|
||||
case LOCAL_GL_FLOAT:
|
||||
bufferType = argType;
|
||||
break;
|
||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
|
||||
bufferType = LOCAL_GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
default:
|
||||
return ErrorMessage("texSubImage2D: pixel packing not supported");
|
||||
if ((PRUint32) tmp > argPixelsLen) {
|
||||
return ErrorMessage("texSubImage2D: array dimensions too small for width, height and pixel format");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
SimpleBuffer sbuffer(bufferType, bufferSize, js.ctx, argPixelsObj, argPixelsLen);
|
||||
if (!sbuffer.Valid())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fTexSubImage2D (argTarget, argLevel, argX, argY, argWidth, argHeight, argFormat, argType, (void *) sbuffer.data);
|
||||
}
|
||||
|
||||
// make sure the size is valid
|
||||
PRInt32 tmp = argWidth * argHeight;
|
||||
if (tmp && tmp / argHeight != argWidth) {
|
||||
return ErrorMessage("texSubImage2D: too large width or height");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
tmp = tmp * bufferSize;
|
||||
if (tmp && tmp / bufferSize != (argWidth * argHeight)) {
|
||||
return ErrorMessage("texSubImage2D: too large width or height (after multiplying with pixel size)");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
if ((PRUint32) tmp > argPixelsLen) {
|
||||
return ErrorMessage("texSubImage2D: array dimensions too small for width, height and pixel format");
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
SimpleBuffer sbuffer(bufferType, bufferSize, js.ctx, argPixelsObj, argPixelsLen);
|
||||
if (!sbuffer.Valid())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fTexSubImage2D (argTarget, argLevel, argX, argY, argWidth, argHeight, argFormat, argType, (void *) sbuffer.data);
|
||||
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::TexImage2D()
|
||||
{
|
||||
//return NS_ERROR_FAILURE;
|
||||
// void texImage2D(in GLenum target, in GLint level, in GLenum internalformat,
|
||||
// in GLsizei width, in GLsizei height, in GLint border, in GLenum format,
|
||||
// in GLenum type, in CanvasArray pixels)
|
||||
// void texImage2D(in GLenum target, in GLint level, in ImageData pixels,
|
||||
// [Optional] GLboolean flipY, [Optional] in asPremultipliedAlpha)
|
||||
// void texImage2D(in GLenum target, in GLint level, in HTMLImageElement image,
|
||||
// [Optional] GLboolean flipY, [Optional] in asPremultipliedAlpha)
|
||||
// void texImage2D(in GLenum target, in GLint level, in HTMLCanvasElement image,
|
||||
// [Optional] GLboolean flipY, [Optional] in asPremultipliedAlpha)
|
||||
// void texImage2D(in GLenum target, in GLint level, in HTMLVideoElement image,
|
||||
// [Optional] GLboolean flipY, [Optional] in asPremultipliedAlpha)
|
||||
|
||||
// XXX TODO
|
||||
//#if 0
|
||||
NativeJSContext js;
|
||||
if (NS_FAILED(js.error))
|
||||
return js.error;
|
||||
|
||||
if (js.argc != 3 && js.argc != 9) {
|
||||
return ErrorMessage("texImage2D: expected 3 or 9 arguments");
|
||||
if (js.argc < 3 || js.argc > 9) {
|
||||
return ErrorMessage("texImage2D: expected 3-5 or 9 arguments, got %d", js.argc);
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
jsuint argTarget, argLevel, argInternalFormat, argWidth, argHeight, argBorder, argFormat, argType;
|
||||
|
||||
if (js.argc == 3) {
|
||||
if (js.argc > 2 && js.argc < 6) {
|
||||
JSObject *argPixelsObj;
|
||||
if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uuo",
|
||||
JSBool flipY = JS_FALSE;
|
||||
JSBool premultiplyAlpha = JS_TRUE;
|
||||
|
||||
if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uuo/bb",
|
||||
&argTarget, &argLevel,
|
||||
&argPixelsObj) ||
|
||||
&argPixelsObj, &flipY, &premultiplyAlpha) ||
|
||||
!argPixelsObj)
|
||||
{
|
||||
return ErrorMessage("texImage2D: argument error");
|
||||
|
@ -3093,7 +3099,7 @@ WebGLContext::TexImage2D()
|
|||
|
||||
nsRefPtr<gfxImageSurface> isurf;
|
||||
|
||||
rv = TexImageElementBase(imgElt, getter_AddRefs(isurf));
|
||||
rv = TexImageElementBase(imgElt, getter_AddRefs(isurf), flipY, premultiplyAlpha);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return ErrorMessage("texImage2D: failed to get image for element");
|
||||
|
@ -3226,7 +3232,6 @@ WebGLContext::TexImage2D()
|
|||
MakeContextCurrent();
|
||||
gl->fTexImage2D (argTarget, argLevel, argInternalFormat, argWidth, argHeight, argBorder, argFormat, argType, (void *) sbuffer.data);
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче