aboutsummaryrefslogtreecommitdiffstats
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
parent65df9cb73a26db2c61100ee8f1ecd13c6a80e225 (diff)
downloadservo-5a9ad011452794a17cbaec47ba584fa607d6bb75.tar.gz
servo-5a9ad011452794a17cbaec47ba584fa607d6bb75.zip
Cache which capabilities are enabled in the context (fixes #20534)
This is needed for #20555.
-rw-r--r--components/canvas/webgl_thread.rs2
-rw-r--r--components/canvas_traits/webgl.rs8
-rw-r--r--components/script/dom/webglrenderingcontext.rs100
3 files changed, 75 insertions, 35 deletions
diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs
index ec65b7d144f..294afbcf226 100644
--- a/components/canvas/webgl_thread.rs
+++ b/components/canvas/webgl_thread.rs
@@ -709,8 +709,6 @@ impl WebGLImpl {
ctx.gl().enable_vertex_attrib_array(attrib_id),
WebGLCommand::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) =>
ctx.gl().line_width(width),
WebGLCommand::PixelStorei(name, val) =>
diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs
index 5fb9d0befb2..0b88fcfec99 100644
--- a/components/canvas_traits/webgl.rs
+++ b/components/canvas_traits/webgl.rs
@@ -225,7 +225,6 @@ pub enum WebGLCommand {
StencilOp(u32, u32, u32),
StencilOpSeparate(u32, u32, u32, u32),
Hint(u32, u32),
- IsEnabled(u32, WebGLSender<bool>),
LineWidth(f32),
PixelStorei(u32, i32),
LinkProgram(WebGLProgramId, WebGLSender<ProgramLinkInfo>),
@@ -511,15 +510,8 @@ macro_rules! parameters {
parameters! {
Parameter {
Bool(ParameterBool {
- Blend = gl::BLEND,
- CullFace = gl::CULL_FACE,
- DepthTest = gl::DEPTH_TEST,
DepthWritemask = gl::DEPTH_WRITEMASK,
- Dither = gl::DITHER,
- PolygonOffsetFill = gl::POLYGON_OFFSET_FILL,
SampleCoverageInvert = gl::SAMPLE_COVERAGE_INVERT,
- ScissorTest = gl::SCISSOR_TEST,
- StencilTest = gl::STENCIL_TEST,
}),
Bool4(ParameterBool4 {
ColorWritemask = gl::COLOR_WRITEMASK,
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,
+}