зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
ddbd16c8f6
Коммит
28e862be2d
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче