diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/api/cocoa/mod.rs | 140 | ||||
| -rw-r--r-- | src/api/egl/mod.rs | 6 | ||||
| -rw-r--r-- | src/api/win32/init.rs | 10 | ||||
| -rw-r--r-- | src/api/x11/mod.rs | 6 | ||||
| -rw-r--r-- | src/lib.rs | 6 | 
5 files changed, 114 insertions, 54 deletions
| diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs index a6bdfa3..28d5ecc 100644 --- a/src/api/cocoa/mod.rs +++ b/src/api/cocoa/mod.rs @@ -156,6 +156,7 @@ pub struct Window {      view: IdRef,      window: IdRef,      context: IdRef, +    pixel_format: PixelFormat,      delegate: WindowDelegate,  } @@ -326,21 +327,23 @@ impl Window {              Some(app) => app,              None      => { return Err(OsError(format!("Couldn't create NSApplication"))); },          }; -        let window = match Window::create_window(builder.dimensions.unwrap_or((800, 600)), -                                                 &*builder.title, -                                                 &builder.monitor) + +        let window = match Window::create_window(&builder)          {              Some(window) => window,              None         => { return Err(OsError(format!("Couldn't create NSWindow"))); },          }; +          let view = match Window::create_view(*window) {              Some(view) => view,              None       => { return Err(OsError(format!("Couldn't create NSView"))); },          }; -        let context = match Window::create_context(*view, &builder) { -            Some(context) => context, -            None          => { return Err(OsError(format!("Couldn't create OpenGL context"))); }, +        // TODO: perhaps we should return error from create_context so we can +        // determine the cause of failure and possibly recover? +        let (context, pf) = match Window::create_context(*view, &builder) { +            (Some(context), Some(pf)) => (context, pf), +            (_,             _)        => { return Err(OsError(format!("Couldn't create OpenGL context"))); },          };          unsafe { @@ -365,6 +368,7 @@ impl Window {              view: view,              window: window,              context: context, +            pixel_format: pf,              delegate: WindowDelegate::new(ds),          }; @@ -384,9 +388,9 @@ impl Window {          }      } -    fn create_window(dimensions: (u32, u32), title: &str, monitor: &Option<MonitorID>) -> Option<IdRef> { +    fn create_window(builder: &BuilderAttribs) -> Option<IdRef> {          unsafe {  -            let screen = match *monitor { +            let screen = match builder.monitor {                  Some(ref monitor_id) => {                      let native_id = match monitor_id.get_native_identifier() {                          NativeMonitorId::Numeric(num) => num, @@ -418,7 +422,7 @@ impl Window {              let frame = match screen {                  Some(screen) => NSScreen::frame(screen),                  None => { -                    let (width, height) = dimensions; +                    let (width, height) = builder.dimensions.unwrap_or((800, 600));                      NSRect::new(NSPoint::new(0., 0.), NSSize::new(width as f64, height as f64))                  }              }; @@ -439,7 +443,7 @@ impl Window {                  NO,              ));              window.non_nil().map(|window| { -                let title = IdRef::new(NSString::alloc(nil).init_str(title)); +                let title = IdRef::new(NSString::alloc(nil).init_str(&builder.title));                  window.setTitle_(*title);                  window.setAcceptsMouseMovedEvents_(YES);                  if screen.is_some() { @@ -464,7 +468,7 @@ impl Window {          }      } -    fn create_context(view: id, builder: &BuilderAttribs) -> Option<IdRef> { +    fn create_context(view: id, builder: &BuilderAttribs) -> (Option<IdRef>, Option<PixelFormat>) {          let profile = match builder.gl_version {              GlRequest::Latest => NSOpenGLProfileVersion4_1Core as u32,              GlRequest::Specific(Api::OpenGl, (1 ... 2, _)) => NSOpenGLProfileVersionLegacy as u32, @@ -477,39 +481,99 @@ impl Window {              GlRequest::GlThenGles { opengl_version: (3, 1 ... 2), .. } => NSOpenGLProfileVersion3_2Core as u32,              GlRequest::GlThenGles { .. } => NSOpenGLProfileVersion4_1Core as u32,          }; -        unsafe { -            let mut attributes = vec![ -                NSOpenGLPFADoubleBuffer as u32, -                NSOpenGLPFAClosestPolicy as u32, -                NSOpenGLPFAColorSize as u32, 24, -                NSOpenGLPFAAlphaSize as u32, 8, -                NSOpenGLPFADepthSize as u32, 24, -                NSOpenGLPFAStencilSize as u32, 8, -                NSOpenGLPFAOpenGLProfile as u32, profile, -            ]; - -            if let Some(samples) = builder.multisampling { -                attributes = attributes + &[ -                    NSOpenGLPFAMultisample as u32, -                    NSOpenGLPFASampleBuffers as u32, 1, -                    NSOpenGLPFASamples as u32, samples as u32, -                ]; -            } -            attributes.push(0); +        // NOTE: OS X no longer has the concept of setting individual +        // color component's bit size. Instead we can only specify the +        // full color size and hope for the best. Another hiccup is that +        // `NSOpenGLPFAColorSize` also includes `NSOpenGLPFAAlphaSize`, +        // so we have to account for that as well. +        let alpha_depth = builder.alpha_bits.unwrap_or(8); +        let color_depth = builder.color_bits.unwrap_or(24) + alpha_depth; + +        let mut attributes = vec![ +            NSOpenGLPFADoubleBuffer as u32, +            NSOpenGLPFAClosestPolicy as u32, +            NSOpenGLPFAColorSize as u32, color_depth as u32, +            NSOpenGLPFAAlphaSize as u32, alpha_depth as u32, +            NSOpenGLPFADepthSize as u32, builder.depth_bits.unwrap_or(24) as u32, +            NSOpenGLPFAStencilSize as u32, builder.stencil_bits.unwrap_or(8) as u32, +            NSOpenGLPFAOpenGLProfile as u32, profile, +        ]; + +        // A color depth higher than 64 implies we're using either 16-bit +        // floats or 32-bit floats and OS X requires a flag to be set +        // accordingly.  +        if color_depth >= 64 { +            attributes.push(NSOpenGLPFAColorFloat as u32); +        } + +        builder.multisampling.map(|samples| { +            attributes.push(NSOpenGLPFAMultisample as u32); +            attributes.push(NSOpenGLPFASampleBuffers as u32); attributes.push(1); +            attributes.push(NSOpenGLPFASamples as u32); attributes.push(samples as u32); +        }); + +        // attribute list must be null terminated. +        attributes.push(0); +        unsafe {              let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&attributes)); -            pixelformat.non_nil().map(|pixelformat| { + +            if let Some(pixelformat) = pixelformat.non_nil() { + +                // TODO: Add context sharing                  let context = IdRef::new(NSOpenGLContext::alloc(nil).initWithFormat_shareContext_(*pixelformat, nil)); -                context.non_nil().map(|context| { -                    context.setView_(view); + +                if let Some(cxt) = context.non_nil() { +                    let pf = { +                        let getValues_forAttribute_forVirtualScreen_ = |fmt: id, +                                                                        vals: *mut GLint, +                                                                        attrib: NSOpenGLPixelFormatAttribute, +                                                                        screen: GLint| -> () { +                            msg_send![fmt, getValues:vals forAttribute:attrib forVirtualScreen:screen] +                        }; +                        let get_attr = |attrib: NSOpenGLPixelFormatAttribute| -> i32 { +                            let mut value = 0; +                            // TODO: Wait for servo/rust-cocoa/#85 to get merged +                            /*NSOpenGLPixelFormat::*/getValues_forAttribute_forVirtualScreen_( +                                *pixelformat, +                                &mut value, +                                attrib, +                                NSOpenGLContext::currentVirtualScreen(*cxt)); + +                            value +                        }; + +                        PixelFormat { +                            hardware_accelerated: get_attr(NSOpenGLPFAAccelerated) != 0, +                            color_bits: (get_attr(NSOpenGLPFAColorSize) - get_attr(NSOpenGLPFAAlphaSize)) as u8, +                            alpha_bits: get_attr(NSOpenGLPFAAlphaSize) as u8, +                            depth_bits: get_attr(NSOpenGLPFADepthSize) as u8, +                            stencil_bits: get_attr(NSOpenGLPFAStencilSize) as u8, +                            stereoscopy: get_attr(NSOpenGLPFAStereo) != 0, +                            double_buffer: get_attr(NSOpenGLPFADoubleBuffer) != 0, +                            multisampling: if get_attr(NSOpenGLPFAMultisample) > 0 { +                                Some(get_attr(NSOpenGLPFASamples) as u16) +                            } else { +                                None +                            }, +                            srgb: true, +                        } +                    }; + +                    cxt.setView_(view);                      if builder.vsync {                          let value = 1; -                        context.setValues_forParameter_(&value, NSOpenGLContextParameter::NSOpenGLCPSwapInterval); +                        cxt.setValues_forParameter_(&value, NSOpenGLContextParameter::NSOpenGLCPSwapInterval);                      } -                    context -                }) -            }).unwrap_or(None) + +                    (Some(cxt), Some(pf)) +                } else { +                    (None, None) +                } +            } else { +                (None, None) +            }          }      } @@ -654,7 +718,7 @@ impl Window {      }      pub fn get_pixel_format(&self) -> PixelFormat { -        unimplemented!(); +        self.pixel_format.clone()      }      pub fn set_window_resize_callback(&mut self, callback: Option<fn(u32, u32)>) { diff --git a/src/api/egl/mod.rs b/src/api/egl/mod.rs index 18e731c..9c8db62 100644 --- a/src/api/egl/mod.rs +++ b/src/api/egl/mod.rs @@ -298,9 +298,9 @@ unsafe fn enumerate_configs(egl: &ffi::egl::Egl, display: ffi::egl::types::EGLDi          result.push((config_id, PixelFormat {              hardware_accelerated: attrib!(egl, display, config_id, ffi::egl::CONFIG_CAVEAT)                                            != ffi::egl::SLOW_CONFIG as i32, -            red_bits: attrib!(egl, display, config_id, ffi::egl::RED_SIZE) as u8, -            green_bits: attrib!(egl, display, config_id, ffi::egl::BLUE_SIZE) as u8, -            blue_bits: attrib!(egl, display, config_id, ffi::egl::GREEN_SIZE) as u8, +            color_bits: attrib!(egl, display, config_id, ffi::egl::RED_SIZE) as u8 + +                        attrib!(egl, display, config_id, ffi::egl::BLUE_SIZE) as u8 + +                        attrib!(egl, display, config_id, ffi::egl::GREEN_SIZE) as u8,              alpha_bits: attrib!(egl, display, config_id, ffi::egl::ALPHA_SIZE) as u8,              depth_bits: attrib!(egl, display, config_id, ffi::egl::DEPTH_SIZE) as u8,              stencil_bits: attrib!(egl, display, config_id, ffi::egl::STENCIL_SIZE) as u8, diff --git a/src/api/win32/init.rs b/src/api/win32/init.rs index a9d77d1..39b9d97 100644 --- a/src/api/win32/init.rs +++ b/src/api/win32/init.rs @@ -438,9 +438,7 @@ unsafe fn enumerate_native_pixel_formats(hdc: &WindowWrapper) -> Vec<(PixelForma          result.push((PixelFormat {              hardware_accelerated: (output.dwFlags & winapi::PFD_GENERIC_FORMAT) == 0, -            red_bits: output.cRedBits, -            green_bits: output.cGreenBits, -            blue_bits: output.cBlueBits, +            color_bits: output.cRedBits + output.cGreenBits + output.cBlueBits,              alpha_bits: output.cAlphaBits,              depth_bits: output.cDepthBits,              stencil_bits: output.cStencilBits, @@ -489,9 +487,9 @@ unsafe fn enumerate_arb_pixel_formats(extra: &gl::wgl_extra::Wgl, hdc: &WindowWr          result.push((PixelFormat {              hardware_accelerated: true, -            red_bits: get_info(index, gl::wgl_extra::RED_BITS_ARB) as u8, -            green_bits: get_info(index, gl::wgl_extra::GREEN_BITS_ARB) as u8, -            blue_bits: get_info(index, gl::wgl_extra::BLUE_BITS_ARB) as u8, +            color_bits: get_info(index, gl::wgl_extra::RED_BITS_ARB) as u8 +  +                        get_info(index, gl::wgl_extra::GREEN_BITS_ARB) as u8 + +                        get_info(index, gl::wgl_extra::BLUE_BITS_ARB) as u8,              alpha_bits: get_info(index, gl::wgl_extra::ALPHA_BITS_ARB) as u8,              depth_bits: get_info(index, gl::wgl_extra::DEPTH_BITS_ARB) as u8,              stencil_bits: get_info(index, gl::wgl_extra::STENCIL_BITS_ARB) as u8, diff --git a/src/api/x11/mod.rs b/src/api/x11/mod.rs index 3dd90d3..6b528ab 100644 --- a/src/api/x11/mod.rs +++ b/src/api/x11/mod.rs @@ -411,9 +411,9 @@ impl Window {              PixelFormat {                  hardware_accelerated: true, -                red_bits: get_attrib(ffi::glx::RED_SIZE as libc::c_int) as u8, -                green_bits: get_attrib(ffi::glx::GREEN_SIZE as libc::c_int) as u8, -                blue_bits: get_attrib(ffi::glx::BLUE_SIZE as libc::c_int) as u8, +                color_bits: get_attrib(ffi::glx::RED_SIZE as libc::c_int) as u8 + +                            get_attrib(ffi::glx::GREEN_SIZE as libc::c_int) as u8 + +                            get_attrib(ffi::glx::BLUE_SIZE as libc::c_int) as u8,                  alpha_bits: get_attrib(ffi::glx::ALPHA_SIZE as libc::c_int) as u8,                  depth_bits: get_attrib(ffi::glx::DEPTH_SIZE as libc::c_int) as u8,                  stencil_bits: get_attrib(ffi::glx::STENCIL_SIZE as libc::c_int) as u8, @@ -211,9 +211,7 @@ pub enum CursorState {  #[derive(Debug, Clone)]  pub struct PixelFormat {      pub hardware_accelerated: bool, -    pub red_bits: u8, -    pub green_bits: u8, -    pub blue_bits: u8, +    pub color_bits: u8,      pub alpha_bits: u8,      pub depth_bits: u8,      pub stencil_bits: u8, @@ -306,7 +304,7 @@ impl<'a> BuilderAttribs<'a> {          // TODO: do this more properly          for (id, format) in iter { -            if format.red_bits + format.green_bits + format.blue_bits < self.color_bits.unwrap_or(0) { +            if format.color_bits < self.color_bits.unwrap_or(0) {                  continue;              } | 
