Store active attribs in DOM and optimise active attributes APIs

This commit is contained in:
Anthony Ramine 2018-07-04 21:39:15 +02:00
parent 0e2e834d18
commit fc593c68c5
6 changed files with 166 additions and 125 deletions

View file

@ -740,8 +740,6 @@ impl WebGLImpl {
Self::active_attrib(ctx.gl(), program_id, index, chan),
WebGLCommand::GetActiveUniform(program_id, index, ref chan) =>
Self::active_uniform(ctx.gl(), program_id, index, chan),
WebGLCommand::GetAttribLocation(program_id, ref name, ref chan) =>
Self::attrib_location(ctx.gl(), program_id, name, chan),
WebGLCommand::GetRenderbufferParameter(target, pname, ref chan) =>
Self::get_renderbuffer_parameter(ctx.gl(), target, pname, chan),
WebGLCommand::GetFramebufferAttachmentParameter(target, attachment, pname, ref chan) =>
@ -790,8 +788,6 @@ impl WebGLImpl {
ctx.gl().bind_renderbuffer(target, id.map_or(0, WebGLRenderbufferId::get)),
WebGLCommand::BindTexture(target, id) =>
ctx.gl().bind_texture(target, id.map_or(0, WebGLTextureId::get)),
WebGLCommand::LinkProgram(program_id) =>
ctx.gl().link_program(program_id.get()),
WebGLCommand::Uniform1f(uniform_id, v) =>
ctx.gl().uniform_1f(uniform_id, v),
WebGLCommand::Uniform1fv(uniform_id, ref v) =>
@ -919,17 +915,17 @@ impl WebGLImpl {
}
sender.send(value).unwrap()
}
WebGLCommand::GetProgramParameterBool(program, param, ref sender) => {
WebGLCommand::GetProgramValidateStatus(program, ref sender) => {
let mut value = [0];
unsafe {
ctx.gl().get_program_iv(program.get(), param as u32, &mut value);
ctx.gl().get_program_iv(program.get(), gl::VALIDATE_STATUS, &mut value);
}
sender.send(value[0] != 0).unwrap()
}
WebGLCommand::GetProgramParameterInt(program, param, ref sender) => {
WebGLCommand::GetProgramActiveUniforms(program, ref sender) => {
let mut value = [0];
unsafe {
ctx.gl().get_program_iv(program.get(), param as u32, &mut value);
ctx.gl().get_program_iv(program.get(), gl::ACTIVE_UNIFORMS, &mut value);
}
sender.send(value[0]).unwrap()
}
@ -966,6 +962,9 @@ impl WebGLImpl {
WebGLCommand::TexParameterf(target, param, value) => {
ctx.gl().tex_parameter_f(target, param as u32, value)
}
WebGLCommand::LinkProgram(program_id, ref sender) => {
return sender.send(Self::link_program(ctx.gl(), program_id)).unwrap();
}
}
// TODO: update test expectations in order to enable debug assertions
@ -976,6 +975,45 @@ impl WebGLImpl {
assert_eq!(error, gl::NO_ERROR, "Unexpected WebGL error: 0x{:x} ({})", error, error);
}
#[allow(unsafe_code)]
fn link_program(gl: &gl::Gl, program: WebGLProgramId) -> ProgramLinkInfo {
gl.link_program(program.get());
let mut linked = [0];
unsafe {
gl.get_program_iv(program.get(), gl::LINK_STATUS, &mut linked);
}
if linked[0] == 0 {
return ProgramLinkInfo {
linked: false,
active_attribs: vec![].into(),
}
}
let mut num_active_attribs = [0];
unsafe {
gl.get_program_iv(program.get(), gl::ACTIVE_ATTRIBUTES, &mut num_active_attribs);
}
let active_attribs = (0..num_active_attribs[0] as u32).map(|i| {
let (size, type_, name) = gl.get_active_attrib(program.get(), i);
let location = if name.starts_with("gl_") {
-1
} else {
gl.get_attrib_location(program.get(), &name)
};
ActiveAttribInfo {
name: from_name_in_compiled_shader(&name),
size,
type_,
location,
}
}).collect::<Vec<_>>().into();
ProgramLinkInfo {
linked: true,
active_attribs,
}
}
fn read_pixels(
gl: &gl::Gl,
x: i32,
@ -1026,21 +1064,6 @@ impl WebGLImpl {
chan.send(result).unwrap();
}
fn attrib_location(gl: &gl::Gl,
program_id: WebGLProgramId,
name: &str,
chan: &WebGLSender<Option<i32>> ) {
let attrib_location = gl.get_attrib_location(program_id.get(), name);
let attrib_location = if attrib_location == -1 {
None
} else {
Some(attrib_location)
};
chan.send(attrib_location).unwrap();
}
fn finish(gl: &gl::Gl, chan: &WebGLSender<()>) {
gl.finish();
chan.send(()).unwrap();