Skip to content

Commit

Permalink
[macos] find latest GL version
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Dec 15, 2017
1 parent 4ca5c27 commit 8f37fe4
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 49 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Cargo.lock
target/
.DS_Store
*~
#*#
5 changes: 4 additions & 1 deletion src/headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ impl<'a> HeadlessRendererBuilder<'a> {
pub fn new(width: u32, height: u32) -> HeadlessRendererBuilder<'a> {
HeadlessRendererBuilder {
dimensions: (width, height),
pf_reqs: Default::default(),
pf_reqs: PixelFormatRequirements {
hardware_accelerated: None,
.. Default::default()
},
opengl: Default::default(),
platform_specific: Default::default(),
}
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#[macro_use]
extern crate lazy_static;

#[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
#[macro_use]
extern crate shared_library;

Expand Down
7 changes: 3 additions & 4 deletions src/platform/macos/headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ impl HeadlessContext {
_: &PlatformSpecificHeadlessBuilderAttributes)
-> Result<HeadlessContext, CreationError>
{
let gl_profile = helpers::get_gl_profile(opengl)?;
let attributes = helpers::build_nsattributes(pf_reqs, gl_profile)?;
let context = unsafe {

let attributes = try!(helpers::build_nsattributes(pf_reqs, opengl));

let pixelformat = NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&attributes);
if pixelformat == nil {
return Err(OsError(format!("Could not create the pixel format")));
Expand All @@ -42,7 +41,7 @@ impl HeadlessContext {
};

let headless = HeadlessContext {
context: context,
context,
};

Ok(headless)
Expand Down
98 changes: 60 additions & 38 deletions src/platform/macos/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,59 @@ use GlRequest;
use PixelFormatRequirements;
use ReleaseBehavior;
use cocoa::appkit::*;

pub fn build_nsattributes<T>(pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&T>)
-> Result<Vec<u32>, CreationError> {

let profile = match (opengl.version, opengl.version.to_gl_version(), opengl.profile) {

use cocoa::base::nil;

pub fn get_gl_profile<T>(
opengl: &GlAttributes<&T>
) -> Result<NSOpenGLPFAOpenGLProfiles, CreationError> {
let version = opengl.version.to_gl_version();
// first, compatibility profile support is strict
if opengl.profile == Some(GlProfile::Compatibility) {
// Note: we are not using ranges because of a rust bug that should be fixed here:
// https://github.com/rust-lang/rust/pull/27050

(GlRequest::Latest, _, Some(GlProfile::Compatibility)) => NSOpenGLProfileVersionLegacy as u32,
(GlRequest::Latest, _, _) => unsafe {
if NSAppKitVersionNumber.floor() >= NSAppKitVersionNumber10_9 {
NSOpenGLProfileVersion4_1Core as u32
} else if NSAppKitVersionNumber.floor() >= NSAppKitVersionNumber10_7 {
NSOpenGLProfileVersion3_2Core as u32
} else {
NSOpenGLProfileVersionLegacy as u32
if version.unwrap_or((2, 1)) < (3, 2) {
Ok(NSOpenGLProfileVersionLegacy)
} else {
Err(CreationError::OpenGlVersionNotSupported)
}
} else if let Some(v) = version {
// second, process exact requested version, if any
if v < (3, 2) {
Err(CreationError::OpenGlVersionNotSupported)
} else if v == (3, 2) {
Ok(NSOpenGLProfileVersion3_2Core)
} else {
Ok(NSOpenGLProfileVersion4_1Core)
}
} else if let GlRequest::Latest = opengl.version {
// now, find the latest supported version automatically
let mut attributes = vec![
// Note: we assume here that non-accelerated contexts don't care
NSOpenGLPFAAccelerated as u32,
NSOpenGLPFAOpenGLProfile as u32,
0, // this is where we put the test profile
0,
];
for &profile in &[NSOpenGLProfileVersion4_1Core, NSOpenGLProfileVersion3_2Core] {
attributes[2] = profile as u32;
let id = unsafe {
NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&attributes)
};
if id != nil {
unsafe { msg_send![id, release] }
return Ok(profile);
}
},

(_, Some((1, _)), _) => NSOpenGLProfileVersionLegacy as u32,
(_, Some((2, _)), _) => NSOpenGLProfileVersionLegacy as u32,
(_, Some((3, 0)), _) => NSOpenGLProfileVersionLegacy as u32,
(_, Some((3, 1)), _) => NSOpenGLProfileVersionLegacy as u32,
(_, Some((3, 2)), _) => NSOpenGLProfileVersion3_2Core as u32,
(_, Some((3, _)), Some(GlProfile::Compatibility)) => return Err(CreationError::OpenGlVersionNotSupported),
(_, Some((3, _)), _) => NSOpenGLProfileVersion4_1Core as u32,
(_, Some((4, _)), Some(GlProfile::Compatibility)) => return Err(CreationError::OpenGlVersionNotSupported),
(_, Some((4, _)), _) => NSOpenGLProfileVersion4_1Core as u32,
_ => return Err(CreationError::OpenGlVersionNotSupported),
};
}
// nothing else to do
Ok(NSOpenGLProfileVersionLegacy)
} else {
Err(CreationError::OpenGlVersionNotSupported)
}
}

pub fn build_nsattributes(
pf_reqs: &PixelFormatRequirements, profile: NSOpenGLPFAOpenGLProfiles
) -> Result<Vec<u32>, CreationError> {
// 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
Expand All @@ -46,19 +67,24 @@ pub fn build_nsattributes<T>(pf_reqs: &PixelFormatRequirements, opengl: &GlAttri
let alpha_depth = pf_reqs.alpha_bits.unwrap_or(8);
let color_depth = pf_reqs.color_bits.unwrap_or(24) + alpha_depth;

// TODO: handle hardware_accelerated parameter of pf_reqs

let mut attributes = vec![
NSOpenGLPFADoubleBuffer as u32,
NSOpenGLPFAOpenGLProfile as u32, profile as u32,
NSOpenGLPFAClosestPolicy as u32,
NSOpenGLPFAColorSize as u32, color_depth as u32,
NSOpenGLPFAAlphaSize as u32, alpha_depth as u32,
NSOpenGLPFADepthSize as u32, pf_reqs.depth_bits.unwrap_or(24) as u32,
NSOpenGLPFAStencilSize as u32, pf_reqs.stencil_bits.unwrap_or(8) as u32,
NSOpenGLPFAAllowOfflineRenderers as u32,
NSOpenGLPFAOpenGLProfile as u32, profile,
];

if let Some(true) = pf_reqs.hardware_accelerated {
attributes.push(NSOpenGLPFAAccelerated as u32);
}

if let Some(true) = pf_reqs.double_buffer {
attributes.push(NSOpenGLPFADoubleBuffer as u32);
}

if pf_reqs.release_behavior != ReleaseBehavior::Flush {
return Err(CreationError::NoAvailablePixelFormat);
}
Expand All @@ -67,19 +93,15 @@ pub fn build_nsattributes<T>(pf_reqs: &PixelFormatRequirements, opengl: &GlAttri
unimplemented!(); // TODO:
}

if pf_reqs.double_buffer == Some(false) {
unimplemented!(); // TODO:
}

if pf_reqs.float_color_buffer {
attributes.push(NSOpenGLPFAColorFloat as u32);
}

pf_reqs.multisampling.map(|samples| {
if let Some(samples) = pf_reqs.multisampling {
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);
Expand Down
12 changes: 6 additions & 6 deletions src/platform/macos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ impl Context {

let view = window.get_nsview() as id;

let attributes = try!(helpers::build_nsattributes(pf_reqs, gl_attr));
let gl_profile = helpers::get_gl_profile(gl_attr)?;
let attributes = helpers::build_nsattributes(pf_reqs, gl_profile)?;
unsafe {
let pixel_format = IdRef::new(NSOpenGLPixelFormat::alloc(nil)
.initWithAttributes_(&attributes));
Expand Down Expand Up @@ -138,13 +139,12 @@ impl Context {
unsafe {
let pool = NSAutoreleasePool::new(nil);
let current = NSOpenGLContext::currentContext(nil);
let mut res = false;
if current != nil {
let res = if current != nil {
let is_equal: BOOL = msg_send![current, isEqual:*self.gl];
res = is_equal != NO
is_equal != NO
} else {
res = false
}
false
};
let _: () = msg_send![pool, release];
res
}
Expand Down

0 comments on commit 8f37fe4

Please sign in to comment.