Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement WebGL getUniform API #20330

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Implement WebGL GetUniform API

  • Loading branch information
gootorov authored and jdm committed Jun 20, 2018
commit a62a4b3ff3b7d72bb1765f4c59ae2e4a121aeb3f
@@ -765,6 +765,8 @@ impl WebGLImpl {
Self::shader_precision_format(ctx.gl(), shader_type, precision_type, chan),
WebGLCommand::GetExtensions(ref chan) =>
Self::get_extensions(ctx.gl(), chan),
WebGLCommand::GetUniform(program, location, ref uniform_type, ref chan) =>
Self::get_uniform(ctx.gl(), program, location, uniform_type, chan),
WebGLCommand::GetUniformLocation(program_id, ref name, ref chan) =>
Self::uniform_location(ctx.gl(), program_id, &name, chan),
WebGLCommand::GetShaderInfoLog(shader_id, ref chan) =>
@@ -1162,6 +1164,44 @@ impl WebGLImpl {
chan.send(location).unwrap();
}

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn get_uniform(
gl: &gl::Gl,
program: u32,
location: i32,
uniform_type: &UniformType,
chan: &WebGLSender<UniformType>,
) {
let uniform = match uniform_type {
UniformType::FloatVec(_) =>
UniformType::FloatVec(gl.get_uniform_fv(program, location)),
UniformType::IntVec(_) =>
UniformType::IntVec(gl.get_uniform_iv(program, location)),
UniformType::BoolVec(_) => {
let result = gl.get_uniform_iv(program, location)
.iter()
.map(|el| *el == 1)
.collect::<Vec<_>>();
UniformType::BoolVec(result)
}
UniformType::Int(_) => {
// returns a single int in a vector
let result = gl.get_uniform_iv(program, location);
UniformType::Int(result[0])
}
UniformType::Bool(_) => {
// returns a single bool in a vector
let result = gl.get_uniform_iv(program, location);
UniformType::Bool(result[0] == 1)
}
UniformType::Float(_) => {
// returns a single float in a vector
let result = gl.get_uniform_fv(program, location);
UniformType::Float(result[0])
}
};
chan.send(uniform).unwrap();
}

fn shader_info_log(gl: &gl::Gl, shader_id: WebGLShaderId, chan: &WebGLSender<String>) {
let log = gl.get_shader_info_log(shader_id.get());
@@ -216,6 +216,7 @@ pub enum WebGLCommand {
GetProgramInfoLog(WebGLProgramId, WebGLSender<String>),
GetFramebufferAttachmentParameter(u32, u32, u32, WebGLSender<i32>),
GetRenderbufferParameter(u32, u32, WebGLSender<i32>),
GetUniform(u32, i32, UniformType, WebGLSender<UniformType>),
PolygonOffset(f32, f32),
RenderbufferStorage(u32, u32, i32, i32),
ReadPixels(i32, i32, i32, i32, u32, u32, WebGLSender<ByteBuf>),
@@ -287,6 +288,16 @@ pub enum WebGLCommand {
TexParameterf(u32, TexParameterFloat, f32),
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum UniformType {
FloatVec(Vec<f32>),
IntVec(Vec<i32>),
BoolVec(Vec<bool>),
Float(f32),
Int(i32),
Bool(bool),
}

macro_rules! define_resource_id_struct {
($name:ident) => {
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
@@ -170,6 +170,17 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
self.base.GetRenderbufferParameter(cx, target, pname)
}

#[allow(unsafe_code)]
/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
unsafe fn GetUniform(
&self,
cx: *mut JSContext,
program: &WebGLProgram,
location: &WebGLUniformLocation
) -> JSVal {
self.base.GetUniform(cx, program, location)
}

/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ActiveTexture(&self, texture: u32) {
self.base.ActiveTexture(texture)
@@ -4,7 +4,9 @@

// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
use canvas_traits::webgl::{WebGLCommand, WebGLError, WebGLMsgSender, WebGLProgramId, WebGLResult};
use canvas_traits::webgl::UniformType;
use canvas_traits::webgl::webgl_channel;
use dom::bindings::codegen::Bindings::WebGLActiveInfoBinding::WebGLActiveInfoBinding::WebGLActiveInfoMethods;
use dom::bindings::codegen::Bindings::WebGLProgramBinding;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::reflector::{DomObject, reflect_dom_object};
@@ -14,8 +16,10 @@ use dom::webglactiveinfo::WebGLActiveInfo;
use dom::webglobject::WebGLObject;
use dom::webglrenderingcontext::MAX_UNIFORM_AND_ATTRIBUTE_LEN;
use dom::webglshader::WebGLShader;
use dom::webgluniformlocation::WebGLUniformLocation;
use dom::window::Window;
use dom_struct::dom_struct;
use gleam::gl;
use std::cell::Cell;

#[dom_struct]
@@ -374,6 +378,50 @@ impl WebGLProgram {
(None, None) => vec![]
})
}

/// glGetUniform
pub fn get_uniform(
&self,
location: &WebGLUniformLocation
) -> WebGLResult<UniformType> {
let is_location_valid = location.program_id().get() == self.id().get();
if !self.is_linked() || !is_location_valid {
return Err(WebGLError::InvalidOperation);
}

// TODO: Alternatively use ANGLE to obtain uniform type.
let uniform_type = self.get_active_uniform(0)?.Type();
let uniform_type = match uniform_type {
gl::FLOAT_VEC2 |
gl::FLOAT_VEC3 |
gl::FLOAT_VEC4 |
gl::FLOAT_MAT2 |
gl::FLOAT_MAT3 |
gl::FLOAT_MAT4 => UniformType::FloatVec(vec![]),

gl::INT_VEC2 |
gl::INT_VEC3 |
gl::INT_VEC4 => UniformType::IntVec(vec![]),

gl::BOOL_VEC2 |
gl::BOOL_VEC3 |
gl::BOOL_VEC4 => UniformType::BoolVec(vec![]),

gl::INT |
gl::SAMPLER_2D |
gl::SAMPLER_CUBE => UniformType::Int(0),

gl::BOOL => UniformType::Bool(false),

gl::FLOAT => UniformType::Float(0.),

_ => return Err(WebGLError::InvalidOperation),
};

let (sender, receiver) = webgl_channel().unwrap();
self.renderer.send(WebGLCommand::GetUniform(self.id().get(), location.id(), uniform_type, sender)).unwrap();
Ok(receiver.recv().unwrap())
}
}

impl Drop for WebGLProgram {
@@ -6,7 +6,7 @@ use byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt};
use canvas_traits::canvas::{byte_swap, multiply_u8_pixel};
use canvas_traits::webgl::{DOMToTextureCommand, Parameter, ProgramParameter};
use canvas_traits::webgl::{ShaderParameter, TexParameter, VertexAttrib, WebGLCommand};
use canvas_traits::webgl::{WebGLContextShareMode, WebGLError};
use canvas_traits::webgl::{WebGLContextShareMode, WebGLError, UniformType};
use canvas_traits::webgl::{WebGLFramebufferBindingRequest, WebGLMsg, WebGLMsgSender};
use canvas_traits::webgl::{WebGLResult, WebGLSLVersion, WebGLVersion};
use canvas_traits::webgl::{WebVRCommand, webgl_channel};
@@ -2579,6 +2579,44 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
})
}

#[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
unsafe fn GetUniform(
&self,
cx: *mut JSContext,
program: &WebGLProgram,
location: &WebGLUniformLocation
) -> JSVal {
let uniform = match program.get_uniform(location) {
Ok(uniform) => uniform,
Err(e) => {
self.webgl_error(e);
return NullValue();
}
};

match uniform {
UniformType::Int(value) => Int32Value(value),
UniformType::Bool(value) => BooleanValue(value),
UniformType::Float(value) => DoubleValue(value as f64),
UniformType::IntVec(values) => {
rooted!(in(cx) let mut result = UndefinedValue());
values.to_jsval(cx, result.handle_mut());
result.get()
},
UniformType::BoolVec(values) => {
rooted!(in(cx) let mut result = UndefinedValue());
values.to_jsval(cx, result.handle_mut());
result.get()
},
UniformType::FloatVec(values) => {
rooted!(in(cx) let mut result = UndefinedValue());
values.to_jsval(cx, result.handle_mut());
result.get()
},
}
}

#[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
unsafe fn GetVertexAttrib(&self, cx: *mut JSContext, index: u32, param: u32) -> JSVal {
@@ -580,7 +580,7 @@ interface WebGLRenderingContextBase

any getTexParameter(GLenum target, GLenum pname);

// any getUniform(WebGLProgram program, WebGLUniformLocation location);
any getUniform(WebGLProgram program, WebGLUniformLocation location);

WebGLUniformLocation? getUniformLocation(WebGLProgram program, DOMString name);

@@ -45,9 +45,6 @@
[WebGL test #19: getError expected: INVALID_OPERATION. Was NO_ERROR : after evaluating: contextA.getShaderSource(shaderB)]
expected: FAIL

[WebGL test #20: contextA.getUniform(programB, locationA) threw exception TypeError: contextA.getUniform is not a function]
expected: FAIL

[WebGL test #21: getError expected: INVALID_OPERATION. Was NO_ERROR : after evaluating: contextA.getUniformLocation(programB, 'u_modelViewProjMatrix')]
expected: FAIL

@@ -1,7 +1,4 @@
[methods.html]
[WebGL test #0: Property either does not exist or is not a function: getUniform]
expected: FAIL

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

This file was deleted.

@@ -1,26 +1,6 @@
[uniform-location.html]
type: testharness
[WebGL test #9: contextA.getUniform(programS, locationSx) should be 333. Threw exception TypeError: contextA.getUniform is not a function]
expected: FAIL

[WebGL test #10: contextA.getUniform(programS, locationArray0) should be 4. Threw exception TypeError: contextA.getUniform is not a function]
expected: FAIL

[WebGL test #11: contextA.getUniform(programS, locationArray1) should be 5. Threw exception TypeError: contextA.getUniform is not a function]
expected: FAIL

[WebGL test #14: contextA.getUniform(programV, locationVec4) should be 1,2,3,4. Threw exception TypeError: contextA.getUniform is not a function]
expected: FAIL

[WebGL test #20: getError expected: INVALID_OPERATION. Was NO_ERROR : after evaluating: contextA.uniform1i(locationSx, 3)]
expected: FAIL

[WebGL test #21: contextA.getUniform(programS, locationSx) threw exception TypeError: contextA.getUniform is not a function]
expected: FAIL

[WebGL test #24: contextA.getUniform(programS, locationSx) should be 3. Threw exception TypeError: contextA.getUniform is not a function]
expected: FAIL

[WebGL test #25: contextA.getUniform(programS, locationArray0) should be 123. Threw exception TypeError: contextA.getUniform is not a function]
expected: FAIL

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.