forked from mirrors/gecko-dev
The first commit allows to cleanup the gl resources of the webgl task earlier if they aren't being used. Right now all resources were cleaned up when the context was destroyed, so I think this is a slightly better approach. The second commit bumps rust-offscreen-rendering-context to remove the duplicated glutin dependency. The third one tries to reenable the webgl reftests. Since the errored builds are deleted, It's the only way I can try to troubleshoot it. Source-Repo: https://github.com/servo/servo Source-Revision: 3282174a9941ec1f8d8821dfac44b850b77e7668
153 lines
5.2 KiB
Rust
153 lines
5.2 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* 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 canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLError, WebGLResult};
|
|
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 ipc_channel::ipc::{self, IpcSender};
|
|
use std::cell::Cell;
|
|
|
|
pub enum TexParameterValue {
|
|
Float(f32),
|
|
Int(i32),
|
|
}
|
|
|
|
#[dom_struct]
|
|
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>,
|
|
}
|
|
|
|
impl WebGLTexture {
|
|
fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32) -> WebGLTexture {
|
|
WebGLTexture {
|
|
webgl_object: WebGLObject::new_inherited(),
|
|
id: id,
|
|
target: Cell::new(None),
|
|
is_deleted: Cell::new(false),
|
|
renderer: renderer,
|
|
}
|
|
}
|
|
|
|
pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
|
|
-> Option<Root<WebGLTexture>> {
|
|
let (sender, receiver) = ipc::channel().unwrap();
|
|
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateTexture(sender))).unwrap();
|
|
|
|
let result = receiver.recv().unwrap();
|
|
result.map(|texture_id| WebGLTexture::new(global, renderer, *texture_id))
|
|
}
|
|
|
|
pub fn new(global: GlobalRef, renderer: IpcSender<CanvasMsg>, id: u32) -> Root<WebGLTexture> {
|
|
reflect_dom_object(box WebGLTexture::new_inherited(renderer, id), global, WebGLTextureBinding::Wrap)
|
|
}
|
|
}
|
|
|
|
|
|
impl WebGLTexture {
|
|
pub fn id(&self) -> u32 {
|
|
self.id
|
|
}
|
|
|
|
// NB: Only valid texture targets come here
|
|
pub 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(())
|
|
}
|
|
|
|
pub fn delete(&self) {
|
|
if !self.is_deleted.get() {
|
|
self.is_deleted.set(true);
|
|
let _ = self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteTexture(self.id)));
|
|
}
|
|
}
|
|
|
|
/// We have to follow the conversion rules for GLES 2.0. See:
|
|
/// https://www.khronos.org/webgl/public-mailing-list/archives/1008/msg00014.html
|
|
///
|
|
pub 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();
|
|
Ok(())
|
|
},
|
|
|
|
_ => 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();
|
|
Ok(())
|
|
},
|
|
|
|
_ => 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();
|
|
Ok(())
|
|
},
|
|
|
|
_ => Err(WebGLError::InvalidEnum),
|
|
}
|
|
},
|
|
|
|
_ => Err(WebGLError::InvalidEnum),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Drop for WebGLTexture {
|
|
fn drop(&mut self) {
|
|
self.delete();
|
|
}
|
|
}
|