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
This commit is contained in:
Jeff Gilbert 2018-08-07 19:12:09 +00:00
Родитель 613dc273cb
Коммит c95b959d03
5 изменённых файлов: 80 добавлений и 123 удалений

Просмотреть файл

@ -15,10 +15,7 @@ WebGL2Context::CreateSampler()
if (IsContextLost()) if (IsContextLost())
return nullptr; return nullptr;
GLuint sampler; RefPtr<WebGLSampler> globj = new WebGLSampler(this);
gl->fGenSamplers(1, &sampler);
RefPtr<WebGLSampler> globj = new WebGLSampler(this, sampler);
return globj.forget(); return globj.forget();
} }

Просмотреть файл

@ -11,18 +11,15 @@
namespace mozilla { namespace mozilla {
WebGLSampler::WebGLSampler(WebGLContext* webgl, GLuint sampler)
WebGLSampler::WebGLSampler(WebGLContext* const webgl)
: WebGLRefCountedObject(webgl) : WebGLRefCountedObject(webgl)
, mGLName(sampler) , mGLName([&]() {
, mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR) GLuint ret = 0;
, mMagFilter(LOCAL_GL_LINEAR) webgl->gl->fGenSamplers(1, &ret);
, mWrapS(LOCAL_GL_REPEAT) return ret;
, mWrapT(LOCAL_GL_REPEAT) }())
, mWrapR(LOCAL_GL_REPEAT)
, mMinLod(-1000)
, mMaxLod(1000)
, mCompareMode(LOCAL_GL_NONE)
, mCompareFunc(LOCAL_GL_LEQUAL)
{ {
mContext->mSamplers.insertBack(this); mContext->mSamplers.insertBack(this);
} }
@ -149,43 +146,26 @@ WebGLSampler::SamplerParameter(const char* funcName, GLenum pname,
switch (pname) { switch (pname) {
case LOCAL_GL_TEXTURE_MIN_FILTER: case LOCAL_GL_TEXTURE_MIN_FILTER:
mMinFilter = param.i; mState.minFilter = param.i;
break; break;
case LOCAL_GL_TEXTURE_MAG_FILTER: case LOCAL_GL_TEXTURE_MAG_FILTER:
mMagFilter = param.i; mState.magFilter = param.i;
break; break;
case LOCAL_GL_TEXTURE_WRAP_S: case LOCAL_GL_TEXTURE_WRAP_S:
mWrapS = param.i; mState.wrapS = param.i;
break; break;
case LOCAL_GL_TEXTURE_WRAP_T: case LOCAL_GL_TEXTURE_WRAP_T:
mWrapT = param.i; mState.wrapT = param.i;
break;
case LOCAL_GL_TEXTURE_WRAP_R:
mWrapR = param.i;
break; break;
case LOCAL_GL_TEXTURE_COMPARE_MODE: case LOCAL_GL_TEXTURE_COMPARE_MODE:
mCompareMode = param.i; mState.compareMode = 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;
break; break;
default: default:
MOZ_CRASH("GFX: Unhandled pname");
break; break;
} }

Просмотреть файл

@ -10,6 +10,7 @@
#include "nsWrapperCache.h" #include "nsWrapperCache.h"
#include "WebGLObjectModel.h" #include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h" #include "WebGLStrongTypes.h"
#include "WebGLTexture.h"
namespace mozilla { namespace mozilla {
@ -21,11 +22,20 @@ class WebGLSampler final
friend class WebGLContext2; friend class WebGLContext2;
friend class WebGLTexture; friend class WebGLTexture;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSampler)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSampler)
public: public:
WebGLSampler(WebGLContext* webgl, GLuint sampler);
const GLuint mGLName; const GLuint mGLName;
private:
webgl::SamplingState mState;
public:
explicit WebGLSampler(WebGLContext* webgl);
private:
~WebGLSampler();
public:
void Delete(); void Delete();
WebGLContext* GetParentObject() const; WebGLContext* GetParentObject() const;
@ -33,22 +43,7 @@ public:
void SamplerParameter(const char* funcName, GLenum pname, const FloatOrInt& param); void SamplerParameter(const char* funcName, GLenum pname, const FloatOrInt& param);
private: const auto& State() const { return mState; }
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();
}; };
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -129,15 +129,10 @@ WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex)
, mGLName(tex) , mGLName(tex)
, mTarget(LOCAL_GL_NONE) , mTarget(LOCAL_GL_NONE)
, mFaceCount(0) , mFaceCount(0)
, mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR)
, mMagFilter(LOCAL_GL_LINEAR)
, mWrapS(LOCAL_GL_REPEAT)
, mWrapT(LOCAL_GL_REPEAT)
, mImmutable(false) , mImmutable(false)
, mImmutableLevelCount(0) , mImmutableLevelCount(0)
, mBaseMipmapLevel(0) , mBaseMipmapLevel(0)
, mMaxMipmapLevel(1000) , mMaxMipmapLevel(1000)
, mTexCompareMode(LOCAL_GL_NONE)
, mIsResolved(false) , mIsResolved(false)
, mResolved_FakeBlack(FakeBlackType::None) , mResolved_FakeBlack(FakeBlackType::None)
, mResolved_Swizzle(nullptr) , mResolved_Swizzle(nullptr)
@ -196,7 +191,6 @@ WebGLTexture::IsMipmapComplete(const char* funcName, uint32_t texUnit,
bool* const out_initFailed) bool* const out_initFailed)
{ {
*out_initFailed = false; *out_initFailed = false;
MOZ_ASSERT(DoesMinFilterRequireMipmap());
// GLES 3.0.4, p161 // GLES 3.0.4, p161
uint32_t maxLevel; uint32_t maxLevel;
@ -343,9 +337,14 @@ WebGLTexture::IsComplete(const char* funcName, uint32_t texUnit,
return false; return false;
} }
WebGLSampler* sampler = mContext->mBoundSamplers[texUnit]; const auto* samplingState = &mSamplingState;
TexMinFilter minFilter = sampler ? sampler->mMinFilter : mMinFilter; const auto& sampler = mContext->mBoundSamplers[texUnit];
TexMagFilter magFilter = sampler ? sampler->mMagFilter : mMagFilter; 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 minification filter requires a mipmap (is neither NEAREST nor LINEAR) and
// the texture is not mipmap complete." // the texture is not mipmap complete."
@ -379,7 +378,7 @@ WebGLTexture::IsComplete(const char* funcName, uint32_t texUnit,
// 3.0.1: // 3.0.1:
// "* Clarify that a texture is incomplete if it has a depth component, no // "* Clarify that a texture is incomplete if it has a depth component, no
// shadow comparison, and linear filtering (also Bug 9481)." // 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; 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 // 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." // CLAMP_TO_EDGE, or the minification filter is neither NEAREST nor LINEAR."
if (!baseImageInfo.IsPowerOfTwo()) { 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" // "either the texture wrap mode is not CLAMP_TO_EDGE"
if (wrapS != LOCAL_GL_CLAMP_TO_EDGE || if (samplingState->wrapS != LOCAL_GL_CLAMP_TO_EDGE ||
wrapT != 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" *out_reason = "Non-power-of-two textures must have a wrap mode of"
" CLAMP_TO_EDGE."; " CLAMP_TO_EDGE.";
@ -458,8 +455,13 @@ WebGLTexture::IsComplete(const char* funcName, uint32_t texUnit,
bool bool
WebGLTexture::MaxEffectiveMipmapLevel(uint32_t texUnit, uint32_t* const out) const WebGLTexture::MaxEffectiveMipmapLevel(uint32_t texUnit, uint32_t* const out) const
{ {
WebGLSampler* sampler = mContext->mBoundSamplers[texUnit]; const auto* samplingState = &mSamplingState;
TexMinFilter minFilter = sampler ? sampler->mMinFilter : mMinFilter; const auto& sampler = mContext->mBoundSamplers[texUnit];
if (sampler) {
samplingState = &(sampler->State());
}
const auto& minFilter = samplingState->minFilter;
if (minFilter == LOCAL_GL_NEAREST || if (minFilter == LOCAL_GL_NEAREST ||
minFilter == LOCAL_GL_LINEAR) minFilter == LOCAL_GL_LINEAR)
{ {
@ -949,7 +951,7 @@ WebGLTexture::GenerateMipmap(TexTarget texTarget)
LOCAL_GL_NEAREST_MIPMAP_NEAREST); LOCAL_GL_NEAREST_MIPMAP_NEAREST);
gl->fGenerateMipmap(texTarget.get()); gl->fGenerateMipmap(texTarget.get());
gl->fTexParameteri(texTarget.get(), LOCAL_GL_TEXTURE_MIN_FILTER, gl->fTexParameteri(texTarget.get(), LOCAL_GL_TEXTURE_MIN_FILTER,
mMinFilter.get()); mSamplingState.minFilter.get());
} else { } else {
gl->fGenerateMipmap(texTarget.get()); gl->fGenerateMipmap(texTarget.get());
} }
@ -968,24 +970,9 @@ WebGLTexture::GetTexParameter(TexTarget texTarget, GLenum pname)
GLfloat f = 0.0f; GLfloat f = 0.0f;
switch (pname) { 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: case LOCAL_GL_TEXTURE_BASE_LEVEL:
return JS::NumberValue(mBaseMipmapLevel); return JS::NumberValue(mBaseMipmapLevel);
case LOCAL_GL_TEXTURE_COMPARE_MODE:
return JS::NumberValue(uint32_t(mTexCompareMode));
case LOCAL_GL_TEXTURE_MAX_LEVEL: case LOCAL_GL_TEXTURE_MAX_LEVEL:
return JS::NumberValue(mMaxMipmapLevel); return JS::NumberValue(mMaxMipmapLevel);
@ -995,8 +982,13 @@ WebGLTexture::GetTexParameter(TexTarget texTarget, GLenum pname)
case LOCAL_GL_TEXTURE_IMMUTABLE_LEVELS: case LOCAL_GL_TEXTURE_IMMUTABLE_LEVELS:
return JS::NumberValue(uint32_t(mImmutableLevelCount)); 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_WRAP_R:
case LOCAL_GL_TEXTURE_COMPARE_MODE:
case LOCAL_GL_TEXTURE_COMPARE_FUNC:
mContext->gl->fGetTexParameteriv(texTarget.get(), pname, &i); mContext->gl->fGetTexParameteriv(texTarget.get(), pname, &i);
return JS::NumberValue(uint32_t(i)); return JS::NumberValue(uint32_t(i));
@ -1169,6 +1161,7 @@ WebGLTexture::TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt&
// Store any needed values // Store any needed values
FloatOrInt clamped = param; FloatOrInt clamped = param;
bool invalidateCaches = true;
switch (pname) { switch (pname) {
case LOCAL_GL_TEXTURE_BASE_LEVEL: case LOCAL_GL_TEXTURE_BASE_LEVEL:
mBaseMipmapLevel = clamped.i; mBaseMipmapLevel = clamped.i;
@ -1183,38 +1176,35 @@ WebGLTexture::TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt&
break; break;
case LOCAL_GL_TEXTURE_MIN_FILTER: case LOCAL_GL_TEXTURE_MIN_FILTER:
mMinFilter = clamped.i; mSamplingState.minFilter = clamped.i;
break; break;
case LOCAL_GL_TEXTURE_MAG_FILTER: case LOCAL_GL_TEXTURE_MAG_FILTER:
mMagFilter = clamped.i; mSamplingState.magFilter = clamped.i;
break; break;
case LOCAL_GL_TEXTURE_WRAP_S: case LOCAL_GL_TEXTURE_WRAP_S:
mWrapS = clamped.i; mSamplingState.wrapS = clamped.i;
break; break;
case LOCAL_GL_TEXTURE_WRAP_T: case LOCAL_GL_TEXTURE_WRAP_T:
mWrapT = clamped.i; mSamplingState.wrapT = clamped.i;
break; break;
case LOCAL_GL_TEXTURE_COMPARE_MODE: case LOCAL_GL_TEXTURE_COMPARE_MODE:
mTexCompareMode = clamped.i; mSamplingState.compareMode = clamped.i;
break; 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. // 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_MAX_ANISOTROPY_EXT:
case LOCAL_GL_TEXTURE_WRAP_R: case LOCAL_GL_TEXTURE_WRAP_R:
case LOCAL_GL_TEXTURE_COMPARE_FUNC:
invalidateCaches = false;
break; break;
}
default: if (invalidateCaches) {
InvalidateResolveCache(); InvalidateResolveCache();
break;
} }
//////////////// ////////////////

Просмотреть файл

@ -51,6 +51,23 @@ bool
DoesTargetMatchDimensions(WebGLContext* webgl, TexImageTarget target, uint8_t dims, DoesTargetMatchDimensions(WebGLContext* webgl, TexImageTarget target, uint8_t dims,
const char* funcName); 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) // NOTE: When this class is switched to new DOM bindings, update the (then-slow)
// WrapObject calls in GetParameter and GetFramebufferAttachmentParameter. // WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
@ -74,10 +91,6 @@ protected:
static const uint8_t kMaxFaceCount = 6; static const uint8_t kMaxFaceCount = 6;
uint8_t mFaceCount; // 6 for cube maps, 1 otherwise. uint8_t mFaceCount; // 6 for cube maps, 1 otherwise.
TexMinFilter mMinFilter;
TexMagFilter mMagFilter;
TexWrap mWrapS, mWrapT;
bool mImmutable; // Set by texStorage* bool mImmutable; // Set by texStorage*
uint8_t mImmutableLevelCount; uint8_t mImmutableLevelCount;
@ -86,7 +99,7 @@ protected:
// You almost certainly don't want to query mMaxMipmapLevel. // You almost certainly don't want to query mMaxMipmapLevel.
// You almost certainly want MaxEffectiveMipmapLevel(). // You almost certainly want MaxEffectiveMipmapLevel().
GLenum mTexCompareMode; webgl::SamplingState mSamplingState;
// Resolvable optimizations: // Resolvable optimizations:
bool mIsResolved; bool mIsResolved;
@ -354,25 +367,7 @@ protected:
uint32_t level); uint32_t level);
bool EnsureLevelInitialized(const char* funcName, 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: public:
bool DoesMinFilterRequireMipmap() const {
return !(mMinFilter == LOCAL_GL_NEAREST ||
mMinFilter == LOCAL_GL_LINEAR);
}
void SetGeneratedMipmap(); void SetGeneratedMipmap();
void SetCustomMipmap(); void SetCustomMipmap();