Backed out 2 changesets (bug 1956355) for causing build bustages @WebGLContextGL.cpp.

Backed out changeset 5e479ac652f4 (bug 1956355)
Backed out changeset 194f0fa0c62e (bug 1956355)
This commit is contained in:
Goloman Adrian
2025-03-28 00:14:41 +02:00
parent 642c75059d
commit 8a1d3d3bcc
9 changed files with 53 additions and 337 deletions

View File

@@ -6,7 +6,6 @@
#include "ClientWebGLContext.h"
#include <bitset>
#include <fmt/format.h>
#include "ClientWebGLExtensions.h"
#include "gfxCrashReporterUtils.h"
@@ -2487,7 +2486,7 @@ void ClientWebGLContext::GetParameter(JSContext* cx, GLenum pname,
case LOCAL_GL_TRANSFORM_FEEDBACK_ACTIVE:
case LOCAL_GL_TRANSFORM_FEEDBACK_PAUSED:
retval.set(JS::BooleanValue(*maybe));
return;
break;
// 4 bools
case LOCAL_GL_COLOR_WRITEMASK: {
@@ -2502,19 +2501,9 @@ void ClientWebGLContext::GetParameter(JSContext* cx, GLenum pname,
return;
}
case LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE: {
auto readType = (GLenum)*maybe;
// Map HALF_FLOAT to HALF_FLOAT_OES for webgl 1 clients.
if (readType == LOCAL_GL_HALF_FLOAT && !mIsWebGL2) {
readType = LOCAL_GL_HALF_FLOAT_OES;
}
retval.set(JS::NumberValue(readType));
return;
}
default:
retval.set(JS::NumberValue(*maybe));
return;
break;
}
}
}
@@ -5139,7 +5128,7 @@ void ClientWebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
dom::CallerType aCallerType,
ErrorResult& out_error) const {
const FuncScope funcScope(*this, "readPixels");
if (!ReadPixels_SharedPrecheck(&type, aCallerType, out_error)) return;
if (!ReadPixels_SharedPrecheck(aCallerType, out_error)) return;
const auto& state = State();
if (!ValidateNonNegative("width", width)) return;
if (!ValidateNonNegative("height", height)) return;
@@ -5159,7 +5148,7 @@ void ClientWebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
dom::CallerType aCallerType,
ErrorResult& out_error) const {
const FuncScope funcScope(*this, "readPixels");
if (!ReadPixels_SharedPrecheck(&type, aCallerType, out_error)) return;
if (!ReadPixels_SharedPrecheck(aCallerType, out_error)) return;
const auto& state = State();
if (!ValidateNonNegative("width", width)) return;
if (!ValidateNonNegative("height", height)) return;
@@ -5256,28 +5245,9 @@ bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
}
bool ClientWebGLContext::ReadPixels_SharedPrecheck(
GLenum* const inout_readType, dom::CallerType aCallerType,
ErrorResult& out_error) const {
dom::CallerType aCallerType, ErrorResult& out_error) const {
if (IsContextLost()) return false;
GLenum validHalfFloatType = LOCAL_GL_HALF_FLOAT;
GLenum forbiddenHalfFloatType = LOCAL_GL_HALF_FLOAT_OES;
if (!mIsWebGL2) {
std::swap(validHalfFloatType, forbiddenHalfFloatType); // Tragic.
}
if (*inout_readType == forbiddenHalfFloatType) {
const auto msg = fmt::format(
FMT_STRING("For WebGL {}, for `type`, enum {} is forbidden. Use {}."),
mIsWebGL2 ? "2" : "1", EnumString(forbiddenHalfFloatType),
EnumString(validHalfFloatType));
EnqueueError({LOCAL_GL_INVALID_ENUM, msg});
return false;
}
// Normalize to HALF_FLOAT non-_OES internally:
if (*inout_readType == LOCAL_GL_HALF_FLOAT_OES) {
*inout_readType = LOCAL_GL_HALF_FLOAT;
}
if (mCanvasElement && mCanvasElement->IsWriteOnly() &&
aCallerType != dom::CallerType::System) {
JsWarning("readPixels: Not allowed");

View File

@@ -2224,8 +2224,7 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
dom::CallerType aCallerType, ErrorResult& out_error) const;
protected:
bool ReadPixels_SharedPrecheck(GLenum* inout_readType,
dom::CallerType aCallerType,
bool ReadPixels_SharedPrecheck(dom::CallerType aCallerType,
ErrorResult& out_error) const;
// ------------------------------ Vertex Array ------------------------------

View File

@@ -304,6 +304,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
const uint32_t mMaxAcceptableFBStatusInvals =
StaticPrefs::webgl_perf_max_acceptable_fb_status_invals();
bool mWarnOnce_DepthTexCompareFilterable = true;
mutable bool mRemapImplReadType_HalfFloatOes = false;
mutable std::optional<bool> mIsSupportedCache_DrawBuffers;
mutable std::optional<bool> mIsSupportedCache_FragDepth;

View File

@@ -38,7 +38,6 @@
#include "WebGLTexelConversions.h"
#include "WebGLValidateStrings.h"
#include <algorithm>
#include <fmt/format.h>
#include "mozilla/DebugOnly.h"
#include "mozilla/dom/BindingUtils.h"
@@ -866,7 +865,13 @@ bool WebGLContext::DoReadPixelsAndConvert(
const auto& x = desc.srcOffset.x;
const auto& y = desc.srcOffset.y;
const auto size = *ivec2::From(desc.size);
const auto& pi = desc.pi;
auto pi = desc.pi;
if (mRemapImplReadType_HalfFloatOes) {
if (pi.type == LOCAL_GL_HALF_FLOAT_OES) {
pi.type = LOCAL_GL_HALF_FLOAT;
}
}
// On at least Win+NV, we'll get PBO errors if we don't have at least
// `rowStride * height` bytes available to read into.
@@ -985,8 +990,8 @@ static webgl::PackingInfo DefaultReadPixelPI(
case webgl::ComponentType::Float:
return {LOCAL_GL_RGBA, LOCAL_GL_FLOAT};
case webgl::ComponentType::NormInt:
MOZ_CRASH("SNORM formats are never color-renderable!");
default:
MOZ_CRASH();
}
}
@@ -1017,48 +1022,33 @@ static bool ArePossiblePackEnums(const webgl::PackingInfo& pi) {
webgl::PackingInfo WebGLContext::ValidImplementationColorReadPI(
const webgl::FormatUsageInfo* usage) const {
if (const auto implPI = usage->implReadPiCache) return *implPI;
const auto defaultPI = DefaultReadPixelPI(usage);
usage->implReadPiCache = [&]() {
if (StaticPrefs::webgl_porting_strict_readpixels_formats())
return defaultPI;
auto implPI = defaultPI;
// ES2_compatibility always returns RGBA/UNSIGNED_BYTE, so branch on actual
// IsGLES(). Also OSX+NV generates an error here.
if (gl->IsGLES()) {
gl->GetInt(LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &implPI.format);
gl->GetInt(LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE, &implPI.type);
} else {
if (StaticPrefs::webgl_porting_strict_readpixels_formats_non_es())
return defaultPI;
// Non-ES GL is way more open, and basically supports reading anything.
// (Sucks to be their driver team!)
if (usage->idealUnpack) {
for (const auto& [validPi, validDui] : usage->validUnpacks) {
if (validDui != *usage->idealUnpack) continue;
implPI = validPi;
break;
}
}
}
// Normalize HALF_FLOAT_OES to HALF_FLOAT internally.
if (implPI.type == LOCAL_GL_HALF_FLOAT_OES) {
implPI.type = LOCAL_GL_HALF_FLOAT;
}
if (!ArePossiblePackEnums(implPI)) return defaultPI;
return implPI;
}();
return *usage->implReadPiCache;
}
std::string webgl::format_as(const PackingInfo& pi) {
return fmt::format(FMT_STRING("{}/{}"), pi.format, pi.type);
// ES2_compatibility always returns RGBA/UNSIGNED_BYTE, so branch on actual
// IsGLES(). Also OSX+NV generates an error here.
if (!gl->IsGLES()) return defaultPI;
webgl::PackingInfo implPI;
gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT,
(GLint*)&implPI.format);
gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE,
(GLint*)&implPI.type);
if (!IsWebGL2()) {
if (implPI.type == LOCAL_GL_HALF_FLOAT) {
mRemapImplReadType_HalfFloatOes = true;
implPI.type = LOCAL_GL_HALF_FLOAT_OES;
}
}
if (!ArePossiblePackEnums(implPI)) return defaultPI;
return implPI;
}
static bool ValidateReadPixelsFormatAndType(
const webgl::FormatUsageInfo* srcUsage, const webgl::PackingInfo& pi,
WebGLContext* webgl) {
gl::GLContext* gl, WebGLContext* webgl) {
if (!ArePossiblePackEnums(pi)) {
webgl->ErrorInvalidEnum("Unexpected format or type.");
return false;
@@ -1072,48 +1062,32 @@ static bool ValidateReadPixelsFormatAndType(
// OpenGL ES 3.0.4 p194 - When the internal format of the rendering surface is
// RGB10_A2, a third combination of format RGBA and type
// UNSIGNED_INT_2_10_10_10_REV is accepted.
std::optional<webgl::PackingInfo> bonusValidPi;
if (srcUsage->format->effectiveFormat == webgl::EffectiveFormat::RGB10_A2) {
bonusValidPi =
webgl::PackingInfo{LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV};
if (webgl->IsWebGL2() &&
srcUsage->format->effectiveFormat == webgl::EffectiveFormat::RGB10_A2 &&
pi.format == LOCAL_GL_RGBA &&
pi.type == LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV) {
return true;
}
if (bonusValidPi && pi == *bonusValidPi) return true;
////
const auto implPI = webgl->ValidImplementationColorReadPI(srcUsage);
MOZ_ASSERT(pi.type != LOCAL_GL_HALF_FLOAT_OES); // HALF_FLOAT-only
MOZ_ASSERT(implPI.type != LOCAL_GL_HALF_FLOAT_OES); // HALF_FLOAT-only
if (pi == implPI) return true;
////
// Map HALF_FLOAT to HALF_FLOAT_OES for error messages in webgl1.
webgl::PackingInfo clientImplPI = implPI;
if (clientImplPI.type == LOCAL_GL_HALF_FLOAT && !webgl->IsWebGL2()) {
clientImplPI.type = LOCAL_GL_HALF_FLOAT_OES;
}
auto validPiStr =
fmt::format(FMT_STRING("{} (spec-required baseline for format {})"),
defaultPI, srcUsage->format->name);
if (implPI != defaultPI) {
validPiStr += fmt::format(
FMT_STRING(
", or {} (spec-optional implementation-chosen format-dependant"
" IMPLEMENTATION_COLOR_READ_FORMAT/_TYPE)"),
clientImplPI);
}
if (bonusValidPi) {
validPiStr +=
fmt::format(FMT_STRING(", or {} (spec-required bonus for format {})"),
*bonusValidPi, srcUsage->format->name);
}
// clang-format off
webgl->ErrorInvalidOperation(
"Format/type %s/%s incompatible with this %s framebuffer. Must use: %s.",
"Format and type %s/%s incompatible with this %s attachment."
" This framebuffer requires either %s/%s or"
" getParameter(IMPLEMENTATION_COLOR_READ_FORMAT/_TYPE) %s/%s.",
EnumString(pi.format).c_str(), EnumString(pi.type).c_str(),
srcUsage->format->name, validPiStr.c_str());
srcUsage->format->name,
EnumString(defaultPI.format).c_str(), EnumString(defaultPI.type).c_str(),
EnumString(implPI.format).c_str(), EnumString(implPI.type).c_str());
// clang-format on
return false;
}
@@ -1127,7 +1101,7 @@ webgl::ReadPixelsResult WebGLContext::ReadPixelsImpl(
//////
if (!ValidateReadPixelsFormatAndType(srcFormat, desc.pi, this)) return {};
if (!ValidateReadPixelsFormatAndType(srcFormat, desc.pi, gl, this)) return {};
//////

View File

@@ -351,9 +351,6 @@ struct FormatUsageInfo {
std::map<PackingInfo, DriverUnpackInfo> validUnpacks;
const DriverUnpackInfo* idealUnpack = nullptr;
// LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT/_TYPE:
mutable std::optional<PackingInfo> implReadPiCache;
const GLint* textureSwizzleRGBA = nullptr;
private:

View File

@@ -553,9 +553,6 @@ struct PackingInfo final {
friend bool operator==(const Self& a, const Self& b) {
return TiedFields(a) == TiedFields(b);
}
friend bool operator!=(const Self& a, const Self& b) {
return TiedFields(a) != TiedFields(b);
}
template <class T>
friend T& operator<<(T& s, const PackingInfo& pi) {
@@ -564,28 +561,13 @@ struct PackingInfo final {
return s;
}
};
std::string format_as(const PackingInfo& pi);
struct DriverUnpackInfo final {
using Self = DriverUnpackInfo;
GLenum internalFormat = 0;
GLenum unpackFormat = 0;
GLenum unpackType = 0;
PackingInfo ToPacking() const { return {unpackFormat, unpackType}; }
template<class ConstOrMutSelf>
static constexpr auto Fields(ConstOrMutSelf& self) {
return std::tie(self.internalFormat, self.unpackFormat, self.unpackType);
}
constexpr bool operator==(const Self& rhs) const {
return Fields(*this) == Fields(rhs);
}
constexpr bool operator!=(const Self& rhs) const {
return Fields(*this) != Fields(rhs);
}
};
// -

View File

@@ -210,9 +210,6 @@ skip-if = [
["test_read_pixels_no_format.html"]
["test_read_pixels_naive_impl_read_formats.html"]
tags = "os_integration"
["test_renderer_strings.html"]
skip-if = ["display == 'wayland'"]
tags = "os_integration"

View File

@@ -1,194 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
</head>
<body>
<h2><pre id=e_results></pre></h2>
<pre id=e_out></pre>
<script>
'use strict';
const RESULTS = {
failures: 0,
tests: 0,
};
window.ok = window.ok || function(e, s) {
const failure = !e;
e_out.textContent += `\n${failure ? 'FAIL' : 'ok '}: ${s}`;
RESULTS.failures += failure|0;
RESULTS.tests += 1;
e_results.textContent = `${RESULTS.failures} failures in ${RESULTS.tests} tests`;
};
// -
function throwv(v) {
throw v;
}
function jsobj_strinify(obj) {
if (typeof(obj) == 'function') return `[function ${obj.name}]`;
if (typeof(obj) == 'string') return `'${obj}'`;
if (typeof(obj) != 'object') return ''+obj;
if (obj.constructor == Object) {
return '{' + Object.entries(obj).map(
([k, v]) => `${k}: ${jsobj_strinify(v)}`
).join(', ') + '}';
}
if (Array.isArray(obj)) {
obj = obj.map(jsobj_strinify);
return '[' + obj + ']';
}
if (ArrayBuffer.isView(obj)) {
if (obj instanceof DataView) throw 'todo';
const ctor = obj.constructor;
obj = [].map.call(obj, jsobj_strinify);
return `new ${ctor.name}([` + obj + `])`;
}
let ret = ''+obj;
if (obj.label) {
ret = ret.replace(']', ` "${obj.label}"]`);
}
return ret;
}
// -
const GL = globalThis.WebGL2RenderingContext || WebGLRenderingContext;
function GL_(enumName) {
const enumNameGl = enumName.toUpperCase().replaceAll('-', '_');
return GL[enumNameGl] || throwv({enumName, enumNameGl, GL});
}
const GL_NAMES_BY_VAL = new Map();
function UNGL_(val, prettyNames=false) {
if (!val) return val; // E.g. 0 => 0
if (!GL_NAMES_BY_VAL.size) {
GL_NAMES_BY_VAL.set(0, ['NONE']);
for (const [k, v] of Object.entries(GL)) {
const existing = GL_NAMES_BY_VAL.get(v);
if (!existing) {
GL_NAMES_BY_VAL.set(v, [k]);
} else {
if (!existing.includes(k)) {
existing.push(v);
}
}
}
}
const enumNameGlList = GL_NAMES_BY_VAL.get(val) || [`0x${val.toString(16)}`];
const enumNameGl = enumNameGlList.join('/');
let enumName = enumNameGl;
if (prettyNames) {
enumName = enumName.replaceAll('_', '-').toLowerCase();
}
return enumName;
}
// -
const gl = document.createElement('canvas').getContext('webgl2');
const WEBGL_debug_renderer_info = gl.getExtension('WEBGL_debug_renderer_info');
const context_info = {
vendor: gl.getParameter(GL_('vendor')),
renderer: gl.getParameter(GL_('renderer')),
};
if (WEBGL_debug_renderer_info) {
const unmasked_vendor = gl.getParameter(WEBGL_debug_renderer_info.UNMASKED_VENDOR_WEBGL);
if (!context_info.vendor.includes(unmasked_vendor)) {
context_info.vendor = `${context_info.vendor} (${unmasked_vendor})`;
}
}
ok(true, jsobj_strinify({context_info}));
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const pbo = gl.createBuffer();
gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo);
pbo.size = 1024
gl.bufferData(gl.PIXEL_PACK_BUFFER, pbo.size, gl.DYNAMIC_READ);
// -
function test(desc) {
ok(true, '(end of section)\n\n---\n');
if (desc.readType.includes('FLOAT')) {
const EXT_color_buffer_float = gl.getExtension('EXT_color_buffer_float');
if (!gl.getExtension('EXT_color_buffer_float')) {
ok(true, {EXT_color_buffer_float, desc});
return;
}
}
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texStorage2D(gl.TEXTURE_2D, 1, GL_(desc.texFormat), 1, 1);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
try {
const setupErr = UNGL_(gl.getError());
ok(!setupErr, jsobj_strinify({setupErr, desc}));
const implFormat = UNGL_(gl.getParameter(GL.IMPLEMENTATION_COLOR_READ_FORMAT));
const implType = UNGL_(gl.getParameter(GL.IMPLEMENTATION_COLOR_READ_TYPE));
ok(implFormat == desc.readFormat && implType == desc.readType, jsobj_strinify({implFormat, implType, desc}));
gl.readPixels(0, 0, 1, 1, GL_(desc.readFormat), GL_(desc.readType), 0);
const readPixelsErr = UNGL_(gl.getError());
ok(!readPixelsErr, jsobj_strinify({readPixelsErr, desc}));
} finally {
gl.deleteTexture(tex);
}
}
// -
[
['R8', 'RED', 'UNSIGNED_BYTE'],
['RG8', 'RG', 'UNSIGNED_BYTE'],
//['RGB8', 'RGB', 'UNSIGNED_BYTE'],
['RGBA8', 'RGBA', 'UNSIGNED_BYTE'],
['RGB10_A2', 'RGBA', 'UNSIGNED_INT_2_10_10_10_REV'],
['RGB10_A2UI', 'RGBA_INTEGER', 'UNSIGNED_INT_2_10_10_10_REV'],
['SRGB8_ALPHA8', 'RGBA', 'UNSIGNED_BYTE'],
['R8I', 'RED_INTEGER', 'BYTE'],
['RG8I', 'RG_INTEGER', 'BYTE'],
['RGBA8I', 'RGBA_INTEGER', 'BYTE'],
['R8UI', 'RED_INTEGER', 'UNSIGNED_BYTE'],
['RG8UI', 'RG_INTEGER', 'UNSIGNED_BYTE'],
['RGBA8UI', 'RGBA_INTEGER', 'UNSIGNED_BYTE'],
['R16I', 'RED_INTEGER', 'SHORT'],
['RG16I', 'RG_INTEGER', 'SHORT'],
['RGBA16I', 'RGBA_INTEGER', 'SHORT'],
['R16UI', 'RED_INTEGER', 'UNSIGNED_SHORT'],
['RG16UI', 'RG_INTEGER', 'UNSIGNED_SHORT'],
['RGBA16UI', 'RGBA_INTEGER', 'UNSIGNED_SHORT'],
['R32I', 'RED_INTEGER', 'INT'],
['RG32I', 'RG_INTEGER', 'INT'],
['RGBA32I', 'RGBA_INTEGER', 'INT'],
['R32UI', 'RED_INTEGER', 'UNSIGNED_INT'],
['RG32UI', 'RG_INTEGER', 'UNSIGNED_INT'],
['RGBA32UI', 'RGBA_INTEGER', 'UNSIGNED_INT'],
['R16F', 'RED', 'HALF_FLOAT'],
['RG16F', 'RG', 'HALF_FLOAT'],
['RGBA16F', 'RGBA', 'HALF_FLOAT'],
['R32F', 'RED', 'FLOAT'],
['RG32F', 'RG', 'FLOAT'],
['RGBA32F', 'RGBA', 'FLOAT'],
].map(
([texFormat, readFormat, readType]) => {
test({texFormat, readFormat, readType});
}
);
const ignoredResults = gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, new Uint8Array(pbo.size));
ok(true, 'done');
</script>
</body>
</html>

View File

@@ -17755,16 +17755,6 @@
value: false
mirror: always
- name: webgl.porting.strict_readpixels_formats
type: RelaxedAtomicBool
value: false
mirror: always
- name: webgl.porting.strict_readpixels_formats.non_es
type: RelaxedAtomicBool
value: false
mirror: always
- name: webgl.dxgl.enabled
type: RelaxedAtomicBool
#ifdef XP_WIN