mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31:30 +11:00
Implement better handling for pixel formats
This commit is contained in:
parent
dfbf2adf4a
commit
6bec85e0cc
53
src/lib.rs
53
src/lib.rs
|
@ -170,6 +170,21 @@ pub enum MouseCursor {
|
||||||
RowResize,
|
RowResize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Describes a possible format. Unused.
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub struct PixelFormat {
|
||||||
|
pub red_bits: u8,
|
||||||
|
pub green_bits: u8,
|
||||||
|
pub blue_bits: u8,
|
||||||
|
pub alpha_bits: u8,
|
||||||
|
pub depth_bits: u8,
|
||||||
|
pub stencil_bits: u8,
|
||||||
|
pub stereoscopy: bool,
|
||||||
|
pub double_buffer: bool,
|
||||||
|
pub multisampling: Option<u16>,
|
||||||
|
pub srgb: bool,
|
||||||
|
}
|
||||||
|
|
||||||
/// Attributes
|
/// Attributes
|
||||||
struct BuilderAttribs<'a> {
|
struct BuilderAttribs<'a> {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -239,5 +254,41 @@ impl<'a> BuilderAttribs<'a> {
|
||||||
|
|
||||||
(new_attribs, sharing)
|
(new_attribs, sharing)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
fn choose_pixel_format<T, I>(&self, iter: I) -> (T, PixelFormat)
|
||||||
|
where I: Iterator<Item=(T, PixelFormat)>, T: Clone
|
||||||
|
{
|
||||||
|
let mut current_result = None;
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if format.alpha_bits < self.alpha_bits.unwrap_or(0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if format.depth_bits < self.depth_bits.unwrap_or(0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if format.stencil_bits < self.stencil_bits.unwrap_or(0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !format.stereoscopy && self.stereoscopy {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.multisampling.is_some() && format.multisampling.is_none() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_result = Some((id, format));
|
||||||
|
}
|
||||||
|
|
||||||
|
current_result.expect("Could not find compliant pixel format")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use super::MonitorID;
|
||||||
use BuilderAttribs;
|
use BuilderAttribs;
|
||||||
use CreationError;
|
use CreationError;
|
||||||
use CreationError::OsError;
|
use CreationError::OsError;
|
||||||
|
use PixelFormat;
|
||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
|
@ -130,31 +131,11 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O
|
||||||
|
|
||||||
// getting the pixel format that we will use
|
// getting the pixel format that we will use
|
||||||
let pixel_format = {
|
let pixel_format = {
|
||||||
// initializing a PIXELFORMATDESCRIPTOR that indicates what we want
|
let formats = enumerate_native_pixel_formats(dummy_hdc);
|
||||||
|
let (id, _) = builder.choose_pixel_format(formats.into_iter().map(|(a, b)| (b, a)));
|
||||||
|
|
||||||
let mut output: winapi::PIXELFORMATDESCRIPTOR = unsafe { mem::zeroed() };
|
let mut output: winapi::PIXELFORMATDESCRIPTOR = unsafe { mem::zeroed() };
|
||||||
output.nSize = mem::size_of::<winapi::PIXELFORMATDESCRIPTOR>() as winapi::WORD;
|
if unsafe { gdi32::DescribePixelFormat(dummy_hdc, id,
|
||||||
output.nVersion = 1;
|
|
||||||
output.dwFlags = winapi::PFD_DRAW_TO_WINDOW | winapi::PFD_DOUBLEBUFFER |
|
|
||||||
winapi::PFD_SUPPORT_OPENGL | winapi::PFD_GENERIC_ACCELERATED;
|
|
||||||
output.iPixelType = winapi::PFD_TYPE_RGBA;
|
|
||||||
output.cColorBits = 24;
|
|
||||||
output.cAlphaBits = 8;
|
|
||||||
output.cAccumBits = 0;
|
|
||||||
output.cDepthBits = 24;
|
|
||||||
output.cStencilBits = 8;
|
|
||||||
output.cAuxBuffers = 0;
|
|
||||||
output.iLayerType = winapi::PFD_MAIN_PLANE;
|
|
||||||
|
|
||||||
let pf_index = unsafe { gdi32::ChoosePixelFormat(dummy_hdc, &output) };
|
|
||||||
|
|
||||||
if pf_index == 0 {
|
|
||||||
let err = Err(OsError(format!("ChoosePixelFormat function failed: {}",
|
|
||||||
os::error_string(os::errno() as usize))));
|
|
||||||
unsafe { user32::DestroyWindow(dummy_window); }
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if unsafe { gdi32::DescribePixelFormat(dummy_hdc, pf_index,
|
|
||||||
mem::size_of::<winapi::PIXELFORMATDESCRIPTOR>() as winapi::UINT, &mut output) } == 0
|
mem::size_of::<winapi::PIXELFORMATDESCRIPTOR>() as winapi::UINT, &mut output) } == 0
|
||||||
{
|
{
|
||||||
let err = Err(OsError(format!("DescribePixelFormat function failed: {}",
|
let err = Err(OsError(format!("DescribePixelFormat function failed: {}",
|
||||||
|
@ -475,3 +456,56 @@ fn create_context(extra: Option<(&gl::wgl_extra::Wgl, &BuilderAttribs<'static>)>
|
||||||
|
|
||||||
Ok(ctxt as winapi::HGLRC)
|
Ok(ctxt as winapi::HGLRC)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn enumerate_native_pixel_formats(hdc: winapi::HDC) -> Vec<(PixelFormat, libc::c_int)> {
|
||||||
|
let size_of_pxfmtdescr = mem::size_of::<winapi::PIXELFORMATDESCRIPTOR>() as u32;
|
||||||
|
let num = unsafe { gdi32::DescribePixelFormat(hdc, 1, size_of_pxfmtdescr, ptr::null_mut()) };
|
||||||
|
|
||||||
|
let mut result = Vec::new();
|
||||||
|
|
||||||
|
for index in (0 .. num) {
|
||||||
|
let mut output: winapi::PIXELFORMATDESCRIPTOR = unsafe { mem::zeroed() };
|
||||||
|
|
||||||
|
if unsafe { gdi32::DescribePixelFormat(hdc, index, size_of_pxfmtdescr,
|
||||||
|
&mut output) } == 0
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output.dwFlags & winapi::PFD_DRAW_TO_WINDOW) == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (output.dwFlags & winapi::PFD_SUPPORT_OPENGL) == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output.dwFlags & winapi::PFD_GENERIC_ACCELERATED) == 0 &&
|
||||||
|
(output.dwFlags & winapi::PFD_GENERIC_FORMAT) == 0
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if output.iPixelType != winapi::PFD_TYPE_RGBA {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push((PixelFormat {
|
||||||
|
red_bits: output.cRedBits,
|
||||||
|
green_bits: output.cGreenBits,
|
||||||
|
blue_bits: output.cBlueBits,
|
||||||
|
alpha_bits: output.cAlphaBits,
|
||||||
|
depth_bits: output.cDepthBits,
|
||||||
|
stencil_bits: output.cStencilBits,
|
||||||
|
stereoscopy: (output.dwFlags & winapi::PFD_STEREO) != 0,
|
||||||
|
double_buffer: (output.dwFlags & winapi::PFD_DOUBLEBUFFER) != 0,
|
||||||
|
multisampling: None,
|
||||||
|
srgb: false,
|
||||||
|
}, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enumerate_arb_pixel_formats(extra: &gl::wgl_extra::Wgl, hdc: winapi::HDC) -> Vec<PixelFormat> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue