diff options
author | tomaka <pierre.krieger1708@gmail.com> | 2015-07-25 16:12:33 +0200 |
---|---|---|
committer | tomaka <pierre.krieger1708@gmail.com> | 2015-07-25 16:12:33 +0200 |
commit | 37b4089015c8d42d4d225c38aab1c1a95933f5f6 (patch) | |
tree | d91649ae6faebc524e830557c21761f37ea1bf61 | |
parent | 752593ebefee7e97d69edccb44e7a50a059879b0 (diff) | |
parent | 2d4c382f0bfd48f69ef5efbb4f8693857f38c8cc (diff) | |
download | glutin-37b4089015c8d42d4d225c38aab1c1a95933f5f6.tar.gz glutin-37b4089015c8d42d4d225c38aab1c1a95933f5f6.zip |
Merge pull request #547 from tomaka/better-choice
Better choice for the pixel format
-rw-r--r-- | src/lib.rs | 83 |
1 files changed, 64 insertions, 19 deletions
@@ -68,6 +68,7 @@ pub use window::{AvailableMonitorsIter, MonitorID, get_available_monitors, get_p pub use native_monitor::NativeMonitorId; use std::io; +use std::cmp::Ordering; mod api; mod platform; @@ -426,56 +427,100 @@ impl<'a> BuilderAttribs<'a> { fn choose_pixel_format<T, I>(&self, iter: I) -> Result<(T, PixelFormat), CreationError> where I: IntoIterator<Item=(T, PixelFormat)>, T: Clone { - let mut current_result = None; - let mut current_software_result = None; - - // TODO: do this more properly - for (id, format) in iter { + // filtering formats that don't match the requirements + let iter = iter.into_iter().filter(|&(_, ref format)| { if format.color_bits < self.color_bits.unwrap_or(0) { - continue; + return false; } if format.alpha_bits < self.alpha_bits.unwrap_or(0) { - continue; + return false; } if format.depth_bits < self.depth_bits.unwrap_or(0) { - continue; + return false; } if format.stencil_bits < self.stencil_bits.unwrap_or(0) { - continue; + return false; } if !format.stereoscopy && self.stereoscopy { - continue; + return false; } if let Some(req_ms) = self.multisampling { match format.multisampling { Some(val) if val >= req_ms => (), - _ => continue + _ => return false } } else { if format.multisampling.is_some() { - continue; + return false; } } if let Some(srgb) = self.srgb { if srgb != format.srgb { - continue; + return false; } } - current_software_result = Some((id.clone(), format.clone())); - if format.hardware_accelerated { - current_result = Some((id, format)); + true + }); + + // sorting so that the preferred format comes first + let mut formats = iter.collect::<Vec<_>>(); + formats.sort_by(|&(_, ref left), &(_, ref right)| { + // prefer hardware-accelerated formats + if left.hardware_accelerated && !right.hardware_accelerated { + return Ordering::Less; + } else if right.hardware_accelerated && !left.hardware_accelerated { + return Ordering::Greater; } - } - current_result.or(current_software_result) - .ok_or(CreationError::NoAvailablePixelFormat) + // prefer sRGB formats + if left.srgb && !right.srgb { + return Ordering::Less; + } else if right.srgb && !left.srgb { + return Ordering::Greater; + } + + // prefer formats with the highest color+alpha bits + if left.color_bits + left.alpha_bits != right.color_bits + right.alpha_bits { + return (right.color_bits + right.alpha_bits) + .cmp(&(left.color_bits + left.alpha_bits)); + } + + // prefer double-buffering formats + if left.double_buffer && !right.double_buffer { + return Ordering::Less; + } else if right.double_buffer && !left.double_buffer { + return Ordering::Greater; + } + + // prefer formats with the highest depth bits + if left.depth_bits != right.depth_bits { + return (right.depth_bits).cmp(&left.depth_bits); + } + + // prefer formats with the highest stencil bits + if left.stencil_bits != right.stencil_bits { + return (right.stencil_bits).cmp(&left.stencil_bits); + } + + // prefer formats with multisampling + if left.multisampling.is_some() && right.multisampling.is_none() { + return Ordering::Less; + } else if right.multisampling.is_some() && left.multisampling.is_none() { + return Ordering::Greater; + } + + // default + return Ordering::Equal; + }); + + formats.into_iter().next().ok_or(CreationError::NoAvailablePixelFormat) } } |