Bug 1535809 - Add warning on use of implicitly enabled extensions r=jgilbert

Differential Revision: https://phabricator.services.mozilla.com/D36431

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Greyson Gilbert 2019-07-09 05:21:30 +00:00
Родитель e10bec305a
Коммит 5ab46fc0a3
13 изменённых файлов: 169 добавлений и 36 удалений

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

@ -1694,7 +1694,8 @@ class WebGLContext : public nsICanvasRenderingContextInternal,
// Enable an extension if it's supported. Return the extension on success. // Enable an extension if it's supported. Return the extension on success.
WebGLExtensionBase* EnableSupportedExtension(dom::CallerType callerType, WebGLExtensionBase* EnableSupportedExtension(dom::CallerType callerType,
WebGLExtensionID ext); WebGLExtensionID ext,
bool explict = true);
public: public:
// returns true if the extension has been enabled by calling getExtension. // returns true if the extension has been enabled by calling getExtension.
@ -1702,6 +1703,10 @@ class WebGLContext : public nsICanvasRenderingContextInternal,
return mExtensions[ext]; return mExtensions[ext];
} }
bool IsExtensionExplicit(const WebGLExtensionID ext) const;
void WarnIfImplicit(const WebGLExtensionID ext);
protected: protected:
// returns true if the extension is supported for this caller type (this // returns true if the extension is supported for this caller type (this
// decides what getSupportedExtensions exposes) // decides what getSupportedExtensions exposes)

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

