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

WebGL: Finish, Flush, DetachShader, GenerateMipmap #10215

Merged
merged 1 commit into from Apr 2, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

webgl: finish, flush, detachShader, generateMipmap, Uniform1i

  • Loading branch information
cbrewster committed Apr 2, 2016
commit 3fd7634f545871603577d83a08950ab6f7026f1c
@@ -266,6 +266,14 @@ macro_rules! make_nonzero_dimension_setter(
/// For use on non-jsmanaged types
/// Use #[derive(JSTraceable)] on JS managed types
macro_rules! no_jsmanaged_fields(
([$ty:ident; $count:expr]) => (
impl $crate::dom::bindings::trace::JSTraceable for [$ty; $count] {
#[inline]
fn trace(&self, _: *mut ::js::jsapi::JSTracer) {
// Do nothing
}
}
);
($($ty:ident),+) => (
$(
impl $crate::dom::bindings::trace::JSTraceable for $ty {
@@ -94,7 +94,10 @@ impl WebGLProgram {
let shader_slot = match shader.gl_type() {
constants::FRAGMENT_SHADER => &self.fragment_shader,
constants::VERTEX_SHADER => &self.vertex_shader,
_ => return Err(WebGLError::InvalidOperation),
_ => {
error!("detachShader: Unexpected shader type");
return Err(WebGLError::InvalidValue);
}
};

// TODO(emilio): Differentiate between same shader already assigned and other previous
@@ -110,6 +113,32 @@ impl WebGLProgram {
Ok(())
}

/// glDetachShader
pub fn detach_shader(&self, shader: &WebGLShader) -> WebGLResult<()> {
let shader_slot = match shader.gl_type() {
constants::FRAGMENT_SHADER => &self.fragment_shader,
constants::VERTEX_SHADER => &self.vertex_shader,
_ => {
error!("detachShader: Unexpected shader type");
return Err(WebGLError::InvalidValue);
}
};

match shader_slot.get() {
Some(ref attached_shader) if attached_shader.id() != shader.id() =>
return Err(WebGLError::InvalidOperation),
None =>
return Err(WebGLError::InvalidOperation),
_ => {}
}

shader_slot.set(None);

self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DetachShader(self.id, shader.id()))).unwrap();

Ok(())
}

/// glBindAttribLocation
pub fn bind_attrib_location(&self, index: u32, name: DOMString) -> WebGLResult<()> {
if name.len() > MAX_UNIFORM_AND_ATTRIBUTE_LEN {
@@ -181,6 +181,22 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
Root::from_ref(&*self.canvas)
}

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
fn Flush(&self) {
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Flush))
.unwrap();
}

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
fn Finish(&self) {
let (sender, receiver) = ipc::channel().unwrap();
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Finish(sender)))
.unwrap();
receiver.recv().unwrap()
}

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
fn DrawingBufferWidth(&self) -> i32 {
let (sender, receiver) = ipc::channel().unwrap();
@@ -331,6 +347,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
}

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
fn DetachShader(&self, program: Option<&WebGLProgram>, shader: Option<&WebGLShader>) {
if let Some(program) = program {
if let Some(shader) = shader {
handle_potential_webgl_error!(self, program.detach_shader(shader));
}
}
}

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
fn BindAttribLocation(&self, program: Option<&WebGLProgram>,
index: u32, name: DOMString) {
@@ -414,6 +439,21 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
}

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
fn GenerateMipmap(&self, target: u32) {
let slot = match target {
constants::TEXTURE_2D => &self.bound_texture_2d,
constants::TEXTURE_CUBE_MAP => &self.bound_texture_cube_map,

_ => return self.webgl_error(InvalidEnum),
};

match slot.get() {
Some(texture) => handle_potential_webgl_error!(self, texture.generate_mipmap()),
None => self.webgl_error(InvalidOperation)
}
}

#[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
fn BufferData(&self, _cx: *mut JSContext, target: u32, data: Option<*mut JSObject>, usage: u32) {
@@ -949,6 +989,25 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
.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()
}

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn Uniform1fv(&self,
uniform: Option<&WebGLUniformLocation>,
@@ -1107,7 +1166,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
internal_format: u32,
format: u32,
data_type: u32,
source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement >) {
source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>) {
let texture = match target {
constants::TEXTURE_2D => self.bound_texture_2d.get(),
constants::TEXTURE_CUBE_MAP => self.bound_texture_cube_map.get(),
@@ -1169,11 +1228,22 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
=> unimplemented!(),
};

if size.width < 0 || size.height < 0 || level < 0 {
self.webgl_error(WebGLError::InvalidOperation);
}

// TODO(emilio): Invert axis, convert colorspace, premultiply alpha if requested
let msg = WebGLCommand::TexImage2D(target, level, internal_format as i32,
size.width, size.height,
format, data_type, pixels);

// depth is always 1 when coming from html elements
handle_potential_webgl_error!(self, texture.unwrap().initialize(size.width as u32,
size.height as u32,
1,
internal_format,
level as u32));

self.ipc_renderer
.send(CanvasMsg::WebGL(msg))
.unwrap()
@@ -99,7 +99,7 @@ impl WebGLShader {
let validator = ShaderValidator::for_webgl(self.gl_type,
SHADER_OUTPUT_FORMAT,
&BuiltInResources::default()).unwrap();
match validator.compile_and_translate(&[source.as_bytes()]) {
match validator.compile_and_translate(&[source]) {
Ok(translated_source) => {
// NOTE: At this point we should be pretty sure that the compilation in the paint thread
// will succeed.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.