@@ -3,26 +3,17 @@ use std::rc::Rc;
33use windows_sys:: {
44 core:: s,
55 Win32 :: {
6- Foundation :: { FreeLibrary , HMODULE , HWND } ,
7- Graphics :: {
8- Gdi :: { GetDC , ReleaseDC , HDC } ,
9- OpenGL :: {
10- wglCreateContext, wglDeleteContext, wglGetProcAddress, wglMakeCurrent,
11- ChoosePixelFormat , DescribePixelFormat , SetPixelFormat , SwapBuffers , HGLRC ,
12- PFD_DOUBLEBUFFER , PFD_DRAW_TO_WINDOW , PFD_MAIN_PLANE , PFD_SUPPORT_OPENGL ,
13- PFD_TYPE_RGBA , PIXELFORMATDESCRIPTOR ,
14- } ,
15- } ,
6+ Foundation :: { FreeLibrary , HMODULE } ,
7+ Graphics :: OpenGL :: { wglGetProcAddress, wglMakeCurrent} ,
168 System :: LibraryLoader :: { GetProcAddress , LoadLibraryA } ,
17- UI :: WindowsAndMessaging :: { DestroyWindow , UnregisterClassW } ,
189 } ,
1910} ;
2011
2112use crate :: gl:: * ;
22- use crate :: wrappers:: win32:: window:: { with_dummy_window , HWnd , PixelFormat } ;
23- // See https://www.khronos.org/registry/OpenGL/extensions/ARB/WGL_ARB_create_context.txt
24-
25- type WglCreateContextAttribsARB = extern "system" fn ( HDC , HGLRC , * const i32 ) -> HGLRC ;
13+ use crate :: wrappers:: win32:: window:: {
14+ with_dummy_window , HWnd , MissingExtensionFunctionError , OwnDeviceContext , PixelFormat ,
15+ WglContext , WglExtra ,
16+ } ;
2617
2718const WGL_CONTEXT_MAJOR_VERSION_ARB : i32 = 0x2091 ;
2819const WGL_CONTEXT_MINOR_VERSION_ARB : i32 = 0x2092 ;
@@ -31,11 +22,6 @@ const WGL_CONTEXT_PROFILE_MASK_ARB: i32 = 0x9126;
3122const WGL_CONTEXT_CORE_PROFILE_BIT_ARB : i32 = 0x00000001 ;
3223const WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : i32 = 0x00000002 ;
3324
34- // See https://www.khronos.org/registry/OpenGL/extensions/ARB/WGL_ARB_pixel_format.txt
35-
36- type WglChoosePixelFormatARB =
37- extern "system" fn ( HDC , * const i32 , * const f32 , u32 , * mut i32 , * mut u32 ) -> i32 ;
38-
3925const WGL_DRAW_TO_WINDOW_ARB : i32 = 0x2001 ;
4026const WGL_ACCELERATION_ARB : i32 = 0x2003 ;
4127const WGL_SUPPORT_OPENGL_ARB : i32 = 0x2010 ;
@@ -60,11 +46,18 @@ const WGL_SAMPLES_ARB: i32 = 0x2042;
6046
6147const WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB : i32 = 0x20A9 ;
6248
63- // See https://www.khronos.org/registry/OpenGL/extensions/EXT/WGL_EXT_swap_control.txt
49+ #[ derive( Debug ) ]
50+ pub enum CreationFailedError {
51+ Win32 ( windows_core:: Error ) ,
52+ MissingWglExtension ( MissingExtensionFunctionError ) ,
53+ }
6454
65- type WglSwapIntervalEXT = extern "system" fn ( i32 ) -> i32 ;
55+ impl From < windows_core:: Error > for CreationFailedError {
56+ fn from ( err : windows_core:: Error ) -> Self {
57+ CreationFailedError :: Win32 ( err)
58+ }
59+ }
6660
67- pub type CreationFailedError = windows_core:: Error ;
6861pub type GlContext = Rc < GlContextInner > ;
6962
7063impl From < CreationFailedError > for GlError {
@@ -73,48 +66,23 @@ impl From<CreationFailedError> for GlError {
7366 }
7467}
7568
76- #[ allow( non_snake_case) ]
77- struct WglExtra {
78- wglCreateContextAttribsARB : Option < WglCreateContextAttribsARB > ,
79- wglChoosePixelFormatARB : Option < WglChoosePixelFormatARB > ,
80- wglSwapIntervalEXT : Option < WglSwapIntervalEXT > ,
81- }
82-
83- impl WglExtra {
84- pub fn load ( ) -> Self {
85- unsafe {
86- Self {
87- wglCreateContextAttribsARB : wglGetProcAddress ( s ! ( "wglCreateContextAttribsARB" ) )
88- . map ( |addr| std:: mem:: transmute ( addr) ) ,
89- wglChoosePixelFormatARB : wglGetProcAddress ( s ! ( "wglChoosePixelFormatARB" ) )
90- . map ( |addr| std:: mem:: transmute ( addr) ) ,
91- wglSwapIntervalEXT : wglGetProcAddress ( s ! ( "wglSwapIntervalEXT" ) )
92- . map ( |addr| std:: mem:: transmute ( addr) ) ,
93- }
94- }
95- }
96- }
97-
9869pub struct GlContextInner {
99- hwnd : HWND ,
100- hdc : HDC ,
101- hglrc : HGLRC ,
70+ hwnd : HWnd ,
71+ hdc : OwnDeviceContext ,
72+ hglrc : WglContext ,
10273 gl_library : HMODULE ,
10374}
10475
10576impl GlContextInner {
10677 pub unsafe fn create ( window : HWnd , config : GlConfig ) -> Result < Self , GlError > {
10778 // Create temporary window and context to load function pointers
108-
10979 let extra = with_dummy_window ( |hwnd_tmp| {
11080 let hdc = hwnd_tmp. get_own_dc ( ) ?;
11181 hdc. set_pixel_format ( & PixelFormat :: default ( ) ) ?;
11282
11383 let wgl_ctx = hdc. create_wgl_context ( ) ?;
114- wgl_ctx. make_current ( & hdc) ?;
115-
116- Ok ( WglExtra :: load ( ) )
117- } ) ?;
84+ wgl_ctx. with_current ( & hdc, || WglExtra :: load ( ) )
85+ } ) ??;
11886
11987 // Create actual context
12088
@@ -145,7 +113,7 @@ impl GlContextInner {
145113 let mut pixel_format = 0 ;
146114 let mut num_formats = 0 ;
147115 extra. wglChoosePixelFormatARB . unwrap ( ) (
148- hdc,
116+ hdc. as_raw ( ) ,
149117 pixel_format_attribs. as_ptr ( ) ,
150118 std:: ptr:: null ( ) ,
151119 1 ,
@@ -177,7 +145,7 @@ impl GlContextInner {
177145 ] ;
178146
179147 extra. wglChoosePixelFormatARB . unwrap ( ) (
180- hdc,
148+ hdc. as_raw ( ) ,
181149 pixel_format_attribs_fallback. as_ptr ( ) ,
182150 std:: ptr:: null ( ) ,
183151 1 ,
@@ -188,37 +156,11 @@ impl GlContextInner {
188156
189157 // if no num_formats are found which happens in Wine for child windows, use fallback
190158 if num_formats == 0 {
191- let fallback_pfd = PIXELFORMATDESCRIPTOR {
192- nSize : std:: mem:: size_of :: < PIXELFORMATDESCRIPTOR > ( ) as u16 ,
193- nVersion : 1 ,
194- dwFlags : PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER ,
195- iPixelType : PFD_TYPE_RGBA ,
196- cColorBits : 32 ,
197- cAlphaBits : config. alpha_bits ,
198- cDepthBits : config. depth_bits ,
199- cStencilBits : config. stencil_bits ,
200- iLayerType : PFD_MAIN_PLANE as u8 ,
201- ..std:: mem:: zeroed ( )
202- } ;
203- pixel_format = ChoosePixelFormat ( hdc, & fallback_pfd) ;
204- }
205-
206- if pixel_format == 0 {
207- ReleaseDC ( hwnd, hdc) ;
208- return Err ( GlError :: CreationFailed ( ( ) ) ) ;
159+ hdc. set_pixel_format ( & PixelFormat :: from_config ( & config) ) ?;
209160 }
210161
211162 hdc. set_pixel_format_from_index ( pixel_format) ?;
212163
213- let mut pfd: PIXELFORMATDESCRIPTOR = std:: mem:: zeroed ( ) ;
214- DescribePixelFormat (
215- hdc,
216- pixel_format,
217- std:: mem:: size_of :: < PIXELFORMATDESCRIPTOR > ( ) as u32 ,
218- & mut pfd,
219- ) ;
220- SetPixelFormat ( hdc, pixel_format, & pfd) ;
221-
222164 let profile_mask = match config. profile {
223165 Profile :: Core => WGL_CONTEXT_CORE_PROFILE_BIT_ARB ,
224166 Profile :: Compatibility => WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ,
@@ -251,11 +193,11 @@ impl GlContextInner {
251193 }
252194
253195 pub unsafe fn make_current ( & self ) {
254- wglMakeCurrent ( self . hdc , self . hglrc ) ;
196+ let _ = self . hglrc . make_current ( & self . hdc ) ;
255197 }
256198
257199 pub unsafe fn make_not_current ( & self ) {
258- wglMakeCurrent ( self . hdc , std :: ptr :: null_mut ( ) ) ;
200+ let _ = self . hglrc . make_not_current ( ) ;
259201 }
260202
261203 pub fn get_proc_address ( & self , symbol : & str ) -> * const c_void {
@@ -273,18 +215,13 @@ impl GlContextInner {
273215 }
274216
275217 pub fn swap_buffers ( & self ) {
276- unsafe {
277- SwapBuffers ( self . hdc ) ;
278- }
218+ let _ = self . hdc . swap_buffers ( ) ;
279219 }
280220}
281221
282222impl Drop for GlContextInner {
283223 fn drop ( & mut self ) {
284224 unsafe {
285- wglMakeCurrent ( std:: ptr:: null_mut ( ) , std:: ptr:: null_mut ( ) ) ;
286- wglDeleteContext ( self . hglrc ) ;
287- ReleaseDC ( self . hwnd , self . hdc ) ;
288225 FreeLibrary ( self . gl_library ) ;
289226 }
290227 }
0 commit comments