mirror of
https://github.com/servo/servo.git
synced 2025-07-21 14:23:41 +01:00
Auto merge of #21246 - servo:webgl, r=emilio
Cache which capabilities are enabled in the context (fixes #20534) <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/21246) <!-- Reviewable:end -->
This commit is contained in:
commit
4c5a7eaa14
3 changed files with 75 additions and 35 deletions
|
@ -709,8 +709,6 @@ impl WebGLImpl {
|
||||||
ctx.gl().enable_vertex_attrib_array(attrib_id),
|
ctx.gl().enable_vertex_attrib_array(attrib_id),
|
||||||
WebGLCommand::Hint(name, val) =>
|
WebGLCommand::Hint(name, val) =>
|
||||||
ctx.gl().hint(name, val),
|
ctx.gl().hint(name, val),
|
||||||
WebGLCommand::IsEnabled(cap, ref chan) =>
|
|
||||||
chan.send(ctx.gl().is_enabled(cap) != 0).unwrap(),
|
|
||||||
WebGLCommand::LineWidth(width) =>
|
WebGLCommand::LineWidth(width) =>
|
||||||
ctx.gl().line_width(width),
|
ctx.gl().line_width(width),
|
||||||
WebGLCommand::PixelStorei(name, val) =>
|
WebGLCommand::PixelStorei(name, val) =>
|
||||||
|
|
|
@ -225,7 +225,6 @@ pub enum WebGLCommand {
|
||||||
StencilOp(u32, u32, u32),
|
StencilOp(u32, u32, u32),
|
||||||
StencilOpSeparate(u32, u32, u32, u32),
|
StencilOpSeparate(u32, u32, u32, u32),
|
||||||
Hint(u32, u32),
|
Hint(u32, u32),
|
||||||
IsEnabled(u32, WebGLSender<bool>),
|
|
||||||
LineWidth(f32),
|
LineWidth(f32),
|
||||||
PixelStorei(u32, i32),
|
PixelStorei(u32, i32),
|
||||||
LinkProgram(WebGLProgramId, WebGLSender<ProgramLinkInfo>),
|
LinkProgram(WebGLProgramId, WebGLSender<ProgramLinkInfo>),
|
||||||
|
@ -511,15 +510,8 @@ macro_rules! parameters {
|
||||||
parameters! {
|
parameters! {
|
||||||
Parameter {
|
Parameter {
|
||||||
Bool(ParameterBool {
|
Bool(ParameterBool {
|
||||||
Blend = gl::BLEND,
|
|
||||||
CullFace = gl::CULL_FACE,
|
|
||||||
DepthTest = gl::DEPTH_TEST,
|
|
||||||
DepthWritemask = gl::DEPTH_WRITEMASK,
|
DepthWritemask = gl::DEPTH_WRITEMASK,
|
||||||
Dither = gl::DITHER,
|
|
||||||
PolygonOffsetFill = gl::POLYGON_OFFSET_FILL,
|
|
||||||
SampleCoverageInvert = gl::SAMPLE_COVERAGE_INVERT,
|
SampleCoverageInvert = gl::SAMPLE_COVERAGE_INVERT,
|
||||||
ScissorTest = gl::SCISSOR_TEST,
|
|
||||||
StencilTest = gl::STENCIL_TEST,
|
|
||||||
}),
|
}),
|
||||||
Bool4(ParameterBool4 {
|
Bool4(ParameterBool4 {
|
||||||
ColorWritemask = gl::COLOR_WRITEMASK,
|
ColorWritemask = gl::COLOR_WRITEMASK,
|
||||||
|
|
|
@ -207,6 +207,7 @@ pub struct WebGLRenderingContext {
|
||||||
#[ignore_malloc_size_of = "Because it's small"]
|
#[ignore_malloc_size_of = "Because it's small"]
|
||||||
current_clear_color: Cell<(f32, f32, f32, f32)>,
|
current_clear_color: Cell<(f32, f32, f32, f32)>,
|
||||||
extension_manager: WebGLExtensions,
|
extension_manager: WebGLExtensions,
|
||||||
|
capabilities: Capabilities,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebGLRenderingContext {
|
impl WebGLRenderingContext {
|
||||||
|
@ -256,6 +257,7 @@ impl WebGLRenderingContext {
|
||||||
current_scissor: Cell::new((0, 0, size.width, size.height)),
|
current_scissor: Cell::new((0, 0, size.width, size.height)),
|
||||||
current_clear_color: Cell::new((0.0, 0.0, 0.0, 0.0)),
|
current_clear_color: Cell::new((0.0, 0.0, 0.0, 0.0)),
|
||||||
extension_manager: WebGLExtensions::new(webgl_version),
|
extension_manager: WebGLExtensions::new(webgl_version),
|
||||||
|
capabilities: Default::default(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1114,19 +1116,6 @@ impl WebGLRenderingContext {
|
||||||
self.send_command(msg);
|
self.send_command(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14
|
|
||||||
fn validate_feature_enum(&self, cap: u32) -> bool {
|
|
||||||
match cap {
|
|
||||||
constants::BLEND | constants::CULL_FACE | constants::DEPTH_TEST | constants::DITHER |
|
|
||||||
constants::POLYGON_OFFSET_FILL | constants::SAMPLE_ALPHA_TO_COVERAGE | constants::SAMPLE_COVERAGE |
|
|
||||||
constants::SCISSOR_TEST | constants::STENCIL_TEST => true,
|
|
||||||
_ => {
|
|
||||||
self.webgl_error(InvalidEnum);
|
|
||||||
false
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_gl_extensions(&self) -> String {
|
fn get_gl_extensions(&self) -> String {
|
||||||
let (sender, receiver) = webgl_channel().unwrap();
|
let (sender, receiver) = webgl_channel().unwrap();
|
||||||
self.send_command(WebGLCommand::GetExtensions(sender));
|
self.send_command(WebGLCommand::GetExtensions(sender));
|
||||||
|
@ -1533,6 +1522,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
return UInt32Value(limit);
|
return UInt32Value(limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Ok(value) = self.capabilities.is_enabled(parameter) {
|
||||||
|
return BooleanValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
if !self.extension_manager.is_get_parameter_name_enabled(parameter) {
|
if !self.extension_manager.is_get_parameter_name_enabled(parameter) {
|
||||||
self.webgl_error(WebGLError::InvalidEnum);
|
self.webgl_error(WebGLError::InvalidEnum);
|
||||||
return NullValue();
|
return NullValue();
|
||||||
|
@ -2190,17 +2183,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
|
||||||
// FIXME: https://github.com/servo/servo/issues/20534
|
|
||||||
fn Enable(&self, cap: u32) {
|
fn Enable(&self, cap: u32) {
|
||||||
if self.validate_feature_enum(cap) {
|
if handle_potential_webgl_error!(self, self.capabilities.set(cap, true), return) {
|
||||||
self.send_command(WebGLCommand::Enable(cap));
|
self.send_command(WebGLCommand::Enable(cap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
|
||||||
// FIXME: https://github.com/servo/servo/issues/20534
|
|
||||||
fn Disable(&self, cap: u32) {
|
fn Disable(&self, cap: u32) {
|
||||||
if self.validate_feature_enum(cap) {
|
if handle_potential_webgl_error!(self, self.capabilities.set(cap, false), return) {
|
||||||
self.send_command(WebGLCommand::Disable(cap));
|
self.send_command(WebGLCommand::Disable(cap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2891,15 +2882,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
|
||||||
// FIXME: https://github.com/servo/servo/issues/20534
|
|
||||||
fn IsEnabled(&self, cap: u32) -> bool {
|
fn IsEnabled(&self, cap: u32) -> bool {
|
||||||
if self.validate_feature_enum(cap) {
|
handle_potential_webgl_error!(self, self.capabilities.is_enabled(cap), false)
|
||||||
let (sender, receiver) = webgl_channel().unwrap();
|
|
||||||
self.send_command(WebGLCommand::IsEnabled(cap, sender));
|
|
||||||
return receiver.recv().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
|
||||||
|
@ -4438,3 +4422,69 @@ impl VertexAttribData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, JSTraceable, MallocSizeOf)]
|
||||||
|
struct Capabilities {
|
||||||
|
value: Cell<CapFlags>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Capabilities {
|
||||||
|
fn set(&self, cap: u32, set: bool) -> WebGLResult<bool> {
|
||||||
|
let cap = CapFlags::from_enum(cap)?;
|
||||||
|
let mut value = self.value.get();
|
||||||
|
if value.contains(cap) == set {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
value.set(cap, set);
|
||||||
|
self.value.set(value);
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_enabled(&self, cap: u32) -> WebGLResult<bool> {
|
||||||
|
Ok(self.value.get().contains(CapFlags::from_enum(cap)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CapFlags {
|
||||||
|
fn default() -> Self {
|
||||||
|
CapFlags::DITHER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! capabilities {
|
||||||
|
($name:ident, $next:ident, $($rest:ident,)*) => {
|
||||||
|
capabilities!($name, $next, $($rest,)* [$name = 1;]);
|
||||||
|
};
|
||||||
|
($prev:ident, $name:ident, $($rest:ident,)* [$($tt:tt)*]) => {
|
||||||
|
capabilities!($name, $($rest,)* [$($tt)* $name = Self::$prev.bits << 1;]);
|
||||||
|
};
|
||||||
|
($prev:ident, [$($name:ident = $value:expr;)*]) => {
|
||||||
|
bitflags! {
|
||||||
|
#[derive(JSTraceable, MallocSizeOf)]
|
||||||
|
struct CapFlags: u16 {
|
||||||
|
$(const $name = $value;)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CapFlags {
|
||||||
|
fn from_enum(cap: u32) -> WebGLResult<Self> {
|
||||||
|
match cap {
|
||||||
|
$(constants::$name => Ok(Self::$name),)*
|
||||||
|
_ => Err(InvalidEnum),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
capabilities! {
|
||||||
|
BLEND,
|
||||||
|
CULL_FACE,
|
||||||
|
DEPTH_TEST,
|
||||||
|
DITHER,
|
||||||
|
POLYGON_OFFSET_FILL,
|
||||||
|
SAMPLE_ALPHA_TO_COVERAGE,
|
||||||
|
SAMPLE_COVERAGE,
|
||||||
|
SCISSOR_TEST,
|
||||||
|
STENCIL_TEST,
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue