Skip to content

Commit

Permalink
Bug 1825673 - Implement WEBGL_provoking_vertex. r=gfx-reviewers,webid…
Browse files Browse the repository at this point in the history
…l,lsalzman,saschanaz

Differential Revision: https://phabricator.services.mozilla.com/D174197
  • Loading branch information
kdashg committed Apr 1, 2023
1 parent f796327 commit 8aec4e1
Show file tree
Hide file tree
Showing 21 changed files with 174 additions and 0 deletions.
5 changes: 5 additions & 0 deletions dom/bindings/Bindings.conf
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,11 @@ DOMInterfaces = {
'headerFile': 'ClientWebGLExtensions.h'
},

'WEBGL_provoking_vertex': {
'nativeType': 'mozilla::ClientWebGLExtensionProvokingVertex',
'headerFile': 'ClientWebGLExtensions.h'
},

'OES_draw_buffers_indexed': {
'nativeType': 'mozilla::ClientWebGLExtensionDrawBuffersIndexed',
'headerFile': 'ClientWebGLExtensions.h'
Expand Down
17 changes: 17 additions & 0 deletions dom/canvas/ClientWebGLContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2000,6 +2000,11 @@ void ClientWebGLContext::GetParameter(JSContext* cx, GLenum pname,
retval.set(JS::NumberValue(state.mPixelUnpackState.colorspaceConversion));
return;

case dom::WEBGL_provoking_vertex_Binding::PROVOKING_VERTEX_WEBGL:
if (!IsExtensionEnabled(WebGLExtensionID::WEBGL_provoking_vertex)) break;
retval.set(JS::NumberValue(UnderlyingValue(state.mProvokingVertex)));
return;

// -
// Array returns

Expand Down Expand Up @@ -5664,6 +5669,18 @@ void ClientWebGLContext::GetSupportedProfilesASTC(
}
}

void ClientWebGLContext::ProvokingVertex(const GLenum rawMode) const {
const FuncScope funcScope(*this, "provokingVertex");
if (IsContextLost()) return;

const auto mode = webgl::AsEnumCase<webgl::ProvokingVertex>(rawMode);
if (!mode) return;

Run<RPROC(ProvokingVertex)>(*mode);

funcScope.mKeepNotLostOrNull->state.mProvokingVertex = *mode;
}

// -

bool ClientWebGLContext::ShouldResistFingerprinting() const {
Expand Down
4 changes: 4 additions & 0 deletions dom/canvas/ClientWebGLContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ class ContextGenerationInfo final {

Maybe<uvec2> mDrawingBufferSize;

webgl::ProvokingVertex mProvokingVertex = webgl::ProvokingVertex::LastVertex;

ObjectId NextId() { return mLastId += 1; }
};

Expand Down Expand Up @@ -2187,6 +2189,8 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
GetParameter(cx, pname, retval, rv, true);
}

void ProvokingVertex(GLenum rawMode) const;

// -------------------------------------------------------------------------
// Client-side methods. Calls in the Host are forwarded to the client.
// -------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions dom/canvas/ClientWebGLExtensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_draw_buffers, WebGLExtensionDrawBuffers)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_explicit_present,
WebGLExtensionExplicitPresent)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_lose_context, WebGLExtensionLoseContext)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_provoking_vertex,
WebGLExtensionProvokingVertex)

// --------------

Expand Down
15 changes: 15 additions & 0 deletions dom/canvas/ClientWebGLExtensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,21 @@ class ClientWebGLExtensionLoseContext : public ClientWebGLExtensionBase {
}
};

class ClientWebGLExtensionProvokingVertex : public ClientWebGLExtensionBase {
public:
virtual JSObject* WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) override;
explicit ClientWebGLExtensionProvokingVertex(ClientWebGLContext&);

void ProvokingVertexWEBGL(const GLenum mode) const {
if (MOZ_UNLIKELY(!mContext)) {
AutoJsWarning("provokingVertexWEBGL: Extension is `invalidated`.");
return;
}
mContext->ProvokingVertex(mode);
}
};

DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionSRGB)

DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionStandardDerivatives)
Expand Down
5 changes: 5 additions & 0 deletions dom/canvas/HostWebGLContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,11 @@ class HostWebGLContext final : public SupportsWeakPtr {
return mContext->GetQueryParameter(*obj, pname);
}

