Bug 1726265 - Prototype webgl draft ext OES_draw_buffers_indexed. r=lsalzman,emilio

Differential Revision: https://phabricator.services.mozilla.com/D122916
This commit is contained in:
Jeff Gilbert 2021-08-20 20:59:54 +00:00
Родитель ddbd16c8f6
Коммит 28e862be2d
31 изменённых файлов: 871 добавлений и 496 удалений

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

@ -1165,6 +1165,11 @@ DOMInterfaces = {
'headerFile': 'ClientWebGLExtensions.h'
},
'OES_draw_buffers_indexed': {
'nativeType': 'mozilla::ClientWebGLExtensionDrawBuffersIndexed',
'headerFile': 'ClientWebGLExtensions.h'
},
'OES_element_index_uint': {
'nativeType': 'mozilla::ClientWebGLExtensionElementIndexUint',
'headerFile': 'ClientWebGLExtensions.h'

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

@ -5,6 +5,8 @@
#include "ClientWebGLContext.h"
#include <bitset>
#include "ClientWebGLExtensions.h"
#include "Layers.h"
#include "gfxCrashReporterUtils.h"
@ -1622,9 +1624,10 @@ bool ClientWebGLContext::IsVertexArray(
// ------------------------- GL State -------------------------
void ClientWebGLContext::Disable(GLenum cap) const { Run<RPROC(Disable)>(cap); }
void ClientWebGLContext::Enable(GLenum cap) const { Run<RPROC(Enable)>(cap); }
void ClientWebGLContext::SetEnabledI(GLenum cap, Maybe<GLuint> i,
bool val) const {
Run<RPROC(SetEnabled)>(cap, i, val);
}
bool ClientWebGLContext::IsEnabled(GLenum cap) const {
const FuncScope funcScope(*this, "isEnabled");
@ -1896,17 +1899,6 @@ void ClientWebGLContext::GetParameter(JSContext* cx, GLenum pname,
retval.set(Create<dom::Int32Array>(cx, this, state.mViewport, rv));
return;
// 4 bools
case LOCAL_GL_COLOR_WRITEMASK: {
JS::Rooted<JS::Value> arr(cx);
const auto& src = state.mColorWriteMask;
if (!dom::ToJSValue(cx, src.data(), src.size(), &arr)) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
retval.set(arr);
return;
}
// any
case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS:
retval.set(Create<dom::Uint32Array>(cx, this,
@ -2186,6 +2178,19 @@ void ClientWebGLContext::GetParameter(JSContext* cx, GLenum pname,
retval.set(JS::BooleanValue(*maybe));
break;
// 4 bools
case LOCAL_GL_COLOR_WRITEMASK: {
const auto mask = uint8_t(*maybe);
const auto bs = std::bitset<4>(mask);
const auto src = std::array<bool, 4>{bs[0], bs[1], bs[2], bs[3]};
JS::Rooted<JS::Value> arr(cx);
if (!dom::ToJSValue(cx, src.data(), src.size(), &arr)) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
retval.set(arr);
return;
}
default:
retval.set(JS::NumberValue(*maybe));
break;
@ -2353,6 +2358,7 @@ void ClientWebGLContext::GetIndexedParameter(
retval.set(JS::NullValue());
const FuncScope funcScope(*this, "getIndexedParameter");
if (IsContextLost()) return;
auto keepalive = mNotLost;
const auto& state = State();
@ -2395,7 +2401,22 @@ void ClientWebGLContext::GetIndexedParameter(
return ret;
}();
if (maybe) {
retval.set(JS::NumberValue(*maybe));
switch (target) {
case LOCAL_GL_COLOR_WRITEMASK: {
const auto bs = std::bitset<4>(*maybe);
const auto src = std::array<bool, 4>{bs[0], bs[1], bs[2], bs[3]};
JS::Rooted<JS::Value> arr(cx);
if (!dom::ToJSValue(cx, src.data(), src.size(), &arr)) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
retval.set(arr);
return;
}
default:
retval.set(JS::NumberValue(*maybe));
return;
}
}
}
@ -2570,14 +2591,15 @@ void ClientWebGLContext::BlendColor(GLclampf r, GLclampf g, GLclampf b,
Run<RPROC(BlendColor)>(r, g, b, a);
}
void ClientWebGLContext::BlendEquationSeparate(GLenum modeRGB,
GLenum modeAlpha) {
Run<RPROC(BlendEquationSeparate)>(modeRGB, modeAlpha);
void ClientWebGLContext::BlendEquationSeparateI(Maybe<GLuint> i, GLenum modeRGB,
GLenum modeAlpha) {
Run<RPROC(BlendEquationSeparate)>(i, modeRGB, modeAlpha);
}
void ClientWebGLContext::BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB,
GLenum srcAlpha, GLenum dstAlpha) {
Run<RPROC(BlendFuncSeparate)>(srcRGB, dstRGB, srcAlpha, dstAlpha);
void ClientWebGLContext::BlendFuncSeparateI(Maybe<GLuint> i, GLenum srcRGB,
GLenum dstRGB, GLenum srcAlpha,
GLenum dstAlpha) {
Run<RPROC(BlendFuncSeparate)>(i, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
GLenum ClientWebGLContext::CheckFramebufferStatus(GLenum target) {
@ -2678,15 +2700,13 @@ void ClientWebGLContext::ClearDepth(GLclampf v) { Run<RPROC(ClearDepth)>(v); }
void ClientWebGLContext::ClearStencil(GLint v) { Run<RPROC(ClearStencil)>(v); }
void ClientWebGLContext::ColorMask(WebGLboolean r, WebGLboolean g,
WebGLboolean b, WebGLboolean a) {
void ClientWebGLContext::ColorMaskI(Maybe<GLuint> i, bool r, bool g,
bool b, bool a) const {
const FuncScope funcScope(*this, "colorMask");
if (IsContextLost()) return;
auto& state = State();
state.mColorWriteMask = {r, g, b, a};
Run<RPROC(ColorMask)>(r, g, b, a);
const uint8_t mask = uint8_t(r << 0) | uint8_t(g << 1) | uint8_t(b << 2) | uint8_t(a << 3);
Run<RPROC(ColorMask)>(i, mask);
}
void ClientWebGLContext::CullFace(GLenum face) { Run<RPROC(CullFace)>(face); }

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

@ -159,7 +159,6 @@ class ContextGenerationInfo final {
std::vector<TypedQuad> mGenericVertexAttribs;
std::array<bool, 4> mColorWriteMask = {{true, true, true, true}};
std::array<int32_t, 4> mScissor = {};
std::array<int32_t, 4> mViewport = {};
std::array<float, 4> mClearColor = {{0, 0, 0, 0}};
@ -1060,8 +1059,9 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
public:
bool IsContextLost() const { return !mNotLost; }
void Disable(GLenum cap) const;
void Enable(GLenum cap) const;
void Disable(GLenum cap) const { SetEnabledI(cap, {}, false); }
void Enable(GLenum cap) const { SetEnabledI(cap, {}, true); }
void SetEnabledI(GLenum cap, Maybe<GLuint> i, bool val) const;
bool IsEnabled(GLenum cap) const;
private:
@ -1228,9 +1228,18 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
BlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
}
void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
BlendEquationSeparateI({}, modeRGB, modeAlpha);
}
void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha,
GLenum dstAlpha);
GLenum dstAlpha) {
BlendFuncSeparateI({}, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void BlendEquationSeparateI(Maybe<GLuint> buf, GLenum modeRGB,
GLenum modeAlpha);
void BlendFuncSeparateI(Maybe<GLuint> buf, GLenum srcRGB, GLenum dstRGB,
GLenum srcAlpha, GLenum dstAlpha);
// -
@ -1272,8 +1281,10 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
void ClearStencil(GLint v);
void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b,
WebGLboolean a);
void ColorMask(bool r, bool g, bool b, bool a) const {
ColorMaskI({}, r, g, b, a);
}
void ColorMaskI(Maybe<GLuint> buf, bool r, bool g, bool b, bool a) const;
void CullFace(GLenum face);

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

@ -28,6 +28,8 @@ DEFINE_WEBGL_EXTENSION_GOOP(EXT_texture_filter_anisotropic,
WebGLExtensionTextureFilterAnisotropic)
DEFINE_WEBGL_EXTENSION_GOOP(EXT_texture_norm16, WebGLExtensionTextureNorm16)
DEFINE_WEBGL_EXTENSION_GOOP(MOZ_debug, WebGLExtensionMOZDebug)
DEFINE_WEBGL_EXTENSION_GOOP(OES_draw_buffers_indexed,
WebGLExtensionDrawBuffersIndexed)
DEFINE_WEBGL_EXTENSION_GOOP(OES_element_index_uint,
WebGLExtensionElementIndexUint)
DEFINE_WEBGL_EXTENSION_GOOP(OES_fbo_render_mipmap,

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

@ -362,6 +362,66 @@ class ClientWebGLExtensionMultiview : public ClientWebGLExtensionBase {
}
};
class ClientWebGLExtensionDrawBuffersIndexed : public ClientWebGLExtensionBase {
public:
virtual JSObject* WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) override;
explicit ClientWebGLExtensionDrawBuffersIndexed(ClientWebGLContext&);
void EnableiOES(const GLenum target, const GLuint buf) const {
if (MOZ_UNLIKELY(!mContext)) {
AutoJsWarning("enableiOES: Extension is `invalidated`.");
return;
}
mContext->SetEnabledI(target, Some(buf), true);
}
void DisableiOES(const GLenum target, const GLuint buf) const {
if (MOZ_UNLIKELY(!mContext)) {
AutoJsWarning("disableiOES: Extension is `invalidated`.");
return;
}
mContext->SetEnabledI(target, Some(buf), false);
}
void BlendEquationiOES(const GLuint buf, const GLenum mode) const {
BlendEquationSeparateiOES(buf, mode, mode);
}
void BlendEquationSeparateiOES(const GLuint buf, const GLenum modeRgb,
const GLenum modeAlpha) const {
if (MOZ_UNLIKELY(!mContext)) {
AutoJsWarning("blendEquationSeparateiOES: Extension is `invalidated`.");
return;
}
mContext->BlendEquationSeparateI(Some(buf), modeRgb, modeAlpha);
}
void BlendFunciOES(const GLuint buf, const GLenum src,
const GLenum dst) const {
BlendFuncSeparateiOES(buf, src, dst, src, dst);
}
void BlendFuncSeparateiOES(const GLuint buf, const GLenum srcRgb,
const GLenum dstRgb, const GLenum srcAlpha,
const GLenum dstAlpha) const {
if (MOZ_UNLIKELY(!mContext)) {
AutoJsWarning("blendFuncSeparateiOES: Extension is `invalidated`.");
return;
}
mContext->BlendFuncSeparateI(Some(buf), srcRgb, dstRgb, srcAlpha, dstAlpha);
}
void ColorMaskiOES(const GLuint buf, const bool r, const bool g, const bool b,
const bool a) const {
if (MOZ_UNLIKELY(!mContext)) {
AutoJsWarning("colorMaskiOES: Extension is `invalidated`.");
return;
}
mContext->ColorMaskI(Some(buf), r, g, b, a);
}
};
} // namespace mozilla
#endif // CLIENTWEBGLEXTENSIONS_H_

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

@ -241,9 +241,9 @@ class HostWebGLContext final : public SupportsWeakPtr {
// ------------------------- GL State -------------------------
bool IsContextLost() const { return mContext->IsContextLost(); }
void Disable(GLenum cap) const { mContext->Disable(cap); }
void Enable(GLenum cap) const { mContext->Enable(cap); }
void SetEnabled(GLenum cap, Maybe<GLuint> i, bool val) const {
mContext->SetEnabled(cap, i, val);
}
bool IsEnabled(GLenum cap) const { return mContext->IsEnabled(cap); }
@ -277,13 +277,14 @@ class HostWebGLContext final : public SupportsWeakPtr {
mContext->BlendColor(r, g, b, a);
}
void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) const {
mContext->BlendEquationSeparate(modeRGB, modeAlpha);
void BlendEquationSeparate(Maybe<GLuint> i, GLenum modeRGB,
GLenum modeAlpha) const {
mContext->BlendEquationSeparate(i, modeRGB, modeAlpha);
}
void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha,
GLenum dstAlpha) const {
mContext->BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
void BlendFuncSeparate(Maybe<GLuint> i, GLenum srcRGB, GLenum dstRGB,
GLenum srcAlpha, GLenum dstAlpha) const {
mContext->BlendFuncSeparate(i, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
GLenum CheckFramebufferStatus(GLenum target) const {
@ -300,9 +301,8 @@ class HostWebGLContext final : public SupportsWeakPtr {
void ClearStencil(GLint v) const { mContext->ClearStencil(v); }
void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b,
WebGLboolean a) const {
mContext->ColorMask(r, g, b, a);
void ColorMask(Maybe<GLuint> i, uint8_t mask) const {
mContext->ColorMask(i, mask);
}
void CompileShader(const ObjectId id) const {

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

@ -25,6 +25,34 @@ Maybe<double> WebGL2Context::GetIndexedParameter(const GLenum pname,
const FuncScope funcScope(*this, "getIndexedParameter");
if (IsContextLost()) return {};
if (IsExtensionEnabled(WebGLExtensionID::OES_draw_buffers_indexed)) {
switch (pname) {
case LOCAL_GL_BLEND_EQUATION_RGB:
case LOCAL_GL_BLEND_EQUATION_ALPHA:
case LOCAL_GL_BLEND_SRC_RGB:
case LOCAL_GL_BLEND_SRC_ALPHA:
case LOCAL_GL_BLEND_DST_RGB:
case LOCAL_GL_BLEND_DST_ALPHA:
case LOCAL_GL_COLOR_WRITEMASK: {
const auto limit = MaxValidDrawBuffers();
if (index >= limit) {
ErrorInvalidValue("`index` (%u) must be < %s (%u)", index,
"MAX_DRAW_BUFFERS", limit);
return {};
}
std::array<GLint, 4> data = {};
gl->fGetIntegeri_v(pname, index, data.data());
auto val = data[0];
if (pname == LOCAL_GL_COLOR_WRITEMASK) {
val = (bool(data[0]) << 0 | bool(data[1]) << 1 | bool(data[2]) << 2 |
bool(data[3]) << 3);
}
return Some(val);
}
}
}
const auto* bindings = &mIndexedUniformBufferBindings;
const char* limitStr = "MAX_UNIFORM_BUFFER_BINDINGS";
switch (pname) {
@ -39,7 +67,7 @@ Maybe<double> WebGL2Context::GetIndexedParameter(const GLenum pname,
break;
default:
ErrorInvalidEnumInfo("pname", pname);
ErrorInvalidEnumArg("pname", pname);
return {};
}

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

@ -6,6 +6,7 @@
#include "WebGLContext.h"
#include <algorithm>
#include <bitset>
#include <queue>
#include <regex>
@ -1246,11 +1247,14 @@ bool WebGLContext::BindDefaultFBForRead() {
}
void WebGLContext::DoColorMask(const uint8_t bitmask) const {
if (mDriverColorMask != bitmask) {
mDriverColorMask = bitmask;
gl->fColorMask(
bool(mDriverColorMask & (1 << 0)), bool(mDriverColorMask & (1 << 1)),
bool(mDriverColorMask & (1 << 2)), bool(mDriverColorMask & (1 << 3)));
if (mDriverColorMask0 != bitmask) {
mDriverColorMask0 = bitmask;
const auto bs = std::bitset<4>(bitmask);
if (gl->IsSupported(gl::GLFeature::draw_buffers_indexed)) {
gl->fColorMaski(0, bs[0], bs[1], bs[2], bs[3]);
} else {
gl->fColorMask(bs[0], bs[1], bs[2], bs[3]);
}
}
}
@ -1258,16 +1262,16 @@ void WebGLContext::DoColorMask(const uint8_t bitmask) const {
ScopedDrawCallWrapper::ScopedDrawCallWrapper(WebGLContext& webgl)
: mWebGL(webgl) {
uint8_t driverColorMask = mWebGL.mColorWriteMask;
uint8_t driverColorMask0 = mWebGL.mColorWriteMask0;
bool driverDepthTest = mWebGL.mDepthTestEnabled;
bool driverStencilTest = mWebGL.mStencilTestEnabled;
const auto& fb = mWebGL.mBoundDrawFramebuffer;
if (!fb) {
if (mWebGL.mDefaultFB_DrawBuffer0 == LOCAL_GL_NONE) {
driverColorMask = 0; // Is this well-optimized enough for depth-first
driverColorMask0 = 0; // Is this well-optimized enough for depth-first
// rendering?
} else {
driverColorMask &= ~(uint8_t(mWebGL.mNeedsFakeNoAlpha) << 3);
driverColorMask0 &= ~(uint8_t(mWebGL.mNeedsFakeNoAlpha) << 3);
}
driverDepthTest &= !mWebGL.mNeedsFakeNoDepth;
driverStencilTest &= !mWebGL.mNeedsFakeNoStencil;
@ -1280,7 +1284,7 @@ ScopedDrawCallWrapper::ScopedDrawCallWrapper(WebGLContext& webgl)
}
const auto& gl = mWebGL.gl;
mWebGL.DoColorMask(driverColorMask);
mWebGL.DoColorMask(driverColorMask0);
if (mWebGL.mDriverDepthTest != driverDepthTest) {
// "When disabled, the depth comparison and subsequent possible updates to
// the

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

@ -6,6 +6,7 @@
#ifndef WEBGLCONTEXT_H_
#define WEBGLCONTEXT_H_
#include <bitset>
#include <memory>
#include <stdarg.h>
@ -538,16 +539,15 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
void BindRenderbuffer(GLenum target, WebGLRenderbuffer* fb);
void BindVertexArray(WebGLVertexArray* vao);
void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha,
GLenum dstAlpha);
void BlendEquationSeparate(Maybe<GLuint> i, GLenum modeRGB, GLenum modeAlpha);
void BlendFuncSeparate(Maybe<GLuint> i, GLenum srcRGB, GLenum dstRGB,
GLenum srcAlpha, GLenum dstAlpha);
GLenum CheckFramebufferStatus(GLenum target);
void Clear(GLbitfield mask);
void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
void ClearDepth(GLclampf v);
void ClearStencil(GLint v);
void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b,
WebGLboolean a);
void ColorMask(Maybe<GLuint> i, uint8_t mask);
void CompileShader(WebGLShader& shader);
private:
@ -703,12 +703,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
// -----------------------------------------------------------------------------
// State and State Requests (WebGLContextState.cpp)
private:
void SetEnabled(const char* funcName, GLenum cap, bool enabled);
public:
void Disable(GLenum cap) { SetEnabled("disabled", cap, false); }
void Enable(GLenum cap) { SetEnabled("enabled", cap, true); }
void SetEnabled(GLenum cap, Maybe<GLuint> i, bool enabled);
bool GetStencilBits(GLint* const out_stencilBits) const;
virtual Maybe<double> GetParameter(GLenum pname);
@ -718,13 +713,12 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
private:
// State tracking slots
realGLboolean mDitherEnabled = 1;
realGLboolean mRasterizerDiscardEnabled = 0;
realGLboolean mScissorTestEnabled = 0;
realGLboolean mDepthTestEnabled = 0;
realGLboolean mStencilTestEnabled = 0;
realGLboolean mBlendEnabled = 0;
GLenum mGenerateMipmapHint = 0;
bool mDitherEnabled = true;
bool mRasterizerDiscardEnabled = false;
bool mScissorTestEnabled = false;
bool mDepthTestEnabled = false;
bool mStencilTestEnabled = false;
GLenum mGenerateMipmapHint = LOCAL_GL_DONT_CARE;
struct ScissorRect final {
GLint x;
@ -737,7 +731,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
ScissorRect mScissorRect = {};
bool ValidateCapabilityEnum(GLenum cap);
realGLboolean* GetStateTrackingSlot(GLenum cap);
bool* GetStateTrackingSlot(GLenum cap, GLuint i);
// Allocation debugging variables
mutable uint64_t mDataAllocGLCallCount = 0;
@ -871,8 +865,8 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
GLuint mActiveTexture = 0;
GLenum mDefaultFB_DrawBuffer0 = 0;
GLenum mDefaultFB_ReadBuffer = 0;
GLenum mDefaultFB_DrawBuffer0 = LOCAL_GL_BACK;
GLenum mDefaultFB_ReadBuffer = LOCAL_GL_BACK;
mutable GLenum mWebGLError = 0;
@ -1151,11 +1145,15 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
GLuint mStencilValueMaskBack = 0;
GLuint mStencilWriteMaskFront = 0;
GLuint mStencilWriteMaskBack = 0;
uint8_t mColorWriteMask = 0xf; // bitmask
realGLboolean mDepthWriteMask = 0;
GLfloat mColorClearValue[4];
uint8_t mColorWriteMask0 = 0xf; // bitmask
mutable uint8_t mDriverColorMask0 = 0xf;
bool mDepthWriteMask = true;
GLfloat mColorClearValue[4] = {0, 0, 0, 0};
GLint mStencilClearValue = 0;
GLfloat mDepthClearValue = 0.0;
GLfloat mDepthClearValue = 1.0f;
std::bitset<webgl::kMaxDrawBuffers> mColorWriteMaskNonzero = -1;
std::bitset<webgl::kMaxDrawBuffers> mBlendEnabled = 0;
GLint mViewportX = 0;
GLint mViewportY = 0;
@ -1163,7 +1161,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
GLsizei mViewportHeight = 0;
bool mAlreadyWarnedAboutViewportLargerThanDest = false;
GLfloat mLineWidth = 0.0;
GLfloat mLineWidth = 1.0;
WebGLContextLossHandler mContextLossHandler;
@ -1186,7 +1184,6 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
bool mNeedsFakeNoStencil = false;
bool mNeedsFakeNoStencil_UserFBs = false;
mutable uint8_t mDriverColorMask = 0;
bool mDriverDepthTest = false;
bool mDriverStencilTest = false;

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

@ -333,18 +333,32 @@ static bool DoSetsIntersect(const std::set<T>& a, const std::set<T>& b) {
return bool(intersection.size());
}
template <size_t N>
static size_t FindFirstOne(const std::bitset<N>& bs) {
MOZ_ASSERT(bs.any());
// We don't need this to be fast, so don't bother with CLZ intrinsics.
for (const auto i : IntegerRange(N)) {
if (bs[i]) return i;
}
return -1;
}
const webgl::CachedDrawFetchLimits* ValidateDraw(WebGLContext* const webgl,
const GLenum mode,
const uint32_t instanceCount) {
if (!webgl->BindCurFBForDraw()) return nullptr;
const auto& fb = webgl->mBoundDrawFramebuffer;
if (fb && webgl->mBlendEnabled) {
if (fb) {
const auto& info = *fb->GetCompletenessInfo();
if (info.hasFloat32) {
const auto isF32WithBlending = info.isAttachmentF32 & webgl->mBlendEnabled;
if (isF32WithBlending.any()) {
if (!webgl->IsExtensionEnabled(WebGLExtensionID::EXT_float_blend)) {
const auto first = FindFirstOne(isF32WithBlending);
webgl->ErrorInvalidOperation(
"Float32 blending requires EXT_float_blend.");
"Attachment %u is float32 with blending enabled, which requires "
"EXT_float_blend.",
uint32_t(first));
return nullptr;
}
webgl->WarnIfImplicit(WebGLExtensionID::EXT_float_blend);
@ -420,14 +434,7 @@ const webgl::CachedDrawFetchLimits* ValidateDraw(WebGLContext* const webgl,
const auto fnValidateFragOutputType =
[&](const uint8_t loc, const webgl::TextureBaseType dstBaseType) {
const auto itr = fragOutputs.find(loc);
if (MOZ_UNLIKELY(itr == fragOutputs.end())) {
webgl->ErrorInvalidOperation(
"Program has no frag output at location %u, but"
" destination draw buffer has an attached"
" image.",
uint32_t(loc));
return false;
}
MOZ_DIAGNOSTIC_ASSERT(itr != fragOutputs.end());
const auto& info = itr->second;
const auto& srcBaseType = info.baseType;
@ -445,9 +452,15 @@ const webgl::CachedDrawFetchLimits* ValidateDraw(WebGLContext* const webgl,
if (!webgl->mRasterizerDiscardEnabled) {
uint8_t fbZLayerCount = 1;
auto hasAttachment = std::bitset<webgl::kMaxDrawBuffers>(1);
auto drawBufferEnabled = std::bitset<webgl::kMaxDrawBuffers>();
if (fb) {
drawBufferEnabled = fb->DrawBufferEnabled();
const auto& info = *fb->GetCompletenessInfo();
fbZLayerCount = info.zLayerCount;
hasAttachment = info.hasAttachment;
} else {
drawBufferEnabled[0] = (webgl->mDefaultFB_DrawBuffer0 == LOCAL_GL_BACK);
}
if (fbZLayerCount != linkInfo->zLayerCount) {
@ -457,19 +470,40 @@ const webgl::CachedDrawFetchLimits* ValidateDraw(WebGLContext* const webgl,
return nullptr;
}
if (webgl->mColorWriteMask) {
const auto writable =
hasAttachment & drawBufferEnabled & webgl->mColorWriteMaskNonzero;
if (writable.any()) {
// Do we have any undefined outputs with real attachments that
// aren't masked-out by color write mask or drawBuffers?
const auto wouldWriteUndefined = ~linkInfo->hasOutput & writable;
if (wouldWriteUndefined.any()) {
const auto first = FindFirstOne(wouldWriteUndefined);
webgl->ErrorInvalidOperation(
"Program has no frag output at location %u, the"
" destination draw buffer has an attached"
" image, and its color write mask is not all false,"
" and DRAW_BUFFER%u is not NONE.",
uint32_t(first), uint32_t(first));
return nullptr;
}
const auto outputWrites = linkInfo->hasOutput & writable;
if (fb) {
for (const auto& attach : fb->ColorDrawBuffers()) {
const auto i =
uint8_t(attach->mAttachmentPoint - LOCAL_GL_COLOR_ATTACHMENT0);
if (!outputWrites[i]) continue;
const auto& imageInfo = attach->GetImageInfo();
if (!imageInfo) continue;
const auto& dstBaseType = imageInfo->mFormat->format->baseType;
if (!fnValidateFragOutputType(i, dstBaseType)) return nullptr;
}
} else {
if (!fnValidateFragOutputType(0, webgl::TextureBaseType::Float))
return nullptr;
if (outputWrites[0]) {
if (!fnValidateFragOutputType(0, webgl::TextureBaseType::Float))
return nullptr;
}
}
}
}

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

@ -9,6 +9,7 @@
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/EnumeratedRange.h"
#include "mozilla/StaticPrefs_webgl.h"
#include "nsString.h"
#include "WebGLContextUtils.h"
#include "WebGLExtensions.h"
@ -40,6 +41,7 @@ const char* GetExtensionName(const WebGLExtensionID ext) {
WEBGL_EXTENSION_IDENTIFIER(EXT_texture_filter_anisotropic)
WEBGL_EXTENSION_IDENTIFIER(EXT_texture_norm16)
WEBGL_EXTENSION_IDENTIFIER(MOZ_debug)
WEBGL_EXTENSION_IDENTIFIER(OES_draw_buffers_indexed)
WEBGL_EXTENSION_IDENTIFIER(OES_element_index_uint)
WEBGL_EXTENSION_IDENTIFIER(OES_fbo_render_mipmap)
WEBGL_EXTENSION_IDENTIFIER(OES_standard_derivatives)
@ -161,6 +163,8 @@ RefPtr<ClientWebGLExtensionBase> ClientWebGLContext::GetExtension(
return new ClientWebGLExtensionMOZDebug(*this);
// OES_
case WebGLExtensionID::OES_draw_buffers_indexed:
return new ClientWebGLExtensionDrawBuffersIndexed(*this);
case WebGLExtensionID::OES_element_index_uint:
return new ClientWebGLExtensionElementIndexUint(*this);
case WebGLExtensionID::OES_fbo_render_mipmap:
@ -283,6 +287,12 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const {
return WebGLExtensionTextureNorm16::IsSupported(this);
// OES_
case WebGLExtensionID::OES_draw_buffers_indexed:
if (!StaticPrefs::webgl_enable_draft_extensions()) return false;
if (!IsWebGL2()) return false;
return gl->IsSupported(gl::GLFeature::draw_buffers_indexed) &&
gl->IsSupported(gl::GLFeature::get_integer_indexed);
case WebGLExtensionID::OES_element_index_uint:
if (IsWebGL2()) return false;
return gl->IsSupported(gl::GLFeature::element_index_uint);
@ -426,6 +436,9 @@ void WebGLContext::RequestExtension(const WebGLExtensionID ext,
break;
// OES_
case WebGLExtensionID::OES_draw_buffers_indexed:
slot.reset(new WebGLExtensionDrawBuffersIndexed(this));
break;
case WebGLExtensionID::OES_element_index_uint:
slot.reset(new WebGLExtensionElementIndexUint(this));
break;

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

@ -123,13 +123,36 @@ void WebGLContext::ClearStencil(GLint v) {
gl->fClearStencil(v);
}
void WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b,
WebGLboolean a) {
void WebGLContext::ColorMask(const Maybe<GLuint> i, const uint8_t mask) {
const FuncScope funcScope(*this, "colorMask");
if (IsContextLost()) return;
mColorWriteMask = uint8_t(bool(r) << 0) | uint8_t(bool(g) << 1) |
uint8_t(bool(b) << 2) | uint8_t(bool(a) << 3);
const auto bs = std::bitset<4>(mask);
if (i) {
MOZ_RELEASE_ASSERT(
IsExtensionEnabled(WebGLExtensionID::OES_draw_buffers_indexed));
const auto limit = MaxValidDrawBuffers();
if (*i >= limit) {
ErrorInvalidValue("`index` (%u) must be < %s (%u)", *i,
"MAX_DRAW_BUFFERS", limit);
return;
}
gl->fColorMaski(*i, bs[0], bs[1], bs[2], bs[3]);
if (*i == 0) {
mColorWriteMask0 = mask;
}
mColorWriteMaskNonzero[*i] = bool(mask);
} else {
gl->fColorMask(bs[0], bs[1], bs[2], bs[3]);
mColorWriteMask0 = mask;
if (mask) {
mColorWriteMaskNonzero.set();
} else {
mColorWriteMaskNonzero.reset();
}
}
}
void WebGLContext::DepthMask(WebGLboolean b) {

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

@ -130,7 +130,8 @@ void WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer* wfb) {
funcScope.mBindFailureGuard = false;
}
void WebGLContext::BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
void WebGLContext::BlendEquationSeparate(Maybe<GLuint> i, GLenum modeRGB,
GLenum modeAlpha) {
const FuncScope funcScope(*this, "blendEquationSeparate");
if (IsContextLost()) return;
@ -139,7 +140,20 @@ void WebGLContext::BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
return;
}
gl->fBlendEquationSeparate(modeRGB, modeAlpha);
if (i) {
MOZ_RELEASE_ASSERT(
IsExtensionEnabled(WebGLExtensionID::OES_draw_buffers_indexed));
const auto limit = MaxValidDrawBuffers();
if (*i >= limit) {
ErrorInvalidValue("`index` (%u) must be < %s (%u)", *i,
"MAX_DRAW_BUFFERS", limit);
return;
}
gl->fBlendEquationSeparatei(*i, modeRGB, modeAlpha);
} else {
gl->fBlendEquationSeparate(modeRGB, modeAlpha);
}
}
static bool ValidateBlendFuncEnum(WebGLContext* webgl, GLenum factor,
@ -193,8 +207,9 @@ static bool ValidateBlendFuncEnums(WebGLContext* webgl, GLenum srcRGB,
return true;
}
void WebGLContext::BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB,
GLenum srcAlpha, GLenum dstAlpha) {
void WebGLContext::BlendFuncSeparate(Maybe<GLuint> i, GLenum srcRGB,
GLenum dstRGB, GLenum srcAlpha,
GLenum dstAlpha) {
const FuncScope funcScope(*this, "blendFuncSeparate");
if (IsContextLost()) return;
@ -206,7 +221,20 @@ void WebGLContext::BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB,
if (!ValidateBlendFuncEnumsCompatibility(srcRGB, dstRGB, "srcRGB and dstRGB"))
return;
gl->fBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
if (i) {
MOZ_RELEASE_ASSERT(
IsExtensionEnabled(WebGLExtensionID::OES_draw_buffers_indexed));
const auto limit = MaxValidDrawBuffers();
if (*i >= limit) {
ErrorInvalidValue("`index` (%u) must be < %s (%u)", *i,
"MAX_DRAW_BUFFERS", limit);
return;
}
gl->fBlendFuncSeparatei(*i, srcRGB, dstRGB, srcAlpha, dstAlpha);
} else {
gl->fBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
}
GLenum WebGLContext::CheckFramebufferStatus(GLenum target) {

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

@ -22,16 +22,40 @@
namespace mozilla {
void WebGLContext::SetEnabled(const char* const funcName, const GLenum cap,
void WebGLContext::SetEnabled(const GLenum cap, const Maybe<GLuint> i,
const bool enabled) {
const FuncScope funcScope(*this, funcName);
const FuncScope funcScope(*this, "enable(i)/disable(i)");
if (IsContextLost()) return;
if (!ValidateCapabilityEnum(cap)) return;
const auto& slot = GetStateTrackingSlot(cap);
if (i) {
if (cap != LOCAL_GL_BLEND) {
ErrorInvalidEnumArg("cap", cap);
return;
}
const auto limit = MaxValidDrawBuffers();
if (*i >= limit) {
ErrorInvalidValue("`index` (%u) must be < %s (%u)", *i,
"MAX_DRAW_BUFFERS", limit);
return;
}
}
const auto slot = GetStateTrackingSlot(cap, i ? *i : 0);
if (slot) {
*slot = enabled;
} else if (cap == LOCAL_GL_BLEND) {
if (i) {
mBlendEnabled[*i] = enabled;
} else {
if (enabled) {
mBlendEnabled.set();
} else {
mBlendEnabled.reset();
}
}
}
switch (cap) {
@ -41,7 +65,15 @@ void WebGLContext::SetEnabled(const char* const funcName, const GLenum cap,
default:
// Non-lazy caps.
gl->SetEnabled(cap, enabled);
if (i) {
if (enabled) {
gl->fEnablei(cap, *i);
} else {
gl->fDisablei(cap, *i);
}
} else {
gl->SetEnabled(cap, enabled);
}
break;
}
}
@ -88,7 +120,8 @@ Maybe<double> WebGLContext::GetParameter(const GLenum pname) {
}
} else {
const auto& fb = *mBoundDrawFramebuffer;
if (fb.IsDrawBufferEnabled(slotId)) {
const auto& bs = fb.DrawBufferEnabled();
if (bs[slotId]) {
ret = LOCAL_GL_COLOR_ATTACHMENT0 + slotId;
}
}
@ -355,6 +388,9 @@ Maybe<double> WebGLContext::GetParameter(const GLenum pname) {
case LOCAL_GL_STENCIL_WRITEMASK:
return Some(mStencilWriteMaskFront);
case LOCAL_GL_COLOR_WRITEMASK:
return Some(mColorWriteMask0);
// float
case LOCAL_GL_LINE_WIDTH:
return Some((double)mLineWidth);
@ -402,7 +438,7 @@ bool WebGLContext::IsEnabled(GLenum cap) {
if (!ValidateCapabilityEnum(cap)) return false;
const auto& slot = GetStateTrackingSlot(cap);
const auto& slot = GetStateTrackingSlot(cap, 0);
if (slot) return *slot;
return gl->fIsEnabled(cap);
@ -428,7 +464,7 @@ bool WebGLContext::ValidateCapabilityEnum(GLenum cap) {
}
}
realGLboolean* WebGLContext::GetStateTrackingSlot(GLenum cap) {
bool* WebGLContext::GetStateTrackingSlot(GLenum cap, GLuint i) {
switch (cap) {
case LOCAL_GL_DEPTH_TEST:
return &mDepthTestEnabled;
@ -440,8 +476,6 @@ realGLboolean* WebGLContext::GetStateTrackingSlot(GLenum cap) {
return &mScissorTestEnabled;
case LOCAL_GL_STENCIL_TEST:
return &mStencilTestEnabled;
case LOCAL_GL_BLEND:
return &mBlendEnabled;
}
return nullptr;

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

@ -63,324 +63,326 @@ TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget) {
// This version is fallible and will return nullptr if unrecognized.
const char* GetEnumName(const GLenum val, const char* const defaultRet) {
switch (val) {
case 0:
return "0";
#define XX(x) \
case LOCAL_GL_##x: \
return #x
XX(NONE);
XX(ALPHA);
XX(COMPRESSED_RGBA_PVRTC_2BPPV1);
XX(COMPRESSED_RGBA_PVRTC_4BPPV1);
XX(COMPRESSED_RGBA_S3TC_DXT1_EXT);
XX(COMPRESSED_RGBA_S3TC_DXT3_EXT);
XX(COMPRESSED_RGBA_S3TC_DXT5_EXT);
XX(COMPRESSED_RGB_PVRTC_2BPPV1);
XX(COMPRESSED_RGB_PVRTC_4BPPV1);
XX(COMPRESSED_RGB_S3TC_DXT1_EXT);
XX(DEPTH_ATTACHMENT);
XX(DEPTH_COMPONENT);
XX(DEPTH_COMPONENT16);
XX(DEPTH_COMPONENT32);
XX(DEPTH_STENCIL);
XX(DEPTH24_STENCIL8);
XX(DRAW_FRAMEBUFFER);
XX(ETC1_RGB8_OES);
XX(FLOAT);
XX(INT);
XX(FRAMEBUFFER);
XX(HALF_FLOAT);
XX(LUMINANCE);
XX(LUMINANCE_ALPHA);
XX(READ_FRAMEBUFFER);
XX(RGB);
XX(RGB16F);
XX(RGB32F);
XX(RGBA);
XX(RGBA16F);
XX(RGBA32F);
XX(SRGB);
XX(SRGB_ALPHA);
XX(TEXTURE_2D);
XX(TEXTURE_3D);
XX(TEXTURE_CUBE_MAP);
XX(TEXTURE_CUBE_MAP_NEGATIVE_X);
XX(TEXTURE_CUBE_MAP_NEGATIVE_Y);
XX(TEXTURE_CUBE_MAP_NEGATIVE_Z);
XX(TEXTURE_CUBE_MAP_POSITIVE_X);
XX(TEXTURE_CUBE_MAP_POSITIVE_Y);
XX(TEXTURE_CUBE_MAP_POSITIVE_Z);
XX(UNSIGNED_BYTE);
XX(UNSIGNED_INT);
XX(UNSIGNED_INT_24_8);
XX(UNSIGNED_SHORT);
XX(UNSIGNED_SHORT_4_4_4_4);
XX(UNSIGNED_SHORT_5_5_5_1);
XX(UNSIGNED_SHORT_5_6_5);
XX(READ_BUFFER);
XX(UNPACK_ROW_LENGTH);
XX(UNPACK_SKIP_ROWS);
XX(UNPACK_SKIP_PIXELS);
XX(PACK_ROW_LENGTH);
XX(PACK_SKIP_ROWS);
XX(PACK_SKIP_PIXELS);
XX(COLOR);
XX(DEPTH);
XX(STENCIL);
XX(RED);
XX(RGB8);
XX(RGBA8);
XX(RGB10_A2);
XX(TEXTURE_BINDING_3D);
XX(UNPACK_SKIP_IMAGES);
XX(UNPACK_IMAGE_HEIGHT);
XX(TEXTURE_WRAP_R);
XX(MAX_3D_TEXTURE_SIZE);
XX(UNSIGNED_INT_2_10_10_10_REV);
XX(MAX_ELEMENTS_VERTICES);
XX(MAX_ELEMENTS_INDICES);
XX(TEXTURE_MIN_LOD);
XX(TEXTURE_MAX_LOD);
XX(TEXTURE_BASE_LEVEL);
XX(TEXTURE_MAX_LEVEL);
XX(MIN);
XX(MAX);
XX(DEPTH_COMPONENT24);
XX(MAX_TEXTURE_LOD_BIAS);
XX(TEXTURE_COMPARE_MODE);
XX(TEXTURE_COMPARE_FUNC);
XX(CURRENT_QUERY);
XX(QUERY_RESULT);
XX(QUERY_RESULT_AVAILABLE);
XX(STREAM_READ);
XX(STREAM_COPY);
XX(STATIC_READ);
XX(STATIC_COPY);
XX(DYNAMIC_READ);
XX(DYNAMIC_COPY);
XX(MAX_DRAW_BUFFERS);
XX(DRAW_BUFFER0);
XX(DRAW_BUFFER1);
XX(DRAW_BUFFER2);
XX(DRAW_BUFFER3);
XX(DRAW_BUFFER4);
XX(DRAW_BUFFER5);
XX(DRAW_BUFFER6);
XX(DRAW_BUFFER7);
XX(DRAW_BUFFER8);
XX(DRAW_BUFFER9);
XX(DRAW_BUFFER10);
XX(DRAW_BUFFER11);
XX(DRAW_BUFFER12);
XX(DRAW_BUFFER13);
XX(DRAW_BUFFER14);
XX(DRAW_BUFFER15);
XX(MAX_FRAGMENT_UNIFORM_COMPONENTS);
XX(MAX_VERTEX_UNIFORM_COMPONENTS);
XX(SAMPLER_3D);
XX(SAMPLER_2D_SHADOW);
XX(FRAGMENT_SHADER_DERIVATIVE_HINT);
XX(PIXEL_PACK_BUFFER);
XX(PIXEL_UNPACK_BUFFER);
XX(PIXEL_PACK_BUFFER_BINDING);
XX(PIXEL_UNPACK_BUFFER_BINDING);
XX(FLOAT_MAT2x3);
XX(FLOAT_MAT2x4);
XX(FLOAT_MAT3x2);
XX(FLOAT_MAT3x4);
XX(FLOAT_MAT4x2);
XX(FLOAT_MAT4x3);
XX(SRGB8);
XX(SRGB8_ALPHA8);
XX(COMPARE_REF_TO_TEXTURE);
XX(VERTEX_ATTRIB_ARRAY_INTEGER);
XX(MAX_ARRAY_TEXTURE_LAYERS);
XX(MIN_PROGRAM_TEXEL_OFFSET);
XX(MAX_PROGRAM_TEXEL_OFFSET);
XX(MAX_VARYING_COMPONENTS);
XX(TEXTURE_2D_ARRAY);
XX(TEXTURE_BINDING_2D_ARRAY);
XX(R11F_G11F_B10F);
XX(UNSIGNED_INT_10F_11F_11F_REV);
XX(RGB9_E5);
XX(UNSIGNED_INT_5_9_9_9_REV);
XX(TRANSFORM_FEEDBACK_BUFFER_MODE);
XX(MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
XX(TRANSFORM_FEEDBACK_VARYINGS);
XX(TRANSFORM_FEEDBACK_BUFFER_START);
XX(TRANSFORM_FEEDBACK_BUFFER_SIZE);
XX(TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
XX(RASTERIZER_DISCARD);
XX(MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
XX(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
XX(INTERLEAVED_ATTRIBS);
XX(SEPARATE_ATTRIBS);
XX(TRANSFORM_FEEDBACK_BUFFER);
XX(TRANSFORM_FEEDBACK_BUFFER_BINDING);
XX(RGBA32UI);
XX(RGB32UI);
XX(RGBA16UI);
XX(RGB16UI);
XX(RGBA8UI);
XX(RGB8UI);
XX(RGBA32I);
XX(RGB32I);
XX(RGBA16I);
XX(RGB16I);
XX(RGBA8I);
XX(RGB8I);
XX(RED_INTEGER);
XX(RGB_INTEGER);
XX(RGBA_INTEGER);
XX(SAMPLER_2D_ARRAY);
XX(SAMPLER_2D_ARRAY_SHADOW);
XX(SAMPLER_CUBE_SHADOW);
XX(UNSIGNED_INT_VEC2);
XX(UNSIGNED_INT_VEC3);
XX(UNSIGNED_INT_VEC4);
XX(INT_SAMPLER_2D);
XX(INT_SAMPLER_3D);
XX(INT_SAMPLER_CUBE);
XX(INT_SAMPLER_2D_ARRAY);
XX(UNSIGNED_INT_SAMPLER_2D);
XX(UNSIGNED_INT_SAMPLER_3D);
XX(UNSIGNED_INT_SAMPLER_CUBE);
XX(UNSIGNED_INT_SAMPLER_2D_ARRAY);
XX(DEPTH_COMPONENT32F);
XX(DEPTH32F_STENCIL8);
XX(FLOAT_32_UNSIGNED_INT_24_8_REV);
XX(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
XX(FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE);
XX(FRAMEBUFFER_ATTACHMENT_RED_SIZE);
XX(FRAMEBUFFER_ATTACHMENT_GREEN_SIZE);
XX(FRAMEBUFFER_ATTACHMENT_BLUE_SIZE);
XX(FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE);
XX(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE);
XX(FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE);
XX(FRAMEBUFFER_DEFAULT);
XX(DEPTH_STENCIL_ATTACHMENT);
XX(UNSIGNED_NORMALIZED);
XX(DRAW_FRAMEBUFFER_BINDING);
XX(READ_FRAMEBUFFER_BINDING);
XX(RENDERBUFFER_SAMPLES);
XX(FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER);
XX(MAX_COLOR_ATTACHMENTS);
XX(COLOR_ATTACHMENT0);
XX(COLOR_ATTACHMENT1);
XX(COLOR_ATTACHMENT2);
XX(COLOR_ATTACHMENT3);
XX(COLOR_ATTACHMENT4);
XX(COLOR_ATTACHMENT5);
XX(COLOR_ATTACHMENT6);
XX(COLOR_ATTACHMENT7);
XX(COLOR_ATTACHMENT8);
XX(COLOR_ATTACHMENT9);
XX(COLOR_ATTACHMENT10);
XX(COLOR_ATTACHMENT11);
XX(COLOR_ATTACHMENT12);
XX(COLOR_ATTACHMENT13);
XX(COLOR_ATTACHMENT14);
XX(COLOR_ATTACHMENT15);
XX(FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
XX(MAX_SAMPLES);
XX(RG);
XX(RG_INTEGER);
XX(R8);
XX(RG8);
XX(R16F);
XX(R32F);
XX(RG16F);
XX(RG32F);
XX(R8I);
XX(R8UI);
XX(R16I);
XX(R16UI);
XX(R32I);
XX(R32UI);
XX(RG8I);
XX(RG8UI);
XX(RG16I);
XX(RG16UI);
XX(RG32I);
XX(RG32UI);
XX(VERTEX_ARRAY_BINDING);
XX(R8_SNORM);
XX(RG8_SNORM);
XX(RGB8_SNORM);
XX(RGBA8_SNORM);
XX(SIGNED_NORMALIZED);
XX(PRIMITIVE_RESTART_FIXED_INDEX);
XX(COPY_READ_BUFFER);
XX(COPY_WRITE_BUFFER);
XX(UNIFORM_BUFFER);
XX(UNIFORM_BUFFER_BINDING);
XX(UNIFORM_BUFFER_START);
XX(UNIFORM_BUFFER_SIZE);
XX(MAX_VERTEX_UNIFORM_BLOCKS);
XX(MAX_FRAGMENT_UNIFORM_BLOCKS);
XX(MAX_COMBINED_UNIFORM_BLOCKS);
XX(MAX_UNIFORM_BUFFER_BINDINGS);
XX(MAX_UNIFORM_BLOCK_SIZE);
XX(MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
XX(MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
XX(UNIFORM_BUFFER_OFFSET_ALIGNMENT);
XX(ACTIVE_UNIFORM_BLOCKS);
XX(UNIFORM_TYPE);
XX(UNIFORM_SIZE);
XX(UNIFORM_BLOCK_INDEX);
XX(UNIFORM_OFFSET);
XX(UNIFORM_ARRAY_STRIDE);
XX(UNIFORM_MATRIX_STRIDE);
XX(UNIFORM_IS_ROW_MAJOR);
XX(UNIFORM_BLOCK_BINDING);
XX(UNIFORM_BLOCK_DATA_SIZE);
XX(UNIFORM_BLOCK_ACTIVE_UNIFORMS);
XX(UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES);
XX(UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER);
XX(UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER);
XX(MAX_VERTEX_OUTPUT_COMPONENTS);
XX(MAX_FRAGMENT_INPUT_COMPONENTS);
XX(MAX_SERVER_WAIT_TIMEOUT);
XX(OBJECT_TYPE);
XX(SYNC_CONDITION);
XX(SYNC_STATUS);
XX(SYNC_FLAGS);
XX(SYNC_FENCE);
XX(SYNC_GPU_COMMANDS_COMPLETE);
XX(UNSIGNALED);
XX(SIGNALED);
XX(ALREADY_SIGNALED);
XX(TIMEOUT_EXPIRED);
XX(CONDITION_SATISFIED);
XX(WAIT_FAILED);
XX(VERTEX_ATTRIB_ARRAY_DIVISOR);
XX(ANY_SAMPLES_PASSED);
XX(ANY_SAMPLES_PASSED_CONSERVATIVE);
XX(SAMPLER_BINDING);
XX(RGB10_A2UI);
XX(TEXTURE_SWIZZLE_R);
XX(TEXTURE_SWIZZLE_G);
XX(TEXTURE_SWIZZLE_B);
XX(TEXTURE_SWIZZLE_A);
XX(GREEN);
XX(BLUE);
XX(INT_2_10_10_10_REV);
XX(TRANSFORM_FEEDBACK);
XX(TRANSFORM_FEEDBACK_PAUSED);
XX(TRANSFORM_FEEDBACK_ACTIVE);
XX(TRANSFORM_FEEDBACK_BINDING);
XX(COMPRESSED_R11_EAC);
XX(COMPRESSED_SIGNED_R11_EAC);
XX(COMPRESSED_RG11_EAC);
XX(COMPRESSED_SIGNED_RG11_EAC);
XX(COMPRESSED_RGB8_ETC2);
XX(COMPRESSED_SRGB8_ETC2);
XX(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
XX(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
XX(COMPRESSED_RGBA8_ETC2_EAC);
XX(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
XX(TEXTURE_IMMUTABLE_FORMAT);
XX(MAX_ELEMENT_INDEX);
XX(NUM_SAMPLE_COUNTS);
XX(TEXTURE_IMMUTABLE_LEVELS);
return #x;
// XX(NONE)
XX(ALPHA)
XX(COMPRESSED_RGBA_PVRTC_2BPPV1)
XX(COMPRESSED_RGBA_PVRTC_4BPPV1)
XX(COMPRESSED_RGBA_S3TC_DXT1_EXT)
XX(COMPRESSED_RGBA_S3TC_DXT3_EXT)
XX(COMPRESSED_RGBA_S3TC_DXT5_EXT)
XX(COMPRESSED_RGB_PVRTC_2BPPV1)
XX(COMPRESSED_RGB_PVRTC_4BPPV1)
XX(COMPRESSED_RGB_S3TC_DXT1_EXT)
XX(DEPTH_ATTACHMENT)
XX(DEPTH_COMPONENT)
XX(DEPTH_COMPONENT16)
XX(DEPTH_COMPONENT32)
XX(DEPTH_STENCIL)
XX(DEPTH24_STENCIL8)
XX(DRAW_FRAMEBUFFER)
XX(ETC1_RGB8_OES)
XX(FLOAT)
XX(INT)
XX(FRAMEBUFFER)
XX(HALF_FLOAT)
XX(LUMINANCE)
XX(LUMINANCE_ALPHA)
XX(READ_FRAMEBUFFER)
XX(RGB)
XX(RGB16F)
XX(RGB32F)
XX(RGBA)
XX(RGBA16F)
XX(RGBA32F)
XX(SRGB)
XX(SRGB_ALPHA)
XX(TEXTURE_2D)
XX(TEXTURE_3D)
XX(TEXTURE_CUBE_MAP)
XX(TEXTURE_CUBE_MAP_NEGATIVE_X)
XX(TEXTURE_CUBE_MAP_NEGATIVE_Y)
XX(TEXTURE_CUBE_MAP_NEGATIVE_Z)
XX(TEXTURE_CUBE_MAP_POSITIVE_X)
XX(TEXTURE_CUBE_MAP_POSITIVE_Y)
XX(TEXTURE_CUBE_MAP_POSITIVE_Z)
XX(UNSIGNED_BYTE)
XX(UNSIGNED_INT)
XX(UNSIGNED_INT_24_8)
XX(UNSIGNED_SHORT)
XX(UNSIGNED_SHORT_4_4_4_4)
XX(UNSIGNED_SHORT_5_5_5_1)
XX(UNSIGNED_SHORT_5_6_5)
XX(READ_BUFFER)
XX(UNPACK_ROW_LENGTH)
XX(UNPACK_SKIP_ROWS)
XX(UNPACK_SKIP_PIXELS)
XX(PACK_ROW_LENGTH)
XX(PACK_SKIP_ROWS)
XX(PACK_SKIP_PIXELS)
XX(COLOR)
XX(DEPTH)
XX(STENCIL)
XX(RED)
XX(RGB8)
XX(RGBA8)
XX(RGB10_A2)
XX(TEXTURE_BINDING_3D)
XX(UNPACK_SKIP_IMAGES)
XX(UNPACK_IMAGE_HEIGHT)
XX(TEXTURE_WRAP_R)
XX(MAX_3D_TEXTURE_SIZE)
XX(UNSIGNED_INT_2_10_10_10_REV)
XX(MAX_ELEMENTS_VERTICES)
XX(MAX_ELEMENTS_INDICES)
XX(TEXTURE_MIN_LOD)
XX(TEXTURE_MAX_LOD)
XX(TEXTURE_BASE_LEVEL)
XX(TEXTURE_MAX_LEVEL)
XX(MIN)
XX(MAX)
XX(DEPTH_COMPONENT24)
XX(MAX_TEXTURE_LOD_BIAS)
XX(TEXTURE_COMPARE_MODE)
XX(TEXTURE_COMPARE_FUNC)
XX(CURRENT_QUERY)
XX(QUERY_RESULT)
XX(QUERY_RESULT_AVAILABLE)
XX(STREAM_READ)
XX(STREAM_COPY)
XX(STATIC_READ)
XX(STATIC_COPY)
XX(DYNAMIC_READ)
XX(DYNAMIC_COPY)
XX(MAX_DRAW_BUFFERS)
XX(DRAW_BUFFER0)
XX(DRAW_BUFFER1)
XX(DRAW_BUFFER2)
XX(DRAW_BUFFER3)
XX(DRAW_BUFFER4)
XX(DRAW_BUFFER5)
XX(DRAW_BUFFER6)
XX(DRAW_BUFFER7)
XX(DRAW_BUFFER8)
XX(DRAW_BUFFER9)
XX(DRAW_BUFFER10)
XX(DRAW_BUFFER11)
XX(DRAW_BUFFER12)
XX(DRAW_BUFFER13)
XX(DRAW_BUFFER14)
XX(DRAW_BUFFER15)
XX(MAX_FRAGMENT_UNIFORM_COMPONENTS)
XX(MAX_VERTEX_UNIFORM_COMPONENTS)
XX(SAMPLER_3D)
XX(SAMPLER_2D_SHADOW)
XX(FRAGMENT_SHADER_DERIVATIVE_HINT)
XX(PIXEL_PACK_BUFFER)
XX(PIXEL_UNPACK_BUFFER)
XX(PIXEL_PACK_BUFFER_BINDING)
XX(PIXEL_UNPACK_BUFFER_BINDING)
XX(FLOAT_MAT2x3)
XX(FLOAT_MAT2x4)
XX(FLOAT_MAT3x2)
XX(FLOAT_MAT3x4)
XX(FLOAT_MAT4x2)
XX(FLOAT_MAT4x3)
XX(SRGB8)
XX(SRGB8_ALPHA8)
XX(COMPARE_REF_TO_TEXTURE)
XX(VERTEX_ATTRIB_ARRAY_INTEGER)
XX(MAX_ARRAY_TEXTURE_LAYERS)
XX(MIN_PROGRAM_TEXEL_OFFSET)
XX(MAX_PROGRAM_TEXEL_OFFSET)
XX(MAX_VARYING_COMPONENTS)
XX(TEXTURE_2D_ARRAY)
XX(TEXTURE_BINDING_2D_ARRAY)
XX(R11F_G11F_B10F)
XX(UNSIGNED_INT_10F_11F_11F_REV)
XX(RGB9_E5)
XX(UNSIGNED_INT_5_9_9_9_REV)
XX(TRANSFORM_FEEDBACK_BUFFER_MODE)
XX(MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS)
XX(TRANSFORM_FEEDBACK_VARYINGS)
XX(TRANSFORM_FEEDBACK_BUFFER_START)
XX(TRANSFORM_FEEDBACK_BUFFER_SIZE)
XX(TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)
XX(RASTERIZER_DISCARD)
XX(MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS)
XX(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
XX(INTERLEAVED_ATTRIBS)
XX(SEPARATE_ATTRIBS)
XX(TRANSFORM_FEEDBACK_BUFFER)
XX(TRANSFORM_FEEDBACK_BUFFER_BINDING)
XX(RGBA32UI)
XX(RGB32UI)
XX(RGBA16UI)
XX(RGB16UI)
XX(RGBA8UI)
XX(RGB8UI)
XX(RGBA32I)
XX(RGB32I)
XX(RGBA16I)
XX(RGB16I)
XX(RGBA8I)
XX(RGB8I)
XX(RED_INTEGER)
XX(RGB_INTEGER)
XX(RGBA_INTEGER)
XX(SAMPLER_2D_ARRAY)
XX(SAMPLER_2D_ARRAY_SHADOW)
XX(SAMPLER_CUBE_SHADOW)
XX(UNSIGNED_INT_VEC2)
XX(UNSIGNED_INT_VEC3)
XX(UNSIGNED_INT_VEC4)
XX(INT_SAMPLER_2D)
XX(INT_SAMPLER_3D)
XX(INT_SAMPLER_CUBE)
XX(INT_SAMPLER_2D_ARRAY)
XX(UNSIGNED_INT_SAMPLER_2D)
XX(UNSIGNED_INT_SAMPLER_3D)
XX(UNSIGNED_INT_SAMPLER_CUBE)
XX(UNSIGNED_INT_SAMPLER_2D_ARRAY)
XX(DEPTH_COMPONENT32F)
XX(DEPTH32F_STENCIL8)
XX(FLOAT_32_UNSIGNED_INT_24_8_REV)
XX(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING)
XX(FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE)
XX(FRAMEBUFFER_ATTACHMENT_RED_SIZE)
XX(FRAMEBUFFER_ATTACHMENT_GREEN_SIZE)
XX(FRAMEBUFFER_ATTACHMENT_BLUE_SIZE)
XX(FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE)
XX(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE)
XX(FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE)
XX(FRAMEBUFFER_DEFAULT)
XX(DEPTH_STENCIL_ATTACHMENT)
XX(UNSIGNED_NORMALIZED)
XX(DRAW_FRAMEBUFFER_BINDING)
XX(READ_FRAMEBUFFER_BINDING)
XX(RENDERBUFFER_SAMPLES)
XX(FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER)
XX(MAX_COLOR_ATTACHMENTS)
XX(COLOR_ATTACHMENT0)
XX(COLOR_ATTACHMENT1)
XX(COLOR_ATTACHMENT2)
XX(COLOR_ATTACHMENT3)
XX(COLOR_ATTACHMENT4)
XX(COLOR_ATTACHMENT5)
XX(COLOR_ATTACHMENT6)
XX(COLOR_ATTACHMENT7)
XX(COLOR_ATTACHMENT8)
XX(COLOR_ATTACHMENT9)
XX(COLOR_ATTACHMENT10)
XX(COLOR_ATTACHMENT11)
XX(COLOR_ATTACHMENT12)
XX(COLOR_ATTACHMENT13)
XX(COLOR_ATTACHMENT14)
XX(COLOR_ATTACHMENT15)
XX(FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
XX(MAX_SAMPLES)
XX(RG)
XX(RG_INTEGER)
XX(R8)
XX(RG8)
XX(R16F)
XX(R32F)
XX(RG16F)
XX(RG32F)
XX(R8I)
XX(R8UI)
XX(R16I)
XX(R16UI)
XX(R32I)
XX(R32UI)
XX(RG8I)
XX(RG8UI)
XX(RG16I)
XX(RG16UI)
XX(RG32I)
XX(RG32UI)
XX(VERTEX_ARRAY_BINDING)
XX(R8_SNORM)
XX(RG8_SNORM)
XX(RGB8_SNORM)
XX(RGBA8_SNORM)
XX(SIGNED_NORMALIZED)
XX(PRIMITIVE_RESTART_FIXED_INDEX)
XX(COPY_READ_BUFFER)
XX(COPY_WRITE_BUFFER)
XX(UNIFORM_BUFFER)
XX(UNIFORM_BUFFER_BINDING)
XX(UNIFORM_BUFFER_START)
XX(UNIFORM_BUFFER_SIZE)
XX(MAX_VERTEX_UNIFORM_BLOCKS)
XX(MAX_FRAGMENT_UNIFORM_BLOCKS)
XX(MAX_COMBINED_UNIFORM_BLOCKS)
XX(MAX_UNIFORM_BUFFER_BINDINGS)
XX(MAX_UNIFORM_BLOCK_SIZE)
XX(MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS)
XX(MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS)
XX(UNIFORM_BUFFER_OFFSET_ALIGNMENT)
XX(ACTIVE_UNIFORM_BLOCKS)
XX(UNIFORM_TYPE)
XX(UNIFORM_SIZE)
XX(UNIFORM_BLOCK_INDEX)
XX(UNIFORM_OFFSET)
XX(UNIFORM_ARRAY_STRIDE)
XX(UNIFORM_MATRIX_STRIDE)
XX(UNIFORM_IS_ROW_MAJOR)
XX(UNIFORM_BLOCK_BINDING)
XX(UNIFORM_BLOCK_DATA_SIZE)
XX(UNIFORM_BLOCK_ACTIVE_UNIFORMS)
XX(UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
XX(UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER)
XX(UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER)
XX(MAX_VERTEX_OUTPUT_COMPONENTS)
XX(MAX_FRAGMENT_INPUT_COMPONENTS)
XX(MAX_SERVER_WAIT_TIMEOUT)
XX(OBJECT_TYPE)
XX(SYNC_CONDITION)
XX(SYNC_STATUS)
XX(SYNC_FLAGS)
XX(SYNC_FENCE)
XX(SYNC_GPU_COMMANDS_COMPLETE)
XX(UNSIGNALED)
XX(SIGNALED)
XX(ALREADY_SIGNALED)
XX(TIMEOUT_EXPIRED)
XX(CONDITION_SATISFIED)
XX(WAIT_FAILED)
XX(VERTEX_ATTRIB_ARRAY_DIVISOR)
XX(ANY_SAMPLES_PASSED)
XX(ANY_SAMPLES_PASSED_CONSERVATIVE)
XX(SAMPLER_BINDING)
XX(RGB10_A2UI)
XX(TEXTURE_SWIZZLE_R)
XX(TEXTURE_SWIZZLE_G)
XX(TEXTURE_SWIZZLE_B)
XX(TEXTURE_SWIZZLE_A)
XX(GREEN)
XX(BLUE)
XX(INT_2_10_10_10_REV)
XX(TRANSFORM_FEEDBACK)
XX(TRANSFORM_FEEDBACK_PAUSED)
XX(TRANSFORM_FEEDBACK_ACTIVE)
XX(TRANSFORM_FEEDBACK_BINDING)
XX(COMPRESSED_R11_EAC)
XX(COMPRESSED_SIGNED_R11_EAC)
XX(COMPRESSED_RG11_EAC)
XX(COMPRESSED_SIGNED_RG11_EAC)
XX(COMPRESSED_RGB8_ETC2)
XX(COMPRESSED_SRGB8_ETC2)
XX(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2)
XX(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2)
XX(COMPRESSED_RGBA8_ETC2_EAC)
XX(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)
XX(TEXTURE_IMMUTABLE_FORMAT)
XX(MAX_ELEMENT_INDEX)
XX(NUM_SAMPLE_COUNTS)
XX(TEXTURE_IMMUTABLE_LEVELS)
#undef XX
}
@ -410,17 +412,22 @@ std::string EnumString(const GLenum val) {
void WebGLContext::ErrorInvalidEnumArg(const char* const argName,
const GLenum val) const {
nsCString enumName;
EnumName(val, &enumName);
ErrorInvalidEnum("Bad `%s`: %s", argName, enumName.BeginReading());
const auto info = nsPrintfCString("Bad `%s`", argName);
ErrorInvalidEnumInfo(info.BeginReading(), val);
}
void WebGLContext::ErrorInvalidEnumInfo(const char* const info,
const GLenum enumValue) const {
nsCString name;
EnumName(enumValue, &name);
return ErrorInvalidEnum("%s: Invalid enum value %s", info,
name.BeginReading());
const char* hint = "";
if (!enumValue) {
hint = " (Did you typo `gl.SOMETHINGG` and pass `undefined`?)";
}
ErrorInvalidEnum("%s: Invalid enum value %s%s", info, name.BeginReading(),
hint);
}
#ifdef DEBUG

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

@ -285,21 +285,6 @@ bool WebGLContext::InitAndValidateGL(FailureReason* const out_failReason) {
mCanLoseContextInForeground =
StaticPrefs::webgl_can_lose_context_in_foreground();
// These are the default values, see 6.2 State tables in the
// OpenGL ES 2.0.25 spec.
mDriverColorMask = mColorWriteMask;
mColorClearValue[0] = 0.f;
mColorClearValue[1] = 0.f;
mColorClearValue[2] = 0.f;
mColorClearValue[3] = 0.f;
mDepthWriteMask = true;
mDepthClearValue = 1.f;
mStencilClearValue = 0;
mStencilRefFront = 0;
mStencilRefBack = 0;
mLineWidth = 1.0;
/*
// Technically, we should be setting mStencil[...] values to
// `allOnes`, but either ANGLE breaks or the SGX540s on Try break.
@ -326,23 +311,7 @@ bool WebGLContext::InitAndValidateGL(FailureReason* const out_failReason) {
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_WRITEMASK,
mStencilWriteMaskBack);
mDitherEnabled = true;
mRasterizerDiscardEnabled = false;
mScissorTestEnabled = false;
mDepthTestEnabled = 0;
mDriverDepthTest = false;
mStencilTestEnabled = 0;
mDriverStencilTest = false;
mGenerateMipmapHint = LOCAL_GL_DONT_CARE;
// Bindings, etc.
mActiveTexture = 0;
mDefaultFB_DrawBuffer0 = LOCAL_GL_BACK;
mDefaultFB_ReadBuffer = LOCAL_GL_BACK;
mWebGLError = LOCAL_GL_NO_ERROR;
mBound2DTextures.Clear();
mBoundCubeMapTextures.Clear();

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

@ -124,6 +124,12 @@ class WebGLExtensionDepthTexture : public WebGLExtensionBase {
static bool IsSupported(const WebGLContext*);
};
class WebGLExtensionDrawBuffersIndexed : public WebGLExtensionBase {
public:
explicit WebGLExtensionDrawBuffersIndexed(WebGLContext* webgl)
: WebGLExtensionBase(webgl) {}
};
class WebGLExtensionElementIndexUint : public WebGLExtensionBase {
public:
explicit WebGLExtensionElementIndexUint(WebGLContext* webgl)

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

@ -505,7 +505,6 @@ WebGLFramebuffer::WebGLFramebuffer(WebGLContext* webgl,
CompletenessInfo info;
info.width = mOpaque->mSize.width;
info.height = mOpaque->mSize.height;
info.hasFloat32 = false;
info.zLayerCount = 1;
info.isMultiview = false;
@ -541,7 +540,7 @@ Maybe<WebGLFBAttachPoint*> WebGLFramebuffer::GetColorAttachPoint(
const size_t colorId = attachPoint - LOCAL_GL_COLOR_ATTACHMENT0;
MOZ_ASSERT(mContext->Limits().maxColorDrawBuffers <= kMaxColorAttachments);
MOZ_ASSERT(mContext->Limits().maxColorDrawBuffers <= webgl::kMaxDrawBuffers);
if (colorId >= mContext->MaxValidDrawBuffers()) return Nothing();
return Some(&mColorAttachments[colorId]);
@ -1013,7 +1012,7 @@ FBStatus WebGLFramebuffer::CheckFramebufferStatus() const {
ResolveAttachmentData();
// Sweet, let's cache that.
auto info = CompletenessInfo{this, UINT32_MAX, UINT32_MAX};
auto info = CompletenessInfo{this};
mCompletenessInfo.ResetInvalidators({});
mCompletenessInfo.AddInvalidator(*this);
@ -1035,12 +1034,20 @@ FBStatus WebGLFramebuffer::CheckFramebufferStatus() const {
}
const auto& imageInfo = cur->GetImageInfo();
MOZ_ASSERT(imageInfo);
info.width = std::min(info.width, imageInfo->mWidth);
info.height = std::min(info.height, imageInfo->mHeight);
info.hasFloat32 |= fnIsFloat32(*imageInfo->mFormat->format);
const auto maybeColorId = cur->ColorAttachmentId();
if (maybeColorId) {
const auto id = *maybeColorId;
info.hasAttachment[id] = true;
info.isAttachmentF32[id] = fnIsFloat32(*imageInfo->mFormat->format);
}
info.width = imageInfo->mWidth;
info.height = imageInfo->mHeight;
info.zLayerCount = cur->ZLayerCount();
info.isMultiview = cur->IsMultiview();
}
MOZ_ASSERT(info.width && info.height);
mCompletenessInfo = Some(std::move(info));
info.fb = nullptr; // Don't trigger the invalidation warning.
return LOCAL_GL_FRAMEBUFFER_COMPLETE;
@ -1108,6 +1115,7 @@ void WebGLFramebuffer::DrawBuffers(const std::vector<GLenum>& buffers) {
std::vector<const WebGLFBAttachPoint*> newColorDrawBuffers;
newColorDrawBuffers.reserve(buffers.size());
mDrawBufferEnabled.reset();
for (const auto i : IntegerRange(buffers.size())) {
// "If the GL is bound to a draw framebuffer object, the `i`th buffer listed
// in bufs must be COLOR_ATTACHMENTi or NONE. Specifying a buffer out of
@ -1124,6 +1132,7 @@ void WebGLFramebuffer::DrawBuffers(const std::vector<GLenum>& buffers) {
if (cur == LOCAL_GL_COLOR_ATTACHMENT0 + i) {
const auto& attach = mColorAttachments[i];
newColorDrawBuffers.push_back(&attach);
mDrawBufferEnabled[i] = true;
} else if (cur != LOCAL_GL_NONE) {
const bool isColorEnum = (cur >= LOCAL_GL_COLOR_ATTACHMENT0 &&
cur < mContext->LastColorAttachmentEnum());
@ -1145,16 +1154,6 @@ void WebGLFramebuffer::DrawBuffers(const std::vector<GLenum>& buffers) {
RefreshDrawBuffers(); // Calls glDrawBuffers.
}
bool WebGLFramebuffer::IsDrawBufferEnabled(const uint32_t slotId) const {
const auto attachEnum = LOCAL_GL_COLOR_ATTACHMENT0 + slotId;
for (const auto& cur : mColorDrawBuffers) {
if (cur->mAttachmentPoint == attachEnum) {
return true;
}
}
return false;
}
void WebGLFramebuffer::ReadBuffer(GLenum attachPoint) {
const auto& maybeAttach = GetColorAttachPoint(attachPoint);
if (!maybeAttach) {

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

@ -6,6 +6,7 @@
#ifndef WEBGL_FRAMEBUFFER_H_
#define WEBGL_FRAMEBUFFER_H_
#include <bitset>
#include <vector>
#include "mozilla/WeakPtr.h"
@ -78,6 +79,12 @@ class WebGLFBAttachPoint final {
WebGLTexture* Texture() const { return mTexturePtr; }
WebGLRenderbuffer* Renderbuffer() const { return mRenderbufferPtr; }
Maybe<size_t> ColorAttachmentId() const {
const size_t id = mAttachmentPoint - LOCAL_GL_COLOR_ATTACHMENT0;
if (id >= webgl::kMaxDrawBuffers) return {};
return Some(id);
}
auto Layer() const { return mTexImageLayer; }
auto ZLayerCount() const { return mTexImageZLayerCount; }
auto MipLevel() const { return mTexImageLevel; }
@ -150,14 +157,8 @@ class WebGLFramebuffer final : public WebGLContextBoundObject,
WebGLFBAttachPoint mStencilAttachment;
WebGLFBAttachPoint mDepthStencilAttachment;
// In theory, this number can be unbounded based on the driver. However, no
// driver appears to expose more than 8. We might as well stop there too, for
// now.
// (http://opengl.gpuinfo.org/gl_stats_caps_single.php?listreportsbycap=GL_MAX_COLOR_ATTACHMENTS)
static const size_t kMaxColorAttachments =
8; // jgilbert's MacBook Pro exposes 8.
WebGLFBAttachPoint mColorAttachments[kMaxColorAttachments];
std::array<WebGLFBAttachPoint, webgl::kMaxDrawBuffers> mColorAttachments = {};
std::bitset<webgl::kMaxDrawBuffers> mDrawBufferEnabled = {1};
////
std::vector<WebGLFBAttachPoint*> mAttachments; // Non-null.
@ -172,7 +173,8 @@ class WebGLFramebuffer final : public WebGLContextBoundObject,
uint32_t width = 0;
uint32_t height = 0;
bool hasFloat32 = false;
std::bitset<webgl::kMaxDrawBuffers> hasAttachment = 0;
std::bitset<webgl::kMaxDrawBuffers> isAttachmentF32 = 0;
uint8_t zLayerCount = 1;
bool isMultiview = false;
@ -236,7 +238,7 @@ class WebGLFramebuffer final : public WebGLContextBoundObject,
#undef GETTER
const auto& ColorAttachment0() const { return mColorAttachments[0]; }
bool IsDrawBufferEnabled(uint32_t slotId) const;
const auto& DrawBufferEnabled() const { return mDrawBufferEnabled; }
////////////////
// Invalidation

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

@ -60,8 +60,7 @@ DEFINE_ASYNC(HostWebGLContext::DeleteTexture)
DEFINE_ASYNC(HostWebGLContext::DeleteTransformFeedback)
DEFINE_ASYNC(HostWebGLContext::DeleteVertexArray)
DEFINE_ASYNC(HostWebGLContext::Disable)
DEFINE_ASYNC(HostWebGLContext::Enable)
DEFINE_ASYNC(HostWebGLContext::SetEnabled)
DEFINE_ASYNC(HostWebGLContext::GenerateError)
DEFINE_ASYNC(HostWebGLContext::Resize)
DEFINE_ASYNC(HostWebGLContext::RequestExtension)

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

@ -348,6 +348,7 @@ RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(WebGLProgram* prog,
const auto version = compileResults->mShaderVersion;
const auto fnAddInfo = [&](const webgl::FragOutputInfo& x) {
info->hasOutput[x.loc] = true;
info->fragOutputs.insert({x.loc, x});
};

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

@ -6,6 +6,7 @@
#ifndef WEBGL_PROGRAM_H_
#define WEBGL_PROGRAM_H_
#include <bitset>
#include <map>
#include <set>
#include <vector>
@ -100,6 +101,7 @@ struct LinkedProgramInfo final : public RefCounted<LinkedProgramInfo>,
WebGLProgram* const prog;
const GLenum transformFeedbackBufferMode;
std::bitset<kMaxDrawBuffers> hasOutput = 0;
std::unordered_map<uint8_t, const FragOutputInfo> fragOutputs;
uint8_t zLayerCount = 1;

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

@ -228,6 +228,7 @@ enum class WebGLExtensionID : uint8_t {
EXT_texture_filter_anisotropic,
EXT_texture_norm16,
MOZ_debug,
OES_draw_buffers_indexed,
OES_element_index_uint,
OES_fbo_render_mipmap,
OES_standard_derivatives,
@ -1156,6 +1157,15 @@ inline void Memcpy(const RangedPtr<uint8_t>& destBytes,
// -
namespace webgl {
// In theory, this number can be unbounded based on the driver. However, no
// driver appears to expose more than 8. We might as well stop there too, for
// now.
// (http://opengl.gpuinfo.org/gl_stats_caps_single.php?listreportsbycap=GL_MAX_COLOR_ATTACHMENTS)
inline constexpr size_t kMaxDrawBuffers = 8;
} // namespace webgl
} // namespace mozilla
#endif

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

@ -0,0 +1,23 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExtFor('webgl', 'OES_draw_buffers_indexed', false);
EnsureExtFor('webgl2', 'OES_draw_buffers_indexed', false);
Lastly_WithDraftExtsEnabled(() => {
EnsureExtFor('webgl', 'OES_draw_buffers_indexed', false);
EnsureExtFor('webgl2', 'OES_draw_buffers_indexed', true);
});
</script>
</body>
</html>

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

@ -56,8 +56,9 @@ var defaultExts = [
];
var draftExts = [
['EXT_texture_norm16' , [FORBID , MACHINE_SPECIFIC]],
['WEBGL_explicit_present', [ENSURE , ENSURE ]],
['EXT_texture_norm16' , [FORBID , MACHINE_SPECIFIC]],
['OES_draw_buffers_indexed', [FORBID , MACHINE_SPECIFIC]],
['WEBGL_explicit_present' , [ENSURE , ENSURE ]],
];
////////////////////

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

@ -29,6 +29,7 @@ fail-if = (os == 'android') || (os == 'linux' && os_version == '16.04') || (os =
fail-if = (os == 'android')
[ensure-exts/test_EXT_texture_filter_anisotropic.html]
fail-if = (os == 'linux')
[ensure-exts/test_OES_draw_buffers_indexed.html]
[ensure-exts/test_OES_fbo_render_mipmap.html]
[ensure-exts/test_OES_standard_derivatives.html]
[ensure-exts/test_OVR_multiview2.html]

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

@ -1182,6 +1182,29 @@ interface WEBGL_explicit_present {
void present();
};
// https://www.khronos.org/registry/webgl/extensions/OES_draw_buffers_indexed/
[Exposed=(Window,Worker), LegacyNoInterfaceObject]
interface OES_draw_buffers_indexed {
void enableiOES(GLenum target, GLuint index);
void disableiOES(GLenum target, GLuint index);
void blendEquationiOES(GLuint buf, GLenum mode);
void blendEquationSeparateiOES(GLuint buf,
GLenum modeRGB, GLenum modeAlpha);
void blendFunciOES(GLuint buf,
GLenum src, GLenum dst);
void blendFuncSeparateiOES(GLuint buf,
GLenum srcRGB, GLenum dstRGB,
GLenum srcAlpha, GLenum dstAlpha);
void colorMaskiOES(GLuint buf,
GLboolean r, GLboolean g, GLboolean b, GLboolean a);
};
// https://immersive-web.github.io/webxr/#dom-webglcontextattributes-xrcompatible
partial dictionary WebGLContextAttributes {
[Pref="dom.vr.webxr.enabled"]

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

@ -201,6 +201,7 @@ static const char* const sExtensionNames[] = {
"GL_OES_depth24",
"GL_OES_depth32",
"GL_OES_depth_texture",
"GL_OES_draw_buffers_indexed",
"GL_OES_element_index_uint",
"GL_OES_fbo_render_mipmap",
"GL_OES_framebuffer_object",
@ -1261,6 +1262,26 @@ void GLContext::LoadMoreSymbols(const SymbolLoader& loader) {
fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::draw_buffers);
}
if (IsSupported(GLFeature::draw_buffers_indexed)) {
const SymLoadStruct coreSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fBlendEquationSeparatei, {{ "glBlendEquationSeparatei" }} },
{ (PRFuncPtr*) &mSymbols.fBlendFuncSeparatei, {{ "glBlendFuncSeparatei" }} },
{ (PRFuncPtr*) &mSymbols.fColorMaski, {{ "glColorMaski" }} },
{ (PRFuncPtr*) &mSymbols.fDisablei, {{ "glDisablei" }} },
{ (PRFuncPtr*) &mSymbols.fEnablei, {{ "glEnablei" }} },
END_SYMBOLS
};
const SymLoadStruct extSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fBlendEquationSeparatei, {{ "glBlendEquationSeparateiOES" }} },
{ (PRFuncPtr*) &mSymbols.fBlendFuncSeparatei, {{ "glBlendFuncSeparateiOES" }} },
{ (PRFuncPtr*) &mSymbols.fColorMaski, {{ "glColorMaskiOES" }} },
{ (PRFuncPtr*) &mSymbols.fDisablei, {{ "glDisableiOES" }} },
{ (PRFuncPtr*) &mSymbols.fEnablei, {{ "glEnableiOES" }} },
END_SYMBOLS
};
fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::draw_buffers);
}
if (IsSupported(GLFeature::get_integer_indexed)) {
const SymLoadStruct coreSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fGetIntegeri_v, {{ "glGetIntegeri_v" }} },

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

@ -79,6 +79,7 @@ enum class GLFeature {
copy_buffer,
depth_texture,
draw_buffers,
draw_buffers_indexed,
draw_instanced,
element_index_uint,
ES2_compatibility,
@ -473,6 +474,7 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
OES_depth24,
OES_depth32,
OES_depth_texture,
OES_draw_buffers_indexed,
OES_element_index_uint,
OES_fbo_render_mipmap,
OES_framebuffer_object,
@ -3311,6 +3313,43 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
AFTER_GL_CALL;
}
// -
// draw_buffers_indexed
void fBlendEquationSeparatei(GLuint i, GLenum modeRGB,
GLenum modeAlpha) const {
BEFORE_GL_CALL;
mSymbols.fBlendEquationSeparatei(i, modeRGB, modeAlpha);
AFTER_GL_CALL;
}
void fBlendFuncSeparatei(GLuint i, GLenum sfactorRGB, GLenum dfactorRGB,
GLenum sfactorAlpha, GLenum dfactorAlpha) const {
BEFORE_GL_CALL;
mSymbols.fBlendFuncSeparatei(i, sfactorRGB, dfactorRGB, sfactorAlpha,
dfactorAlpha);
AFTER_GL_CALL;
}
void fColorMaski(GLuint i, realGLboolean red, realGLboolean green,
realGLboolean blue, realGLboolean alpha) const {
BEFORE_GL_CALL;
mSymbols.fColorMaski(i, red, green, blue, alpha);
AFTER_GL_CALL;
}
void fDisablei(GLenum capability, GLuint i) const {
BEFORE_GL_CALL;
mSymbols.fDisablei(capability, i);
AFTER_GL_CALL;
}
void fEnablei(GLenum capability, GLuint i) const {
BEFORE_GL_CALL;
mSymbols.fEnablei(capability, i);
AFTER_GL_CALL;
}
#undef BEFORE_GL_CALL
#undef AFTER_GL_CALL
#undef ASSERT_SYMBOL_PRESENT

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

@ -104,6 +104,11 @@ static const FeatureInfo sFeatureInfoArr[] = {
GLContext::Extension_None,
{GLContext::ARB_draw_buffers, GLContext::EXT_draw_buffers,
GLContext::Extensions_End}},
{"draw_buffers_indexed",
GLVersion::GL3,
GLESVersion::ES3_2,
GLContext::Extension_None,
{GLContext::OES_draw_buffers_indexed, GLContext::Extensions_End}},
{"draw_instanced",
GLVersion::GL3_1,
GLESVersion::ES3,

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

@ -448,6 +448,14 @@ struct GLContextSymbols final {
GLuint texture, GLint level,
GLint baseViewIndex,
GLsizei numViews);
// draw_buffers_indexed
void(GLAPIENTRY* fBlendEquationSeparatei)(GLuint, GLenum, GLenum);
void(GLAPIENTRY* fBlendFuncSeparatei)(GLuint, GLenum, GLenum, GLenum, GLenum);
void(GLAPIENTRY* fColorMaski)(GLuint, realGLboolean, realGLboolean,
realGLboolean, realGLboolean);
void(GLAPIENTRY* fDisablei)(GLenum, GLuint);
void(GLAPIENTRY* fEnablei)(GLenum, GLuint);
};
} // namespace gl