@ -333,13 +333,15 @@ const webgl::CachedDrawFetchLimits* ValidateDraw(WebGLContext* const webgl,
if (!webgl->BindCurFBForDraw()) return nullptr; if (!webgl->BindCurFBForDraw()) return nullptr;
const auto& fb = webgl->mBoundDrawFramebuffer; const auto& fb = webgl->mBoundDrawFramebuffer;
if (fb && !webgl->IsExtensionEnabled(WebGLExtensionID::EXT_float_blend) && if (fb && webgl->mBlendEnabled) {
webgl->mBlendEnabled) {
const auto& info = *fb->GetCompletenessInfo(); const auto& info = *fb->GetCompletenessInfo();
if (info.hasFloat32) { if (info.hasFloat32) {
webgl->ErrorInvalidOperation( if (!webgl->IsExtensionEnabled(WebGLExtensionID::EXT_float_blend)) {
"Float32 blending requires EXT_float_blend."); webgl->ErrorInvalidOperation(
return nullptr; "Float32 blending requires EXT_float_blend.");
return nullptr;
}
webgl->WarnIfImplicit(WebGLExtensionID::EXT_float_blend);
} }
} }

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

@ -235,20 +235,44 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const {
return false; return false;
} }
bool WebGLContext::IsExtensionExplicit(const WebGLExtensionID ext) const {
MOZ_ASSERT(ext < WebGLExtensionID::Max);
return mExtensions[ext] && mExtensions[ext]->IsExplicit();
}
void WebGLContext::WarnIfImplicit(const WebGLExtensionID ext) {
MOZ_ASSERT(ext < WebGLExtensionID::Max);
const auto& extension = mExtensions[ext];
if (!extension || extension->IsExplicit()) return;
GenerateWarning(
"Using format enabled by implicitly enabled extension: %s. "
"For maximal portability enable it explicitly.",
GetExtensionString(ext));
// Don't spam warnings
extension->SetExplicit();
}
static bool CompareWebGLExtensionName(const nsACString& name, static bool CompareWebGLExtensionName(const nsACString& name,
const char* other) { const char* other) {
return name.Equals(other, nsCaseInsensitiveCStringComparator()); return name.Equals(other, nsCaseInsensitiveCStringComparator());
} }
WebGLExtensionBase* WebGLContext::EnableSupportedExtension( WebGLExtensionBase* WebGLContext::EnableSupportedExtension(
dom::CallerType callerType, WebGLExtensionID ext) { dom::CallerType callerType, WebGLExtensionID ext, bool explict) {
if (!IsExtensionEnabled(ext)) { if (!IsExtensionEnabled(ext)) {
if (!IsExtensionSupported(callerType, ext)) return nullptr; if (!IsExtensionSupported(callerType, ext)) return nullptr;
EnableExtension(ext); EnableExtension(ext);
} }
return mExtensions[ext]; const auto extension = mExtensions[ext];
MOZ_ASSERT(extension);
if (explict && !extension->IsExplicit()) {
extension->SetExplicit();
}
return extension;
} }
void WebGLContext::GetExtension(JSContext* cx, const nsAString& wideName, void WebGLContext::GetExtension(JSContext* cx, const nsAString& wideName,
@ -285,22 +309,25 @@ void WebGLContext::GetExtension(JSContext* cx, const nsAString& wideName,
// Step 4: Enable any implied extensions. // Step 4: Enable any implied extensions.
switch (ext) { switch (ext) {
case WebGLExtensionID::EXT_color_buffer_float: case WebGLExtensionID::EXT_color_buffer_float:
EnableSupportedExtension(callerType, WebGLExtensionID::EXT_float_blend); EnableSupportedExtension(callerType, WebGLExtensionID::EXT_float_blend,
false);
break; break;
case WebGLExtensionID::OES_texture_float: case WebGLExtensionID::OES_texture_float:
EnableSupportedExtension(callerType, EnableSupportedExtension(
WebGLExtensionID::WEBGL_color_buffer_float); callerType, WebGLExtensionID::WEBGL_color_buffer_float, false);
EnableSupportedExtension(callerType, WebGLExtensionID::EXT_float_blend); EnableSupportedExtension(callerType, WebGLExtensionID::EXT_float_blend,
false);
break; break;
case WebGLExtensionID::OES_texture_half_float: case WebGLExtensionID::OES_texture_half_float:
EnableSupportedExtension(callerType, EnableSupportedExtension(
WebGLExtensionID::EXT_color_buffer_half_float); callerType, WebGLExtensionID::EXT_color_buffer_half_float, false);
break; break;
case WebGLExtensionID::WEBGL_color_buffer_float: case WebGLExtensionID::WEBGL_color_buffer_float:
EnableSupportedExtension(callerType, WebGLExtensionID::EXT_float_blend); EnableSupportedExtension(callerType, WebGLExtensionID::EXT_float_blend,
false);
break; break;
default: default:

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

@ -72,11 +72,27 @@ void WebGLContext::ClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
const FuncScope funcScope(*this, "clearColor"); const FuncScope funcScope(*this, "clearColor");
if (IsContextLost()) return; if (IsContextLost()) return;
const bool supportsFloatColorBuffers = if (IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_float)) {
(IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_float) || MOZ_ASSERT(IsExtensionExplicit(WebGLExtensionID::EXT_color_buffer_float));
IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float) ||
IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float)); } else if (IsExtensionEnabled(
if (!supportsFloatColorBuffers) { WebGLExtensionID::EXT_color_buffer_half_float) ||
IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float)) {
const bool explict =
(IsExtensionExplicit(WebGLExtensionID::EXT_color_buffer_half_float) ||
IsExtensionExplicit(WebGLExtensionID::WEBGL_color_buffer_float));
const bool wouldHaveClamped =
(r != GLClampFloat(r) || g != GLClampFloat(g) || b != GLClampFloat(b) ||
a != GLClampFloat(a));
if (!explict && wouldHaveClamped) {
if (IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float)) {
WarnIfImplicit(WebGLExtensionID::EXT_color_buffer_half_float);
} else if (IsExtensionEnabled(
WebGLExtensionID::WEBGL_color_buffer_float)) {
WarnIfImplicit(WebGLExtensionID::WEBGL_color_buffer_float);
}
}
} else {
r = GLClampFloat(r); r = GLClampFloat(r);
g = GLClampFloat(g); g = GLClampFloat(g);
b = GLClampFloat(b); b = GLClampFloat(b);

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

@ -15,13 +15,18 @@ WebGLExtensionColorBufferFloat::WebGLExtensionColorBufferFloat(
WebGLContext* webgl) WebGLContext* webgl)
: WebGLExtensionBase(webgl) { : WebGLExtensionBase(webgl) {
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
SetRenderable(webgl::FormatRenderableState::Implicit(
WebGLExtensionID::WEBGL_color_buffer_float));
}
auto& fua = webgl->mFormatUsage; void WebGLExtensionColorBufferFloat::SetRenderable(
const webgl::FormatRenderableState state) {
auto& fua = mContext->mFormatUsage;
auto fnUpdateUsage = [&fua](GLenum sizedFormat, auto fnUpdateUsage = [&](GLenum sizedFormat,
webgl::EffectiveFormat effFormat) { webgl::EffectiveFormat effFormat) {
auto usage = fua->EditUsage(effFormat); auto usage = fua->EditUsage(effFormat);
usage->SetRenderable(); usage->SetRenderable(state);
fua->AllowRBFormat(sizedFormat, usage); fua->AllowRBFormat(sizedFormat, usage);
}; };
@ -33,6 +38,10 @@ WebGLExtensionColorBufferFloat::WebGLExtensionColorBufferFloat(
#undef FOO #undef FOO
} }
void WebGLExtensionColorBufferFloat::OnSetExplicit() {
SetRenderable(webgl::FormatRenderableState::Explicit());
}
WebGLExtensionColorBufferFloat::~WebGLExtensionColorBufferFloat() {} WebGLExtensionColorBufferFloat::~WebGLExtensionColorBufferFloat() {}
bool WebGLExtensionColorBufferFloat::IsSupported(const WebGLContext* webgl) { bool WebGLExtensionColorBufferFloat::IsSupported(const WebGLContext* webgl) {

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

@ -15,15 +15,19 @@ WebGLExtensionColorBufferHalfFloat::WebGLExtensionColorBufferHalfFloat(
WebGLContext* webgl) WebGLContext* webgl)
: WebGLExtensionBase(webgl) { : WebGLExtensionBase(webgl) {
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
SetRenderable(webgl::FormatRenderableState::Implicit(
WebGLExtensionID::EXT_color_buffer_half_float));
}
auto& fua = webgl->mFormatUsage; void WebGLExtensionColorBufferHalfFloat::SetRenderable(
const webgl::FormatRenderableState state) {
auto& fua = mContext->mFormatUsage;
auto fnUpdateUsage = [&fua](GLenum sizedFormat, auto fnUpdateUsage = [&](GLenum sizedFormat, webgl::EffectiveFormat effFormat,
webgl::EffectiveFormat effFormat, const bool renderable) {
const bool renderable) {
auto usage = fua->EditUsage(effFormat); auto usage = fua->EditUsage(effFormat);
if (renderable) { if (renderable) {
usage->SetRenderable(); usage->SetRenderable(state);
} }
fua->AllowRBFormat(sizedFormat, usage, renderable); fua->AllowRBFormat(sizedFormat, usage, renderable);
}; };
@ -37,6 +41,10 @@ WebGLExtensionColorBufferHalfFloat::WebGLExtensionColorBufferHalfFloat(
#undef FOO #undef FOO
} }
void WebGLExtensionColorBufferHalfFloat::OnSetExplicit() {
SetRenderable(webgl::FormatRenderableState::Explicit());
}
WebGLExtensionColorBufferHalfFloat::~WebGLExtensionColorBufferHalfFloat() {} WebGLExtensionColorBufferHalfFloat::~WebGLExtensionColorBufferHalfFloat() {}
bool WebGLExtensionColorBufferHalfFloat::IsSupported( bool WebGLExtensionColorBufferHalfFloat::IsSupported(

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

@ -12,8 +12,8 @@
namespace mozilla { namespace mozilla {
WebGLExtensionBase::WebGLExtensionBase(WebGLContext* context) WebGLExtensionBase::WebGLExtensionBase(WebGLContext* webgl)
: WebGLContextBoundObject(context), mIsLost(false) {} : WebGLContextBoundObject(webgl), mIsLost(false), mIsExplicit(false) {}
WebGLExtensionBase::~WebGLExtensionBase() {} WebGLExtensionBase::~WebGLExtensionBase() {}

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

@ -12,6 +12,7 @@
#include "nsWrapperCache.h" #include "nsWrapperCache.h"
#include "WebGLObjectModel.h" #include "WebGLObjectModel.h"
#include "WebGLTypes.h" #include "WebGLTypes.h"
#include "WebGLFormats.h"
namespace mozilla { namespace mozilla {
class ErrorResult; class ErrorResult;
@ -42,6 +43,13 @@ class WebGLExtensionBase : public nsWrapperCache,
void MarkLost(); void MarkLost();
void SetExplicit() {
mIsExplicit = true;
OnSetExplicit();
}
bool IsExplicit() { return mIsExplicit; }
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLExtensionBase) NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLExtensionBase)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLExtensionBase) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLExtensionBase)
@ -51,6 +59,10 @@ class WebGLExtensionBase : public nsWrapperCache,
virtual void OnMarkLost() {} virtual void OnMarkLost() {}
bool mIsLost; bool mIsLost;
virtual void OnSetExplicit() {}
bool mIsExplicit;
}; };
#define DECL_WEBGL_EXTENSION_GOOP \ #define DECL_WEBGL_EXTENSION_GOOP \
@ -321,6 +333,10 @@ class WebGLExtensionColorBufferFloat : public WebGLExtensionBase {
static bool IsSupported(const WebGLContext*); static bool IsSupported(const WebGLContext*);
void SetRenderable(const webgl::FormatRenderableState);
void OnSetExplicit() override;
DECL_WEBGL_EXTENSION_GOOP DECL_WEBGL_EXTENSION_GOOP
}; };
@ -331,6 +347,10 @@ class WebGLExtensionColorBufferHalfFloat : public WebGLExtensionBase {
static bool IsSupported(const WebGLContext*); static bool IsSupported(const WebGLContext*);
void SetRenderable(const webgl::FormatRenderableState);
void OnSetExplicit() override;
DECL_WEBGL_EXTENSION_GOOP DECL_WEBGL_EXTENSION_GOOP
}; };

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

@ -765,8 +765,10 @@ static bool AddUnsizedFormats(FormatUsageAuthority* fua, gl::GLContext* gl) {
// clang-format on // clang-format on
} }
void FormatUsageInfo::SetRenderable() { void FormatUsageInfo::SetRenderable(const FormatRenderableState& state) {
this->isRenderable = true; if (!renderableState.IsExplicit()) {
renderableState = state;
}
#ifdef DEBUG #ifdef DEBUG
const auto format = this->format; const auto format = this->format;
@ -1125,6 +1127,11 @@ void FormatUsageAuthority::AllowRBFormat(GLenum sizedFormat,
MOZ_ASSERT(usage->format->sizedFormat); MOZ_ASSERT(usage->format->sizedFormat);
MOZ_ASSERT(usage->IsRenderable() || !expectRenderable); MOZ_ASSERT(usage->IsRenderable() || !expectRenderable);
const auto& found = mRBFormatMap.find(sizedFormat);
if (found != mRBFormatMap.end()) {
MOZ_ASSERT(found->second == usage);
return;
}
AlwaysInsert(mRBFormatMap, sizedFormat, usage); AlwaysInsert(mRBFormatMap, sizedFormat, usage);
} }

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

@ -309,11 +309,35 @@ GLenum ComponentType(const FormatInfo* format);
*/ */
//////////////////////////////////////// ////////////////////////////////////////
struct FormatRenderableState final {
private:
enum class RenderableState {
Disabled,
Implicit,
Explicit,
};
public:
RenderableState state = RenderableState::Disabled;
WebGLExtensionID extid = WebGLExtensionID::Max;
static FormatRenderableState Explicit() {
return {RenderableState::Explicit};
}
static FormatRenderableState Implicit(WebGLExtensionID extid) {
return {RenderableState::Implicit, extid};
}
bool IsRenderable() const { return state != RenderableState::Disabled; }
bool IsExplicit() const { return state == RenderableState::Explicit; }
};
struct FormatUsageInfo { struct FormatUsageInfo {
const FormatInfo* const format; const FormatInfo* const format;
private: private:
bool isRenderable = false; FormatRenderableState renderableState;
public: public:
bool isFilterable = false; bool isFilterable = false;
@ -338,8 +362,14 @@ struct FormatUsageInfo {
} }
} }
bool IsRenderable() const { return isRenderable; } bool IsRenderable() const { return renderableState.IsRenderable(); }
void SetRenderable(); void SetRenderable(
const FormatRenderableState& state = FormatRenderableState::Explicit());
bool IsExplicitlyRenderable() const { return renderableState.IsExplicit(); }
WebGLExtensionID GetExtensionID() const {
MOZ_ASSERT(renderableState.extid != WebGLExtensionID::Max);
return renderableState.extid;
}
bool IsUnpackValid(const PackingInfo& key, bool IsUnpackValid(const PackingInfo& key,
const DriverUnpackInfo** const out_value) const; const DriverUnpackInfo** const out_value) const;

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

