diff --git a/Cargo.toml b/Cargo.toml index 67458338..4d0407fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "offscreen_gl_context" license = "MIT / Apache-2.0" -version = "0.6.1" +version = "0.7.0" authors = ["Emilio Cobos Álvarez ", "The Servo Project Developers"] description = "Creation and manipulation of HW accelerated offscreen rendering contexts in multiple platforms. Originally intended for the Servo project's WebGL implementation." repository = "https://github.com/emilio/rust-offscreen-rendering-context" diff --git a/src/draw_buffer.rs b/src/draw_buffer.rs index f4be2742..3b879b0c 100644 --- a/src/draw_buffer.rs +++ b/src/draw_buffer.rs @@ -52,9 +52,6 @@ impl ColorAttachment { /// a depth or stencil buffer, depending on context /// requirements. pub struct DrawBuffer { - // See the comment in GLContext to see why this is safe, we never let a - // buffer outlive the context (we only return it by reference in - // borrow_draw_buffer). gl_: Rc, size: Size2D, framebuffer: GLuint, @@ -119,9 +116,10 @@ impl DrawBuffer { try!(draw_buffer.init(context, color_attachment_type)); - debug_assert!( - draw_buffer.gl().check_frame_buffer_status(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE); - debug_assert!(draw_buffer.gl().get_error() == gl::NO_ERROR); + debug_assert_eq!(draw_buffer.gl().check_frame_buffer_status(gl::FRAMEBUFFER), + gl::FRAMEBUFFER_COMPLETE); + debug_assert_eq!(draw_buffer.gl().get_error(), + gl::NO_ERROR); Ok(draw_buffer) } @@ -158,8 +156,6 @@ impl DrawBuffer { } fn gl(&self) -> &gl::Gl { - // See the comment on top the GLContext field to see why our usage of - // this is safe. &*self.gl_ } @@ -201,7 +197,7 @@ impl DrawBuffer { self.gl().bind_texture(gl::TEXTURE_2D, 0); - debug_assert!(self.gl().get_error() == gl::NO_ERROR); + debug_assert_eq!(self.gl().get_error(), gl::NO_ERROR); Some(ColorAttachment::Texture(texture)) }, @@ -228,7 +224,7 @@ impl DrawBuffer { fn attach_to_framebuffer(&mut self) -> Result<(), &'static str> { self.gl().bind_framebuffer(gl::FRAMEBUFFER, self.framebuffer); // NOTE: The assertion fails if the framebuffer is not bound - debug_assert!(self.gl().is_framebuffer(self.framebuffer) == gl::TRUE); + debug_assert_eq!(self.gl().is_framebuffer(self.framebuffer), gl::TRUE); match *self.color_attachment.as_ref().unwrap() { ColorAttachment::Renderbuffer(color_renderbuffer) => { @@ -236,7 +232,7 @@ impl DrawBuffer { gl::COLOR_ATTACHMENT0, gl::RENDERBUFFER, color_renderbuffer); - debug_assert!(self.gl().is_renderbuffer(color_renderbuffer) == gl::TRUE); + debug_assert_eq!(self.gl().is_renderbuffer(color_renderbuffer), gl::TRUE); }, ColorAttachment::Texture(texture_id) => { self.gl().framebuffer_texture_2d(gl::FRAMEBUFFER, @@ -251,7 +247,7 @@ impl DrawBuffer { gl::DEPTH_ATTACHMENT, gl::RENDERBUFFER, self.depth_renderbuffer); - debug_assert!(self.gl().is_renderbuffer(self.depth_renderbuffer) == gl::TRUE); + debug_assert_eq!(self.gl().is_renderbuffer(self.depth_renderbuffer), gl::TRUE); } if self.stencil_renderbuffer != 0 { @@ -259,7 +255,7 @@ impl DrawBuffer { gl::STENCIL_ATTACHMENT, gl::RENDERBUFFER, self.stencil_renderbuffer); - debug_assert!(self.gl().is_renderbuffer(self.stencil_renderbuffer) == gl::TRUE); + debug_assert_eq!(self.gl().is_renderbuffer(self.stencil_renderbuffer), gl::TRUE); } Ok(()) diff --git a/src/gl_context.rs b/src/gl_context.rs index a792faff..436b67ba 100644 --- a/src/gl_context.rs +++ b/src/gl_context.rs @@ -13,10 +13,6 @@ use ColorAttachmentType; /// This is a wrapper over a native headless GL context pub struct GLContext { - /// Immutable, always non-null, and owned by the context. - /// - /// Done this way so the buffer and attachments can have references to it, - /// which is safe because it's completely immutable. gl_: Rc, native_context: Native, /// This an abstraction over a custom framebuffer @@ -34,16 +30,22 @@ pub struct GLContext { impl GLContext where Native: NativeGLContextMethods, { - pub fn create(shared_with: Option<&Native::Handle>) -> Result { - Self::create_shared_with_dispatcher(shared_with, None) + pub fn create(api_type: gl::GlType, + shared_with: Option<&Native::Handle>) + -> Result { + Self::create_shared_with_dispatcher(api_type, shared_with, None) } - pub fn create_shared_with_dispatcher(shared_with: Option<&Native::Handle>, + pub fn create_shared_with_dispatcher(api_type: gl::GlType, + shared_with: Option<&Native::Handle>, dispatcher: Option>) -> Result { let native_context = try!(Native::create_shared_with_dispatcher(shared_with, dispatcher)); - // XXX how to handle GLES instantiation? - let gl_ = gl::GlFns::load_with(|s| GLContext::::get_proc_address(s) as *const _); + let gl_ = match api_type { + gl::GlType::Gl => gl::GlFns::load_with(|s| Self::get_proc_address(s) as *const _), + gl::GlType::Gles => gl::GlesFns::load_with(|s| Self::get_proc_address(s) as *const _), + }; + try!(native_context.make_current()); let attributes = GLContextAttributes::any(); let formats = GLFormats::detect(&attributes); @@ -73,11 +75,13 @@ impl GLContext pub fn new(size: Size2D, attributes: GLContextAttributes, color_attachment_type: ColorAttachmentType, + api_type: gl::GlType, shared_with: Option<&Native::Handle>) -> Result { Self::new_shared_with_dispatcher(size, attributes, color_attachment_type, + api_type, shared_with, None) } @@ -85,12 +89,16 @@ impl GLContext pub fn new_shared_with_dispatcher(size: Size2D, attributes: GLContextAttributes, color_attachment_type: ColorAttachmentType, + api_type: gl::GlType, shared_with: Option<&Native::Handle>, dispatcher: Option>) -> Result { // We create a headless context with a dummy size, we're painting to the // draw_buffer's framebuffer anyways. - let mut context = try!(Self::create_shared_with_dispatcher(shared_with, dispatcher)); + let mut context = + try!(Self::create_shared_with_dispatcher(api_type, + shared_with, + dispatcher)); context.formats = GLFormats::detect(&attributes); context.attributes = attributes; @@ -103,9 +111,10 @@ impl GLContext #[inline(always)] pub fn with_default_color_attachment(size: Size2D, attributes: GLContextAttributes, + api_type: gl::GlType, shared_with: Option<&Native::Handle>) -> Result { - GLContext::new(size, attributes, ColorAttachmentType::default(), shared_with) + Self::new(size, attributes, ColorAttachmentType::default(), api_type, shared_with) } #[inline(always)] diff --git a/src/tests.rs b/src/tests.rs index 8f4f1042..230d827b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -54,6 +54,7 @@ fn test_unbinding() { let ctx = GLContext::::new(Size2D::new(256, 256), GLContextAttributes::default(), ColorAttachmentType::Renderbuffer, + gl::GlType::default(), None).unwrap(); assert!(NativeGLContext::current_handle().is_some()); @@ -67,6 +68,7 @@ fn test_renderbuffer_color_attachment() { test_gl_context(&GLContext::::new(Size2D::new(256, 256), GLContextAttributes::default(), ColorAttachmentType::Renderbuffer, + gl::GlType::default(), None).unwrap()); } @@ -76,6 +78,7 @@ fn test_texture_color_attachment() { let context = GLContext::::new(size, GLContextAttributes::default(), ColorAttachmentType::Texture, + gl::GlType::default(), None).unwrap(); test_gl_context(&context); @@ -101,6 +104,7 @@ fn test_sharing() { let primary = GLContext::::new(size, GLContextAttributes::default(), ColorAttachmentType::Texture, + gl::GlType::default(), None).unwrap(); let primary_texture_id = primary.borrow_draw_buffer().unwrap().get_bound_texture_id().unwrap(); @@ -109,6 +113,7 @@ fn test_sharing() { let secondary = GLContext::::new(size, GLContextAttributes::default(), ColorAttachmentType::Texture, + gl::GlType::default(), Some(&primary.handle())).unwrap(); // Paint the second context red @@ -149,6 +154,7 @@ fn test_multithread_render() { let primary = GLContext::::new(size, GLContextAttributes::default(), ColorAttachmentType::Texture, + gl::GlType::default(), None).unwrap(); test_gl_context(&primary); let (tx, rx) = mpsc::channel(); @@ -156,9 +162,10 @@ fn test_multithread_render() { thread::spawn(move ||{ //create the context in a different thread let secondary = GLContext::::new(size, - GLContextAttributes::default(), - ColorAttachmentType::Texture, - None).unwrap(); + GLContextAttributes::default(), + ColorAttachmentType::Texture, + gl::GlType::default(), + None).unwrap(); secondary.make_current().unwrap(); assert!(secondary.is_current()); //render green adn test pixels @@ -195,6 +202,7 @@ fn test_multithread_sharing() { let primary = GLContext::::new(size, GLContextAttributes::default(), ColorAttachmentType::Texture, + gl::GlType::default(), None).unwrap(); primary.make_current().unwrap(); @@ -213,6 +221,7 @@ fn test_multithread_sharing() { let secondary = GLContext::::new(size, GLContextAttributes::default(), ColorAttachmentType::Texture, + gl::GlType::default(), Some(&primary_handle)).unwrap(); // Make the context current on this thread only secondary.make_current().unwrap(); @@ -258,6 +267,7 @@ fn test_limits() { let context = GLContext::::new(size, GLContextAttributes::default(), ColorAttachmentType::Texture, + gl::GlType::default(), None).unwrap(); assert!(context.borrow_limits().max_vertex_attribs != 0); } @@ -271,6 +281,7 @@ fn test_no_alpha() { let context = GLContext::::new(size, attributes, ColorAttachmentType::Texture, + gl::GlType::default(), None).unwrap(); assert!(context.borrow_limits().max_vertex_attribs != 0); } @@ -284,6 +295,7 @@ fn test_no_depth() { let context = GLContext::::new(size, attributes, ColorAttachmentType::Texture, + gl::GlType::default(), None).unwrap(); assert!(context.borrow_limits().max_vertex_attribs != 0); } @@ -298,6 +310,7 @@ fn test_no_depth_no_alpha() { let context = GLContext::::new(size, attributes, ColorAttachmentType::Texture, + gl::GlType::default(), None).unwrap(); assert!(context.borrow_limits().max_vertex_attribs != 0); } @@ -313,6 +326,7 @@ fn test_no_premul_alpha() { let context = GLContext::::new(size, attributes, ColorAttachmentType::Texture, + gl::GlType::default(), None).unwrap(); assert!(context.borrow_limits().max_vertex_attribs != 0); } @@ -328,6 +342,7 @@ fn test_in_a_row() { let context = GLContext::::new(size, attributes.clone(), ColorAttachmentType::Texture, + gl::GlType::default(), None).unwrap(); let handle = context.handle(); @@ -335,11 +350,13 @@ fn test_in_a_row() { GLContext::::new(size, attributes.clone(), ColorAttachmentType::Texture, + gl::GlType::default(), Some(&handle)).unwrap(); GLContext::::new(size, attributes.clone(), ColorAttachmentType::Texture, + gl::GlType::default(), Some(&handle)).unwrap(); } @@ -348,5 +365,6 @@ fn test_zero_size() { GLContext::::new(Size2D::new(0, 320), GLContextAttributes::default(), ColorAttachmentType::Texture, + gl::GlType::default(), None).unwrap(); }