From c95b959d038919a0388ee88e81b4c35ed8bd607e Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Tue, 7 Aug 2018 19:12:09 +0000 Subject: [PATCH] Bug 1481283 - Use SamplingState for both WebGLTexture and WebGLSampler state. r=kvark Differential Revision: https://phabricator.services.mozilla.com/D2795 --HG-- extra : moz-landing-system : lando --- dom/canvas/WebGL2ContextSamplers.cpp | 5 +- dom/canvas/WebGLSampler.cpp | 46 +++++----------- dom/canvas/WebGLSampler.h | 31 +++++------ dom/canvas/WebGLTexture.cpp | 80 ++++++++++++---------------- dom/canvas/WebGLTexture.h | 41 +++++++------- 5 files changed, 80 insertions(+), 123 deletions(-) diff --git a/dom/canvas/WebGL2ContextSamplers.cpp b/dom/canvas/WebGL2ContextSamplers.cpp index 3fd56479eed3..de97e8332f85 100644 --- a/dom/canvas/WebGL2ContextSamplers.cpp +++ b/dom/canvas/WebGL2ContextSamplers.cpp @@ -15,10 +15,7 @@ WebGL2Context::CreateSampler() if (IsContextLost()) return nullptr; - GLuint sampler; - gl->fGenSamplers(1, &sampler); - - RefPtr globj = new WebGLSampler(this, sampler); + RefPtr globj = new WebGLSampler(this); return globj.forget(); } diff --git a/dom/canvas/WebGLSampler.cpp b/dom/canvas/WebGLSampler.cpp index 7ca26f4a3bc4..fca07b60b51f 100644 --- a/dom/canvas/WebGLSampler.cpp +++ b/dom/canvas/WebGLSampler.cpp @@ -11,18 +11,15 @@ namespace mozilla { -WebGLSampler::WebGLSampler(WebGLContext* webgl, GLuint sampler) + + +WebGLSampler::WebGLSampler(WebGLContext* const webgl) : WebGLRefCountedObject(webgl) - , mGLName(sampler) - , mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR) - , mMagFilter(LOCAL_GL_LINEAR) - , mWrapS(LOCAL_GL_REPEAT) - , mWrapT(LOCAL_GL_REPEAT) - , mWrapR(LOCAL_GL_REPEAT) - , mMinLod(-1000) - , mMaxLod(1000) - , mCompareMode(LOCAL_GL_NONE) - , mCompareFunc(LOCAL_GL_LEQUAL) + , mGLName([&]() { + GLuint ret = 0; + webgl->gl->fGenSamplers(1, &ret); + return ret; + }()) { mContext->mSamplers.insertBack(this); } @@ -149,43 +146,26 @@ WebGLSampler::SamplerParameter(const char* funcName, GLenum pname, switch (pname) { case LOCAL_GL_TEXTURE_MIN_FILTER: - mMinFilter = param.i; + mState.minFilter = param.i; break; case LOCAL_GL_TEXTURE_MAG_FILTER: - mMagFilter = param.i; + mState.magFilter = param.i; break; case LOCAL_GL_TEXTURE_WRAP_S: - mWrapS = param.i; + mState.wrapS = param.i; break; case LOCAL_GL_TEXTURE_WRAP_T: - mWrapT = param.i; - break; - - case LOCAL_GL_TEXTURE_WRAP_R: - mWrapR = param.i; + mState.wrapT = param.i; break; case LOCAL_GL_TEXTURE_COMPARE_MODE: - mCompareMode = param.i; - break; - - case LOCAL_GL_TEXTURE_COMPARE_FUNC: - mCompareFunc = param.i; - break; - - case LOCAL_GL_TEXTURE_MIN_LOD: - mMinLod = param.f; - break; - - case LOCAL_GL_TEXTURE_MAX_LOD: - mMaxLod = param.f; + mState.compareMode = param.i; break; default: - MOZ_CRASH("GFX: Unhandled pname"); break; } diff --git a/dom/canvas/WebGLSampler.h b/dom/canvas/WebGLSampler.h index 1cf039984159..0651b9f2f9c1 100644 --- a/dom/canvas/WebGLSampler.h +++ b/dom/canvas/WebGLSampler.h @@ -10,6 +10,7 @@ #include "nsWrapperCache.h" #include "WebGLObjectModel.h" #include "WebGLStrongTypes.h" +#include "WebGLTexture.h" namespace mozilla { @@ -21,11 +22,20 @@ class WebGLSampler final friend class WebGLContext2; friend class WebGLTexture; + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSampler) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSampler) + public: - WebGLSampler(WebGLContext* webgl, GLuint sampler); - const GLuint mGLName; +private: + webgl::SamplingState mState; +public: + explicit WebGLSampler(WebGLContext* webgl); +private: + ~WebGLSampler(); + +public: void Delete(); WebGLContext* GetParentObject() const; @@ -33,22 +43,7 @@ public: void SamplerParameter(const char* funcName, GLenum pname, const FloatOrInt& param); -private: - NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSampler) - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSampler) - - TexMinFilter mMinFilter; - TexMagFilter mMagFilter; - TexWrap mWrapS; - TexWrap mWrapT; - TexWrap mWrapR; - GLfloat mMinLod; - GLfloat mMaxLod; - TexCompareMode mCompareMode; - TexCompareFunc mCompareFunc; - -private: - ~WebGLSampler(); + const auto& State() const { return mState; } }; } // namespace mozilla diff --git a/dom/canvas/WebGLTexture.cpp b/dom/canvas/WebGLTexture.cpp index f8a846e6cb73..fd2835ca5633 100644 --- a/dom/canvas/WebGLTexture.cpp +++ b/dom/canvas/WebGLTexture.cpp @@ -129,15 +129,10 @@ WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex) , mGLName(tex) , mTarget(LOCAL_GL_NONE) , mFaceCount(0) - , mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR) - , mMagFilter(LOCAL_GL_LINEAR) - , mWrapS(LOCAL_GL_REPEAT) - , mWrapT(LOCAL_GL_REPEAT) , mImmutable(false) , mImmutableLevelCount(0) , mBaseMipmapLevel(0) , mMaxMipmapLevel(1000) - , mTexCompareMode(LOCAL_GL_NONE) , mIsResolved(false) , mResolved_FakeBlack(FakeBlackType::None) , mResolved_Swizzle(nullptr) @@ -196,7 +191,6 @@ WebGLTexture::IsMipmapComplete(const char* funcName, uint32_t texUnit, bool* const out_initFailed) { *out_initFailed = false; - MOZ_ASSERT(DoesMinFilterRequireMipmap()); // GLES 3.0.4, p161 uint32_t maxLevel; @@ -343,9 +337,14 @@ WebGLTexture::IsComplete(const char* funcName, uint32_t texUnit, return false; } - WebGLSampler* sampler = mContext->mBoundSamplers[texUnit]; - TexMinFilter minFilter = sampler ? sampler->mMinFilter : mMinFilter; - TexMagFilter magFilter = sampler ? sampler->mMagFilter : mMagFilter; + const auto* samplingState = &mSamplingState; + const auto& sampler = mContext->mBoundSamplers[texUnit]; + if (sampler) { + samplingState = &(sampler->State()); + } + + const auto& minFilter = samplingState->minFilter; + const auto& magFilter = samplingState->magFilter; // "* The minification filter requires a mipmap (is neither NEAREST nor LINEAR) and // the texture is not mipmap complete." @@ -379,7 +378,7 @@ WebGLTexture::IsComplete(const char* funcName, uint32_t texUnit, // 3.0.1: // "* Clarify that a texture is incomplete if it has a depth component, no // shadow comparison, and linear filtering (also Bug 9481)." - if (format->d && mTexCompareMode != LOCAL_GL_NONE) { + if (format->d && samplingState->compareMode != LOCAL_GL_NONE) { isFilterable = true; } @@ -423,11 +422,9 @@ WebGLTexture::IsComplete(const char* funcName, uint32_t texUnit, // 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()) { - TexWrap wrapS = sampler ? sampler->mWrapS : mWrapS; - TexWrap wrapT = sampler ? sampler->mWrapT : mWrapT; // "either the texture wrap mode is not CLAMP_TO_EDGE" - if (wrapS != LOCAL_GL_CLAMP_TO_EDGE || - wrapT != LOCAL_GL_CLAMP_TO_EDGE) + if (samplingState->wrapS != LOCAL_GL_CLAMP_TO_EDGE || + samplingState->wrapT != LOCAL_GL_CLAMP_TO_EDGE) { *out_reason = "Non-power-of-two textures must have a wrap mode of" " CLAMP_TO_EDGE."; @@ -458,8 +455,13 @@ WebGLTexture::IsComplete(const char* funcName, uint32_t texUnit, bool WebGLTexture::MaxEffectiveMipmapLevel(uint32_t texUnit, uint32_t* const out) const { - WebGLSampler* sampler = mContext->mBoundSamplers[texUnit]; - TexMinFilter minFilter = sampler ? sampler->mMinFilter : mMinFilter; + const auto* samplingState = &mSamplingState; + const auto& sampler = mContext->mBoundSamplers[texUnit]; + if (sampler) { + samplingState = &(sampler->State()); + } + + const auto& minFilter = samplingState->minFilter; if (minFilter == LOCAL_GL_NEAREST || minFilter == LOCAL_GL_LINEAR) { @@ -949,7 +951,7 @@ WebGLTexture::GenerateMipmap(TexTarget texTarget) LOCAL_GL_NEAREST_MIPMAP_NEAREST); gl->fGenerateMipmap(texTarget.get()); gl->fTexParameteri(texTarget.get(), LOCAL_GL_TEXTURE_MIN_FILTER, - mMinFilter.get()); + mSamplingState.minFilter.get()); } else { gl->fGenerateMipmap(texTarget.get()); } @@ -968,24 +970,9 @@ WebGLTexture::GetTexParameter(TexTarget texTarget, GLenum pname) GLfloat f = 0.0f; switch (pname) { - case LOCAL_GL_TEXTURE_MIN_FILTER: - return JS::NumberValue(uint32_t(mMinFilter.get())); - - case LOCAL_GL_TEXTURE_MAG_FILTER: - return JS::NumberValue(uint32_t(mMagFilter.get())); - - case LOCAL_GL_TEXTURE_WRAP_S: - return JS::NumberValue(uint32_t(mWrapS.get())); - - case LOCAL_GL_TEXTURE_WRAP_T: - return JS::NumberValue(uint32_t(mWrapT.get())); - case LOCAL_GL_TEXTURE_BASE_LEVEL: return JS::NumberValue(mBaseMipmapLevel); - case LOCAL_GL_TEXTURE_COMPARE_MODE: - return JS::NumberValue(uint32_t(mTexCompareMode)); - case LOCAL_GL_TEXTURE_MAX_LEVEL: return JS::NumberValue(mMaxMipmapLevel); @@ -995,8 +982,13 @@ WebGLTexture::GetTexParameter(TexTarget texTarget, GLenum pname) case LOCAL_GL_TEXTURE_IMMUTABLE_LEVELS: return JS::NumberValue(uint32_t(mImmutableLevelCount)); - case LOCAL_GL_TEXTURE_COMPARE_FUNC: + 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_WRAP_R: + case LOCAL_GL_TEXTURE_COMPARE_MODE: + case LOCAL_GL_TEXTURE_COMPARE_FUNC: mContext->gl->fGetTexParameteriv(texTarget.get(), pname, &i); return JS::NumberValue(uint32_t(i)); @@ -1169,6 +1161,7 @@ WebGLTexture::TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt& // Store any needed values FloatOrInt clamped = param; + bool invalidateCaches = true; switch (pname) { case LOCAL_GL_TEXTURE_BASE_LEVEL: mBaseMipmapLevel = clamped.i; @@ -1183,38 +1176,35 @@ WebGLTexture::TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt& break; case LOCAL_GL_TEXTURE_MIN_FILTER: - mMinFilter = clamped.i; + mSamplingState.minFilter = clamped.i; break; case LOCAL_GL_TEXTURE_MAG_FILTER: - mMagFilter = clamped.i; + mSamplingState.magFilter = clamped.i; break; case LOCAL_GL_TEXTURE_WRAP_S: - mWrapS = clamped.i; + mSamplingState.wrapS = clamped.i; break; case LOCAL_GL_TEXTURE_WRAP_T: - mWrapT = clamped.i; + mSamplingState.wrapT = clamped.i; break; case LOCAL_GL_TEXTURE_COMPARE_MODE: - mTexCompareMode = clamped.i; + mSamplingState.compareMode = clamped.i; break; - // We don't actually need to store the WRAP_R, since it doesn't change texture - // completeness rules. - } - // Only a couple of pnames don't need to invalidate our resolve status cache. - switch (pname) { case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT: case LOCAL_GL_TEXTURE_WRAP_R: + case LOCAL_GL_TEXTURE_COMPARE_FUNC: + invalidateCaches = false; break; + } - default: + if (invalidateCaches) { InvalidateResolveCache(); - break; } //////////////// diff --git a/dom/canvas/WebGLTexture.h b/dom/canvas/WebGLTexture.h index 128b09328a9f..347d0da252f9 100644 --- a/dom/canvas/WebGLTexture.h +++ b/dom/canvas/WebGLTexture.h @@ -51,6 +51,23 @@ bool DoesTargetMatchDimensions(WebGLContext* webgl, TexImageTarget target, uint8_t dims, const char* funcName); +namespace webgl { + +struct SamplingState final +{ + // Only store that which changes validation. + TexMinFilter minFilter = LOCAL_GL_NEAREST_MIPMAP_LINEAR; + TexMagFilter magFilter = LOCAL_GL_LINEAR; + TexWrap wrapS = LOCAL_GL_REPEAT; + TexWrap wrapT = LOCAL_GL_REPEAT; + //TexWrap wrapR = LOCAL_GL_REPEAT; + //GLfloat minLod = -1000; + //GLfloat maxLod = 1000; + TexCompareMode compareMode = LOCAL_GL_NONE; + //TexCompareFunc compareFunc = LOCAL_GL_LEQUAL; +}; + +} // namespace webgl // NOTE: When this class is switched to new DOM bindings, update the (then-slow) // WrapObject calls in GetParameter and GetFramebufferAttachmentParameter. @@ -74,10 +91,6 @@ protected: static const uint8_t kMaxFaceCount = 6; uint8_t mFaceCount; // 6 for cube maps, 1 otherwise. - TexMinFilter mMinFilter; - TexMagFilter mMagFilter; - TexWrap mWrapS, mWrapT; - bool mImmutable; // Set by texStorage* uint8_t mImmutableLevelCount; @@ -86,7 +99,7 @@ protected: // You almost certainly don't want to query mMaxMipmapLevel. // You almost certainly want MaxEffectiveMipmapLevel(). - GLenum mTexCompareMode; + webgl::SamplingState mSamplingState; // Resolvable optimizations: bool mIsResolved; @@ -354,25 +367,7 @@ protected: uint32_t level); bool EnsureLevelInitialized(const char* funcName, uint32_t level); - bool CheckFloatTextureFilterParams() const { - // Without OES_texture_float_linear, only NEAREST and - // NEAREST_MIMPAMP_NEAREST are supported. - return mMagFilter == LOCAL_GL_NEAREST && - (mMinFilter == LOCAL_GL_NEAREST || - mMinFilter == LOCAL_GL_NEAREST_MIPMAP_NEAREST); - } - - bool AreBothWrapModesClampToEdge() const { - return mWrapS == LOCAL_GL_CLAMP_TO_EDGE && - mWrapT == LOCAL_GL_CLAMP_TO_EDGE; - } - public: - bool DoesMinFilterRequireMipmap() const { - return !(mMinFilter == LOCAL_GL_NEAREST || - mMinFilter == LOCAL_GL_LINEAR); - } - void SetGeneratedMipmap(); void SetCustomMipmap();