mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Added remaining uniforms
This commit is contained in:
parent
d21ff2fa13
commit
89c432b2d2
5 changed files with 263 additions and 163 deletions
|
@ -3,6 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use canvas_traits::{CanvasCommonMsg, CanvasMsg};
|
||||
use dom::bindings::codegen::Bindings::WebGLActiveInfoBinding::WebGLActiveInfoMethods;
|
||||
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
|
||||
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{WebGLRenderingContextMethods};
|
||||
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes};
|
||||
|
@ -66,6 +67,45 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum UniformType {
|
||||
Int,
|
||||
IntVec2,
|
||||
IntVec3,
|
||||
IntVec4,
|
||||
Float,
|
||||
FloatVec2,
|
||||
FloatVec3,
|
||||
FloatVec4,
|
||||
}
|
||||
|
||||
impl UniformType {
|
||||
fn element_count(&self) -> usize {
|
||||
match *self {
|
||||
UniformType::Int => 1,
|
||||
UniformType::IntVec2 => 2,
|
||||
UniformType::IntVec3 => 3,
|
||||
UniformType::IntVec4 => 4,
|
||||
UniformType::Float => 1,
|
||||
UniformType::FloatVec2 => 2,
|
||||
UniformType::FloatVec3 => 3,
|
||||
UniformType::FloatVec4 => 4,
|
||||
}
|
||||
}
|
||||
|
||||
fn as_gl_constant(&self) -> u32 {
|
||||
match *self {
|
||||
UniformType::Int => constants::INT,
|
||||
UniformType::IntVec2 => constants::INT_VEC2,
|
||||
UniformType::IntVec3 => constants::INT_VEC3,
|
||||
UniformType::IntVec4 => constants::INT_VEC4,
|
||||
UniformType::Float => constants::FLOAT,
|
||||
UniformType::FloatVec2 => constants::FLOAT_VEC2,
|
||||
UniformType::FloatVec3 => constants::FLOAT_VEC3,
|
||||
UniformType::FloatVec4 => constants::FLOAT_VEC4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[dom_struct]
|
||||
pub struct WebGLRenderingContext {
|
||||
reflector_: Reflector,
|
||||
|
@ -178,6 +218,59 @@ impl WebGLRenderingContext {
|
|||
.send(CanvasMsg::WebGL(WebGLCommand::VertexAttrib(indx, x, y, z, w)))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
// https://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml
|
||||
// https://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf#nameddest=section-2.10.4
|
||||
fn validate_uniform_parameters<T>(&self,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
type_: UniformType,
|
||||
data: Option<&[T]>) -> bool {
|
||||
let uniform = match uniform {
|
||||
Some(uniform) => uniform,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let program = self.current_program.get();
|
||||
let program = match program {
|
||||
Some(ref program) if program.id() == uniform.program_id() => program,
|
||||
_ => {
|
||||
self.webgl_error(InvalidOperation);
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
let data = match data {
|
||||
Some(data) => data,
|
||||
None => {
|
||||
self.webgl_error(InvalidOperation);
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
// TODO(autrilla): Don't request this every time, cache it
|
||||
let active_uniform = match program.get_active_uniform(
|
||||
uniform.id() as u32) {
|
||||
Ok(active_uniform) => active_uniform,
|
||||
Err(_) => {
|
||||
self.webgl_error(InvalidOperation);
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
if data.len() % type_.element_count() != 0 ||
|
||||
(data.len() / type_.element_count() > active_uniform.Size() as usize) {
|
||||
self.webgl_error(InvalidOperation);
|
||||
return false;
|
||||
}
|
||||
|
||||
if type_.as_gl_constant() != active_uniform.Type() {
|
||||
self.webgl_error(InvalidOperation);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for WebGLRenderingContext {
|
||||
|
@ -1018,38 +1111,22 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
fn Uniform1f(&self,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
val: f32) {
|
||||
let uniform = match uniform {
|
||||
Some(uniform) => uniform,
|
||||
None => return,
|
||||
};
|
||||
|
||||
match self.current_program.get() {
|
||||
Some(ref program) if program.id() == uniform.program_id() => {},
|
||||
_ => return self.webgl_error(InvalidOperation),
|
||||
};
|
||||
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform1f(uniform.id(), val)))
|
||||
.unwrap()
|
||||
if self.validate_uniform_parameters(uniform, UniformType::Float, Some(&[val])) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform1f(uniform.unwrap().id(), val)))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
fn Uniform1i(&self,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
val: i32) {
|
||||
let uniform = match uniform {
|
||||
Some(uniform) => uniform,
|
||||
None => return,
|
||||
};
|
||||
|
||||
match self.current_program.get() {
|
||||
Some(ref program) if program.id() == uniform.program_id() => {},
|
||||
_ => return self.webgl_error(InvalidOperation),
|
||||
};
|
||||
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform1i(uniform.id(), val)))
|
||||
.unwrap()
|
||||
if self.validate_uniform_parameters(uniform, UniformType::Int, Some(&[val])) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform1i(uniform.unwrap().id(), val)))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
|
@ -1057,50 +1134,36 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
_cx: *mut JSContext,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
data: Option<*mut JSObject>) {
|
||||
let data = match data {
|
||||
Some(data) => data,
|
||||
None => return self.webgl_error(InvalidValue),
|
||||
};
|
||||
|
||||
if let Some(data) = array_buffer_view_to_vec_checked::<i32>(data) {
|
||||
if data.len() < 1 {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
}
|
||||
|
||||
self.Uniform1i(uniform, data[0]);
|
||||
} else {
|
||||
self.webgl_error(InvalidValue);
|
||||
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d));
|
||||
if self.validate_uniform_parameters(uniform, UniformType::Int, data_vec.as_ref().map(Vec::as_slice)) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform1iv(uniform.unwrap().id(), data_vec.unwrap())))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
fn Uniform1fv(&self,
|
||||
_cx: *mut JSContext,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
data: Vec<f32>) {
|
||||
if data.is_empty() {
|
||||
return self.webgl_error(InvalidValue);
|
||||
data: Option<*mut JSObject>) {
|
||||
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d));
|
||||
if self.validate_uniform_parameters(uniform, UniformType::Float, data_vec.as_ref().map(Vec::as_slice)) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform1fv(uniform.unwrap().id(), data_vec.unwrap())))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
self.Uniform1f(uniform, data[0]);
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
fn Uniform2f(&self,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
x: f32, y: f32) {
|
||||
let uniform = match uniform {
|
||||
Some(uniform) => uniform,
|
||||
None => return,
|
||||
};
|
||||
|
||||
match self.current_program.get() {
|
||||
Some(ref program) if program.id() == uniform.program_id() => {},
|
||||
_ => return self.webgl_error(InvalidOperation),
|
||||
};
|
||||
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform2f(uniform.id(), x, y)))
|
||||
.unwrap()
|
||||
if self.validate_uniform_parameters(uniform, UniformType::FloatVec2, Some(&[x, y])) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform2f(uniform.unwrap().id(), x, y)))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
|
@ -1108,19 +1171,83 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
_cx: *mut JSContext,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
data: Option<*mut JSObject>) {
|
||||
let data = match data {
|
||||
Some(data) => data,
|
||||
None => return self.webgl_error(InvalidValue),
|
||||
};
|
||||
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d));
|
||||
if self.validate_uniform_parameters(uniform, UniformType::FloatVec2, data_vec.as_ref().map(Vec::as_slice)) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform2fv(uniform.unwrap().id(), data_vec.unwrap())))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(data) = array_buffer_view_to_vec_checked::<f32>(data) {
|
||||
if data.len() < 2 {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
}
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
fn Uniform2i(&self,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
x: i32, y: i32) {
|
||||
if self.validate_uniform_parameters(uniform, UniformType::IntVec2, Some(&[x, y])) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform2i(uniform.unwrap().id(), x, y)))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
self.Uniform2f(uniform, data[0], data[1]);
|
||||
} else {
|
||||
self.webgl_error(InvalidValue);
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
fn Uniform2iv(&self,
|
||||
_cx: *mut JSContext,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
data: Option<*mut JSObject>) {
|
||||
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d));
|
||||
if self.validate_uniform_parameters(uniform, UniformType::IntVec2, data_vec.as_ref().map(Vec::as_slice)) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform2iv(uniform.unwrap().id(), data_vec.unwrap())))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
fn Uniform3f(&self,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
x: f32, y: f32, z: f32) {
|
||||
if self.validate_uniform_parameters(uniform, UniformType::FloatVec3, Some(&[x, y, z])) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform3f(uniform.unwrap().id(), x, y, z)))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
fn Uniform3fv(&self,
|
||||
_cx: *mut JSContext,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
data: Option<*mut JSObject>) {
|
||||
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d));
|
||||
if self.validate_uniform_parameters(uniform, UniformType::FloatVec3, data_vec.as_ref().map(Vec::as_slice)) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform3fv(uniform.unwrap().id(), data_vec.unwrap())))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
fn Uniform3i(&self,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
x: i32, y: i32, z: i32) {
|
||||
if self.validate_uniform_parameters(uniform, UniformType::IntVec3, Some(&[x, y, z])) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform3i(uniform.unwrap().id(), x, y, z)))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
fn Uniform3iv(&self,
|
||||
_cx: *mut JSContext,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
data: Option<*mut JSObject>) {
|
||||
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d));
|
||||
if self.validate_uniform_parameters(uniform, UniformType::IntVec3, data_vec.as_ref().map(Vec::as_slice)) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform3iv(uniform.unwrap().id(), data_vec.unwrap())))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1128,19 +1255,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
fn Uniform4i(&self,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
x: i32, y: i32, z: i32, w: i32) {
|
||||
let uniform = match uniform {
|
||||
Some(uniform) => uniform,
|
||||
None => return,
|
||||
};
|
||||
|
||||
match self.current_program.get() {
|
||||
Some(ref program) if program.id() == uniform.program_id() => {},
|
||||
_ => return self.webgl_error(InvalidOperation),
|
||||
};
|
||||
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform4i(uniform.id(), x, y, z, w)))
|
||||
.unwrap()
|
||||
if self.validate_uniform_parameters(uniform, UniformType::IntVec4, Some(&[x, y, z, w])) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform4i(uniform.unwrap().id(), x, y, z, w)))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1149,19 +1268,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
_cx: *mut JSContext,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
data: Option<*mut JSObject>) {
|
||||
let data = match data {
|
||||
Some(data) => data,
|
||||
None => return self.webgl_error(InvalidValue),
|
||||
};
|
||||
|
||||
if let Some(data) = array_buffer_view_to_vec_checked::<i32>(data) {
|
||||
if data.len() < 4 {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
}
|
||||
|
||||
self.Uniform4i(uniform, data[0], data[1], data[2], data[3]);
|
||||
} else {
|
||||
self.webgl_error(InvalidValue);
|
||||
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d));
|
||||
if self.validate_uniform_parameters(uniform, UniformType::IntVec4, data_vec.as_ref().map(Vec::as_slice)) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform4iv(uniform.unwrap().id(), data_vec.unwrap())))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1169,19 +1280,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
fn Uniform4f(&self,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
x: f32, y: f32, z: f32, w: f32) {
|
||||
let uniform = match uniform {
|
||||
Some(uniform) => uniform,
|
||||
None => return,
|
||||
};
|
||||
|
||||
match self.current_program.get() {
|
||||
Some(ref program) if program.id() == uniform.program_id() => {},
|
||||
_ => return self.webgl_error(InvalidOperation),
|
||||
};
|
||||
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform4f(uniform.id(), x, y, z, w)))
|
||||
.unwrap()
|
||||
if self.validate_uniform_parameters(uniform, UniformType::FloatVec4, Some(&[x, y, z, w])) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform4f(uniform.unwrap().id(), x, y, z, w)))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||
|
@ -1189,19 +1292,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
_cx: *mut JSContext,
|
||||
uniform: Option<&WebGLUniformLocation>,
|
||||
data: Option<*mut JSObject>) {
|
||||
let data = match data {
|
||||
Some(data) => data,
|
||||
None => return self.webgl_error(InvalidValue),
|
||||
};
|
||||
|
||||
if let Some(data) = array_buffer_view_to_vec_checked::<f32>(data) {
|
||||
if data.len() < 4 {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
}
|
||||
|
||||
self.Uniform4f(uniform, data[0], data[1], data[2], data[3]);
|
||||
} else {
|
||||
self.webgl_error(InvalidValue);
|
||||
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d));
|
||||
if self.validate_uniform_parameters(uniform, UniformType::FloatVec4, data_vec.as_ref().map(Vec::as_slice)) {
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::Uniform4fv(uniform.unwrap().id(), data_vec.unwrap())))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue