Bug 738126 - Enforce spec for webgl.generateMipmap, and zero is not PoT - r=bjacob

This commit is contained in:
Jeff Gilbert 2012-04-03 16:42:06 -07:00
parent 81c2476edd
commit 9c6c3991f0
3 changed files with 55 additions and 13 deletions

View File

@ -127,9 +127,10 @@ struct WebGLTexelPremultiplicationOp {
int GetWebGLTexelFormat(GLenum format, GLenum type);
// Zero is not an integer power of two.
inline bool is_pot_assuming_nonnegative(WebGLsizei x)
{
return (x & (x-1)) == 0;
return x && (x & (x-1)) == 0;
}
/* Each WebGL object class WebGLFoo wants to:
@ -585,6 +586,7 @@ public:
nsresult ErrorOutOfMemory(const char *fmt = 0, ...);
const char *ErrorName(GLenum error);
bool IsTextureFormatCompressed(GLenum format);
nsresult DummyFramebufferOperation(const char *info);
@ -1247,14 +1249,26 @@ public:
class ImageInfo : public WebGLRectangleObject {
public:
ImageInfo() : mFormat(0), mType(0), mIsDefined(false) {}
ImageInfo()
: mFormat(0)
, mType(0)
, mIsDefined(false)
{}
ImageInfo(WebGLsizei width, WebGLsizei height,
WebGLenum format, WebGLenum type)
: WebGLRectangleObject(width, height), mFormat(format), mType(type), mIsDefined(true) {}
: WebGLRectangleObject(width, height)
, mFormat(format)
, mType(type)
, mIsDefined(true)
{}
bool operator==(const ImageInfo& a) const {
return mWidth == a.mWidth && mHeight == a.mHeight &&
mFormat == a.mFormat && mType == a.mType;
return mIsDefined == a.mIsDefined &&
mWidth == a.mWidth &&
mHeight == a.mHeight &&
mFormat == a.mFormat &&
mType == a.mType;
}
bool operator!=(const ImageInfo& a) const {
return !(*this == a);

View File

@ -1911,15 +1911,20 @@ WebGLContext::GenerateMipmap(WebGLenum target)
WebGLTexture *tex = activeBoundTextureForTarget(target);
if (!tex)
return ErrorInvalidOperation("generateMipmap: no texture is bound to this target");
return ErrorInvalidOperation("generateMipmap: No texture is bound to this target.");
if (!tex->IsFirstImagePowerOfTwo()) {
return ErrorInvalidOperation("generateMipmap: the width or height of this texture is not a power of two");
}
if (!tex->HasImageInfoAt(0, 0))
return ErrorInvalidOperation("generateMipmap: Level zero of texture is not defined.");
if (!tex->AreAllLevel0ImageInfosEqual()) {
return ErrorInvalidOperation("generateMipmap: the six faces of this cube map have different dimensions, format, or type.");
}
if (!tex->IsFirstImagePowerOfTwo())
return ErrorInvalidOperation("generateMipmap: Level zero of texture does not have power-of-two width and height.");
GLenum format = tex->ImageInfoAt(0, 0).Format();
if (IsTextureFormatCompressed(format))
return ErrorInvalidOperation("generateMipmap: Texture data at level zero is compressed.");
if (!tex->AreAllLevel0ImageInfosEqual())
return ErrorInvalidOperation("generateMipmap: The six faces of this cube map have different dimensions, format, or type.");
tex->SetGeneratedMipmap();

View File

@ -239,4 +239,27 @@ WebGLContext::ErrorName(GLenum error)
NS_ABORT();
return "[unknown WebGL error!]";
}
};
}
bool
WebGLContext::IsTextureFormatCompressed(GLenum format)
{
switch(format) {
case LOCAL_GL_RGB:
case LOCAL_GL_RGBA:
case LOCAL_GL_ALPHA:
case LOCAL_GL_LUMINANCE:
case LOCAL_GL_LUMINANCE_ALPHA:
return false;
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
return true;
}
NS_NOTREACHED("Invalid WebGL texture format?");
NS_ABORT();
return false;
}