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

Refactor WebGL implementation to move logic inside the DOM interfaces #6380

Merged
merged 4 commits into from Jul 6, 2015
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

webgl: Make bind* calls more spec-compliant

  • Loading branch information
emilio committed Jul 6, 2015
commit 42bd43a696939c3259284a01b8ef64aa13a9939c
@@ -2,7 +2,7 @@
* 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/. */

use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg};
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg, WebGLShaderParameter, WebGLFramebufferBindingRequest};
use euclid::size::Size2D;
use core::nonzero::NonZero;
use gleam::gl;
@@ -109,8 +109,8 @@ impl WebGLPaintTask {
self.delete_shader(id),
CanvasWebGLMsg::BindBuffer(target, id) =>
self.bind_buffer(target, id),
CanvasWebGLMsg::BindFramebuffer(target, id) =>
self.bind_framebuffer(target, id),
CanvasWebGLMsg::BindFramebuffer(target, request) =>
self.bind_framebuffer(target, request),
CanvasWebGLMsg::BindRenderbuffer(target, id) =>
self.bind_renderbuffer(target, id),
CanvasWebGLMsg::BindTexture(target, id) =>
@@ -329,7 +329,13 @@ impl WebGLPaintTask {
}

#[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);
}

@@ -37,6 +37,14 @@ pub enum CanvasMsg {
WebGL(CanvasWebGLMsg),
}

#[derive(Clone)]
pub enum CanvasCommonMsg {
Close,
Recreate(Size2D<i32>),
SendPixelContents(Sender<Vec<u8>>),
SendNativeSurface(Sender<NativeSurface>),
}

