mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 13:56:29 +00:00
Bug 1329815 - GeneratePerfWarning and warn on completed-FB invalidation. - r=kvark
MozReview-Commit-ID: C9J3qdnsaZF
This commit is contained in:
parent
9d6dc35064
commit
4da6480883
@ -114,6 +114,9 @@ WebGLContextOptions::WebGLContextOptions()
|
||||
|
||||
WebGLContext::WebGLContext()
|
||||
: WebGLContextUnchecked(nullptr)
|
||||
, mMaxPerfWarnings(gfxPrefs::WebGLMaxPerfWarnings())
|
||||
, mNumPerfWarnings(0)
|
||||
, mMaxAcceptableFBStatusInvals(gfxPrefs::WebGLMaxAcceptableFBStatusInvals())
|
||||
, mBufferFetchingIsVerified(false)
|
||||
, mBufferFetchingHasPerVertex(false)
|
||||
, mMaxFetchedVertices(0)
|
||||
|
@ -331,6 +331,10 @@ class WebGLContext
|
||||
static const uint32_t kMinMaxColorAttachments;
|
||||
static const uint32_t kMinMaxDrawBuffers;
|
||||
|
||||
const uint32_t mMaxPerfWarnings;
|
||||
mutable uint64_t mNumPerfWarnings;
|
||||
const uint32_t mMaxAcceptableFBStatusInvals;
|
||||
|
||||
public:
|
||||
WebGLContext();
|
||||
|
||||
@ -1937,6 +1941,10 @@ protected:
|
||||
|
||||
bool ShouldGenerateWarnings() const;
|
||||
|
||||
bool ShouldGeneratePerfWarnings() const {
|
||||
return mNumPerfWarnings < mMaxPerfWarnings;
|
||||
}
|
||||
|
||||
uint64_t mLastUseIndex;
|
||||
|
||||
bool mNeedsFakeNoAlpha;
|
||||
@ -2029,6 +2037,8 @@ public:
|
||||
void GenerateWarning(const char* fmt, ...);
|
||||
void GenerateWarning(const char* fmt, va_list ap);
|
||||
|
||||
void GeneratePerfWarning(const char* fmt, ...) const;
|
||||
|
||||
public:
|
||||
UniquePtr<webgl::FormatUsageAuthority> mFormatUsage;
|
||||
|
||||
|
@ -348,16 +348,17 @@ WebGLContext::DeleteFramebuffer(WebGLFramebuffer* fbuf)
|
||||
void
|
||||
WebGLContext::DeleteRenderbuffer(WebGLRenderbuffer* rbuf)
|
||||
{
|
||||
if (!ValidateDeleteObject("deleteRenderbuffer", rbuf))
|
||||
const char funcName[] = "deleteRenderbuffer";
|
||||
if (!ValidateDeleteObject(funcName, rbuf))
|
||||
return;
|
||||
|
||||
if (mBoundDrawFramebuffer)
|
||||
mBoundDrawFramebuffer->DetachRenderbuffer(rbuf);
|
||||
mBoundDrawFramebuffer->DetachRenderbuffer(funcName, rbuf);
|
||||
|
||||
if (mBoundReadFramebuffer)
|
||||
mBoundReadFramebuffer->DetachRenderbuffer(rbuf);
|
||||
mBoundReadFramebuffer->DetachRenderbuffer(funcName, rbuf);
|
||||
|
||||
rbuf->InvalidateStatusOfAttachedFBs();
|
||||
rbuf->InvalidateStatusOfAttachedFBs(funcName);
|
||||
|
||||
if (mBoundRenderbuffer == rbuf)
|
||||
BindRenderbuffer(LOCAL_GL_RENDERBUFFER, nullptr);
|
||||
@ -368,14 +369,15 @@ WebGLContext::DeleteRenderbuffer(WebGLRenderbuffer* rbuf)
|
||||
void
|
||||
WebGLContext::DeleteTexture(WebGLTexture* tex)
|
||||
{
|
||||
if (!ValidateDeleteObject("deleteTexture", tex))
|
||||
const char funcName[] = "deleteTexture";
|
||||
if (!ValidateDeleteObject(funcName, tex))
|
||||
return;
|
||||
|
||||
if (mBoundDrawFramebuffer)
|
||||
mBoundDrawFramebuffer->DetachTexture(tex);
|
||||
mBoundDrawFramebuffer->DetachTexture(funcName, tex);
|
||||
|
||||
if (mBoundReadFramebuffer)
|
||||
mBoundReadFramebuffer->DetachTexture(tex);
|
||||
mBoundReadFramebuffer->DetachTexture(funcName, tex);
|
||||
|
||||
GLuint activeTexture = mActiveTexture;
|
||||
for (int32_t i = 0; i < mGLMaxTextureUnits; i++) {
|
||||
|
@ -90,7 +90,7 @@ WebGLContext::GenerateWarning(const char* fmt, va_list ap)
|
||||
}
|
||||
|
||||
JSContext* cx = api.cx();
|
||||
JS_ReportWarningASCII(cx, "WebGL: %s", buf);
|
||||
JS_ReportWarningASCII(cx, "WebGL warning: %s", buf);
|
||||
if (!ShouldGenerateWarnings()) {
|
||||
JS_ReportWarningASCII(cx,
|
||||
"WebGL: No further warnings will be reported for"
|
||||
@ -109,6 +109,43 @@ WebGLContext::ShouldGenerateWarnings() const
|
||||
return mAlreadyGeneratedWarnings < mMaxWarnings;
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::GeneratePerfWarning(const char* fmt, ...) const
|
||||
{
|
||||
if (!ShouldGeneratePerfWarnings())
|
||||
return;
|
||||
|
||||
if (!mCanvasElement)
|
||||
return;
|
||||
|
||||
dom::AutoJSAPI api;
|
||||
if (!api.Init(mCanvasElement->OwnerDoc()->GetScopeObject()))
|
||||
return;
|
||||
JSContext* cx = api.cx();
|
||||
|
||||
////
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
char buf[1024];
|
||||
PR_vsnprintf(buf, 1024, fmt, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
////
|
||||
|
||||
JS_ReportWarningASCII(cx, "WebGL perf warning: %s", buf);
|
||||
mNumPerfWarnings++;
|
||||
|
||||
if (!ShouldGeneratePerfWarnings()) {
|
||||
JS_ReportWarningASCII(cx,
|
||||
"WebGL: After reporting %u, no further perf warnings will"
|
||||
" be reported for this WebGL context.",
|
||||
uint32_t(mNumPerfWarnings));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::SynthesizeGLError(GLenum err)
|
||||
{
|
||||
|
@ -47,7 +47,8 @@ WebGLFBAttachPoint::~WebGLFBAttachPoint()
|
||||
void
|
||||
WebGLFBAttachPoint::Unlink()
|
||||
{
|
||||
Clear();
|
||||
const char funcName[] = "WebGLFramebuffer::GC";
|
||||
Clear(funcName);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -114,7 +115,7 @@ WebGLFBAttachPoint::IsReadableFloat() const
|
||||
}
|
||||
|
||||
void
|
||||
WebGLFBAttachPoint::Clear()
|
||||
WebGLFBAttachPoint::Clear(const char* funcName)
|
||||
{
|
||||
if (mRenderbufferPtr) {
|
||||
MOZ_ASSERT(!mTexturePtr);
|
||||
@ -126,14 +127,14 @@ WebGLFBAttachPoint::Clear()
|
||||
mTexturePtr = nullptr;
|
||||
mRenderbufferPtr = nullptr;
|
||||
|
||||
OnBackingStoreRespecified();
|
||||
OnBackingStoreRespecified(funcName);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLFBAttachPoint::SetTexImage(WebGLTexture* tex, TexImageTarget target, GLint level,
|
||||
GLint layer)
|
||||
WebGLFBAttachPoint::SetTexImage(const char* funcName, WebGLTexture* tex,
|
||||
TexImageTarget target, GLint level, GLint layer)
|
||||
{
|
||||
Clear();
|
||||
Clear(funcName);
|
||||
|
||||
mTexturePtr = tex;
|
||||
mTexImageTarget = target;
|
||||
@ -146,9 +147,9 @@ WebGLFBAttachPoint::SetTexImage(WebGLTexture* tex, TexImageTarget target, GLint
|
||||
}
|
||||
|
||||
void
|
||||
WebGLFBAttachPoint::SetRenderbuffer(WebGLRenderbuffer* rb)
|
||||
WebGLFBAttachPoint::SetRenderbuffer(const char* funcName, WebGLRenderbuffer* rb)
|
||||
{
|
||||
Clear();
|
||||
Clear(funcName);
|
||||
|
||||
mRenderbufferPtr = rb;
|
||||
|
||||
@ -226,9 +227,9 @@ WebGLFBAttachPoint::Size(uint32_t* const out_width, uint32_t* const out_height)
|
||||
}
|
||||
|
||||
void
|
||||
WebGLFBAttachPoint::OnBackingStoreRespecified() const
|
||||
WebGLFBAttachPoint::OnBackingStoreRespecified(const char* funcName) const
|
||||
{
|
||||
mFB->InvalidateFramebufferStatus();
|
||||
mFB->InvalidateFramebufferStatus(funcName);
|
||||
}
|
||||
|
||||
void
|
||||
@ -619,6 +620,7 @@ WebGLFBAttachPoint::GetParameter(const char* funcName, WebGLContext* webgl, JSCo
|
||||
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* webgl, GLuint fbo)
|
||||
: WebGLRefCountedObject(webgl)
|
||||
, mGLName(fbo)
|
||||
, mNumFBStatusInvals(0)
|
||||
#ifdef ANDROID
|
||||
, mIsFB(false)
|
||||
#endif
|
||||
@ -641,14 +643,16 @@ WebGLFramebuffer::WebGLFramebuffer(WebGLContext* webgl, GLuint fbo)
|
||||
void
|
||||
WebGLFramebuffer::Delete()
|
||||
{
|
||||
InvalidateFramebufferStatus();
|
||||
const char funcName[] = "WebGLFramebuffer::Delete";
|
||||
|
||||
mDepthAttachment.Clear();
|
||||
mStencilAttachment.Clear();
|
||||
mDepthStencilAttachment.Clear();
|
||||
InvalidateFramebufferStatus(funcName);
|
||||
|
||||
mDepthAttachment.Clear(funcName);
|
||||
mStencilAttachment.Clear(funcName);
|
||||
mDepthStencilAttachment.Clear(funcName);
|
||||
|
||||
for (auto& cur : mColorAttachments) {
|
||||
cur.Clear();
|
||||
cur.Clear(funcName);
|
||||
}
|
||||
|
||||
mContext->MakeContextCurrent();
|
||||
@ -709,11 +713,11 @@ WebGLFramebuffer::GetAttachPoint(GLenum attachPoint)
|
||||
}
|
||||
|
||||
void
|
||||
WebGLFramebuffer::DetachTexture(const WebGLTexture* tex)
|
||||
WebGLFramebuffer::DetachTexture(const char* funcName, const WebGLTexture* tex)
|
||||
{
|
||||
const auto fnDetach = [&](WebGLFBAttachPoint& attach) {
|
||||
if (attach.Texture() == tex) {
|
||||
attach.Clear();
|
||||
attach.Clear(funcName);
|
||||
}
|
||||
};
|
||||
|
||||
@ -721,11 +725,11 @@ WebGLFramebuffer::DetachTexture(const WebGLTexture* tex)
|
||||
}
|
||||
|
||||
void
|
||||
WebGLFramebuffer::DetachRenderbuffer(const WebGLRenderbuffer* rb)
|
||||
WebGLFramebuffer::DetachRenderbuffer(const char* funcName, const WebGLRenderbuffer* rb)
|
||||
{
|
||||
const auto fnDetach = [&](WebGLFBAttachPoint& attach) {
|
||||
if (attach.Renderbuffer() == rb) {
|
||||
attach.Clear();
|
||||
attach.Clear(funcName);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1135,6 +1139,21 @@ WebGLFramebuffer::ResolvedData::ResolvedData(const WebGLFramebuffer& parent)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGLFramebuffer::InvalidateFramebufferStatus(const char* funcName)
|
||||
{
|
||||
if (mResolvedCompleteData) {
|
||||
mNumFBStatusInvals++;
|
||||
if (mNumFBStatusInvals > mContext->mMaxAcceptableFBStatusInvals) {
|
||||
mContext->GeneratePerfWarning("%s: FB was invalidated after being complete %u"
|
||||
" times.",
|
||||
funcName, uint32_t(mNumFBStatusInvals));
|
||||
}
|
||||
}
|
||||
|
||||
mResolvedCompleteData = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
WebGLFramebuffer::RefreshResolvedData()
|
||||
{
|
||||
@ -1354,13 +1373,13 @@ WebGLFramebuffer::FramebufferRenderbuffer(const char* funcName, GLenum attachEnu
|
||||
// End of validation.
|
||||
|
||||
if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
|
||||
mDepthAttachment.SetRenderbuffer(rb);
|
||||
mStencilAttachment.SetRenderbuffer(rb);
|
||||
mDepthAttachment.SetRenderbuffer(funcName, rb);
|
||||
mStencilAttachment.SetRenderbuffer(funcName, rb);
|
||||
} else {
|
||||
attach->SetRenderbuffer(rb);
|
||||
attach->SetRenderbuffer(funcName, rb);
|
||||
}
|
||||
|
||||
InvalidateFramebufferStatus();
|
||||
InvalidateFramebufferStatus(funcName);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1442,13 +1461,13 @@ WebGLFramebuffer::FramebufferTexture2D(const char* funcName, GLenum attachEnum,
|
||||
// End of validation.
|
||||
|
||||
if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
|
||||
mDepthAttachment.SetTexImage(tex, texImageTarget, level);
|
||||
mStencilAttachment.SetTexImage(tex, texImageTarget, level);
|
||||
mDepthAttachment.SetTexImage(funcName, tex, texImageTarget, level);
|
||||
mStencilAttachment.SetTexImage(funcName, tex, texImageTarget, level);
|
||||
} else {
|
||||
attach->SetTexImage(tex, texImageTarget, level);
|
||||
attach->SetTexImage(funcName, tex, texImageTarget, level);
|
||||
}
|
||||
|
||||
InvalidateFramebufferStatus();
|
||||
InvalidateFramebufferStatus(funcName);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1526,13 +1545,13 @@ WebGLFramebuffer::FramebufferTextureLayer(const char* funcName, GLenum attachEnu
|
||||
// End of validation.
|
||||
|
||||
if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
|
||||
mDepthAttachment.SetTexImage(tex, texImageTarget, level, layer);
|
||||
mStencilAttachment.SetTexImage(tex, texImageTarget, level, layer);
|
||||
mDepthAttachment.SetTexImage(funcName, tex, texImageTarget, level, layer);
|
||||
mStencilAttachment.SetTexImage(funcName, tex, texImageTarget, level, layer);
|
||||
} else {
|
||||
attach->SetTexImage(tex, texImageTarget, level, layer);
|
||||
attach->SetTexImage(funcName, tex, texImageTarget, level, layer);
|
||||
}
|
||||
|
||||
InvalidateFramebufferStatus();
|
||||
InvalidateFramebufferStatus(funcName);
|
||||
}
|
||||
|
||||
JS::Value
|
||||
|
@ -66,11 +66,11 @@ public:
|
||||
bool HasAlpha() const;
|
||||
bool IsReadableFloat() const;
|
||||
|
||||
void Clear();
|
||||
void Clear(const char* funcName);
|
||||
|
||||
void SetTexImage(WebGLTexture* tex, TexImageTarget target, GLint level,
|
||||
GLint layer = 0);
|
||||
void SetRenderbuffer(WebGLRenderbuffer* rb);
|
||||
void SetTexImage(const char* funcName, WebGLTexture* tex, TexImageTarget target,
|
||||
GLint level, GLint layer = 0);
|
||||
void SetRenderbuffer(const char* funcName, WebGLRenderbuffer* rb);
|
||||
|
||||
WebGLTexture* Texture() const { return mTexturePtr; }
|
||||
WebGLRenderbuffer* Renderbuffer() const { return mRenderbufferPtr; }
|
||||
@ -100,7 +100,7 @@ public:
|
||||
GLenum target, GLenum attachment, GLenum pname,
|
||||
ErrorResult* const out_error) const;
|
||||
|
||||
void OnBackingStoreRespecified() const;
|
||||
void OnBackingStoreRespecified(const char* funcName) const;
|
||||
|
||||
bool IsEquivalentForFeedback(const WebGLFBAttachPoint& other) const {
|
||||
if (!IsDefined() || !other.IsDefined())
|
||||
@ -154,6 +154,9 @@ public:
|
||||
|
||||
const GLuint mGLName;
|
||||
|
||||
private:
|
||||
uint64_t mNumFBStatusInvals;
|
||||
|
||||
protected:
|
||||
#ifdef ANDROID
|
||||
// Bug 1140459: Some drivers (including our test slaves!) don't
|
||||
@ -230,8 +233,8 @@ protected:
|
||||
bool ResolveAttachmentData(const char* funcName) const;
|
||||
|
||||
public:
|
||||
void DetachTexture(const WebGLTexture* tex);
|
||||
void DetachRenderbuffer(const WebGLRenderbuffer* rb);
|
||||
void DetachTexture(const char* funcName, const WebGLTexture* tex);
|
||||
void DetachRenderbuffer(const char* funcName, const WebGLRenderbuffer* rb);
|
||||
bool ValidateAndInitAttachments(const char* funcName);
|
||||
bool ValidateClearBufferType(const char* funcName, GLenum buffer, uint32_t drawBuffer,
|
||||
GLenum funcType) const;
|
||||
@ -258,11 +261,7 @@ public:
|
||||
// Invalidation
|
||||
|
||||
bool IsResolvedComplete() const { return bool(mResolvedCompleteData); }
|
||||
|
||||
void InvalidateFramebufferStatus() {
|
||||
mResolvedCompleteData = nullptr;
|
||||
}
|
||||
|
||||
void InvalidateFramebufferStatus(const char* funcName);
|
||||
void RefreshResolvedData();
|
||||
|
||||
////////////////
|
||||
|
@ -31,12 +31,12 @@ WebGLFramebufferAttachable::UnmarkAttachment(const WebGLFBAttachPoint& attachmen
|
||||
}
|
||||
|
||||
void
|
||||
WebGLFramebufferAttachable::InvalidateStatusOfAttachedFBs() const
|
||||
WebGLFramebufferAttachable::InvalidateStatusOfAttachedFBs(const char* funcName) const
|
||||
{
|
||||
const size_t count = mAttachmentPoints.Length();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
MOZ_ASSERT(mAttachmentPoints[i]->mFB);
|
||||
mAttachmentPoints[i]->mFB->InvalidateFramebufferStatus();
|
||||
mAttachmentPoints[i]->mFB->InvalidateFramebufferStatus(funcName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
// Track FBO/Attachment combinations
|
||||
void MarkAttachment(const WebGLFBAttachPoint& attachment);
|
||||
void UnmarkAttachment(const WebGLFBAttachPoint& attachment);
|
||||
void InvalidateStatusOfAttachedFBs() const;
|
||||
void InvalidateStatusOfAttachedFBs(const char* funcName) const;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -224,7 +224,7 @@ WebGLRenderbuffer::RenderbufferStorage(const char* funcName, uint32_t samples,
|
||||
mHeight = height;
|
||||
mImageDataStatus = WebGLImageDataStatus::UninitializedImageData;
|
||||
|
||||
InvalidateStatusOfAttachedFBs();
|
||||
InvalidateStatusOfAttachedFBs(funcName);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -33,12 +33,12 @@ Mutable(const T& x)
|
||||
}
|
||||
|
||||
void
|
||||
WebGLTexture::ImageInfo::Clear()
|
||||
WebGLTexture::ImageInfo::Clear(const char* funcName)
|
||||
{
|
||||
if (!IsDefined())
|
||||
return;
|
||||
|
||||
OnRespecify();
|
||||
OnRespecify(funcName);
|
||||
|
||||
Mutable(mFormat) = LOCAL_GL_NONE;
|
||||
Mutable(mWidth) = 0;
|
||||
@ -48,8 +48,8 @@ WebGLTexture::ImageInfo::Clear()
|
||||
MOZ_ASSERT(!IsDefined());
|
||||
}
|
||||
|
||||
WebGLTexture::ImageInfo&
|
||||
WebGLTexture::ImageInfo::operator =(const ImageInfo& a)
|
||||
void
|
||||
WebGLTexture::ImageInfo::Set(const char* funcName, const ImageInfo& a)
|
||||
{
|
||||
MOZ_ASSERT(a.IsDefined());
|
||||
|
||||
@ -62,9 +62,7 @@ WebGLTexture::ImageInfo::operator =(const ImageInfo& a)
|
||||
|
||||
// But *don't* transfer mAttachPoints!
|
||||
MOZ_ASSERT(a.mAttachPoints.empty());
|
||||
OnRespecify();
|
||||
|
||||
return *this;
|
||||
OnRespecify(funcName);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -91,10 +89,10 @@ WebGLTexture::ImageInfo::RemoveAttachPoint(WebGLFBAttachPoint* attachPoint)
|
||||
}
|
||||
|
||||
void
|
||||
WebGLTexture::ImageInfo::OnRespecify() const
|
||||
WebGLTexture::ImageInfo::OnRespecify(const char* funcName) const
|
||||
{
|
||||
for (auto cur : mAttachPoints) {
|
||||
cur->OnBackingStoreRespecified();
|
||||
cur->OnBackingStoreRespecified(funcName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,8 +147,9 @@ WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex)
|
||||
void
|
||||
WebGLTexture::Delete()
|
||||
{
|
||||
const char funcName[] = "WebGLTexture::Delete";
|
||||
for (auto& cur : mImageInfoArr) {
|
||||
cur.Clear();
|
||||
cur.Clear(funcName);
|
||||
}
|
||||
|
||||
mContext->MakeContextCurrent();
|
||||
@ -173,18 +172,20 @@ WebGLTexture::MemoryUsage() const
|
||||
}
|
||||
|
||||
void
|
||||
WebGLTexture::SetImageInfo(ImageInfo* target, const ImageInfo& newInfo)
|
||||
WebGLTexture::SetImageInfo(const char* funcName, ImageInfo* target,
|
||||
const ImageInfo& newInfo)
|
||||
{
|
||||
*target = newInfo;
|
||||
target->Set(funcName, newInfo);
|
||||
|
||||
InvalidateResolveCache();
|
||||
}
|
||||
|
||||
void
|
||||
WebGLTexture::SetImageInfosAtLevel(uint32_t level, const ImageInfo& newInfo)
|
||||
WebGLTexture::SetImageInfosAtLevel(const char* funcName, uint32_t level,
|
||||
const ImageInfo& newInfo)
|
||||
{
|
||||
for (uint8_t i = 0; i < mFaceCount; i++) {
|
||||
ImageInfoAtFace(i, level) = newInfo;
|
||||
ImageInfoAtFace(i, level).Set(funcName, newInfo);
|
||||
}
|
||||
|
||||
InvalidateResolveCache();
|
||||
@ -773,7 +774,8 @@ WebGLTexture::ClampLevelBaseAndMax()
|
||||
}
|
||||
|
||||
void
|
||||
WebGLTexture::PopulateMipChain(uint32_t firstLevel, uint32_t lastLevel)
|
||||
WebGLTexture::PopulateMipChain(const char* funcName, uint32_t firstLevel,
|
||||
uint32_t lastLevel)
|
||||
{
|
||||
const ImageInfo& baseImageInfo = ImageInfoAtFace(0, firstLevel);
|
||||
MOZ_ASSERT(baseImageInfo.IsDefined());
|
||||
@ -804,7 +806,7 @@ WebGLTexture::PopulateMipChain(uint32_t firstLevel, uint32_t lastLevel)
|
||||
const ImageInfo cur(baseImageInfo.mFormat, refWidth, refHeight, refDepth,
|
||||
baseImageInfo.IsDataInitialized());
|
||||
|
||||
SetImageInfosAtLevel(level, cur);
|
||||
SetImageInfosAtLevel(funcName, level, cur);
|
||||
}
|
||||
}
|
||||
|
||||
@ -854,6 +856,7 @@ WebGLTexture::BindTexture(TexTarget texTarget)
|
||||
void
|
||||
WebGLTexture::GenerateMipmap(TexTarget texTarget)
|
||||
{
|
||||
const char funcName[] = "generateMipmap";
|
||||
// GLES 3.0.4 p160:
|
||||
// "Mipmap generation replaces texel array levels level base + 1 through q with arrays
|
||||
// derived from the level base array, regardless of their previous contents. All
|
||||
@ -861,33 +864,35 @@ WebGLTexture::GenerateMipmap(TexTarget texTarget)
|
||||
// computation."
|
||||
const ImageInfo& baseImageInfo = BaseImageInfo();
|
||||
if (!baseImageInfo.IsDefined()) {
|
||||
mContext->ErrorInvalidOperation("generateMipmap: The base level of the texture is"
|
||||
" not defined.");
|
||||
mContext->ErrorInvalidOperation("%s: The base level of the texture is not"
|
||||
" defined.",
|
||||
funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsCubeMap() && !IsCubeComplete()) {
|
||||
mContext->ErrorInvalidOperation("generateMipmap: Cube maps must be \"cube"
|
||||
" complete\".");
|
||||
mContext->ErrorInvalidOperation("%s: Cube maps must be \"cube complete\".",
|
||||
funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mContext->IsWebGL2() && !baseImageInfo.IsPowerOfTwo()) {
|
||||
mContext->ErrorInvalidOperation("generateMipmap: The base level of the texture"
|
||||
" does not have power-of-two dimensions.");
|
||||
mContext->ErrorInvalidOperation("%s: The base level of the texture does not have"
|
||||
" power-of-two dimensions.",
|
||||
funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
auto format = baseImageInfo.mFormat->format;
|
||||
if (format->compression) {
|
||||
mContext->ErrorInvalidOperation("generateMipmap: Texture data at base level is"
|
||||
" compressed.");
|
||||
mContext->ErrorInvalidOperation("%s: Texture data at base level is compressed.",
|
||||
funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (format->d) {
|
||||
mContext->ErrorInvalidOperation("generateMipmap: Depth textures are not"
|
||||
" supported.");
|
||||
mContext->ErrorInvalidOperation("%s: Depth textures are not supported.",
|
||||
funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -910,9 +915,10 @@ WebGLTexture::GenerateMipmap(TexTarget texTarget)
|
||||
}
|
||||
|
||||
if (!canGenerateMipmap) {
|
||||
mContext->ErrorInvalidOperation("generateMipmap: Texture at base level is not unsized"
|
||||
mContext->ErrorInvalidOperation("%s: Texture at base level is not unsized"
|
||||
" internal format or is not"
|
||||
" color-renderable or texture-filterable.");
|
||||
" color-renderable or texture-filterable.",
|
||||
funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -940,7 +946,7 @@ WebGLTexture::GenerateMipmap(TexTarget texTarget)
|
||||
// Note that we don't use MaxEffectiveMipmapLevel() here, since that returns
|
||||
// mBaseMipmapLevel if the min filter doesn't require mipmaps.
|
||||
const uint32_t maxLevel = mBaseMipmapLevel + baseImageInfo.PossibleMipmapLevels() - 1;
|
||||
PopulateMipChain(mBaseMipmapLevel, maxLevel);
|
||||
PopulateMipChain(funcName, mBaseMipmapLevel, maxLevel);
|
||||
}
|
||||
|
||||
JS::Value
|
||||
|
@ -105,17 +105,19 @@ public:
|
||||
// And in turn, it needs these forwards:
|
||||
protected:
|
||||
// We need to forward these.
|
||||
void SetImageInfo(ImageInfo* target, const ImageInfo& newInfo);
|
||||
void SetImageInfosAtLevel(uint32_t level, const ImageInfo& newInfo);
|
||||
void SetImageInfo(const char* funcName, ImageInfo* target, const ImageInfo& newInfo);
|
||||
void SetImageInfosAtLevel(const char* funcName, uint32_t level,
|
||||
const ImageInfo& newInfo);
|
||||
|
||||
public:
|
||||
// We store information about the various images that are part of this
|
||||
// texture. (cubemap faces, mipmap levels)
|
||||
class ImageInfo
|
||||
{
|
||||
friend void WebGLTexture::SetImageInfo(ImageInfo* target,
|
||||
friend void WebGLTexture::SetImageInfo(const char* funcName, ImageInfo* target,
|
||||
const ImageInfo& newInfo);
|
||||
friend void WebGLTexture::SetImageInfosAtLevel(uint32_t level,
|
||||
friend void WebGLTexture::SetImageInfosAtLevel(const char* funcName,
|
||||
uint32_t level,
|
||||
const ImageInfo& newInfo);
|
||||
|
||||
public:
|
||||
@ -155,15 +157,14 @@ public:
|
||||
MOZ_ASSERT(mFormat);
|
||||
}
|
||||
|
||||
void Clear();
|
||||
void Clear(const char* funcName);
|
||||
|
||||
~ImageInfo() {
|
||||
if (!IsDefined())
|
||||
Clear();
|
||||
MOZ_ASSERT(!mAttachPoints.size());
|
||||
}
|
||||
|
||||
protected:
|
||||
ImageInfo& operator =(const ImageInfo& a);
|
||||
void Set(const char* funcName, const ImageInfo& a);
|
||||
|
||||
public:
|
||||
uint32_t PossibleMipmapLevels() const {
|
||||
@ -177,7 +178,7 @@ public:
|
||||
|
||||
void AddAttachPoint(WebGLFBAttachPoint* attachPoint);
|
||||
void RemoveAttachPoint(WebGLFBAttachPoint* attachPoint);
|
||||
void OnRespecify() const;
|
||||
void OnRespecify(const char* funcName) const;
|
||||
|
||||
size_t MemoryUsage() const;
|
||||
|
||||
@ -289,7 +290,7 @@ public:
|
||||
protected:
|
||||
void ClampLevelBaseAndMax();
|
||||
|
||||
void PopulateMipChain(uint32_t baseLevel, uint32_t maxLevel);
|
||||
void PopulateMipChain(const char* funcName, uint32_t baseLevel, uint32_t maxLevel);
|
||||
|
||||
bool MaxEffectiveMipmapLevel(uint32_t texUnit, uint32_t* const out) const;
|
||||
|
||||
@ -330,11 +331,11 @@ public:
|
||||
return const_cast<WebGLTexture*>(this)->ImageInfoAt(texImageTarget, level);
|
||||
}
|
||||
|
||||
void SetImageInfoAt(TexImageTarget texImageTarget, GLint level,
|
||||
void SetImageInfoAt(const char* funcName, TexImageTarget texImageTarget, GLint level,
|
||||
const ImageInfo& val)
|
||||
{
|
||||
ImageInfo* target = &ImageInfoAt(texImageTarget, level);
|
||||
SetImageInfo(target, val);
|
||||
SetImageInfo(funcName, target, val);
|
||||
}
|
||||
|
||||
const ImageInfo& BaseImageInfo() const {
|
||||
|
@ -1185,9 +1185,9 @@ WebGLTexture::TexStorage(const char* funcName, TexTarget target, GLsizei levels,
|
||||
const bool isDataInitialized = false;
|
||||
const WebGLTexture::ImageInfo newInfo(dstUsage, width, height, depth,
|
||||
isDataInitialized);
|
||||
SetImageInfosAtLevel(0, newInfo);
|
||||
SetImageInfosAtLevel(funcName, 0, newInfo);
|
||||
|
||||
PopulateMipChain(0, levels-1);
|
||||
PopulateMipChain(funcName, 0, levels-1);
|
||||
|
||||
mImmutable = true;
|
||||
mImmutableLevelCount = levels;
|
||||
@ -1317,7 +1317,7 @@ WebGLTexture::TexImage(const char* funcName, TexImageTarget target, GLint level,
|
||||
////////////////////////////////////
|
||||
// Update our specification data.
|
||||
|
||||
SetImageInfo(imageInfo, newImageInfo);
|
||||
SetImageInfo(funcName, imageInfo, newImageInfo);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1523,7 +1523,7 @@ WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GL
|
||||
const bool isDataInitialized = true;
|
||||
const ImageInfo newImageInfo(usage, blob->mWidth, blob->mHeight, blob->mDepth,
|
||||
isDataInitialized);
|
||||
SetImageInfo(imageInfo, newImageInfo);
|
||||
SetImageInfo(funcName, imageInfo, newImageInfo);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
@ -2170,7 +2170,7 @@ WebGLTexture::CopyTexImage2D(TexImageTarget target, GLint level, GLenum internal
|
||||
|
||||
const bool isDataInitialized = true;
|
||||
const ImageInfo newImageInfo(dstUsage, width, height, depth, isDataInitialized);
|
||||
SetImageInfo(imageInfo, newImageInfo);
|
||||
SetImageInfo(funcName, imageInfo, newImageInfo);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -617,6 +617,9 @@ private:
|
||||
DECL_GFX_PREF(Live, "webgl.allow-immediate-queries", WebGLImmediateQueries, bool, false);
|
||||
DECL_GFX_PREF(Live, "webgl.allow-fb-invalidation", WebGLFBInvalidation, bool, false);
|
||||
|
||||
DECL_GFX_PREF(Live, "webgl.max-perf-warnings", WebGLMaxPerfWarnings, int32_t, 0);
|
||||
DECL_GFX_PREF(Live, "webgl.max-acceptable-fb-status-invals", WebGLMaxAcceptableFBStatusInvals, int32_t, 0);
|
||||
|
||||
DECL_GFX_PREF(Live, "webgl.webgl2-compat-mode", WebGL2CompatMode, bool, false);
|
||||
|
||||
// WARNING:
|
||||
|
@ -4510,6 +4510,9 @@ pref("webgl.disable-DOM-blit-uploads", false);
|
||||
pref("webgl.allow-fb-invalidation", false);
|
||||
pref("webgl.webgl2-compat-mode", false);
|
||||
|
||||
pref("webgl.max-perf-warnings", 0);
|
||||
pref("webgl.max-acceptable-fb-status-invals", 0);
|
||||
|
||||
pref("webgl.enable-webgl2", true);
|
||||
|
||||
#ifdef RELEASE_OR_BETA
|
||||
|
Loading…
x
Reference in New Issue
Block a user