mirror of
https://github.com/servo/servo.git
synced 2025-06-08 08:33:26 +00:00
webgl: Make bind* calls more spec-compliant
This commit is contained in:
parent
b1765c6882
commit
42bd43a696
8 changed files with 72 additions and 37 deletions
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg};
|
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg, WebGLShaderParameter, WebGLFramebufferBindingRequest};
|
||||||
use euclid::size::Size2D;
|
use euclid::size::Size2D;
|
||||||
use core::nonzero::NonZero;
|
use core::nonzero::NonZero;
|
||||||
use gleam::gl;
|
use gleam::gl;
|
||||||
|
@ -109,8 +109,8 @@ impl WebGLPaintTask {
|
||||||
self.delete_shader(id),
|
self.delete_shader(id),
|
||||||
CanvasWebGLMsg::BindBuffer(target, id) =>
|
CanvasWebGLMsg::BindBuffer(target, id) =>
|
||||||
self.bind_buffer(target, id),
|
self.bind_buffer(target, id),
|
||||||
CanvasWebGLMsg::BindFramebuffer(target, id) =>
|
CanvasWebGLMsg::BindFramebuffer(target, request) =>
|
||||||
self.bind_framebuffer(target, id),
|
self.bind_framebuffer(target, request),
|
||||||
CanvasWebGLMsg::BindRenderbuffer(target, id) =>
|
CanvasWebGLMsg::BindRenderbuffer(target, id) =>
|
||||||
self.bind_renderbuffer(target, id),
|
self.bind_renderbuffer(target, id),
|
||||||
CanvasWebGLMsg::BindTexture(target, id) =>
|
CanvasWebGLMsg::BindTexture(target, id) =>
|
||||||
|
@ -329,7 +329,13 @@ impl WebGLPaintTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bind_framebuffer(&self, target: u32, id: u32) {
|
fn bind_framebuffer(&self, target: u32, request: WebGLFramebufferBindingRequest) {
|
||||||
|
let id = match request {
|
||||||
|
WebGLFramebufferBindingRequest::Explicit(id) => id,
|
||||||
|
WebGLFramebufferBindingRequest::Default =>
|
||||||
|
self.gl_context.borrow_draw_buffer().unwrap().get_framebuffer(),
|
||||||
|
};
|
||||||
|
|
||||||
gl::bind_framebuffer(target, id);
|
gl::bind_framebuffer(target, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,14 @@ pub enum CanvasMsg {
|
||||||
WebGL(CanvasWebGLMsg),
|
WebGL(CanvasWebGLMsg),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum CanvasCommonMsg {
|
||||||
|
Close,
|
||||||
|
Recreate(Size2D<i32>),
|
||||||
|
SendPixelContents(Sender<Vec<u8>>),
|
||||||
|
SendNativeSurface(Sender<NativeSurface>),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum Canvas2dMsg {
|
pub enum Canvas2dMsg {
|
||||||
Arc(Point2D<f32>, f32, f32, f32, bool),
|
Arc(Point2D<f32>, f32, f32, f32, bool),
|
||||||
|
@ -102,7 +110,7 @@ pub enum CanvasWebGLMsg {
|
||||||
DeleteProgram(u32),
|
DeleteProgram(u32),
|
||||||
DeleteShader(u32),
|
DeleteShader(u32),
|
||||||
BindBuffer(u32, u32),
|
BindBuffer(u32, u32),
|
||||||
BindFramebuffer(u32, u32),
|
BindFramebuffer(u32, WebGLFramebufferBindingRequest),
|
||||||
BindRenderbuffer(u32, u32),
|
BindRenderbuffer(u32, u32),
|
||||||
BindTexture(u32, u32),
|
BindTexture(u32, u32),
|
||||||
DrawArrays(u32, i32, i32),
|
DrawArrays(u32, i32, i32),
|
||||||
|
@ -132,6 +140,12 @@ pub enum WebGLError {
|
||||||
|
|
||||||
pub type WebGLResult<T> = Result<T, WebGLError>;
|
pub type WebGLResult<T> = Result<T, WebGLError>;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum WebGLFramebufferBindingRequest {
|
||||||
|
Explicit(u32),
|
||||||
|
Default,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum WebGLShaderParameter {
|
pub enum WebGLShaderParameter {
|
||||||
Int(i32),
|
Int(i32),
|
||||||
|
@ -139,15 +153,6 @@ pub enum WebGLShaderParameter {
|
||||||
Invalid,
|
Invalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum CanvasCommonMsg {
|
|
||||||
Close,
|
|
||||||
Recreate(Size2D<i32>),
|
|
||||||
SendPixelContents(Sender<Vec<u8>>),
|
|
||||||
SendNativeSurface(Sender<NativeSurface>),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CanvasGradientStop {
|
pub struct CanvasGradientStop {
|
||||||
pub offset: f64,
|
pub offset: f64,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
|
||||||
use dom::bindings::codegen::Bindings::WebGLBufferBinding;
|
use dom::bindings::codegen::Bindings::WebGLBufferBinding;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{Temporary, JSRef};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::utils::reflect_dom_object;
|
||||||
use dom::webglobject::WebGLObject;
|
use dom::webglobject::WebGLObject;
|
||||||
|
|
||||||
|
@ -44,9 +44,9 @@ impl WebGLBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait WebGLBufferHelpers {
|
pub trait WebGLBufferHelpers {
|
||||||
fn id(&self) -> u32;
|
fn id(self) -> u32;
|
||||||
fn bind(&self, target: u32);
|
fn bind(self, target: u32);
|
||||||
fn delete(&self);
|
fn delete(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WebGLBufferHelpers for &'a WebGLBuffer {
|
impl<'a> WebGLBufferHelpers for &'a WebGLBuffer {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::utils::reflect_dom_object;
|
||||||
use dom::webglobject::WebGLObject;
|
use dom::webglobject::WebGLObject;
|
||||||
|
|
||||||
use canvas_traits::{CanvasMsg, CanvasWebGLMsg};
|
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLFramebufferBindingRequest};
|
||||||
use std::sync::mpsc::{channel, Sender};
|
use std::sync::mpsc::{channel, Sender};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
|
@ -49,13 +49,15 @@ pub trait WebGLFramebufferHelpers {
|
||||||
fn delete(self);
|
fn delete(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WebGLFramebufferHelpers for JSRef<'a, WebGLFramebuffer> {
|
impl<'a> WebGLFramebufferHelpers for &'a WebGLFramebuffer {
|
||||||
fn id(self) -> u32 {
|
fn id(self) -> u32 {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind(self, target: u32) {
|
fn bind(self, target: u32) {
|
||||||
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindFramebuffer(target, self.id))).unwrap();
|
self.renderer.send(
|
||||||
|
CanvasMsg::WebGL(
|
||||||
|
CanvasWebGLMsg::BindFramebuffer(target, WebGLFramebufferBindingRequest::Explicit(self.id)))).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete(self) {
|
fn delete(self) {
|
||||||
|
|
|
@ -5,9 +5,17 @@
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
|
||||||
use dom::bindings::codegen::Bindings::WebGLProgramBinding;
|
use dom::bindings::codegen::Bindings::WebGLProgramBinding;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::utils::reflect_dom_object;
|
||||||
use dom::webglobject::WebGLObject;
|
use dom::webglobject::WebGLObject;
|
||||||
|
use dom::webglshader::{WebGLShader, WebGLShaderHelpers};
|
||||||
|
use dom::webglrenderingcontext::MAX_UNIFORM_AND_ATTRIBUTE_LEN;
|
||||||
|
|
||||||
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
|
||||||
|
|
||||||
|
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLResult, WebGLError};
|
||||||
|
use std::sync::mpsc::{channel, Sender};
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct WebGLProgram {
|
pub struct WebGLProgram {
|
||||||
|
@ -47,7 +55,7 @@ pub trait WebGLProgramHelpers {
|
||||||
fn delete(self);
|
fn delete(self);
|
||||||
fn link(self);
|
fn link(self);
|
||||||
fn use_program(self);
|
fn use_program(self);
|
||||||
fn attach_shader(self, shader: JSRef<WebGLShader>) -> WebGLResult<()>;
|
fn attach_shader(self, shader: &WebGLShader) -> WebGLResult<()>;
|
||||||
fn get_attrib_location(self, name: String) -> WebGLResult<Option<i32>>;
|
fn get_attrib_location(self, name: String) -> WebGLResult<Option<i32>>;
|
||||||
fn get_uniform_location(self, name: String) -> WebGLResult<Option<i32>>;
|
fn get_uniform_location(self, name: String) -> WebGLResult<Option<i32>>;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +80,7 @@ impl<'a> WebGLProgramHelpers for &'a WebGLProgram {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// glAttachShader
|
/// glAttachShader
|
||||||
fn attach_shader(self, shader: &'a WebGLShader) -> WebGLResult<()> {
|
fn attach_shader(self, shader: &WebGLShader) -> WebGLResult<()> {
|
||||||
let shader_slot = match shader.gl_type() {
|
let shader_slot = match shader.gl_type() {
|
||||||
constants::FRAGMENT_SHADER => &self.fragment_shader,
|
constants::FRAGMENT_SHADER => &self.fragment_shader,
|
||||||
constants::VERTEX_SHADER => &self.vertex_shader,
|
constants::VERTEX_SHADER => &self.vertex_shader,
|
||||||
|
@ -85,7 +93,7 @@ impl<'a> WebGLProgramHelpers for &'a WebGLProgram {
|
||||||
return Err(WebGLError::InvalidOperation);
|
return Err(WebGLError::InvalidOperation);
|
||||||
}
|
}
|
||||||
|
|
||||||
shader_slot.set(Some(JS::from_rooted(shader)));
|
shader_slot.set(Some(JS::from_ref(shader)));
|
||||||
|
|
||||||
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::AttachShader(self.id, shader.id()))).unwrap();
|
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::AttachShader(self.id, shader.id()))).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,13 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use canvas::webgl_paint_task::WebGLPaintTask;
|
use canvas::webgl_paint_task::WebGLPaintTask;
|
||||||
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg};
|
use canvas_traits::
|
||||||
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding;
|
{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg, WebGLError,
|
||||||
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{
|
WebGLShaderParameter, WebGLFramebufferBindingRequest};
|
||||||
WebGLContextAttributes, WebGLRenderingContextMethods, WebGLRenderingContextConstants};
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::
|
||||||
|
{self, WebGLContextAttributes, WebGLRenderingContextMethods};
|
||||||
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
|
||||||
|
|
||||||
use dom::bindings::global::{GlobalRef, GlobalField};
|
use dom::bindings::global::{GlobalRef, GlobalField};
|
||||||
use dom::bindings::js::{JS, LayoutJS, Root};
|
use dom::bindings::js::{JS, LayoutJS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
|
@ -22,7 +25,7 @@ use dom::webgluniformlocation::{WebGLUniformLocation, WebGLUniformLocationHelper
|
||||||
use euclid::size::Size2D;
|
use euclid::size::Size2D;
|
||||||
use js::jsapi::{JSContext, JSObject, RootedValue};
|
use js::jsapi::{JSContext, JSObject, RootedValue};
|
||||||
use js::jsapi::{JS_GetFloat32ArrayData, JS_GetObjectAsArrayBufferView};
|
use js::jsapi::{JS_GetFloat32ArrayData, JS_GetObjectAsArrayBufferView};
|
||||||
use js::jsval::{JSVal, UndefinedValue, NullValue, Int32Value};
|
use js::jsval::{JSVal, UndefinedValue, NullValue, Int32Value, BooleanValue};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
@ -116,10 +119,10 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
|
||||||
// TODO(ecoal95): Implement the missing parameters from the spec
|
// TODO(ecoal95): Implement the missing parameters from the spec
|
||||||
let mut rval = RootedValue::new(cx, UndefinedValue());
|
let mut rval = RootedValue::new(cx, UndefinedValue());
|
||||||
match parameter {
|
match parameter {
|
||||||
WebGLRenderingContextConstants::VERSION =>
|
constants::VERSION =>
|
||||||
"WebGL 1.0".to_jsval(cx, rval.handle_mut()),
|
"WebGL 1.0".to_jsval(cx, rval.handle_mut()),
|
||||||
WebGLRenderingContextConstants::RENDERER |
|
constants::RENDERER |
|
||||||
WebGLRenderingContextConstants::VENDOR =>
|
constants::VENDOR =>
|
||||||
"Mozilla/Servo".to_jsval(cx, rval.handle_mut()),
|
"Mozilla/Servo".to_jsval(cx, rval.handle_mut()),
|
||||||
_ => rval.ptr = NullValue(),
|
_ => rval.ptr = NullValue(),
|
||||||
}
|
}
|
||||||
|
@ -199,6 +202,9 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
|
||||||
fn BindBuffer(self, target: u32, buffer: Option<&WebGLBuffer>) {
|
fn BindBuffer(self, target: u32, buffer: Option<&WebGLBuffer>) {
|
||||||
if let Some(buffer) = buffer {
|
if let Some(buffer) = buffer {
|
||||||
buffer.bind(target)
|
buffer.bind(target)
|
||||||
|
} else {
|
||||||
|
// Unbind the current buffer
|
||||||
|
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, 0))).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +212,11 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
|
||||||
fn BindFramebuffer(self, target: u32, framebuffer: Option<&WebGLFramebuffer>) {
|
fn BindFramebuffer(self, target: u32, framebuffer: Option<&WebGLFramebuffer>) {
|
||||||
if let Some(framebuffer) = framebuffer {
|
if let Some(framebuffer) = framebuffer {
|
||||||
framebuffer.bind(target)
|
framebuffer.bind(target)
|
||||||
|
} else {
|
||||||
|
// Bind the default framebuffer
|
||||||
|
self.renderer.send(
|
||||||
|
CanvasMsg::WebGL(
|
||||||
|
CanvasWebGLMsg::BindFramebuffer(target, WebGLFramebufferBindingRequest::Default))).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +224,9 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
|
||||||
fn BindRenderbuffer(self, target: u32, renderbuffer: Option<&WebGLRenderbuffer>) {
|
fn BindRenderbuffer(self, target: u32, renderbuffer: Option<&WebGLRenderbuffer>) {
|
||||||
if let Some(renderbuffer) = renderbuffer {
|
if let Some(renderbuffer) = renderbuffer {
|
||||||
renderbuffer.bind(target)
|
renderbuffer.bind(target)
|
||||||
|
} else {
|
||||||
|
// Unbind the currently bound renderbuffer
|
||||||
|
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, 0))).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +239,7 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn BufferData(self, cx: *mut JSContext, target: u32, data: Option<*mut JSObject>, usage: u32) {
|
fn BufferData(self, _cx: *mut JSContext, target: u32, data: Option<*mut JSObject>, usage: u32) {
|
||||||
let data = match data {
|
let data = match data {
|
||||||
Some(data) => data,
|
Some(data) => data,
|
||||||
None => return,
|
None => return,
|
||||||
|
@ -447,7 +461,7 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
|
||||||
fn VertexAttribPointer(self, attrib_id: u32, size: i32, data_type: u32,
|
fn VertexAttribPointer(self, attrib_id: u32, size: i32, data_type: u32,
|
||||||
normalized: bool, stride: i32, offset: i64) {
|
normalized: bool, stride: i32, offset: i64) {
|
||||||
match data_type {
|
match data_type {
|
||||||
WebGLRenderingContextConstants::FLOAT => {
|
constants::FLOAT => {
|
||||||
let msg = CanvasMsg::WebGL(
|
let msg = CanvasMsg::WebGL(
|
||||||
CanvasWebGLMsg::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset));
|
CanvasWebGLMsg::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset));
|
||||||
self.renderer.send(msg).unwrap()
|
self.renderer.send(msg).unwrap()
|
||||||
|
|
|
@ -69,7 +69,7 @@ pub trait WebGLShaderHelpers {
|
||||||
fn set_source(self, src: String);
|
fn set_source(self, src: String);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WebGLShaderHelpers for JSRef<'a, WebGLShader> {
|
impl<'a> WebGLShaderHelpers for &'a WebGLShader {
|
||||||
fn id(self) -> u32 {
|
fn id(self) -> u32 {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub trait WebGLTextureHelpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WebGLTextureHelpers for &'a WebGLTexture {
|
impl<'a> WebGLTextureHelpers for &'a WebGLTexture {
|
||||||
fn id(&self) -> u32 {
|
fn id(self) -> u32 {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue