Skip to content

Commit

Permalink
Add support for WebGL2 uniform matrix operations
Browse files Browse the repository at this point in the history
Adds support for the `uniformMatrix[234]x[234]fv` WebGL2 functions.

See: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
  • Loading branch information
mmatyas committed Jan 17, 2020
1 parent 0650fc3 commit 7d5048f
Show file tree
Hide file tree
Showing 10 changed files with 369 additions and 190 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 @@ -34,7 +34,7 @@ num-traits = "0.2"
raqote = {git = "https://github.com/jrmuizel/raqote", optional = true}
pixels = {path = "../pixels"}
servo_config = {path = "../config"}
sparkle = "0.1.14"
sparkle = "0.1.16"
webrender = {git = "https://github.com/servo/webrender"}
webrender_api = {git = "https://github.com/servo/webrender"}
webrender_traits = {path = "../webrender_traits"}
Expand Down
60 changes: 60 additions & 0 deletions components/canvas/webgl_thread.rs
Expand Up @@ -1343,6 +1343,24 @@ impl WebGLImpl {
WebGLCommand::UniformMatrix4fv(uniform_id, ref v) => {
gl.uniform_matrix_4fv(uniform_id, false, v)
},
WebGLCommand::UniformMatrix3x2fv(uniform_id, ref v) => {
gl.uniform_matrix_3x2fv(uniform_id, false, v)
},
WebGLCommand::UniformMatrix4x2fv(uniform_id, ref v) => {
gl.uniform_matrix_4x2fv(uniform_id, false, v)
},
WebGLCommand::UniformMatrix2x3fv(uniform_id, ref v) => {
gl.uniform_matrix_2x3fv(uniform_id, false, v)
},
WebGLCommand::UniformMatrix4x3fv(uniform_id, ref v) => {
gl.uniform_matrix_4x3fv(uniform_id, false, v)
},
WebGLCommand::UniformMatrix2x4fv(uniform_id, ref v) => {
gl.uniform_matrix_2x4fv(uniform_id, false, v)
},
WebGLCommand::UniformMatrix3x4fv(uniform_id, ref v) => {
gl.uniform_matrix_3x4fv(uniform_id, false, v)
},
WebGLCommand::ValidateProgram(program_id) => gl.validate_program(program_id.get()),
WebGLCommand::VertexAttrib(attrib_id, x, y, z, w) => {
gl.vertex_attrib_4f(attrib_id, x, y, z, w)
Expand Down Expand Up @@ -1783,6 +1801,48 @@ impl WebGLImpl {
}
sender.send(value).unwrap();
},
WebGLCommand::GetUniformFloat2x3(program_id, loc, ref sender) => {
let mut value = [0.; 2 * 3];
unsafe {
gl.get_uniform_fv(program_id.get(), loc, &mut value);
}
sender.send(value).unwrap()
},
WebGLCommand::GetUniformFloat2x4(program_id, loc, ref sender) => {
let mut value = [0.; 2 * 4];
unsafe {
gl.get_uniform_fv(program_id.get(), loc, &mut value);
}
sender.send(value).unwrap()
},
WebGLCommand::GetUniformFloat3x2(program_id, loc, ref sender) => {
let mut value = [0.; 3 * 2];
unsafe {
gl.get_uniform_fv(program_id.get(), loc, &mut value);
}
sender.send(value).unwrap()
},
WebGLCommand::GetUniformFloat3x4(program_id, loc, ref sender) => {
let mut value = [0.; 3 * 4];
unsafe {
gl.get_uniform_fv(program_id.get(), loc, &mut value);
}
sender.send(value).unwrap()
},
WebGLCommand::GetUniformFloat4x2(program_id, loc, ref sender) => {
let mut value = [0.; 4 * 2];
unsafe {
gl.get_uniform_fv(program_id.get(), loc, &mut value);
}
sender.send(value).unwrap()
},
WebGLCommand::GetUniformFloat4x3(program_id, loc, ref sender) => {
let mut value = [0.; 4 * 3];
unsafe {
gl.get_uniform_fv(program_id.get(), loc, &mut value);
}
sender.send(value).unwrap()
},
WebGLCommand::GetUniformBlockIndex(program_id, ref name, ref sender) => {
let name = to_name_in_compiled_shader(name);
let index = gl.get_uniform_block_index(program_id.get(), &name);
Expand Down
12 changes: 12 additions & 0 deletions components/canvas_traits/webgl.rs
Expand Up @@ -351,6 +351,12 @@ pub enum WebGLCommand {
UniformMatrix2fv(i32, Vec<f32>),
UniformMatrix3fv(i32, Vec<f32>),
UniformMatrix4fv(i32, Vec<f32>),
UniformMatrix3x2fv(i32, Vec<f32>),
UniformMatrix4x2fv(i32, Vec<f32>),
UniformMatrix2x3fv(i32, Vec<f32>),
UniformMatrix4x3fv(i32, Vec<f32>),
UniformMatrix2x4fv(i32, Vec<f32>),
UniformMatrix3x4fv(i32, Vec<f32>),
UseProgram(Option<WebGLProgramId>),
ValidateProgram(WebGLProgramId),
VertexAttrib(u32, f32, f32, f32, f32),
Expand Down Expand Up @@ -474,6 +480,12 @@ pub enum WebGLCommand {
GetUniformFloat4(WebGLProgramId, i32, WebGLSender<[f32; 4]>),
GetUniformFloat9(WebGLProgramId, i32, WebGLSender<[f32; 9]>),
GetUniformFloat16(WebGLProgramId, i32, WebGLSender<[f32; 16]>),
GetUniformFloat2x3(WebGLProgramId, i32, WebGLSender<[f32; 2 * 3]>),
GetUniformFloat2x4(WebGLProgramId, i32, WebGLSender<[f32; 2 * 4]>),
GetUniformFloat3x2(WebGLProgramId, i32, WebGLSender<[f32; 3 * 2]>),
GetUniformFloat3x4(WebGLProgramId, i32, WebGLSender<[f32; 3 * 4]>),
GetUniformFloat4x2(WebGLProgramId, i32, WebGLSender<[f32; 4 * 2]>),
GetUniformFloat4x3(WebGLProgramId, i32, WebGLSender<[f32; 4 * 3]>),
GetUniformBlockIndex(WebGLProgramId, String, WebGLSender<u32>),
GetUniformIndices(WebGLProgramId, Vec<String>, WebGLSender<Vec<u32>>),
GetActiveUniforms(WebGLProgramId, Vec<u32>, u32, WebGLSender<Vec<i32>>),
Expand Down
221 changes: 217 additions & 4 deletions components/script/dom/webgl2renderingcontext.rs
Expand Up @@ -50,7 +50,7 @@ use js::jsapi::{JSObject, Type};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, UInt32Value};
use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue};
use js::rust::CustomAutoRooterGuard;
use js::typedarray::{ArrayBufferView, CreateWith, Uint32, Uint32Array};
use js::typedarray::{ArrayBufferView, CreateWith, Float32, Uint32, Uint32Array};
use script_layout_interface::HTMLCanvasDataSource;
use std::cell::Cell;
use std::cmp;
Expand Down Expand Up @@ -1744,8 +1744,11 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
location: Option<&WebGLUniformLocation>,
transpose: bool,
v: Float32ArrayOrUnrestrictedFloatSequence,
src_offset: u32,
src_length: u32,
) {
self.base.UniformMatrix2fv(location, transpose, v)
self.base
.UniformMatrix2fv(location, transpose, v, src_offset, src_length)
}

/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
Expand All @@ -1754,8 +1757,11 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
location: Option<&WebGLUniformLocation>,
transpose: bool,
v: Float32ArrayOrUnrestrictedFloatSequence,
src_offset: u32,
src_length: u32,
) {
self.base.UniformMatrix3fv(location, transpose, v)
self.base
.UniformMatrix3fv(location, transpose, v, src_offset, src_length)
}

