mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 697560 - Generate WebGL errors in readPixels according to spec - r=bjacob
* * * Bug 697560 - Disallow conformance failures on read-pixels-test - r=bjacob
This commit is contained in:
parent
4ce6514d96
commit
5b4030b08d
@ -580,7 +580,7 @@ protected:
|
|||||||
int jsArrayType,
|
int jsArrayType,
|
||||||
int srcFormat, bool srcPremultiplied);
|
int srcFormat, bool srcPremultiplied);
|
||||||
nsresult ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height,
|
nsresult ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height,
|
||||||
WebGLenum format, WebGLenum type, void *data, PRUint32 byteLength);
|
WebGLenum format, WebGLenum type, JSObject* pixels);
|
||||||
nsresult TexParameter_base(WebGLenum target, WebGLenum pname,
|
nsresult TexParameter_base(WebGLenum target, WebGLenum pname,
|
||||||
WebGLint *intParamPtr, WebGLfloat *floatParamPtr);
|
WebGLint *intParamPtr, WebGLfloat *floatParamPtr);
|
||||||
|
|
||||||
|
@ -3340,7 +3340,7 @@ WebGLContext::ReadPixels(PRInt32)
|
|||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height,
|
WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height,
|
||||||
WebGLenum format, WebGLenum type, void *data, PRUint32 byteLength)
|
WebGLenum format, WebGLenum type, JSObject* pixels)
|
||||||
{
|
{
|
||||||
if (HTMLCanvasElement()->IsWriteOnly() && !nsContentUtils::IsCallerTrustedForRead()) {
|
if (HTMLCanvasElement()->IsWriteOnly() && !nsContentUtils::IsCallerTrustedForRead()) {
|
||||||
LogMessageIfVerbose("ReadPixels: Not allowed");
|
LogMessageIfVerbose("ReadPixels: Not allowed");
|
||||||
@ -3350,43 +3350,61 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||||||
if (width < 0 || height < 0)
|
if (width < 0 || height < 0)
|
||||||
return ErrorInvalidValue("ReadPixels: negative size passed");
|
return ErrorInvalidValue("ReadPixels: negative size passed");
|
||||||
|
|
||||||
// there's nothing to do in this case, since we won't read any pixels
|
if (!pixels)
|
||||||
if (width == 0 || height == 0)
|
return ErrorInvalidValue("ReadPixels: null array passed");
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
WebGLsizei boundWidth = mBoundFramebuffer ? mBoundFramebuffer->width() : mWidth;
|
WebGLsizei boundWidth = mBoundFramebuffer ? mBoundFramebuffer->width() : mWidth;
|
||||||
WebGLsizei boundHeight = mBoundFramebuffer ? mBoundFramebuffer->height() : mHeight;
|
WebGLsizei boundHeight = mBoundFramebuffer ? mBoundFramebuffer->height() : mHeight;
|
||||||
|
|
||||||
PRUint32 size = 0;
|
void* data = JS_GetTypedArrayData(pixels);
|
||||||
bool badFormat = false, badType = false;
|
PRUint32 dataByteLen = JS_GetTypedArrayByteLength(pixels);
|
||||||
|
int dataType = JS_GetTypedArrayType(pixels);
|
||||||
|
|
||||||
|
PRUint32 channels = 0;
|
||||||
|
|
||||||
|
// Check the format param
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case LOCAL_GL_RGBA:
|
case LOCAL_GL_ALPHA:
|
||||||
size = 4;
|
channels = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
case LOCAL_GL_RGB:
|
||||||
badFormat = true;
|
channels = 3;
|
||||||
break;
|
break;
|
||||||
|
case LOCAL_GL_RGBA:
|
||||||
|
channels = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ErrorInvalidEnum("readPixels: Bad format");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRUint32 bytesPerPixel = 0;
|
||||||
|
int requiredDataType = 0;
|
||||||
|
|
||||||
|
// Check the type param
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case LOCAL_GL_UNSIGNED_BYTE:
|
case LOCAL_GL_UNSIGNED_BYTE:
|
||||||
break;
|
bytesPerPixel = 1 * channels;
|
||||||
default:
|
requiredDataType = js::TypedArray::TYPE_UINT8;
|
||||||
badType = true;
|
break;
|
||||||
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:
|
||||||
|
bytesPerPixel = 2;
|
||||||
|
requiredDataType = js::TypedArray::TYPE_UINT16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ErrorInvalidEnum("readPixels: Bad type");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (badFormat && badType)
|
// Check the pixels param type
|
||||||
return ErrorInvalidOperation("readPixels: bad format and type");
|
if (dataType != requiredDataType)
|
||||||
if (badFormat)
|
return ErrorInvalidOperation("readPixels: Mismatched type/pixels types");
|
||||||
return ErrorInvalidEnumInfo("readPixels: format", format);
|
|
||||||
if (badType)
|
|
||||||
return ErrorInvalidEnumInfo("ReadPixels: type", type);
|
|
||||||
|
|
||||||
|
// Check the pixels param size
|
||||||
CheckedUint32 checked_neededByteLength =
|
CheckedUint32 checked_neededByteLength =
|
||||||
GetImageSize(height, width, size, mPixelStorePackAlignment);
|
GetImageSize(height, width, bytesPerPixel, mPixelStorePackAlignment);
|
||||||
|
|
||||||
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * size;
|
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * bytesPerPixel;
|
||||||
|
|
||||||
CheckedUint32 checked_alignedRowSize =
|
CheckedUint32 checked_alignedRowSize =
|
||||||
RoundedToNextMultipleOf(checked_plainRowSize, mPixelStorePackAlignment);
|
RoundedToNextMultipleOf(checked_plainRowSize, mPixelStorePackAlignment);
|
||||||
@ -3394,9 +3412,28 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||||||
if (!checked_neededByteLength.valid())
|
if (!checked_neededByteLength.valid())
|
||||||
return ErrorInvalidOperation("ReadPixels: integer overflow computing the needed buffer size");
|
return ErrorInvalidOperation("ReadPixels: integer overflow computing the needed buffer size");
|
||||||
|
|
||||||
if (checked_neededByteLength.value() > byteLength)
|
if (checked_neededByteLength.value() > dataByteLen)
|
||||||
return ErrorInvalidOperation("ReadPixels: buffer too small");
|
return ErrorInvalidOperation("ReadPixels: buffer too small");
|
||||||
|
|
||||||
|
// Check the format and type params to assure they are an acceptable pair (as per spec)
|
||||||
|
switch (format) {
|
||||||
|
case LOCAL_GL_RGBA: {
|
||||||
|
switch (type) {
|
||||||
|
case LOCAL_GL_UNSIGNED_BYTE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ErrorInvalidOperation("readPixels: Invalid format/type pair");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return ErrorInvalidOperation("readPixels: Invalid format/type pair");
|
||||||
|
}
|
||||||
|
|
||||||
|
// there's nothing to do in this case, since we won't read any pixels
|
||||||
|
if (width == 0 || height == 0)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
MakeContextCurrent();
|
MakeContextCurrent();
|
||||||
|
|
||||||
if (mBoundFramebuffer) {
|
if (mBoundFramebuffer) {
|
||||||
@ -3407,7 +3444,6 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||||||
EnsureBackbufferClearedAsNeeded();
|
EnsureBackbufferClearedAsNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, boundWidth, boundHeight)) {
|
if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, boundWidth, boundHeight)) {
|
||||||
// the easy case: we're not reading out-of-range pixels
|
// the easy case: we're not reading out-of-range pixels
|
||||||
gl->fReadPixels(x, y, width, height, format, type, data);
|
gl->fReadPixels(x, y, width, height, format, type, data);
|
||||||
@ -3421,7 +3457,7 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||||||
|
|
||||||
// zero the whole destination buffer. Too bad for the part that's going to be overwritten, we're not
|
// zero the whole destination buffer. Too bad for the part that's going to be overwritten, we're not
|
||||||
// 100% efficient here, but in practice this is a quite rare case anyway.
|
// 100% efficient here, but in practice this is a quite rare case anyway.
|
||||||
memset(data, 0, byteLength);
|
memset(data, 0, dataByteLen);
|
||||||
|
|
||||||
if ( x >= boundWidth
|
if ( x >= boundWidth
|
||||||
|| x+width <= 0
|
|| x+width <= 0
|
||||||
@ -3449,7 +3485,7 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||||||
|
|
||||||
// now, same computation as above to find the size of the intermediate buffer to allocate for the subrect
|
// now, same computation as above to find the size of the intermediate buffer to allocate for the subrect
|
||||||
// no need to check again for integer overflow here, since we already know the sizes aren't greater than before
|
// no need to check again for integer overflow here, since we already know the sizes aren't greater than before
|
||||||
PRUint32 subrect_plainRowSize = subrect_width * size;
|
PRUint32 subrect_plainRowSize = subrect_width * bytesPerPixel;
|
||||||
// There are checks above to ensure that this doesn't overflow.
|
// There are checks above to ensure that this doesn't overflow.
|
||||||
PRUint32 subrect_alignedRowSize =
|
PRUint32 subrect_alignedRowSize =
|
||||||
RoundedToNextMultipleOf(subrect_plainRowSize, mPixelStorePackAlignment).value();
|
RoundedToNextMultipleOf(subrect_plainRowSize, mPixelStorePackAlignment).value();
|
||||||
@ -3465,7 +3501,7 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||||||
GLint subrect_y_in_dest_buffer = subrect_y - y;
|
GLint subrect_y_in_dest_buffer = subrect_y - y;
|
||||||
memcpy(static_cast<GLubyte*>(data)
|
memcpy(static_cast<GLubyte*>(data)
|
||||||
+ checked_alignedRowSize.value() * (subrect_y_in_dest_buffer + y_inside_subrect)
|
+ checked_alignedRowSize.value() * (subrect_y_in_dest_buffer + y_inside_subrect)
|
||||||
+ size * subrect_x_in_dest_buffer, // destination
|
+ bytesPerPixel * subrect_x_in_dest_buffer, // destination
|
||||||
subrect_data + subrect_alignedRowSize * y_inside_subrect, // source
|
subrect_data + subrect_alignedRowSize * y_inside_subrect, // source
|
||||||
subrect_plainRowSize); // size
|
subrect_plainRowSize); // size
|
||||||
}
|
}
|
||||||
@ -3527,9 +3563,7 @@ WebGLContext::ReadPixels_array(WebGLint x, WebGLint y, WebGLsizei width, WebGLsi
|
|||||||
if (mContextLost)
|
if (mContextLost)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
return ReadPixels_base(x, y, width, height, format, type,
|
return ReadPixels_base(x, y, width, height, format, type, pixels);
|
||||||
pixels ? JS_GetTypedArrayData(pixels) : 0,
|
|
||||||
pixels ? JS_GetTypedArrayByteLength(pixels) : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -4,7 +4,6 @@ conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
|||||||
conformance/glsl/misc/shader-with-long-line.html
|
conformance/glsl/misc/shader-with-long-line.html
|
||||||
conformance/misc/uninitialized-test.html
|
conformance/misc/uninitialized-test.html
|
||||||
conformance/programs/gl-get-active-attribute.html
|
conformance/programs/gl-get-active-attribute.html
|
||||||
conformance/reading/read-pixels-test.html
|
|
||||||
conformance/renderbuffers/framebuffer-object-attachment.html
|
conformance/renderbuffers/framebuffer-object-attachment.html
|
||||||
conformance/textures/texture-mips.html
|
conformance/textures/texture-mips.html
|
||||||
conformance/uniforms/gl-uniform-bool.html
|
conformance/uniforms/gl-uniform-bool.html
|
||||||
|
@ -5,7 +5,6 @@ conformance/glsl/misc/glsl-long-variable-names.html
|
|||||||
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
||||||
conformance/glsl/misc/shader-with-long-line.html
|
conformance/glsl/misc/shader-with-long-line.html
|
||||||
conformance/programs/program-test.html
|
conformance/programs/program-test.html
|
||||||
conformance/reading/read-pixels-test.html
|
|
||||||
conformance/renderbuffers/framebuffer-object-attachment.html
|
conformance/renderbuffers/framebuffer-object-attachment.html
|
||||||
conformance/state/gl-object-get-calls.html
|
conformance/state/gl-object-get-calls.html
|
||||||
conformance/textures/tex-input-validation.html
|
conformance/textures/tex-input-validation.html
|
||||||
|
@ -5,7 +5,6 @@ conformance/glsl/functions/glsl-function-mod-gentype.html
|
|||||||
conformance/glsl/misc/glsl-long-variable-names.html
|
conformance/glsl/misc/glsl-long-variable-names.html
|
||||||
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
||||||
conformance/glsl/misc/shader-with-long-line.html
|
conformance/glsl/misc/shader-with-long-line.html
|
||||||
conformance/reading/read-pixels-test.html
|
|
||||||
conformance/renderbuffers/framebuffer-object-attachment.html
|
conformance/renderbuffers/framebuffer-object-attachment.html
|
||||||
conformance/more/conformance/quickCheckAPI-S_V.html
|
conformance/more/conformance/quickCheckAPI-S_V.html
|
||||||
conformance/more/functions/copyTexImage2D.html
|
conformance/more/functions/copyTexImage2D.html
|
||||||
|
Loading…
Reference in New Issue
Block a user