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())
return nullptr;
GLuint sampler;
gl->fGenSamplers(1, &sampler);
RefPtr<WebGLSampler> globj = new WebGLSampler(this, sampler);
RefPtr<WebGLSampler> globj = new WebGLSampler(this);
return globj.forget();
}

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

@ -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;
}

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

@ -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

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

@ -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;
}
////////////////

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

@ -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();