// WEBGL_provoking_vertex
void ProvokingVertex(const webgl::ProvokingVertex mode) const {
mContext->ProvokingVertex(mode);
}

// -------------------------------------------------------------------------
// Client-side methods. Calls in the Host are forwarded to the client.
// -------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions dom/canvas/WebGLContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
void LineWidth(GLfloat width);
void LinkProgram(WebGLProgram& prog);
void PolygonOffset(GLfloat factor, GLfloat units);
void ProvokingVertex(webgl::ProvokingVertex) const;

////

Expand Down
19 changes: 19 additions & 0 deletions dom/canvas/WebGLContextExtensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const char* GetExtensionName(const WebGLExtensionID ext) {
WEBGL_EXTENSION_IDENTIFIER(WEBGL_draw_buffers)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_explicit_present)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_lose_context)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_provoking_vertex)

#undef WEBGL_EXTENSION_IDENTIFIER
}
Expand Down Expand Up @@ -217,6 +218,8 @@ RefPtr<ClientWebGLExtensionBase> ClientWebGLContext::GetExtension(
return new ClientWebGLExtensionDrawBuffers(*this);
case WebGLExtensionID::WEBGL_explicit_present:
return new ClientWebGLExtensionExplicitPresent(*this);
case WebGLExtensionID::WEBGL_provoking_vertex:
return new ClientWebGLExtensionProvokingVertex(*this);

case WebGLExtensionID::WEBGL_lose_context:
case WebGLExtensionID::Max:
Expand Down Expand Up @@ -358,6 +361,19 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const {
case WebGLExtensionID::WEBGL_explicit_present:
return WebGLExtensionExplicitPresent::IsSupported(this);

case WebGLExtensionID::WEBGL_provoking_vertex:
if (!gl->IsSupported(gl::GLFeature::provoking_vertex)) return false;

// > Implementations SHOULD only expose this extension when
// > FIRST_VERTEX_CONVENTION is more efficient than the default behavior
// > of LAST_VERTEX_CONVENTION.
if (gl->IsANGLE()) return true; // Better on D3D.
if (kIsMacOS) {
// Better on Metal, so probably Mac in general.
return true;
}
return false; // Probably not better for Win+GL, Linux, or Android.

case WebGLExtensionID::Max:
break;
}
Expand Down Expand Up @@ -508,6 +524,9 @@ void WebGLContext::RequestExtension(const WebGLExtensionID ext,
case WebGLExtensionID::WEBGL_lose_context:
slot.reset(new WebGLExtensionLoseContext(this));
break;
case WebGLExtensionID::WEBGL_provoking_vertex:
slot.reset(new WebGLExtensionProvokingVertex(this));
break;

case WebGLExtensionID::Max:
MOZ_CRASH();
Expand Down
9 changes: 9 additions & 0 deletions dom/canvas/WebGLContextGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1561,6 +1561,15 @@ void WebGLContext::PolygonOffset(GLfloat factor, GLfloat units) {
gl->fPolygonOffset(factor, units);
}

void WebGLContext::ProvokingVertex(const webgl::ProvokingVertex mode) const {
const FuncScope funcScope(*this, "provokingVertex");
if (IsContextLost()) return;
MOZ_RELEASE_ASSERT(
IsExtensionEnabled(WebGLExtensionID::WEBGL_provoking_vertex));

gl->fProvokingVertex(UnderlyingValue(mode));
}

void WebGLContext::SampleCoverage(GLclampf value, WebGLboolean invert) {
const FuncScope funcScope(*this, "sampleCoverage");
if (IsContextLost()) return;
Expand Down
6 changes: 6 additions & 0 deletions dom/canvas/WebGLExtensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ class WebGLExtensionMultiview : public WebGLExtensionBase {
static bool IsSupported(const WebGLContext*);
};

class WebGLExtensionProvokingVertex : public WebGLExtensionBase {
public:
explicit WebGLExtensionProvokingVertex(WebGLContext* webgl)
: WebGLExtensionBase(webgl) {}
};

class WebGLExtensionSRGB : public WebGLExtensionBase {
public:
explicit WebGLExtensionSRGB(WebGLContext*);
Expand Down
1 change: 1 addition & 0 deletions dom/canvas/WebGLMethodDispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ DEFINE_ASYNC(HostWebGLContext::Hint)
DEFINE_ASYNC(HostWebGLContext::LineWidth)
DEFINE_ASYNC(HostWebGLContext::LinkProgram)
DEFINE_ASYNC(HostWebGLContext::PolygonOffset)
DEFINE_ASYNC(HostWebGLContext::ProvokingVertex)
DEFINE_ASYNC(HostWebGLContext::Present)
DEFINE_ASYNC(HostWebGLContext::SampleCoverage)
DEFINE_ASYNC(HostWebGLContext::Scissor)
Expand Down
1 change: 1 addition & 0 deletions dom/canvas/WebGLQueueParamTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ static_assert(!IsEnumCase(dom::WebGLPowerPreference(5)));
USE_IS_ENUM_CASE(dom::WebGLPowerPreference)
USE_IS_ENUM_CASE(dom::PredefinedColorSpace)
USE_IS_ENUM_CASE(webgl::AttribBaseType)
USE_IS_ENUM_CASE(webgl::ProvokingVertex)

#undef USE_IS_ENUM_CASE

Expand Down
22 changes: 22 additions & 0 deletions dom/canvas/WebGLTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ enum class WebGLExtensionID : uint8_t {
WEBGL_draw_buffers,
WEBGL_explicit_present,
WEBGL_lose_context,
WEBGL_provoking_vertex,
Max
};

Expand Down Expand Up @@ -1226,6 +1227,27 @@ union UniformDataVal {
uint32_t u32;
};

enum class ProvokingVertex : GLenum {
FirstVertex = LOCAL_GL_FIRST_VERTEX_CONVENTION,
LastVertex = LOCAL_GL_LAST_VERTEX_CONVENTION,
};
inline constexpr bool IsEnumCase(const ProvokingVertex raw) {
switch (raw) {
case ProvokingVertex::FirstVertex:
case ProvokingVertex::LastVertex:
return true;
}
return false;
}

template <class E>
inline constexpr std::optional<E> AsEnumCase(
const std::underlying_type_t<E> raw) {
const auto ret = static_cast<E>(raw);
if (!IsEnumCase(ret)) return {};
return ret;
}

} // namespace webgl

} // namespace mozilla
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!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', 'WEBGL_provoking_vertex');
EnsureExtFor('webgl2', 'WEBGL_provoking_vertex');

</script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
['WEBGL_compressed_texture_etc1' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
['WEBGL_compressed_texture_pvrtc' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
['WEBGL_compressed_texture_s3tc_srgb', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
['WEBGL_provoking_vertex' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
];

var draftExts = [
Expand Down
2 changes: 2 additions & 0 deletions dom/canvas/test/webgl-mochitest/mochitest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ fail-if = (os == 'android')
[ensure-exts/test_WEBGL_depth_texture.html]
[ensure-exts/test_WEBGL_draw_buffers.html]
fail-if = (os == 'android')
[ensure-exts/test_WEBGL_provoking_vertex.html]
fail-if = (os == 'android') || (os == 'linux')

[ensure-exts/test_common.html]
[ensure-exts/test_implicit.html]
Expand Down
9 changes: 9 additions & 0 deletions dom/webidl/WebGLRenderingContext.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,15 @@ interface OES_draw_buffers_indexed {
GLboolean r, GLboolean g, GLboolean b, GLboolean a);
};

[Exposed=(Window,Worker), LegacyNoInterfaceObject]
interface WEBGL_provoking_vertex {
const GLenum FIRST_VERTEX_CONVENTION_WEBGL = 0x8E4D;
const GLenum LAST_VERTEX_CONVENTION_WEBGL = 0x8E4E; // default
const GLenum PROVOKING_VERTEX_WEBGL = 0x8E4F;

undefined provokingVertexWEBGL(GLenum provokeMode);
};

// https://immersive-web.github.io/webxr/#dom-webglcontextattributes-xrcompatible
partial dictionary WebGLContextAttributes {
[Pref="dom.vr.webxr.enabled"]
Expand Down
14 changes: 14 additions & 0 deletions gfx/gl/GLContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ static const char* const sExtensionNames[] = {
"GL_ANGLE_framebuffer_multisample",
"GL_ANGLE_instanced_arrays",
"GL_ANGLE_multiview",
"GL_ANGLE_provoking_vertex",
"GL_ANGLE_texture_compression_dxt3",
"GL_ANGLE_texture_compression_dxt5",
"GL_ANGLE_timer_query",
Expand Down Expand Up @@ -117,6 +118,7 @@ static const char* const sExtensionNames[] = {
"GL_ARB_map_buffer_range",
"GL_ARB_occlusion_query2",
"GL_ARB_pixel_buffer_object",
"GL_ARB_provoking_vertex",
"GL_ARB_robust_buffer_access_behavior",
"GL_ARB_robustness",
"GL_ARB_sampler_objects",
Expand Down Expand Up @@ -158,6 +160,7 @@ static const char* const sExtensionNames[] = {
"GL_EXT_multisampled_render_to_texture",
"GL_EXT_occlusion_query_boolean",
"GL_EXT_packed_depth_stencil",
"GL_EXT_provoking_vertex",
"GL_EXT_read_format_bgra",
"GL_EXT_robustness",
"GL_EXT_sRGB",
Expand Down Expand Up @@ -1499,6 +1502,17 @@ void GLContext::LoadMoreSymbols(const SymbolLoader& loader) {
fnLoadForExt(symbols, APPLE_framebuffer_multisample);
}

if (IsSupported(GLFeature::provoking_vertex)) {
const SymLoadStruct symbols[] = {{(PRFuncPtr*)&mSymbols.fProvokingVertex,
{{
"glProvokingVertex",
"glProvokingVertexANGLE",
"glProvokingVertexEXT",
}}},
END_SYMBOLS};
fnLoadForFeature(symbols, GLFeature::provoking_vertex);
}

// Load developer symbols, don't fail if we can't find them.
const SymLoadStruct devSymbols[] = {CORE_SYMBOL(GetTexImage),
CORE_SYMBOL(GetTexLevelParameteriv),
Expand Down
14 changes: 14 additions & 0 deletions gfx/gl/GLContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ enum class GLFeature {
packed_depth_stencil,
prim_restart,
prim_restart_fixed,
provoking_vertex,
query_counter,
query_objects,
query_time_elapsed,
Expand Down Expand Up @@ -350,6 +351,7 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
ANGLE_framebuffer_multisample,
ANGLE_instanced_arrays,
ANGLE_multiview,
ANGLE_provoking_vertex,
ANGLE_texture_compression_dxt3,
ANGLE_texture_compression_dxt5,
ANGLE_timer_query,
Expand Down Expand Up @@ -377,6 +379,7 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
ARB_map_buffer_range,
ARB_occlusion_query2,
ARB_pixel_buffer_object,
ARB_provoking_vertex,
ARB_robust_buffer_access_behavior,
ARB_robustness,
ARB_sampler_objects,
Expand Down Expand Up @@ -418,6 +421,7 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
EXT_multisampled_render_to_texture,
EXT_occlusion_query_boolean,
EXT_packed_depth_stencil,
EXT_provoking_vertex,
EXT_read_format_bgra,
EXT_robustness,
EXT_sRGB,
Expand Down Expand Up @@ -3387,6 +3391,16 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
AFTER_GL_CALL;
}

// -

void fProvokingVertex(GLenum mode) const {
BEFORE_GL_CALL;
mSymbols.fProvokingVertex(mode);
AFTER_GL_CALL;
}

// -

#undef BEFORE_GL_CALL
#undef AFTER_GL_CALL
#undef ASSERT_SYMBOL_PRESENT
Expand Down
6 changes: 6 additions & 0 deletions gfx/gl/GLContextFeatures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ static const FeatureInfo sFeatureInfoArr[] = {
GLESVersion::ES3,
GLContext::ARB_ES3_compatibility,
{GLContext::Extensions_End}},
{"provoking_vertex",
GLVersion::GL3_2,
GLESVersion::NONE,
GLContext::ARB_provoking_vertex,
{GLContext::ANGLE_provoking_vertex, GLContext::EXT_provoking_vertex,
GLContext::Extensions_End}},
{"query_counter",
GLVersion::GL3_3,
GLESVersion::NONE,
Expand Down
Loading

0 comments on commit 8aec4e1

Please sign in to comment.