@ -143,6 +143,9 @@ bool WebGLFBAttachPoint::IsComplete(WebGLContext* webgl,
fnWriteErrorInfo(info.BeginReading()); fnWriteErrorInfo(info.BeginReading());
return false; return false;
} }
if (!formatUsage->IsExplicitlyRenderable()) {
webgl->WarnIfImplicit(formatUsage->GetExtensionID());
}
const auto format = formatUsage->format; const auto format = formatUsage->format;

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

@ -775,6 +775,10 @@ void WebGLTexture::GenerateMipmap() {
return; return;
} }
if (usage->IsRenderable() && !usage->IsExplicitlyRenderable()) {
mContext->WarnIfImplicit(usage->GetExtensionID());
}
// Done with validation. Do the operation. // Done with validation. Do the operation.
gl::GLContext* gl = mContext->gl; gl::GLContext* gl = mContext->gl;

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

@ -1670,12 +1670,14 @@ ScopedCopyTexImageSource::ScopedCopyTexImageSource(
if (webgl->IsExtensionEnabled( if (webgl->IsExtensionEnabled(
WebGLExtensionID::WEBGL_color_buffer_float)) { WebGLExtensionID::WEBGL_color_buffer_float)) {
sizedFormat = LOCAL_GL_RGBA32F; sizedFormat = LOCAL_GL_RGBA32F;
webgl->WarnIfImplicit(WebGLExtensionID::WEBGL_color_buffer_float);
break; break;
} }
if (webgl->IsExtensionEnabled( if (webgl->IsExtensionEnabled(
WebGLExtensionID::EXT_color_buffer_half_float)) { WebGLExtensionID::EXT_color_buffer_half_float)) {
sizedFormat = LOCAL_GL_RGBA16F; sizedFormat = LOCAL_GL_RGBA16F;
webgl->WarnIfImplicit(WebGLExtensionID::EXT_color_buffer_half_float);
break; break;
} }
MOZ_CRASH("GFX: Should be able to request CopyTexImage from Float."); MOZ_CRASH("GFX: Should be able to request CopyTexImage from Float.");