From cf252c29b4c3a0f4705bc92598c858b895b94f22 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Sun, 1 Mar 2015 10:33:25 +0100 Subject: [PATCH 1/3] Use the WGL API to determine extended pixel format, plus fix creation --- src/lib.rs | 1 + src/win32/init.rs | 68 +++++++++++++++++++++++------------------------ 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4ab577a3..138f87ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -195,6 +195,7 @@ pub enum MouseCursor { /// Describes a possible format. Unused. #[allow(missing_docs)] +#[derive(Debug)] pub struct PixelFormat { pub red_bits: u8, pub green_bits: u8, diff --git a/src/win32/init.rs b/src/win32/init.rs index d4688206..6fdafea6 100644 --- a/src/win32/init.rs +++ b/src/win32/init.rs @@ -99,9 +99,8 @@ fn init(title: Vec, builder: BuilderAttribs<'static>, builder_sharelists: O // adjusting the window coordinates using the style unsafe { user32::AdjustWindowRectEx(&mut rect, style, 0, ex_style) }; - // getting the address of wglCreateContextAttribsARB and the pixel format - // that we will use - let (extra_functions, pixel_format) = { + // getting the address of wglCreateContextAttribsARB + let extra_functions = { // creating a dummy invisible window for GL initialization let dummy_window = unsafe { let handle = user32::CreateWindowExW(ex_style, class_name.as_ptr(), @@ -132,32 +131,11 @@ fn init(title: Vec, builder: BuilderAttribs<'static>, builder_sharelists: O hdc }; - // getting the pixel format that we will use - let pixel_format = { + // getting the pixel format that we will use and setting it + { 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() }; - if unsafe { gdi32::DescribePixelFormat(dummy_hdc, id, - mem::size_of::() as winapi::UINT, &mut output) } == 0 - { - let err = Err(OsError(format!("DescribePixelFormat function failed: {}", - os::error_string(os::errno())))); - unsafe { user32::DestroyWindow(dummy_window); } - return err; - } - - output - }; - - // calling SetPixelFormat - unsafe { - if gdi32::SetPixelFormat(dummy_hdc, 1, &pixel_format) == 0 { - let err = Err(OsError(format!("SetPixelFormat function failed: {}", - os::error_string(os::errno())))); - user32::DestroyWindow(dummy_window); - return err; - } + try!(set_pixel_format(dummy_hdc, id)); } // creating the dummy OpenGL context @@ -186,7 +164,7 @@ fn init(title: Vec, builder: BuilderAttribs<'static>, builder_sharelists: O unsafe { user32::DestroyWindow(dummy_window); } // returning the address - (extra_functions, pixel_format) + extra_functions }; // creating the real window this time @@ -233,13 +211,15 @@ fn init(title: Vec, builder: BuilderAttribs<'static>, builder_sharelists: O }; // calling SetPixelFormat - unsafe { - if gdi32::SetPixelFormat(hdc, 1, &pixel_format) == 0 { - let err = Err(OsError(format!("SetPixelFormat function failed: {}", - os::error_string(os::errno())))); - user32::DestroyWindow(real_window); - return err; - } + { + let formats = if extra_functions.GetPixelFormatAttribivARB.is_loaded() { + enumerate_arb_pixel_formats(&extra_functions, hdc) + } else { + enumerate_native_pixel_formats(hdc) + }; + + let (id, _) = builder.choose_pixel_format(formats.into_iter().map(|(a, b)| (b, a))); + try!(set_pixel_format(hdc, id)); } // creating the OpenGL context @@ -512,6 +492,24 @@ fn enumerate_arb_pixel_formats(extra: &gl::wgl_extra::Wgl, hdc: winapi::HDC) result } +fn set_pixel_format(hdc: winapi::HDC, id: libc::c_int) -> Result<(), CreationError> { + let mut output: winapi::PIXELFORMATDESCRIPTOR = unsafe { mem::zeroed() }; + + if unsafe { gdi32::DescribePixelFormat(hdc, id, + mem::size_of::() as winapi::UINT, &mut output) } == 0 + { + return Err(OsError(format!("DescribePixelFormat function failed: {}", + os::error_string(os::errno())))); + } + + if unsafe { gdi32::SetPixelFormat(hdc, id, &output) } == 0 { + return Err(OsError(format!("SetPixelFormat function failed: {}", + os::error_string(os::errno())))); + } + + Ok(()) +} + fn load_opengl32_dll() -> Result { let name = "opengl32.dll".utf16_units().chain(Some(0).into_iter()) .collect::>().as_ptr(); From 7ba8fdf3f33b9502007901a2399f915047cac8fc Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Sun, 1 Mar 2015 11:07:46 +0100 Subject: [PATCH 2/3] Fix creating non-hardware-accelerated contexts --- src/lib.rs | 5 +++++ src/win32/init.rs | 9 +++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 138f87ba..ecb69807 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -197,6 +197,7 @@ pub enum MouseCursor { #[allow(missing_docs)] #[derive(Debug)] pub struct PixelFormat { + pub hardware_accelerated: bool, pub red_bits: u8, pub green_bits: u8, pub blue_bits: u8, @@ -286,6 +287,10 @@ impl<'a> BuilderAttribs<'a> { // TODO: do this more properly for (id, format) in iter { + if !format.hardware_accelerated { + continue; + } + if format.red_bits + format.green_bits + format.blue_bits < self.color_bits.unwrap_or(0) { continue; } diff --git a/src/win32/init.rs b/src/win32/init.rs index 6fdafea6..260b0ab0 100644 --- a/src/win32/init.rs +++ b/src/win32/init.rs @@ -411,13 +411,8 @@ fn enumerate_native_pixel_formats(hdc: winapi::HDC) -> Vec<(PixelFormat, libc::c 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 - { + if (output.dwFlags & winapi::PFD_SUPPORT_OPENGL) == 0 { continue; } @@ -426,6 +421,7 @@ fn enumerate_native_pixel_formats(hdc: winapi::HDC) -> Vec<(PixelFormat, libc::c } result.push((PixelFormat { + hardware_accelerated: (output.dwFlags & winapi::PFD_GENERIC_FORMAT) == 0, red_bits: output.cRedBits, green_bits: output.cGreenBits, blue_bits: output.cBlueBits, @@ -476,6 +472,7 @@ fn enumerate_arb_pixel_formats(extra: &gl::wgl_extra::Wgl, hdc: winapi::HDC) } 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, From 42d38e66ab51c1095d65683494dfabf80552bf92 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Sun, 1 Mar 2015 11:46:58 +0100 Subject: [PATCH 3/3] Allow using non-hardware-accelerated pixel formats --- src/lib.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ecb69807..10727d1a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -195,7 +195,7 @@ pub enum MouseCursor { /// Describes a possible format. Unused. #[allow(missing_docs)] -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct PixelFormat { pub hardware_accelerated: bool, pub red_bits: u8, @@ -284,13 +284,10 @@ impl<'a> BuilderAttribs<'a> { where I: Iterator, T: Clone { let mut current_result = None; + let mut current_software_result = None; // TODO: do this more properly for (id, format) in iter { - if !format.hardware_accelerated { - continue; - } - if format.red_bits + format.green_bits + format.blue_bits < self.color_bits.unwrap_or(0) { continue; } @@ -315,9 +312,13 @@ impl<'a> BuilderAttribs<'a> { continue; } - current_result = Some((id, format)); + current_software_result = Some((id.clone(), format.clone())); + if format.hardware_accelerated { + current_result = Some((id, format)); + } } - current_result.expect("Could not find compliant pixel format") + current_result.or(current_software_result) + .expect("Could not find compliant pixel format") } }