Skip to content

Commit

Permalink
Add support for WebGL2 clear buffer operations
Browse files Browse the repository at this point in the history
Adds support for the following WebGL2 methods:

- `clearBufferfv`
- `clearBufferiv`
- `clearBufferuiv`
- `clearBufferfi`

See: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.11
  • Loading branch information
mmatyas committed Feb 24, 2020
1 parent 92f5b36 commit 8701d45
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 125 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion components/canvas/Cargo.toml
Expand Up @@ -37,7 +37,7 @@ raqote = {git = "https://github.com/jrmuizel/raqote", optional = true}
time = { version = "0.1.0", optional = true }
pixels = {path = "../pixels"}
servo_config = {path = "../config"}
sparkle = "0.1.16"
sparkle = "0.1.17"
webrender = {git = "https://github.com/servo/webrender"}
webrender_api = {git = "https://github.com/servo/webrender"}
webrender_traits = {path = "../webrender_traits"}
Expand Down
12 changes: 12 additions & 0 deletions components/canvas/webgl_thread.rs
Expand Up @@ -1956,6 +1956,18 @@ impl WebGLImpl {
offset as isize,
size as isize,
),
WebGLCommand::ClearBufferfv(buffer, draw_buffer, ref value) => {
gl.clear_buffer_fv(buffer, draw_buffer, value)
},
WebGLCommand::ClearBufferiv(buffer, draw_buffer, ref value) => {
gl.clear_buffer_iv(buffer, draw_buffer, value)
},
WebGLCommand::ClearBufferuiv(buffer, draw_buffer, ref value) => {
gl.clear_buffer_uiv(buffer, draw_buffer, value)
},
WebGLCommand::ClearBufferfi(buffer, draw_buffer, depth, stencil) => {
gl.clear_buffer_fi(buffer, draw_buffer, depth, stencil)
},
}

// If debug asertions are enabled, then check the error state.
Expand Down
4 changes: 4 additions & 0 deletions components/canvas_traits/webgl.rs
Expand Up @@ -529,6 +529,10 @@ pub enum WebGLCommand {
GetSamplerParameterInt(WebGLSamplerId, u32, WebGLSender<i32>),
BindBufferBase(u32, u32, Option<WebGLBufferId>),
BindBufferRange(u32, u32, Option<WebGLBufferId>, i64, i64),
ClearBufferfv(u32, i32, Vec<f32>),
ClearBufferiv(u32, i32, Vec<i32>),
ClearBufferuiv(u32, i32, Vec<u32>),
ClearBufferfi(u32, i32, f32, i32),
}

macro_rules! nonzero_type {
Expand Down
132 changes: 132 additions & 0 deletions components/script/dom/webgl2renderingcontext.rs
Expand Up @@ -557,6 +557,52 @@ impl WebGL2RenderingContext {
let retval = receiver.recv().unwrap();
Ok(Int32Value(retval))
}

fn clearbuffer_array_size(&self, buffer: u32, draw_buffer: i32) -> WebGLResult<usize> {
match buffer {
constants::COLOR => {
if draw_buffer < 0 || draw_buffer as u32 >= self.base.limits().max_draw_buffers {
return Err(InvalidValue);
}
Ok(4)
},
constants::DEPTH | constants::STENCIL | constants::DEPTH_STENCIL => {
if draw_buffer != 0 {
return Err(InvalidValue);
}
Ok(1)
},
_ => unreachable!(),
}
}

fn clear_buffer<T: Clone>(
&self,
buffer: u32,
draw_buffer: i32,
valid_buffers: &[u32],
src_offset: u32,
array: Vec<T>,
msg: fn(u32, i32, Vec<T>) -> WebGLCommand,
) {
if !valid_buffers.contains(&buffer) {
return self.base.webgl_error(InvalidEnum);
}

let array_size = handle_potential_webgl_error!(
self.base,
self.clearbuffer_array_size(buffer, draw_buffer),
return
);
let src_offset = src_offset as usize;

if array.len() < src_offset + array_size {
return self.base.webgl_error(InvalidValue);
}
let array = array[src_offset..src_offset + array_size].to_vec();

self.base.send_command(msg(buffer, draw_buffer, array));
}
}

impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
Expand Down Expand Up @@ -3365,6 +3411,92 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
return
)
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.11
fn ClearBufferfv(
&self,
buffer: u32,
draw_buffer: i32,
values: Float32ArrayOrUnrestrictedFloatSequence,
src_offset: u32,
) {
let array = match values {
Float32ArrayOrUnrestrictedFloatSequence::Float32Array(v) => v.to_vec(),
Float32ArrayOrUnrestrictedFloatSequence::UnrestrictedFloatSequence(v) => v,
};
self.clear_buffer::<f32>(
buffer,
draw_buffer,
&[constants::COLOR, constants::DEPTH],
src_offset,
array,
WebGLCommand::ClearBufferfv,
)
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.11
fn ClearBufferiv(
&self,
buffer: u32,
draw_buffer: i32,
values: Int32ArrayOrLongSequence,
src_offset: u32,
) {
let array = match values {
Int32ArrayOrLongSequence::Int32Array(v) => v.to_vec(),
Int32ArrayOrLongSequence::LongSequence(v) => v,
};
self.clear_buffer::<i32>(
buffer,
draw_buffer,
&[constants::COLOR, constants::STENCIL],
src_offset,
array,
WebGLCommand::ClearBufferiv,
)
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.11
fn ClearBufferuiv(
&self,
buffer: u32,
draw_buffer: i32,
values: Uint32ArrayOrUnsignedLongSequence,
src_offset: u32,
) {
let array = match values {
Uint32ArrayOrUnsignedLongSequence::Uint32Array(v) => v.to_vec(),
Uint32ArrayOrUnsignedLongSequence::UnsignedLongSequence(v) => v,
};
self.clear_buffer::<u32>(
buffer,
draw_buffer,
&[constants::COLOR],
src_offset,
array,
WebGLCommand::ClearBufferuiv,
)
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.11
fn ClearBufferfi(&self, buffer: u32, draw_buffer: i32, depth: f32, stencil: i32) {
if buffer != constants::DEPTH_STENCIL {
return self.base.webgl_error(InvalidEnum);
}

handle_potential_webgl_error!(
self.base,
self.clearbuffer_array_size(buffer, draw_buffer),
return
);

self.base.send_command(WebGLCommand::ClearBufferfi(
buffer,
draw_buffer,
depth,
stencil,
));
}
}

impl LayoutCanvasWebGLRenderingContextHelpers for LayoutDom<WebGL2RenderingContext> {
Expand Down
16 changes: 8 additions & 8 deletions components/script/dom/webidls/WebGL2RenderingContext.webidl
Expand Up @@ -481,14 +481,14 @@ interface mixin WebGL2RenderingContextBase
/* Multiple Render Targets */
// void drawBuffers(sequence<GLenum> buffers);

// void clearBufferfv(GLenum buffer, GLint drawbuffer, Float32List values,
// optional GLuint srcOffset = 0);
// void clearBufferiv(GLenum buffer, GLint drawbuffer, Int32List values,
// optional GLuint srcOffset = 0);
// void clearBufferuiv(GLenum buffer, GLint drawbuffer, Uint32List values,
// optional GLuint srcOffset = 0);

// void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
void clearBufferfv(GLenum buffer, GLint drawbuffer, Float32List values,
optional GLuint srcOffset = 0);
void clearBufferiv(GLenum buffer, GLint drawbuffer, Int32List values,
optional GLuint srcOffset = 0);
void clearBufferuiv(GLenum buffer, GLint drawbuffer, Uint32List values,
optional GLuint srcOffset = 0);

void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);

/* Query Objects */
WebGLQuery? createQuery();
Expand Down
115 changes: 11 additions & 104 deletions tests/wpt/webgl/meta/conformance2/context/methods-2.html.ini
@@ -1,91 +1,4 @@
[methods-2.html]
[WebGL test #11: Property either does not exist or is not a function: compressedTexSubImage3D]
expected: FAIL

[WebGL test #8: Property either does not exist or is not a function: texSubImage3D]
expected: FAIL

[WebGL test #28: Property either does not exist or is not a function: bindVertexArray]
expected: FAIL

[WebGL test #14: Property either does not exist or is not a function: vertexAttribI4iv]
expected: FAIL

[WebGL test #23: Property either does not exist or is not a function: clearBufferfi]
expected: FAIL

[WebGL test #15: Property either does not exist or is not a function: vertexAttribI4ui]
expected: FAIL

[WebGL test #27: Property either does not exist or is not a function: isVertexArray]
expected: FAIL

[WebGL test #20: Property either does not exist or is not a function: clearBufferiv]
expected: FAIL

[WebGL test #22: Property either does not exist or is not a function: clearBufferfv]
expected: FAIL

[WebGL test #6: Property either does not exist or is not a function: texStorage2D]
expected: FAIL

[WebGL test #1: Property either does not exist or is not a function: blitFramebuffer]
expected: FAIL

[WebGL test #13: Property either does not exist or is not a function: vertexAttribI4i]
expected: FAIL

[WebGL test #5: Property either does not exist or is not a function: texImage3D]
expected: FAIL

[WebGL test #21: Property either does not exist or is not a function: clearBufferuiv]
expected: FAIL

[WebGL test #26: Property either does not exist or is not a function: deleteVertexArray]
expected: FAIL

[WebGL test #4: Property either does not exist or is not a function: renderbufferStorageMultisample]
expected: FAIL

[WebGL test #19: Property either does not exist or is not a function: drawBuffers]
expected: FAIL

[WebGL test #10: Property either does not exist or is not a function: compressedTexImage3D]
expected: FAIL

[WebGL test #7: Property either does not exist or is not a function: texStorage3D]
expected: FAIL

[WebGL test #16: Property either does not exist or is not a function: vertexAttribI4uiv]
expected: FAIL

[WebGL test #18: Property either does not exist or is not a function: drawRangeElements]
expected: FAIL

[WebGL test #9: Property either does not exist or is not a function: copyTexSubImage3D]
expected: FAIL

[WebGL test #0: Property either does not exist or is not a function: isContextLost]
expected: FAIL

[WebGL test #17: Property either does not exist or is not a function: vertexAttribIPointer]
expected: FAIL

[WebGL test #24: Property either does not exist or is not a function: getIndexedParameter]
expected: FAIL

[WebGL test #2: Property either does not exist or is not a function: getInternalformatParameter]
expected: FAIL

[WebGL test #25: Property either does not exist or is not a function: createVertexArray]
expected: FAIL

[WebGL test #3: Property either does not exist or is not a function: readBuffer]
expected: FAIL

[WebGL test #12: Property either does not exist or is not a function: getFragDataLocation]
expected: FAIL

[WebGL test #16: Property either does not exist or is not a function: vertexAttribI4i]
expected: FAIL

Expand All @@ -107,16 +20,13 @@
[WebGL test #4: Property either does not exist or is not a function: invalidateFramebuffer]
expected: FAIL

[WebGL test #30: Property either does not exist or is not a function: isVertexArray]
expected: FAIL

[WebGL test #7: Property either does not exist or is not a function: renderbufferStorageMultisample]
expected: FAIL

[WebGL test #10: Property either does not exist or is not a function: texStorage3D]
expected: FAIL

[WebGL test #29: Property either does not exist or is not a function: deleteVertexArray]
[WebGL test #1: Property either does not exist or is not a function: blitFramebuffer]
expected: FAIL

[WebGL test #11: Property either does not exist or is not a function: texSubImage3D]
Expand All @@ -125,19 +35,22 @@
[WebGL test #20: Property either does not exist or is not a function: vertexAttribIPointer]
expected: FAIL

[WebGL test #27: Property either does not exist or is not a function: getIndexedParameter]
[WebGL test #25: Property either does not exist or is not a function: deleteVertexArray]
expected: FAIL

[WebGL test #3: Property either does not exist or is not a function: getInternalformatParameter]
[WebGL test #23: Property either does not exist or is not a function: getIndexedParameter]
expected: FAIL

[WebGL test #26: Property either does not exist or is not a function: isVertexArray]
expected: FAIL

[WebGL test #23: Property either does not exist or is not a function: clearBufferiv]
[WebGL test #3: Property either does not exist or is not a function: getInternalformatParameter]
expected: FAIL

[WebGL test #21: Property either does not exist or is not a function: drawRangeElements]
expected: FAIL

[WebGL test #26: Property either does not exist or is not a function: clearBufferfi]
[WebGL test #27: Property either does not exist or is not a function: bindVertexArray]
expected: FAIL

[WebGL test #13: Property either does not exist or is not a function: compressedTexImage3D]
Expand All @@ -152,16 +65,13 @@
[WebGL test #8: Property either does not exist or is not a function: texImage3D]
expected: FAIL

[WebGL test #28: Property either does not exist or is not a function: createVertexArray]
expected: FAIL

[WebGL test #25: Property either does not exist or is not a function: clearBufferfv]
[WebGL test #0: Property either does not exist or is not a function: isContextLost]
expected: FAIL

[WebGL test #24: Property either does not exist or is not a function: clearBufferuiv]
[WebGL test #9: Property either does not exist or is not a function: texStorage2D]
expected: FAIL

[WebGL test #9: Property either does not exist or is not a function: texStorage2D]
[WebGL test #24: Property either does not exist or is not a function: createVertexArray]
expected: FAIL

[WebGL test #6: Property either does not exist or is not a function: readBuffer]
Expand All @@ -173,6 +83,3 @@
[WebGL test #14: Property either does not exist or is not a function: compressedTexSubImage3D]
expected: FAIL

[WebGL test #31: Property either does not exist or is not a function: bindVertexArray]
expected: FAIL

@@ -1,11 +1,10 @@
[clear-srgb-color-buffer.html]
expected: ERROR
[WebGL test #1: Framebuffer incomplete.]
expected: FAIL

[WebGL test #3: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
[WebGL test #2: \nat (0, 0) expected: 124,193,222,255 was 0,0,0,0]
expected: FAIL

[WebGL test #2: \nat (0, 0) expected: 124,193,222,255 was 0,0,0,0]
[WebGL test #3: \nat (0, 0) expected: 124,193,222,255 was 0,0,0,0]
expected: FAIL

0 comments on commit 8701d45

Please sign in to comment.