mirror of
https://github.com/servo/servo.git
synced 2025-07-19 05:13:55 +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),
|
||||
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) =>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue