diff options
author | bors-servo <metajack+bors@gmail.com> | 2015-08-25 09:23:00 -0600 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2015-08-25 09:23:00 -0600 |
commit | a109a333f1f95d4fc677b29e3613b2615514c080 (patch) | |
tree | 3509f4dc996823641e384972baf7a22aa5ad1ad9 /components/script/dom/webgltexture.rs | |
parent | 4d0b4a7b8cda681d1cd6b6cd8e690c0793532d0b (diff) | |
parent | 6341c77700fa5f914c32c6153e9c532bc69474fd (diff) | |
download | servo-a109a333f1f95d4fc677b29e3613b2615514c080.tar.gz servo-a109a333f1f95d4fc677b29e3613b2615514c080.zip |
Auto merge of #6770 - ecoal95:webgl-again, r=jdm
Add multiple WebGL calls and improve error detection
Since it probably won't merge until multiprocess lands, I plan to use this PR to keep improving WebGL support until it can land.
Main TODOs are integration of tests, since it seems https://github.com/KhronosGroup/WebGL/issues/1105 is going nowhere, adding missing calls and proper painting via native surfaces instead of readback.
I can't resolve conflicts right now because of time but I will do it soon.
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6770)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom/webgltexture.rs')
-rw-r--r-- | components/script/dom/webgltexture.rs | 93 |
1 files changed, 90 insertions, 3 deletions
diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs index 579c196e90a..7fa44178155 100644 --- a/components/script/dom/webgltexture.rs +++ b/components/script/dom/webgltexture.rs @@ -3,21 +3,29 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl +use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use dom::bindings::codegen::Bindings::WebGLTextureBinding; use dom::bindings::global::GlobalRef; use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; -use canvas_traits::{CanvasMsg, CanvasWebGLMsg}; +use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLError, WebGLResult}; use ipc_channel::ipc::{self, IpcSender}; use std::cell::Cell; +pub enum TexParameterValue { + Float(f32), + Int(i32), +} + #[dom_struct] #[derive(HeapSizeOf)] pub struct WebGLTexture { webgl_object: WebGLObject, id: u32, + /// The target to which this texture was bound the first time + target: Cell<Option<u32>>, is_deleted: Cell<bool>, #[ignore_heap_size_of = "Defined in ipc-channel"] renderer: IpcSender<CanvasMsg>, @@ -28,6 +36,7 @@ impl WebGLTexture { WebGLTexture { webgl_object: WebGLObject::new_inherited(), id: id, + target: Cell::new(None), is_deleted: Cell::new(false), renderer: renderer, } @@ -49,8 +58,12 @@ impl WebGLTexture { pub trait WebGLTextureHelpers { fn id(self) -> u32; - fn bind(self, target: u32); + fn bind(self, target: u32) -> WebGLResult<()>; fn delete(self); + fn tex_parameter(self, + target: u32, + name: u32, + value: TexParameterValue) -> WebGLResult<()>; } impl<'a> WebGLTextureHelpers for &'a WebGLTexture { @@ -58,8 +71,19 @@ impl<'a> WebGLTextureHelpers for &'a WebGLTexture { self.id } - fn bind(self, target: u32) { + // NB: Only valid texture targets come here + fn bind(self, target: u32) -> WebGLResult<()> { + if let Some(previous_target) = self.target.get() { + if target != previous_target { + return Err(WebGLError::InvalidOperation); + } + } else { + self.target.set(Some(target)); + } + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindTexture(self.id, target))).unwrap(); + + Ok(()) } fn delete(self) { @@ -68,4 +92,67 @@ impl<'a> WebGLTextureHelpers for &'a WebGLTexture { self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteTexture(self.id))).unwrap(); } } + + /// We have to follow the conversion rules for GLES 2.0. See: + /// https://www.khronos.org/webgl/public-mailing-list/archives/1008/msg00014.html + /// + fn tex_parameter(self, + target: u32, + name: u32, + value: TexParameterValue) -> WebGLResult<()> { + let (int_value, _float_value) = match value { + TexParameterValue::Int(int_value) => (int_value, int_value as f32), + TexParameterValue::Float(float_value) => (float_value as i32, float_value), + }; + + match name { + constants::TEXTURE_MIN_FILTER => { + match int_value as u32 { + constants::NEAREST | + constants::LINEAR | + constants::NEAREST_MIPMAP_NEAREST | + constants::LINEAR_MIPMAP_NEAREST | + constants::NEAREST_MIPMAP_LINEAR | + constants::LINEAR_MIPMAP_LINEAR => { + self.renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::TexParameteri(target, name, int_value))) + .unwrap(); + return Ok(()); + }, + + _ => return Err(WebGLError::InvalidEnum), + } + }, + constants::TEXTURE_MAG_FILTER => { + match int_value as u32 { + constants::NEAREST | + constants::LINEAR => { + self.renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::TexParameteri(target, name, int_value))) + .unwrap(); + return Ok(()); + }, + + _ => return Err(WebGLError::InvalidEnum), + } + }, + constants::TEXTURE_WRAP_S | + constants::TEXTURE_WRAP_T => { + match int_value as u32 { + constants::CLAMP_TO_EDGE | + constants::MIRRORED_REPEAT | + constants::REPEAT => { + self.renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::TexParameteri(target, name, int_value))) + .unwrap(); + return Ok(()); + }, + + _ => return Err(WebGLError::InvalidEnum), + } + }, + + _ => return Err(WebGLError::InvalidEnum), + } + } } |