summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2022-10-26 13:52:42 +0000
committerMoonchild <moonchild@palemoon.org>2022-10-26 14:50:05 +0000
commit71ae69aea85ec8ddb9bf7baa93ae3926990a3693 (patch)
tree337c01b8620c9d98d7c2ef9482eaef2d225e7faf
parent9e34d697c700f380136364499d9005d6cdfa9f0a (diff)
downloaduxp-71ae69aea85ec8ddb9bf7baa93ae3926990a3693.tar.gz
[WebGL] Implement webgl.max-size-per-texture-mibRC_20221026RB_20221101
-rw-r--r--dom/canvas/WebGLTextureUpload.cpp50
-rw-r--r--gfx/thebes/gfxPrefs.h1
-rw-r--r--modules/libpref/init/all.js1
3 files changed, 38 insertions, 14 deletions
diff --git a/dom/canvas/WebGLTextureUpload.cpp b/dom/canvas/WebGLTextureUpload.cpp
index ae60d2a2b0..ed199cfb43 100644
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -303,13 +303,13 @@ WebGLContext::FromDomElem(const char* funcName, TexImageTarget target, uint32_t
uint32_t height, uint32_t depth, const dom::Element& elem,
ErrorResult* const out_error)
{
- if (elem.IsHTMLElement(nsGkAtoms::canvas)) {
- const dom::HTMLCanvasElement* canvas = static_cast<const dom::HTMLCanvasElement*>(&elem);
- if (canvas->IsWriteOnly()) {
- out_error->Throw(NS_ERROR_DOM_SECURITY_ERR);
- return nullptr;
- }
- }
+ if (elem.IsHTMLElement(nsGkAtoms::canvas)) {
+ const dom::HTMLCanvasElement* canvas = static_cast<const dom::HTMLCanvasElement*>(&elem);
+ if (canvas->IsWriteOnly()) {
+ out_error->Throw(NS_ERROR_DOM_SECURITY_ERR);
+ return nullptr;
+ }
+ }
uint32_t flags = nsLayoutUtils::SFE_WANT_IMAGE_SURFACE |
nsLayoutUtils::SFE_USE_ELEMENT_SIZE_IF_VECTOR;
@@ -1032,9 +1032,27 @@ ValidateCompressedTexImageRestrictions(const char* funcName, WebGLContext* webgl
}
static bool
-ValidateTargetForFormat(const char* funcName, WebGLContext* webgl, TexImageTarget target,
- const webgl::FormatInfo* format)
-{
+ValidateFormatAndSize(const char* funcName,
+ WebGLContext* webgl,
+ TexImageTarget target,
+ const webgl::FormatInfo* format,
+ const uint32_t width,
+ const uint32_t height,
+ const uint32_t depth) {
+ // Check if texture size will likely be rejected by the driver and give a more
+ // meaningful error message.
+ auto baseImageSize = CheckedInt<uint64_t>(format->estimatedBytesPerPixel) *
+ width * height * depth;
+ if (target == LOCAL_GL_TEXTURE_CUBE_MAP) {
+ baseImageSize *= 6;
+ }
+
+ if (!baseImageSize.isValid() ||
+ baseImageSize.value() > (uint64_t)gfxPrefs::WebGLMaxSizePerTextureMB * (1024 * 1024)) {
+ webgl->ErrorOutOfMemory("Texture size too large; base image MB > webgl.max-size-per-texture-mb");
+ return false;
+ }
+
// GLES 3.0.4 p127:
// "Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are
// supported by texture image specification commands only if `target` is TEXTURE_2D,
@@ -1137,7 +1155,8 @@ WebGLTexture::TexStorage(const char* funcName, TexTarget target, GLsizei levels,
}
auto dstFormat = dstUsage->format;
- if (!ValidateTargetForFormat(funcName, mContext, testTarget, dstFormat))
+ if (!ValidateFormatAndSize(funcName, mContext, testTarget, dstFormat,
+ width, height, depth))
return;
if (dstFormat->compression) {
@@ -1264,7 +1283,8 @@ WebGLTexture::TexImage(const char* funcName, TexImageTarget target, GLint level,
// Check that source and dest info are compatible
auto dstFormat = dstUsage->format;
- if (!ValidateTargetForFormat(funcName, mContext, target, dstFormat))
+ if (!ValidateFormatAndSize(funcName, mContext, target, dstFormat,
+ blob->mWidth, blob->mHeight, blob->mDepth))
return;
if (!mContext->IsWebGL2() && dstFormat->d) {
@@ -1484,7 +1504,8 @@ WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GL
return;
}
- if (!ValidateTargetForFormat(funcName, mContext, target, format))
+ if (!ValidateFormatAndSize(funcName, mContext, target, format,
+ blob->mWidth, blob->mHeight, blob->mDepth))
return;
////////////////////////////////////
@@ -2143,7 +2164,8 @@ WebGLTexture::CopyTexImage2D(TexImageTarget target, GLint level, GLenum internal
return;
const auto& dstFormat = dstUsage->format;
- if (!ValidateTargetForFormat(funcName, mContext, target, dstFormat))
+ if (!ValidateFormatAndSize(funcName, mContext, target, dstFormat,
+ width, height, depth))
return;
if (!mContext->IsWebGL2() && dstFormat->d) {
diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h
index ac5bdd45a2..389393f8f6 100644
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -591,6 +591,7 @@ private:
DECL_GFX_PREF(Once, "webgl.force-layers-readback", WebGLForceLayersReadback, bool, false);
DECL_GFX_PREF(Live, "webgl.lose-context-on-memory-pressure", WebGLLoseContextOnMemoryPressure, bool, false);
DECL_GFX_PREF(Live, "webgl.max-warnings-per-context", WebGLMaxWarningsPerContext, uint32_t, 32);
+ DECL_GFX_PREF(Live, "webgl.max-size-per-texture-mb", WebGLMaxSizePerTextureMB, uint32_t, 1024);
DECL_GFX_PREF(Live, "webgl.min_capability_mode", WebGLMinCapabilityMode, bool, false);
DECL_GFX_PREF(Live, "webgl.msaa-force", WebGLForceMSAA, bool, false);
DECL_GFX_PREF(Live, "webgl.prefer-16bpp", WebGLPrefer16bpp, bool, false);
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index 317de736b0..a237cfca57 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4228,6 +4228,7 @@ pref("webgl.lose-context-on-memory-pressure", false);
pref("webgl.can-lose-context-in-foreground", true);
pref("webgl.restore-context-when-visible", true);
pref("webgl.max-warnings-per-context", 32);
+pref("webgl.max-size-per-texture-mb", 1024);
pref("webgl.enable-draft-extensions", false);
pref("webgl.enable-privileged-extensions", false);
pref("webgl.bypass-shader-validation", false);