mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
WebGL2: Support non-power-of-two textures. (bug 1080921, r=jgilbert).
--HG-- extra : rebase_source : 6d948f27ec14cea54211f62dc0dc813419eb5151
This commit is contained in:
parent
f15da1a3dd
commit
e290f953ea
@ -292,7 +292,7 @@ WebGL2Context::TexSubImage3D(GLenum rawTarget, GLint level,
|
||||
if (coversWholeImage) {
|
||||
tex->SetImageDataStatus(texImageTarget, level, WebGLImageDataStatus::InitializedImageData);
|
||||
} else {
|
||||
tex->DoDeferredImageInitialization(texImageTarget, level);
|
||||
tex->EnsureNoUninitializedImageData(texImageTarget, level);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,7 +453,7 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||
tex->SetImageInfo(texImageTarget, level, width, height, 1,
|
||||
effectiveInternalFormat,
|
||||
WebGLImageDataStatus::UninitializedImageData);
|
||||
tex->DoDeferredImageInitialization(texImageTarget, level);
|
||||
tex->EnsureNoUninitializedImageData(texImageTarget, level);
|
||||
}
|
||||
|
||||
// if we are completely outside of the framebuffer, we can exit now with our black texture
|
||||
@ -601,7 +601,7 @@ WebGLContext::CopyTexSubImage2D(GLenum rawTexImgTarget,
|
||||
if (coversWholeImage) {
|
||||
tex->SetImageDataStatus(texImageTarget, level, WebGLImageDataStatus::InitializedImageData);
|
||||
} else {
|
||||
tex->DoDeferredImageInitialization(texImageTarget, level);
|
||||
tex->EnsureNoUninitializedImageData(texImageTarget, level);
|
||||
}
|
||||
}
|
||||
|
||||
@ -927,7 +927,7 @@ WebGLContext::GenerateMipmap(GLenum rawTarget)
|
||||
return ErrorInvalidOperation("generateMipmap: Level zero of texture is not defined.");
|
||||
}
|
||||
|
||||
if (!tex->IsFirstImagePowerOfTwo())
|
||||
if (!IsWebGL2() && !tex->IsFirstImagePowerOfTwo())
|
||||
return ErrorInvalidOperation("generateMipmap: Level zero of texture does not have power-of-two width and height.");
|
||||
|
||||
TexInternalFormat internalformat = tex->ImageInfoAt(imageTarget, 0).EffectiveInternalFormat();
|
||||
@ -3436,7 +3436,7 @@ WebGLContext::CompressedTexSubImage2D(GLenum rawTexImgTarget, GLint level, GLint
|
||||
if (coversWholeImage) {
|
||||
tex->SetImageDataStatus(texImageTarget, level, WebGLImageDataStatus::InitializedImageData);
|
||||
} else {
|
||||
tex->DoDeferredImageInitialization(texImageTarget, level);
|
||||
tex->EnsureNoUninitializedImageData(texImageTarget, level);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3972,7 +3972,7 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
if (coversWholeImage) {
|
||||
tex->SetImageDataStatus(texImageTarget, level, WebGLImageDataStatus::InitializedImageData);
|
||||
} else {
|
||||
tex->DoDeferredImageInitialization(texImageTarget, level);
|
||||
tex->EnsureNoUninitializedImageData(texImageTarget, level);
|
||||
}
|
||||
}
|
||||
MakeContextCurrent();
|
||||
|
@ -816,8 +816,10 @@ WebGLContext::ValidateTexImageSize(TexImageTarget texImageTarget, GLint level,
|
||||
* "If level is greater than zero, and either width or
|
||||
* height is not a power-of-two, the error INVALID_VALUE is
|
||||
* generated."
|
||||
*
|
||||
* This restriction does not apply to GL ES Version 3.0+.
|
||||
*/
|
||||
if (level > 0) {
|
||||
if (!IsWebGL2() && level > 0) {
|
||||
if (!is_pot_assuming_nonnegative(width)) {
|
||||
ErrorInvalidValue("%s: level >= 0, width of %d must be a power of two.",
|
||||
InfoFrom(func, dims), width);
|
||||
@ -839,7 +841,7 @@ WebGLContext::ValidateTexImageSize(TexImageTarget texImageTarget, GLint level,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (depth > 0 && !is_pot_assuming_nonnegative(depth)) {
|
||||
if (!IsWebGL2() && !is_pot_assuming_nonnegative(depth)) {
|
||||
ErrorInvalidValue("%s: level >= 0, depth of %d must be a power of two.",
|
||||
InfoFrom(func, dims), depth);
|
||||
return false;
|
||||
|
@ -186,11 +186,12 @@ WebGLTexture::SetCustomMipmap() {
|
||||
// since we were in GeneratedMipmap mode, we know that the level 0 images all have the same info,
|
||||
// and are power-of-two.
|
||||
ImageInfo imageInfo = ImageInfoAtFace(0, 0);
|
||||
NS_ASSERTION(imageInfo.IsPowerOfTwo(), "this texture is NPOT, so how could GenerateMipmap() ever accept it?");
|
||||
NS_ASSERTION(mContext->IsWebGL2() || imageInfo.IsPowerOfTwo(),
|
||||
"this texture is NPOT, so how could GenerateMipmap() ever accept it?");
|
||||
|
||||
GLsizei size = std::max(std::max(imageInfo.mWidth, imageInfo.mHeight), imageInfo.mDepth);
|
||||
|
||||
// so, the size is a power of two, let's find its log in base 2.
|
||||
// Find floor(log2(size)). (ES 3.0.4, 3.8 - Mipmapping).
|
||||
size_t maxLevel = 0;
|
||||
for (GLsizei n = size; n > 1; n >>= 1)
|
||||
++maxLevel;
|
||||
@ -198,7 +199,6 @@ WebGLTexture::SetCustomMipmap() {
|
||||
EnsureMaxLevelWithCustomImagesAtLeast(maxLevel);
|
||||
|
||||
for (size_t level = 1; level <= maxLevel; ++level) {
|
||||
// again, since the sizes are powers of two, no need for any max(1,x) computation
|
||||
imageInfo.mWidth = std::max(imageInfo.mWidth / 2, 1);
|
||||
imageInfo.mHeight = std::max(imageInfo.mHeight / 2, 1);
|
||||
imageInfo.mDepth = std::max(imageInfo.mDepth / 2, 1);
|
||||
@ -285,7 +285,7 @@ WebGLTexture::ResolvedFakeBlackStatus() {
|
||||
("%s is a %dD texture, with a minification filter requiring a mipmap, "
|
||||
"and is not mipmap complete (as defined in section 3.7.10).", msg_rendering_as_black, dim);
|
||||
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
|
||||
} else if (!ImageInfoBase().IsPowerOfTwo()) {
|
||||
} else if (!mContext->IsWebGL2() && !ImageInfoBase().IsPowerOfTwo()) {
|
||||
mContext->GenerateWarning
|
||||
("%s is a %dD texture, with a minification filter requiring a mipmap, "
|
||||
"and either its width or height is not a power of two.", msg_rendering_as_black);
|
||||
@ -299,7 +299,7 @@ WebGLTexture::ResolvedFakeBlackStatus() {
|
||||
("%s is a %dD texture and its width or height is equal to zero.",
|
||||
msg_rendering_as_black, dim);
|
||||
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
|
||||
} else if (!AreBothWrapModesClampToEdge() && !ImageInfoBase().IsPowerOfTwo()) {
|
||||
} else if (!AreBothWrapModesClampToEdge() && !mContext->IsWebGL2() && !ImageInfoBase().IsPowerOfTwo()) {
|
||||
mContext->GenerateWarning
|
||||
("%s is a %dD texture, with a minification filter not requiring a mipmap, "
|
||||
"with its width or height not a power of two, and with a wrap mode "
|
||||
@ -310,9 +310,11 @@ WebGLTexture::ResolvedFakeBlackStatus() {
|
||||
}
|
||||
else // cube map
|
||||
{
|
||||
bool areAllLevel0ImagesPOT = true;
|
||||
for (size_t face = 0; face < mFacesCount; ++face)
|
||||
areAllLevel0ImagesPOT &= ImageInfoAtFace(face, 0).IsPowerOfTwo();
|
||||
bool legalImageSize = true;
|
||||
if (!mContext->IsWebGL2()) {
|
||||
for (size_t face = 0; face < mFacesCount; ++face)
|
||||
legalImageSize &= ImageInfoAtFace(face, 0).IsPowerOfTwo();
|
||||
}
|
||||
|
||||
if (DoesMinFilterRequireMipmap())
|
||||
{
|
||||
@ -321,7 +323,7 @@ WebGLTexture::ResolvedFakeBlackStatus() {
|
||||
"and is not mipmap cube complete (as defined in section 3.7.10).",
|
||||
msg_rendering_as_black);
|
||||
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
|
||||
} else if (!areAllLevel0ImagesPOT) {
|
||||
} else if (!legalImageSize) {
|
||||
mContext->GenerateWarning("%s is a cube map texture, with a minification filter requiring a mipmap, "
|
||||
"and either the width or the height of some level 0 image is not a power of two.",
|
||||
msg_rendering_as_black);
|
||||
@ -335,7 +337,7 @@ WebGLTexture::ResolvedFakeBlackStatus() {
|
||||
"and is not cube complete (as defined in section 3.7.10).",
|
||||
msg_rendering_as_black);
|
||||
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
|
||||
} else if (!AreBothWrapModesClampToEdge() && !areAllLevel0ImagesPOT) {
|
||||
} else if (!AreBothWrapModesClampToEdge() && !legalImageSize) {
|
||||
mContext->GenerateWarning("%s is a cube map texture, with a minification filter not requiring a mipmap, "
|
||||
"with some level 0 image having width or height not a power of two, and with a wrap mode "
|
||||
"different from CLAMP_TO_EDGE.", msg_rendering_as_black);
|
||||
@ -422,7 +424,7 @@ WebGLTexture::ResolvedFakeBlackStatus() {
|
||||
TexImageTarget imageTarget = TexImageTargetForTargetAndFace(mTarget, face);
|
||||
const ImageInfo& imageInfo = ImageInfoAt(imageTarget, level);
|
||||
if (imageInfo.mImageDataStatus == WebGLImageDataStatus::UninitializedImageData) {
|
||||
DoDeferredImageInitialization(imageTarget, level);
|
||||
EnsureNoUninitializedImageData(imageTarget, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -542,10 +544,11 @@ ClearWithTempFB(WebGLContext* context, GLuint tex,
|
||||
|
||||
|
||||
void
|
||||
WebGLTexture::DoDeferredImageInitialization(TexImageTarget imageTarget, GLint level)
|
||||
WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget, GLint level)
|
||||
{
|
||||
const ImageInfo& imageInfo = ImageInfoAt(imageTarget, level);
|
||||
MOZ_ASSERT(imageInfo.mImageDataStatus == WebGLImageDataStatus::UninitializedImageData);
|
||||
if (!imageInfo.HasUninitializedImageData())
|
||||
return;
|
||||
|
||||
mContext->MakeContextCurrent();
|
||||
|
||||
|
@ -199,7 +199,7 @@ public:
|
||||
imageInfo.mImageDataStatus = newStatus;
|
||||
}
|
||||
|
||||
void DoDeferredImageInitialization(TexImageTarget imageTarget, GLint level);
|
||||
void EnsureNoUninitializedImageData(TexImageTarget imageTarget, GLint level);
|
||||
|
||||
protected:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user