#[derive(Clone)]
pub enum Canvas2dMsg {
Arc(Point2D<f32>, f32, f32, f32, bool),
@@ -102,7 +110,7 @@ pub enum CanvasWebGLMsg {
DeleteProgram(u32),
DeleteShader(u32),
BindBuffer(u32, u32),
BindFramebuffer(u32, u32),
BindFramebuffer(u32, WebGLFramebufferBindingRequest),
BindRenderbuffer(u32, u32),
BindTexture(u32, u32),
DrawArrays(u32, i32, i32),
@@ -132,22 +140,19 @@ pub enum WebGLError {

pub type WebGLResult<T> = Result<T, WebGLError>;

#[derive(Clone)]
pub enum WebGLFramebufferBindingRequest {
Explicit(u32),
Default,
}

#[derive(Clone)]
pub enum WebGLShaderParameter {
Int(i32),
Bool(bool),
Invalid,
}

#[derive(Clone)]
pub enum CanvasCommonMsg {
Close,
Recreate(Size2D<i32>),
SendPixelContents(Sender<Vec<u8>>),
SendNativeSurface(Sender<NativeSurface>),
}


#[derive(Clone)]
pub struct CanvasGradientStop {
pub offset: f64,
@@ -5,7 +5,7 @@
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
use dom::bindings::codegen::Bindings::WebGLBufferBinding;
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::webglobject::WebGLObject;

@@ -44,9 +44,9 @@ impl WebGLBuffer {
}

pub trait WebGLBufferHelpers {
fn id(&self) -> u32;
fn bind(&self, target: u32);
fn delete(&self);
fn id(self) -> u32;
fn bind(self, target: u32);
fn delete(self);
}

impl<'a> WebGLBufferHelpers for &'a WebGLBuffer {
@@ -9,7 +9,7 @@ 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, WebGLFramebufferBindingRequest};
use std::sync::mpsc::{channel, Sender};
use std::cell::Cell;

@@ -49,13 +49,15 @@ pub trait WebGLFramebufferHelpers {
fn delete(self);
}

impl<'a> WebGLFramebufferHelpers for JSRef<'a, WebGLFramebuffer> {
impl<'a> WebGLFramebufferHelpers for &'a WebGLFramebuffer {
fn id(self) -> u32 {
self.id
}

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) {
@@ -5,9 +5,17 @@
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
use dom::bindings::codegen::Bindings::WebGLProgramBinding;
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::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]
pub struct WebGLProgram {
@@ -47,7 +55,7 @@ pub trait WebGLProgramHelpers {
fn delete(self);
fn link(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_uniform_location(self, name: String) -> WebGLResult<Option<i32>>;
}
@@ -72,7 +80,7 @@ impl<'a> WebGLProgramHelpers for &'a WebGLProgram {
}

/// glAttachShader
fn attach_shader(self, shader: &'a WebGLShader) -> WebGLResult<()> {
fn attach_shader(self, shader: &WebGLShader) -> WebGLResult<()> {
let shader_slot = match shader.gl_type() {
constants::FRAGMENT_SHADER => &self.fragment_shader,
constants::VERTEX_SHADER => &self.vertex_shader,
@@ -85,7 +93,7 @@ impl<'a> WebGLProgramHelpers for &'a WebGLProgram {
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();

@@ -3,10 +3,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use canvas::webgl_paint_task::WebGLPaintTask;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg};
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{
WebGLContextAttributes, WebGLRenderingContextMethods, WebGLRenderingContextConstants};
use canvas_traits::
{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg, WebGLError,
WebGLShaderParameter, WebGLFramebufferBindingRequest};
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::js::{JS, LayoutJS, Root};
use dom::bindings::utils::{Reflector, reflect_dom_object};
@@ -22,7 +25,7 @@ use dom::webgluniformlocation::{WebGLUniformLocation, WebGLUniformLocationHelper
use euclid::size::Size2D;
use js::jsapi::{JSContext, JSObject, RootedValue};
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::ptr;
use std::slice;
@@ -116,10 +119,10 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// TODO(ecoal95): Implement the missing parameters from the spec
let mut rval = RootedValue::new(cx, UndefinedValue());
match parameter {
WebGLRenderingContextConstants::VERSION =>
constants::VERSION =>
"WebGL 1.0".to_jsval(cx, rval.handle_mut()),
WebGLRenderingContextConstants::RENDERER |
WebGLRenderingContextConstants::VENDOR =>
constants::RENDERER |
constants::VENDOR =>
"Mozilla/Servo".to_jsval(cx, rval.handle_mut()),
_ => rval.ptr = NullValue(),
}
@@ -199,20 +202,31 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
fn BindBuffer(self, target: u32, buffer: Option<&WebGLBuffer>) {
if let Some(buffer) = buffer {
buffer.bind(target)
} else {
// Unbind the current buffer
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, 0))).unwrap()
}
}

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
fn BindFramebuffer(self, target: u32, framebuffer: Option<&WebGLFramebuffer>) {
if let Some(framebuffer) = framebuffer {
framebuffer.bind(target)
} else {
// Bind the default framebuffer
self.renderer.send(
CanvasMsg::WebGL(
CanvasWebGLMsg::BindFramebuffer(target, WebGLFramebufferBindingRequest::Default))).unwrap()
}
}

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
fn BindRenderbuffer(self, target: u32, renderbuffer: Option<&WebGLRenderbuffer>) {
if let Some(renderbuffer) = renderbuffer {
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
#[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 {
Some(data) => data,
None => return,
@@ -447,7 +461,7 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
fn VertexAttribPointer(self, attrib_id: u32, size: i32, data_type: u32,
normalized: bool, stride: i32, offset: i64) {
match data_type {
WebGLRenderingContextConstants::FLOAT => {
constants::FLOAT => {
let msg = CanvasMsg::WebGL(
CanvasWebGLMsg::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset));
self.renderer.send(msg).unwrap()
@@ -69,7 +69,7 @@ pub trait WebGLShaderHelpers {
fn set_source(self, src: String);
}

impl<'a> WebGLShaderHelpers for JSRef<'a, WebGLShader> {
impl<'a> WebGLShaderHelpers for &'a WebGLShader {
fn id(self) -> u32 {
self.id
}
@@ -50,7 +50,7 @@ pub trait WebGLTextureHelpers {
}

impl<'a> WebGLTextureHelpers for &'a WebGLTexture {
fn id(&self) -> u32 {
fn id(self) -> u32 {
self.id
}

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