aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/webglrenderingcontext.rs
diff options
context:
space:
mode:
authorAnthony Ramine <n.oxyde@gmail.com>2018-07-25 13:23:05 +0200
committerAnthony Ramine <n.oxyde@gmail.com>2018-07-25 19:58:02 +0200
commit5a9ad011452794a17cbaec47ba584fa607d6bb75 (patch)
tree22dc88a38bfc7d0965227c422efdd3de28bc9112 /components/script/dom/webglrenderingcontext.rs
parent65df9cb73a26db2c61100ee8f1ecd13c6a80e225 (diff)
downloadservo-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.rs100
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,
+}