зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1230089 - If sampler is bound, use parameter of sampler. r=jgilbert
--HG-- extra : commitid : JF12eiQS7m8
This commit is contained in:
Родитель
8fbc15e43a
Коммит
6e90a4c6fc
|
@ -47,6 +47,8 @@ WebGL2Context::DeleteSampler(WebGLSampler* sampler)
|
|||
for (int n = 0; n < mGLMaxTextureUnits; n++) {
|
||||
if (mBoundSamplers[n] == sampler) {
|
||||
mBoundSamplers[n] = nullptr;
|
||||
|
||||
InvalidateResolveCacheForTextureWithTexUnit(n);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,6 +90,7 @@ WebGL2Context::BindSampler(GLuint unit, WebGLSampler* sampler)
|
|||
return ErrorInvalidOperation("bindSampler: binding deleted sampler");
|
||||
|
||||
WebGLContextUnchecked::BindSampler(unit, sampler);
|
||||
InvalidateResolveCacheForTextureWithTexUnit(unit);
|
||||
|
||||
mBoundSamplers[unit] = sampler;
|
||||
}
|
||||
|
@ -104,6 +107,7 @@ WebGL2Context::SamplerParameteri(WebGLSampler* sampler, GLenum pname, GLint para
|
|||
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param), "samplerParameteri"))
|
||||
return;
|
||||
|
||||
sampler->SamplerParameter1i(pname, param);
|
||||
WebGLContextUnchecked::SamplerParameteri(sampler, pname, param);
|
||||
}
|
||||
|
||||
|
@ -124,6 +128,7 @@ WebGL2Context::SamplerParameteriv(WebGLSampler* sampler, GLenum pname, const dom
|
|||
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param.Data()[0]), "samplerParameteriv"))
|
||||
return;
|
||||
|
||||
sampler->SamplerParameter1i(pname, param.Data()[0]);
|
||||
WebGLContextUnchecked::SamplerParameteriv(sampler, pname, param.Data());
|
||||
}
|
||||
|
||||
|
@ -143,6 +148,7 @@ WebGL2Context::SamplerParameteriv(WebGLSampler* sampler, GLenum pname, const dom
|
|||
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param[0]), "samplerParameteriv"))
|
||||
return;
|
||||
|
||||
sampler->SamplerParameter1i(pname, param[0]);
|
||||
WebGLContextUnchecked::SamplerParameteriv(sampler, pname, param.Elements());
|
||||
}
|
||||
|
||||
|
@ -158,6 +164,7 @@ WebGL2Context::SamplerParameterf(WebGLSampler* sampler, GLenum pname, GLfloat pa
|
|||
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param), "samplerParameterf"))
|
||||
return;
|
||||
|
||||
sampler->SamplerParameter1f(pname, param);
|
||||
WebGLContextUnchecked::SamplerParameterf(sampler, pname, param);
|
||||
}
|
||||
|
||||
|
@ -178,6 +185,7 @@ WebGL2Context::SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const dom
|
|||
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param.Data()[0]), "samplerParameterfv"))
|
||||
return;
|
||||
|
||||
sampler->SamplerParameter1f(pname, param.Data()[0]);
|
||||
WebGLContextUnchecked::SamplerParameterfv(sampler, pname, param.Data());
|
||||
}
|
||||
|
||||
|
@ -197,6 +205,7 @@ WebGL2Context::SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const dom
|
|||
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param[0]), "samplerParameterfv"))
|
||||
return;
|
||||
|
||||
sampler->SamplerParameter1f(pname, param[0]);
|
||||
WebGLContextUnchecked::SamplerParameterfv(sampler, pname, param.Elements());
|
||||
}
|
||||
|
||||
|
|
|
@ -332,6 +332,8 @@ public:
|
|||
return ActiveBoundTextureForTarget(texTarget);
|
||||
}
|
||||
|
||||
void InvalidateResolveCacheForTextureWithTexUnit(const GLuint);
|
||||
|
||||
already_AddRefed<Layer>
|
||||
GetCanvasLayer(nsDisplayListBuilder* builder, Layer* oldLayer,
|
||||
LayerManager* manager) override;
|
||||
|
|
|
@ -187,6 +187,19 @@ WebGLContext::IsTexParamValid(GLenum pname) const
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::InvalidateResolveCacheForTextureWithTexUnit(const GLuint texUnit)
|
||||
{
|
||||
if (mBound2DTextures[texUnit])
|
||||
mBound2DTextures[texUnit]->InvalidateResolveCache();
|
||||
if (mBoundCubeMapTextures[texUnit])
|
||||
mBoundCubeMapTextures[texUnit]->InvalidateResolveCache();
|
||||
if (mBound3DTextures[texUnit])
|
||||
mBound3DTextures[texUnit]->InvalidateResolveCache();
|
||||
if (mBound2DArrayTextures[texUnit])
|
||||
mBound2DArrayTextures[texUnit]->InvalidateResolveCache();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GL calls
|
||||
|
||||
|
|
|
@ -14,6 +14,15 @@ namespace mozilla {
|
|||
WebGLSampler::WebGLSampler(WebGLContext* webgl, GLuint sampler)
|
||||
: WebGLContextBoundObject(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)
|
||||
{
|
||||
mContext->mSamplers.insertBack(this);
|
||||
}
|
||||
|
@ -44,6 +53,72 @@ WebGLSampler::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
|
|||
return dom::WebGLSamplerBinding::Wrap(cx, this, givenProto);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLSampler::SamplerParameter1i(GLenum pname, GLint param)
|
||||
{
|
||||
switch (pname) {
|
||||
case LOCAL_GL_TEXTURE_MIN_FILTER:
|
||||
mMinFilter = param;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_TEXTURE_MAG_FILTER:
|
||||
mMagFilter = param;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_TEXTURE_WRAP_S:
|
||||
mWrapS = param;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_TEXTURE_WRAP_T:
|
||||
mWrapT = param;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_TEXTURE_WRAP_R:
|
||||
mWrapR = param;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_TEXTURE_COMPARE_MODE:
|
||||
mCompareMode = param;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_TEXTURE_COMPARE_FUNC:
|
||||
mCompareFunc = param;
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Unhandled pname");
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mContext->mBoundSamplers.Length(); ++i) {
|
||||
if (this == mContext->mBoundSamplers[i])
|
||||
mContext->InvalidateResolveCacheForTextureWithTexUnit(i);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGLSampler::SamplerParameter1f(GLenum pname, GLfloat param)
|
||||
{
|
||||
switch (pname) {
|
||||
case LOCAL_GL_TEXTURE_MIN_LOD:
|
||||
mMinLod = param;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_TEXTURE_MAX_LOD:
|
||||
mMaxLod = param;
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Unhandled pname");
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mContext->mBoundSamplers.Length(); ++i) {
|
||||
if (this == mContext->mBoundSamplers[i])
|
||||
mContext->InvalidateResolveCacheForTextureWithTexUnit(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLSampler)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLSampler, AddRef)
|
||||
|
|
|
@ -19,6 +19,7 @@ class WebGLSampler final
|
|||
, public WebGLContextBoundObject
|
||||
{
|
||||
friend class WebGLContext2;
|
||||
friend class WebGLTexture;
|
||||
|
||||
public:
|
||||
explicit WebGLSampler(WebGLContext* webgl, GLuint sampler);
|
||||
|
@ -30,11 +31,24 @@ public:
|
|||
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
|
||||
|
||||
void SamplerParameter1i(GLenum pname, GLint param);
|
||||
void SamplerParameter1f(GLenum pname, GLfloat 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;
|
||||
GLint mMinLod;
|
||||
GLint mMaxLod;
|
||||
TexCompareMode mCompareMode;
|
||||
TexCompareFunc mCompareFunc;
|
||||
|
||||
private:
|
||||
~WebGLSampler();
|
||||
};
|
||||
|
|
|
@ -269,6 +269,22 @@ STRONG_GLENUM_BEGIN(TexWrap)
|
|||
STRONG_GLENUM_VALUE(MIRRORED_REPEAT),
|
||||
STRONG_GLENUM_END(TexWrap)
|
||||
|
||||
STRONG_GLENUM_BEGIN(TexCompareMode)
|
||||
STRONG_GLENUM_VALUE(NONE),
|
||||
STRONG_GLENUM_VALUE(COMPARE_REF_TO_TEXTURE),
|
||||
STRONG_GLENUM_END(TexCompareMode)
|
||||
|
||||
STRONG_GLENUM_BEGIN(TexCompareFunc)
|
||||
STRONG_GLENUM_VALUE(LEQUAL),
|
||||
STRONG_GLENUM_VALUE(GEQUAL),
|
||||
STRONG_GLENUM_VALUE(LESS),
|
||||
STRONG_GLENUM_VALUE(GREATER),
|
||||
STRONG_GLENUM_VALUE(EQUAL),
|
||||
STRONG_GLENUM_VALUE(NOTEQUAL),
|
||||
STRONG_GLENUM_VALUE(ALWAYS),
|
||||
STRONG_GLENUM_VALUE(NEVER),
|
||||
STRONG_GLENUM_END(TexCompareFunc)
|
||||
|
||||
STRONG_GLENUM_BEGIN(TexFormat)
|
||||
STRONG_GLENUM_VALUE(NONE), // 0x0000
|
||||
STRONG_GLENUM_VALUE(DEPTH_COMPONENT), // 0x1902
|
||||
|
|
|
@ -190,12 +190,12 @@ WebGLTexture::SetImageInfosAtLevel(uint32_t level, const ImageInfo& newInfo)
|
|||
}
|
||||
|
||||
bool
|
||||
WebGLTexture::IsMipmapComplete() const
|
||||
WebGLTexture::IsMipmapComplete(uint32_t texUnit) const
|
||||
{
|
||||
MOZ_ASSERT(DoesMinFilterRequireMipmap());
|
||||
// GLES 3.0.4, p161
|
||||
|
||||
const uint32_t maxLevel = MaxEffectiveMipmapLevel();
|
||||
const uint32_t maxLevel = MaxEffectiveMipmapLevel(texUnit);
|
||||
|
||||
// "* `level_base <= level_max`"
|
||||
if (mBaseMipmapLevel > maxLevel)
|
||||
|
@ -290,7 +290,7 @@ WebGLTexture::IsCubeComplete() const
|
|||
}
|
||||
|
||||
bool
|
||||
WebGLTexture::IsComplete(const char** const out_reason) const
|
||||
WebGLTexture::IsComplete(uint32_t texUnit, const char** const out_reason) const
|
||||
{
|
||||
// Texture completeness is established at GLES 3.0.4, p160-161.
|
||||
// "[A] texture is complete unless any of the following conditions hold true:"
|
||||
|
@ -315,19 +315,23 @@ WebGLTexture::IsComplete(const char** const out_reason) const
|
|||
return false;
|
||||
}
|
||||
|
||||
WebGLSampler* sampler = mContext->mBoundSamplers[texUnit];
|
||||
TexMinFilter minFilter = sampler ? sampler->mMinFilter : mMinFilter;
|
||||
TexMagFilter magFilter = sampler ? sampler->mMagFilter : mMagFilter;
|
||||
|
||||
// "* The minification filter requires a mipmap (is neither NEAREST nor LINEAR) and
|
||||
// the texture is not mipmap complete."
|
||||
const bool requiresMipmap = (mMinFilter != LOCAL_GL_NEAREST &&
|
||||
mMinFilter != LOCAL_GL_LINEAR);
|
||||
if (requiresMipmap && !IsMipmapComplete()) {
|
||||
const bool requiresMipmap = (minFilter != LOCAL_GL_NEAREST &&
|
||||
minFilter != LOCAL_GL_LINEAR);
|
||||
if (requiresMipmap && !IsMipmapComplete(texUnit)) {
|
||||
*out_reason = "Because the minification filter requires mipmapping, the texture"
|
||||
" must be \"mipmap complete\".";
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool isMinFilteringNearest = (mMinFilter == LOCAL_GL_NEAREST ||
|
||||
mMinFilter == LOCAL_GL_NEAREST_MIPMAP_NEAREST);
|
||||
const bool isMagFilteringNearest = (mMagFilter == LOCAL_GL_NEAREST);
|
||||
const bool isMinFilteringNearest = (minFilter == LOCAL_GL_NEAREST ||
|
||||
minFilter == LOCAL_GL_NEAREST_MIPMAP_NEAREST);
|
||||
const bool isMagFilteringNearest = (magFilter == LOCAL_GL_NEAREST);
|
||||
const bool isFilteringNearestOnly = (isMinFilteringNearest && isMagFilteringNearest);
|
||||
if (!isFilteringNearestOnly) {
|
||||
auto formatUsage = baseImageInfo.mFormat;
|
||||
|
@ -394,9 +398,11 @@ WebGLTexture::IsComplete(const char** const out_reason) const
|
|||
// 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 (mWrapS != LOCAL_GL_CLAMP_TO_EDGE ||
|
||||
mWrapT != LOCAL_GL_CLAMP_TO_EDGE)
|
||||
if (wrapS != LOCAL_GL_CLAMP_TO_EDGE ||
|
||||
wrapT != LOCAL_GL_CLAMP_TO_EDGE)
|
||||
{
|
||||
*out_reason = "Non-power-of-two textures must have a wrap mode of"
|
||||
" CLAMP_TO_EDGE.";
|
||||
|
@ -421,10 +427,12 @@ WebGLTexture::IsComplete(const char** const out_reason) const
|
|||
|
||||
|
||||
uint32_t
|
||||
WebGLTexture::MaxEffectiveMipmapLevel() const
|
||||
WebGLTexture::MaxEffectiveMipmapLevel(uint32_t texUnit) const
|
||||
{
|
||||
if (mMinFilter == LOCAL_GL_NEAREST ||
|
||||
mMinFilter == LOCAL_GL_LINEAR)
|
||||
WebGLSampler* sampler = mContext->mBoundSamplers[texUnit];
|
||||
TexMinFilter minFilter = sampler ? sampler->mMinFilter : mMinFilter;
|
||||
if (minFilter == LOCAL_GL_NEAREST ||
|
||||
minFilter == LOCAL_GL_LINEAR)
|
||||
{
|
||||
// No mips used.
|
||||
return mBaseMipmapLevel;
|
||||
|
@ -442,7 +450,7 @@ WebGLTexture::GetFakeBlackType(const char* funcName, uint32_t texUnit,
|
|||
FakeBlackType* const out_fakeBlack)
|
||||
{
|
||||
const char* incompleteReason;
|
||||
if (!IsComplete(&incompleteReason)) {
|
||||
if (!IsComplete(texUnit, &incompleteReason)) {
|
||||
if (incompleteReason) {
|
||||
mContext->GenerateWarning("%s: Active texture %u for target 0x%04x is"
|
||||
" 'incomplete', and will be rendered as"
|
||||
|
@ -458,7 +466,7 @@ WebGLTexture::GetFakeBlackType(const char* funcName, uint32_t texUnit,
|
|||
bool hasUninitializedData = false;
|
||||
bool hasInitializedData = false;
|
||||
|
||||
const auto maxLevel = MaxEffectiveMipmapLevel();
|
||||
const auto maxLevel = MaxEffectiveMipmapLevel(texUnit);
|
||||
MOZ_ASSERT(mBaseMipmapLevel <= maxLevel);
|
||||
for (uint32_t level = mBaseMipmapLevel; level <= maxLevel; level++) {
|
||||
for (uint8_t face = 0; face < mFaceCount; face++) {
|
||||
|
|
|
@ -284,7 +284,7 @@ protected:
|
|||
|
||||
void PopulateMipChain(uint32_t baseLevel, uint32_t maxLevel);
|
||||
|
||||
uint32_t MaxEffectiveMipmapLevel() const;
|
||||
uint32_t MaxEffectiveMipmapLevel(uint32_t texUnit) const;
|
||||
|
||||
static uint8_t FaceForTarget(TexImageTarget texImageTarget) {
|
||||
GLenum rawTexImageTarget = texImageTarget.get();
|
||||
|
@ -369,11 +369,11 @@ public:
|
|||
|
||||
bool AreAllLevel0ImageInfosEqual() const;
|
||||
|
||||
bool IsMipmapComplete() const;
|
||||
bool IsMipmapComplete(uint32_t texUnit) const;
|
||||
|
||||
bool IsCubeComplete() const;
|
||||
|
||||
bool IsComplete(const char** const out_reason) const;
|
||||
bool IsComplete(uint32_t texUnit, const char** const out_reason) const;
|
||||
|
||||
bool IsMipmapCubeComplete() const;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче