diff options
author | Anthony Ramine <n.oxyde@gmail.com> | 2018-07-25 13:23:05 +0200 |
---|---|---|
committer | Anthony Ramine <n.oxyde@gmail.com> | 2018-07-25 19:58:02 +0200 |
commit | 5a9ad011452794a17cbaec47ba584fa607d6bb75 (patch) | |
tree | 22dc88a38bfc7d0965227c422efdd3de28bc9112 /components/script/dom/webglrenderingcontext.rs | |
parent | 65df9cb73a26db2c61100ee8f1ecd13c6a80e225 (diff) | |
download | servo-5a9ad011452794a17cbaec47ba584fa607d6bb75.tar.gz servo-5a9ad011452794a17cbaec47ba584fa607d6bb75.zip |
Cache which capabilities are enabled in the context (fixes #20534)
This is needed for #20555.
Diffstat (limited to 'components/script/dom/webglrenderingcontext.rs')
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 100 |
1 files changed, 75 insertions, 25 deletions
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 627eb29dff6..78dde389f04 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -207,6 +207,7 @@ pub struct WebGLRenderingContext { #[ignore_malloc_size_of = "Because it's small"] current_clear_color: Cell<(f32, f32, f32, f32)>, extension_manager: WebGLExtensions, + capabilities: Capabilities, } impl WebGLRenderingContext { @@ -256,6 +257,7 @@ impl WebGLRenderingContext { current_scissor: Cell::new((0, 0, size.width, size.height)), current_clear_color: Cell::new((0.0, 0.0, 0.0, 0.0)), extension_manager: WebGLExtensions::new(webgl_version), + capabilities: Default::default(), } }) } @@ -1114,19 +1116,6 @@ impl WebGLRenderingContext { 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 { let (sender, receiver) = webgl_channel().unwrap(); self.send_command(WebGLCommand::GetExtensions(sender)); @@ -1533,6 +1522,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { 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) { self.webgl_error(WebGLError::InvalidEnum); return NullValue(); @@ -2190,17 +2183,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // 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) { - if self.validate_feature_enum(cap) { + if handle_potential_webgl_error!(self, self.capabilities.set(cap, true), return) { self.send_command(WebGLCommand::Enable(cap)); } } // 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) { - if self.validate_feature_enum(cap) { + if handle_potential_webgl_error!(self, self.capabilities.set(cap, false), return) { 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 - // FIXME: https://github.com/servo/servo/issues/20534 fn IsEnabled(&self, cap: u32) -> bool { - if self.validate_feature_enum(cap) { - let (sender, receiver) = webgl_channel().unwrap(); - self.send_command(WebGLCommand::IsEnabled(cap, sender)); - return receiver.recv().unwrap(); - } - - false + handle_potential_webgl_error!(self, self.capabilities.is_enabled(cap), false) } // 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, +} |