/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
Expand All @@ -1764,8 +1770,179 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
location: Option<&WebGLUniformLocation>,
transpose: bool,
v: Float32ArrayOrUnrestrictedFloatSequence,
src_offset: u32,
src_length: u32,
) {
self.base
.UniformMatrix4fv(location, transpose, v, src_offset, src_length)
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
fn UniformMatrix3x2fv(
&self,
location: Option<&WebGLUniformLocation>,
transpose: bool,
val: Float32ArrayOrUnrestrictedFloatSequence,
src_offset: u32,
src_length: u32,
) {
self.base.UniformMatrix4fv(location, transpose, v)
self.base.with_location(location, |location| {
match location.type_() {
constants::FLOAT_MAT3x2 => {},
_ => return Err(InvalidOperation),
}
let val = self.base.uniform_matrix_section(
val,
src_offset,
src_length,
transpose,
3 * 2,
location,
)?;
self.base
.send_command(WebGLCommand::UniformMatrix3x2fv(location.id(), val));
Ok(())
});
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
fn UniformMatrix4x2fv(
&self,
location: Option<&WebGLUniformLocation>,
transpose: bool,
val: Float32ArrayOrUnrestrictedFloatSequence,
src_offset: u32,
src_length: u32,
) {
self.base.with_location(location, |location| {
match location.type_() {
constants::FLOAT_MAT4x2 => {},
_ => return Err(InvalidOperation),
}
let val = self.base.uniform_matrix_section(
val,
src_offset,
src_length,
transpose,
4 * 2,
location,
)?;
self.base
.send_command(WebGLCommand::UniformMatrix4x2fv(location.id(), val));
Ok(())
});
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
fn UniformMatrix2x3fv(
&self,
location: Option<&WebGLUniformLocation>,
transpose: bool,
val: Float32ArrayOrUnrestrictedFloatSequence,
src_offset: u32,
src_length: u32,
) {
self.base.with_location(location, |location| {
match location.type_() {
constants::FLOAT_MAT2x3 => {},
_ => return Err(InvalidOperation),
}
let val = self.base.uniform_matrix_section(
val,
src_offset,
src_length,
transpose,
2 * 3,
location,
)?;
self.base
.send_command(WebGLCommand::UniformMatrix2x3fv(location.id(), val));
Ok(())
});
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
fn UniformMatrix4x3fv(
&self,
location: Option<&WebGLUniformLocation>,
transpose: bool,
val: Float32ArrayOrUnrestrictedFloatSequence,
src_offset: u32,
src_length: u32,
) {
self.base.with_location(location, |location| {
match location.type_() {
constants::FLOAT_MAT4x3 => {},
_ => return Err(InvalidOperation),
}
let val = self.base.uniform_matrix_section(
val,
src_offset,
src_length,
transpose,
4 * 3,
location,
)?;
self.base
.send_command(WebGLCommand::UniformMatrix4x3fv(location.id(), val));
Ok(())
});
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
fn UniformMatrix2x4fv(
&self,
location: Option<&WebGLUniformLocation>,
transpose: bool,
val: Float32ArrayOrUnrestrictedFloatSequence,
src_offset: u32,
src_length: u32,
) {
self.base.with_location(location, |location| {
match location.type_() {
constants::FLOAT_MAT2x4 => {},
_ => return Err(InvalidOperation),
}
let val = self.base.uniform_matrix_section(
val,
src_offset,
src_length,
transpose,
2 * 4,
location,
)?;
self.base
.send_command(WebGLCommand::UniformMatrix2x4fv(location.id(), val));
Ok(())
});
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
fn UniformMatrix3x4fv(
&self,
location: Option<&WebGLUniformLocation>,
transpose: bool,
val: Float32ArrayOrUnrestrictedFloatSequence,
src_offset: u32,
src_length: u32,
) {
self.base.with_location(location, |location| {
match location.type_() {
constants::FLOAT_MAT3x4 => {},
_ => return Err(InvalidOperation),
}
let val = self.base.uniform_matrix_section(
val,
src_offset,
src_length,
transpose,
3 * 4,
location,
)?;
self.base
.send_command(WebGLCommand::UniformMatrix3x4fv(location.id(), val));
Ok(())
});
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
Expand Down Expand Up @@ -1797,6 +1974,42 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
constants::UNSIGNED_INT_VEC4 => unsafe {
uniform_typed::<Uint32>(*cx, &uniform_get(triple, WebGLCommand::GetUniformUint4))
},
constants::FLOAT_MAT2x3 => unsafe {
uniform_typed::<Float32>(
*cx,
&uniform_get(triple, WebGLCommand::GetUniformFloat2x3),
)
},
constants::FLOAT_MAT2x4 => unsafe {
uniform_typed::<Float32>(
*cx,
&uniform_get(triple, WebGLCommand::GetUniformFloat2x4),
)
},
constants::FLOAT_MAT3x2 => unsafe {
uniform_typed::<Float32>(
*cx,
&uniform_get(triple, WebGLCommand::GetUniformFloat3x2),
)
},
constants::FLOAT_MAT3x4 => unsafe {
uniform_typed::<Float32>(
*cx,
&uniform_get(triple, WebGLCommand::GetUniformFloat3x4),
)
},
constants::FLOAT_MAT4x2 => unsafe {
uniform_typed::<Float32>(
*cx,
&uniform_get(triple, WebGLCommand::GetUniformFloat4x2),
)
},
constants::FLOAT_MAT4x3 => unsafe {
uniform_typed::<Float32>(
*cx,
&uniform_get(triple, WebGLCommand::GetUniformFloat4x3),
)
},
_ => self.base.GetUniform(cx, program, location),
}
}
Expand Down

0 comments on commit 7d5048f

Please sign in to comment.