WebGL2 (Get)TexParam, and more TEX_2D_ARRAY. Also no 'required' format exts for WebGL2.
draft
WebGL2 (Get)TexParam, and more TEX_2D_ARRAY. Also no 'required' format exts for WebGL2.
--- a/dom/canvas/WebGL2Context.cpp
+++ b/dom/canvas/WebGL2Context.cpp
@@ -54,23 +54,19 @@ WebGL2Context::WrapObject(JSContext* cx,
////////////////////////////////////////////////////////////////////////////////
// WebGL 2 initialisation
// These WebGL 1 extensions are natively supported by WebGL 2.
static const WebGLExtensionID kNativelySupportedExtensions[] = {
WebGLExtensionID::ANGLE_instanced_arrays,
WebGLExtensionID::EXT_blend_minmax,
- WebGLExtensionID::EXT_sRGB,
WebGLExtensionID::OES_element_index_uint,
WebGLExtensionID::OES_standard_derivatives,
- WebGLExtensionID::OES_texture_float_linear,
- WebGLExtensionID::OES_texture_half_float_linear,
WebGLExtensionID::OES_vertex_array_object,
- WebGLExtensionID::WEBGL_depth_texture,
WebGLExtensionID::WEBGL_draw_buffers
};
static const gl::GLFeature kRequiredFeatures[] = {
gl::GLFeature::blend_minmax,
gl::GLFeature::clear_buffers,
gl::GLFeature::copy_buffer,
gl::GLFeature::depth_texture,
--- a/dom/canvas/WebGL2ContextTextures.cpp
+++ b/dom/canvas/WebGL2ContextTextures.cpp
@@ -227,17 +227,17 @@ WebGL2Context::CopyTexSubImage3D(GLenum
{
return;
}
tex->CopyTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, x, y, width,
height);
}
-bool
+/*virtual*/ bool
WebGL2Context::IsTexParamValid(GLenum pname) const
{
switch (pname) {
case LOCAL_GL_TEXTURE_BASE_LEVEL:
case LOCAL_GL_TEXTURE_COMPARE_FUNC:
case LOCAL_GL_TEXTURE_COMPARE_MODE:
case LOCAL_GL_TEXTURE_IMMUTABLE_FORMAT:
case LOCAL_GL_TEXTURE_IMMUTABLE_LEVELS:
--- a/dom/canvas/WebGLContextTextures.cpp
+++ b/dom/canvas/WebGLContextTextures.cpp
@@ -56,16 +56,17 @@ IsValidTexTarget(WebGLContext* webgl, GL
TexTarget* const out)
{
switch (rawTexTarget) {
case LOCAL_GL_TEXTURE_2D:
case LOCAL_GL_TEXTURE_CUBE_MAP:
break;
case LOCAL_GL_TEXTURE_3D:
+ case LOCAL_GL_TEXTURE_2D_ARRAY:
if (!webgl->IsWebGL2())
return false;
break;
default:
return false;
}
@@ -87,16 +88,17 @@ IsValidTexImageTarget(WebGLContext* webg
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:
targetDims = 2;
break;
case LOCAL_GL_TEXTURE_3D:
+ case LOCAL_GL_TEXTURE_2D_ARRAY:
if (!webgl->IsWebGL2())
return false;
targetDims = 3;
break;
default:
return false;
@@ -153,17 +155,17 @@ ValidateTexImageTarget(WebGLContext* web
return false;
}
*out_texImageTarget = texImageTarget;
*out_tex = tex;
return true;
}
-bool
+/*virtual*/ bool
WebGLContext::IsTexParamValid(GLenum pname) const
{
switch (pname) {
case LOCAL_GL_TEXTURE_MIN_FILTER:
case LOCAL_GL_TEXTURE_MAG_FILTER:
case LOCAL_GL_TEXTURE_WRAP_S:
case LOCAL_GL_TEXTURE_WRAP_T:
return true;
--- a/dom/canvas/WebGLTexture.cpp
+++ b/dom/canvas/WebGLTexture.cpp
@@ -395,17 +395,17 @@ WebGLTexture::IsComplete(const char** co
// CLAMP_TO_EDGE, or the minification filter is neither NEAREST nor LINEAR."
// "* A cube map sampler is called, any of the corresponding texture images are
// non-power-of-two images, and either the texture wrap mode is not
// CLAMP_TO_EDGE, or the minification filter is neither NEAREST nor LINEAR."
if (!baseImageInfo.IsPowerOfTwo()) {
// "either the texture wrap mode is not CLAMP_TO_EDGE"
if (mWrapS != LOCAL_GL_CLAMP_TO_EDGE ||
- mWrapS != LOCAL_GL_CLAMP_TO_EDGE)
+ mWrapT != LOCAL_GL_CLAMP_TO_EDGE)
{
*out_reason = "Non-power-of-two textures must have a wrap mode of"
" CLAMP_TO_EDGE.";
return false;
}
// "or the minification filter is neither NEAREST nor LINEAR"
if (requiresMipmap) {
@@ -634,24 +634,27 @@ WebGLTexture::BindTexture(TexTarget texT
mTarget = texTarget;
mContext->gl->fBindTexture(mTarget.get(), mGLName);
if (isFirstBinding) {
mFaceCount = IsCubeMap() ? 6 : 1;
+ gl::GLContext* gl = mContext->gl;
+
// Thanks to the WebKit people for finding this out: GL_TEXTURE_WRAP_R
// is not present in GLES 2, but is present in GL and it seems as if for
// cube maps we need to set it to GL_CLAMP_TO_EDGE to get the expected
// GLES behavior.
- if (IsCubeMap() && !mContext->gl->IsGLES()) {
- mContext->gl->fTexParameteri(texTarget.get(),
- LOCAL_GL_TEXTURE_WRAP_R,
- LOCAL_GL_CLAMP_TO_EDGE);
+ // If we are WebGL 2 though, we'll want to leave it as REPEAT.
+ const bool hasWrapR = gl->IsSupported(gl::GLFeature::texture_3D);
+ if (IsCubeMap() && hasWrapR && !mContext->IsWebGL2()) {
+ gl->fTexParameteri(texTarget.get(), LOCAL_GL_TEXTURE_WRAP_R,
+ LOCAL_GL_CLAMP_TO_EDGE);
}
}
if (mFakeBlackStatus != WebGLTextureFakeBlackStatus::NotNeeded) {
mContext->InvalidateFakeBlackCache();
}
return true;
@@ -730,27 +733,30 @@ WebGLTexture::GetTexParameter(TexTarget
switch (pname) {
case LOCAL_GL_TEXTURE_MIN_FILTER:
case LOCAL_GL_TEXTURE_MAG_FILTER:
case LOCAL_GL_TEXTURE_WRAP_S:
case LOCAL_GL_TEXTURE_WRAP_T:
case LOCAL_GL_TEXTURE_BASE_LEVEL:
case LOCAL_GL_TEXTURE_COMPARE_FUNC:
case LOCAL_GL_TEXTURE_COMPARE_MODE:
- case LOCAL_GL_TEXTURE_IMMUTABLE_FORMAT:
case LOCAL_GL_TEXTURE_IMMUTABLE_LEVELS:
case LOCAL_GL_TEXTURE_MAX_LEVEL:
case LOCAL_GL_TEXTURE_SWIZZLE_A:
case LOCAL_GL_TEXTURE_SWIZZLE_B:
case LOCAL_GL_TEXTURE_SWIZZLE_G:
case LOCAL_GL_TEXTURE_SWIZZLE_R:
case LOCAL_GL_TEXTURE_WRAP_R:
mContext->gl->fGetTexParameteriv(texTarget.get(), pname, &i);
return JS::NumberValue(uint32_t(i));
+ case LOCAL_GL_TEXTURE_IMMUTABLE_FORMAT:
+ mContext->gl->fGetTexParameteriv(texTarget.get(), pname, &i);
+ return JS::BooleanValue(bool(i));
+
case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
case LOCAL_GL_TEXTURE_MAX_LOD:
case LOCAL_GL_TEXTURE_MIN_LOD:
mContext->gl->fGetTexParameterfv(texTarget.get(), pname, &f);
return JS::NumberValue(float(f));
default:
MOZ_CRASH("Unhandled pname.");
@@ -770,144 +776,134 @@ void
WebGLTexture::TexParameter(TexTarget texTarget, GLenum pname, GLint* maybeIntParam,
GLfloat* maybeFloatParam)
{
MOZ_ASSERT(maybeIntParam || maybeFloatParam);
GLint intParam = maybeIntParam ? *maybeIntParam : GLint(*maybeFloatParam);
GLfloat floatParam = maybeFloatParam ? *maybeFloatParam : GLfloat(*maybeIntParam);
+ bool isPNameValid = false;
+ switch (pname) {
+ // GLES 2.0.25 p76:
+ case LOCAL_GL_TEXTURE_WRAP_S:
+ case LOCAL_GL_TEXTURE_WRAP_T:
+ case LOCAL_GL_TEXTURE_MIN_FILTER:
+ case LOCAL_GL_TEXTURE_MAG_FILTER:
+ isPNameValid = true;
+ break;
+
+ // GLES 3.0.4 p149-150:
+ case LOCAL_GL_TEXTURE_BASE_LEVEL:
+ case LOCAL_GL_TEXTURE_COMPARE_MODE:
+ case LOCAL_GL_TEXTURE_COMPARE_FUNC:
+ case LOCAL_GL_TEXTURE_MAX_LEVEL:
+ case LOCAL_GL_TEXTURE_MAX_LOD:
+ case LOCAL_GL_TEXTURE_MIN_LOD:
+ case LOCAL_GL_TEXTURE_WRAP_R:
+ if (mContext->IsWebGL2())
+ isPNameValid = true;
+ break;
+
+ case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (mContext->IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic))
+ isPNameValid = false;
+ break;
+ }
+
+ if (!isPNameValid) {
+ mContext->ErrorInvalidEnumInfo("texParameter: pname", pname);
+ return;
+ }
+
+ ////////////////
+ // Validate params and invalidate if needed.
+
bool paramBadEnum = false;
bool paramBadValue = false;
switch (pname) {
case LOCAL_GL_TEXTURE_BASE_LEVEL:
case LOCAL_GL_TEXTURE_MAX_LEVEL:
- if (!mContext->IsWebGL2())
- return mContext->ErrorInvalidEnumInfo("texParameter: pname", pname);
-
- if (intParam < 0) {
- paramBadValue = true;
- break;
- }
-
- InvalidateFakeBlackCache();
-
- if (pname == LOCAL_GL_TEXTURE_BASE_LEVEL)
- mBaseMipmapLevel = intParam;
- else
- mMaxMipmapLevel = intParam;
-
- ClampLevelBaseAndMax();
-
+ paramBadValue = (intParam < 0);
break;
case LOCAL_GL_TEXTURE_COMPARE_MODE:
- if (!mContext->IsWebGL2())
- return mContext->ErrorInvalidEnumInfo("texParameter: pname", pname);
-
- InvalidateFakeBlackCache();
-
paramBadValue = (intParam != LOCAL_GL_NONE &&
intParam != LOCAL_GL_COMPARE_REF_TO_TEXTURE);
break;
case LOCAL_GL_TEXTURE_COMPARE_FUNC:
- if (!mContext->IsWebGL2())
- return mContext->ErrorInvalidEnumInfo("texParameter: pname", pname);
-
- InvalidateFakeBlackCache();
-
switch (intParam) {
case LOCAL_GL_LEQUAL:
case LOCAL_GL_GEQUAL:
case LOCAL_GL_LESS:
case LOCAL_GL_GREATER:
case LOCAL_GL_EQUAL:
case LOCAL_GL_NOTEQUAL:
case LOCAL_GL_ALWAYS:
case LOCAL_GL_NEVER:
break;
default:
paramBadValue = true;
+ break;
}
break;
case LOCAL_GL_TEXTURE_MIN_FILTER:
switch (intParam) {
case LOCAL_GL_NEAREST:
case LOCAL_GL_LINEAR:
case LOCAL_GL_NEAREST_MIPMAP_NEAREST:
case LOCAL_GL_LINEAR_MIPMAP_NEAREST:
case LOCAL_GL_NEAREST_MIPMAP_LINEAR:
case LOCAL_GL_LINEAR_MIPMAP_LINEAR:
- InvalidateFakeBlackCache();
- mMinFilter = intParam;
break;
default:
paramBadEnum = true;
+ break;
}
break;
case LOCAL_GL_TEXTURE_MAG_FILTER:
switch (intParam) {
case LOCAL_GL_NEAREST:
case LOCAL_GL_LINEAR:
- InvalidateFakeBlackCache();
- mMagFilter = intParam;
- break;
-
- default:
- paramBadEnum = true;
- }
- break;
-
- case LOCAL_GL_TEXTURE_WRAP_S:
- switch (intParam) {
- case LOCAL_GL_CLAMP_TO_EDGE:
- case LOCAL_GL_MIRRORED_REPEAT:
- case LOCAL_GL_REPEAT:
- InvalidateFakeBlackCache();
- mWrapS = intParam;
break;
default:
paramBadEnum = true;
+ break;
}
break;
+ case LOCAL_GL_TEXTURE_WRAP_S:
case LOCAL_GL_TEXTURE_WRAP_T:
+ case LOCAL_GL_TEXTURE_WRAP_R:
switch (intParam) {
case LOCAL_GL_CLAMP_TO_EDGE:
case LOCAL_GL_MIRRORED_REPEAT:
case LOCAL_GL_REPEAT:
- InvalidateFakeBlackCache();
- mWrapT = intParam;
break;
default:
paramBadEnum = true;
+ break;
}
break;
case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
- if (!mContext->IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic))
- return mContext->ErrorInvalidEnumInfo("texParameter: pname", pname);
-
if (maybeFloatParam && floatParam < 1.0f)
paramBadValue = true;
else if (maybeIntParam && intParam < 1)
paramBadValue = true;
break;
-
- default:
- return mContext->ErrorInvalidEnumInfo("texParameter: pname", pname);
}
if (paramBadEnum) {
if (maybeIntParam) {
mContext->ErrorInvalidEnum("texParameteri: pname 0x%04x: Invalid param"
" 0x%04x.",
pname, intParam);
} else {
@@ -924,16 +920,58 @@ WebGLTexture::TexParameter(TexTarget tex
pname, intParam, intParam);
} else {
mContext->ErrorInvalidValue("texParameterf: pname 0x%04x: Invalid param %g.",
pname, floatParam);
}
return;
}
+ ////////////////
+ // Store any needed values
+
+ switch (pname) {
+ case LOCAL_GL_TEXTURE_BASE_LEVEL:
+ mBaseMipmapLevel = intParam;
+ ClampLevelBaseAndMax();
+ break;
+
+ case LOCAL_GL_TEXTURE_MAX_LEVEL:
+ mMaxMipmapLevel = intParam;
+ ClampLevelBaseAndMax();
+ break;
+
+ case LOCAL_GL_TEXTURE_MIN_FILTER:
+ mMinFilter = intParam;
+ break;
+
+ case LOCAL_GL_TEXTURE_MAG_FILTER:
+ mMagFilter = intParam;
+ break;
+
+ case LOCAL_GL_TEXTURE_WRAP_S:
+ mWrapS = intParam;
+ break;
+
+ case LOCAL_GL_TEXTURE_WRAP_T:
+ mWrapT = intParam;
+ break;
+
+ // We don't actually need to store the WRAP_R, since it doesn't change texture
+ // completeness rules.
+ }
+
+ // The only pname that doesn't actually need fake-black invalidation is
+ // LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT.
+ if (pname != LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT) {
+ InvalidateFakeBlackCache();
+ }
+
+ ////////////////
+
mContext->MakeContextCurrent();
if (maybeIntParam)
mContext->gl->fTexParameteri(texTarget.get(), pname, intParam);
else
mContext->gl->fTexParameterf(texTarget.get(), pname, floatParam);
}
////////////////////////////////////////////////////////////////////////////////
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -9,16 +9,17 @@
#include "CanvasUtils.h"
#include "GLBlitHelper.h"
#include "GLContext.h"
#include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/ImageData.h"
#include "mozilla/gfx/SourceSurfaceRawData.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/Scoped.h"
+#include "mozilla/unused.h"
#include "ScopedGLHelpers.h"
#include "TexUnpackBlob.h"
#include "WebGLContext.h"
#include "WebGLContextUtils.h"
#include "WebGLFramebuffer.h"
#include "WebGLTexelConversions.h"
namespace mozilla {
@@ -947,17 +948,17 @@ WebGLTexture::TexStorage(const char* fun
WebGLTexture::ImageInfo* testImageInfo;
if (!ValidateTexImageSpecification(funcName, testTarget, testLevel, width, height,
depth, border, &testImageInfo))
{
return;
}
MOZ_ASSERT(testImageInfo);
- mozilla::unused << testImageInfo;
+ mozilla::Unused << testImageInfo;
auto dstUsage = mContext->mFormatUsage->GetSizedTexUsage(sizedFormat);
if (!dstUsage) {
mContext->ErrorInvalidEnum("%s: Invalid internalformat: 0x%04x", funcName,
sizedFormat);
return;
}
auto dstFormat = dstUsage->format;