diff --git a/Cargo.toml b/Cargo.toml index cc92d5bb..5c17cf82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,14 +78,18 @@ features = ["egl", "build_dlls"] optional = true [target.'cfg(target_os = "windows")'.dependencies] -wio = "0.2" -winapi = { version = "0.3", features = [ - "d3d11", - "libloaderapi", - "winbase", - "winerror", - "wingdi", - "winuser", +windows = { version = "0.58", features = [ + "Win32_Foundation", + "Win32_System_Com", + "Win32_UI_WindowsAndMessaging", + "Win32_Graphics_Dxgi", + "Win32_Graphics_Dxgi_Common", + "Win32_Graphics_OpenGL", + "Win32_Graphics_Gdi", + "Win32_Graphics_Direct3D", + "Win32_Graphics_Direct3D11", + "Win32_System_LibraryLoader", + "Win32_System_SystemServices", ] } [target.'cfg(target_os = "android")'.dependencies] diff --git a/examples/chaos_game.rs b/examples/chaos_game.rs index cae27a57..1d0a1ee5 100644 --- a/examples/chaos_game.rs +++ b/examples/chaos_game.rs @@ -6,7 +6,7 @@ use euclid::default::Point2D; use rand::{self, Rng}; use surfman::{SurfaceAccess, SurfaceType}; use winit::dpi::PhysicalSize; -use winit::event::{DeviceEvent, Event, KeyboardInput, VirtualKeyCode, WindowEvent}; +use winit::event::{DeviceEvent, Event, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::window::WindowBuilder; diff --git a/src/platform/generic/egl/device.rs b/src/platform/generic/egl/device.rs index 31f34aa1..ece4ec1c 100644 --- a/src/platform/generic/egl/device.rs +++ b/src/platform/generic/egl/device.rs @@ -11,11 +11,11 @@ use std::os::raw::{c_char, c_void}; #[cfg(not(target_os = "windows"))] use libc::{dlopen, dlsym, RTLD_LAZY}; #[cfg(target_os = "windows")] -use winapi::shared::minwindef::HMODULE; +use windows::core::PCSTR; #[cfg(target_os = "windows")] -use winapi::shared::ntdef::LPCSTR; +use windows::Win32::Foundation::HMODULE; #[cfg(target_os = "windows")] -use winapi::um::libloaderapi; +use windows::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryA}; thread_local! { pub static EGL_FUNCTIONS: Egl = Egl::load_with(get_proc_address); @@ -25,7 +25,7 @@ thread_local! { lazy_static! { static ref EGL_LIBRARY: EGLLibraryWrapper = { unsafe { - let module = libloaderapi::LoadLibraryA(&b"libEGL.dll\0"[0] as *const u8 as LPCSTR); + let module = LoadLibraryA(PCSTR(&b"libEGL.dll\0"[0] as *const u8)).unwrap(); EGLLibraryWrapper(module) } }; @@ -58,8 +58,8 @@ unsafe impl Sync for EGLLibraryWrapper {} fn get_proc_address(symbol_name: &str) -> *const c_void { unsafe { let symbol_name: CString = CString::new(symbol_name).unwrap(); - let symbol_ptr = symbol_name.as_ptr() as *const u8 as LPCSTR; - libloaderapi::GetProcAddress(EGL_LIBRARY.0, symbol_ptr) as *const c_void + let symbol_ptr = PCSTR(symbol_name.as_ptr() as *const u8); + GetProcAddress(EGL_LIBRARY.0, symbol_ptr).unwrap() as *const c_void } } diff --git a/src/platform/windows/angle/connection.rs b/src/platform/windows/angle/connection.rs index a4015825..ca2bc520 100644 --- a/src/platform/windows/angle/connection.rs +++ b/src/platform/windows/angle/connection.rs @@ -14,13 +14,11 @@ use crate::Error; use crate::GLApi; use euclid::default::Size2D; +use windows::Win32::Graphics::Direct3D::{D3D_DRIVER_TYPE_UNKNOWN, D3D_DRIVER_TYPE_WARP}; use std::os::raw::c_void; -use winapi::shared::minwindef::UINT; -use winapi::um::d3dcommon::{D3D_DRIVER_TYPE_UNKNOWN, D3D_DRIVER_TYPE_WARP}; - -const INTEL_PCI_ID: UINT = 0x8086; +const INTEL_PCI_ID: u32 = 0x8086; /// A no-op connection. /// diff --git a/src/platform/windows/angle/context.rs b/src/platform/windows/angle/context.rs index 86daafff..b7ce8c30 100644 --- a/src/platform/windows/angle/context.rs +++ b/src/platform/windows/angle/context.rs @@ -17,11 +17,11 @@ use crate::{ContextAttributes, Error, Gl, SurfaceInfo}; use std::mem; use std::os::raw::c_void; use std::thread; -use winapi::shared::winerror::S_OK; -use winapi::um::winbase::INFINITE; pub use crate::platform::generic::egl::context::{ContextDescriptor, NativeContext}; +const INFINITE: u32 = 0xFFFFFFFF; + thread_local! { #[doc(hidden)] pub static GL_FUNCTIONS: Gl = Gl::load_with(context::get_proc_address); @@ -300,7 +300,7 @@ impl Device { .. } => unsafe { let result = keyed_mutex.AcquireSync(0, INFINITE); - assert_eq!(result, S_OK); + assert!(result.is_ok()); }, _ => {} } @@ -340,7 +340,7 @@ impl Device { .. } => unsafe { let result = keyed_mutex.ReleaseSync(0); - assert_eq!(result, S_OK); + assert!(result.is_ok()); }, _ => {} } diff --git a/src/platform/windows/angle/device.rs b/src/platform/windows/angle/device.rs index d104f86b..6b1646fc 100644 --- a/src/platform/windows/angle/device.rs +++ b/src/platform/windows/angle/device.rs @@ -2,6 +2,18 @@ // //! A thread-local handle to the device. +use windows::core::Interface; +use windows::Win32::Foundation::HMODULE; +use windows::Win32::Graphics::Direct3D::{ + D3D_DRIVER_TYPE, D3D_DRIVER_TYPE_UNKNOWN, D3D_DRIVER_TYPE_WARP, D3D_FEATURE_LEVEL_9_3, +}; +use windows::Win32::Graphics::Direct3D11::{ + D3D11CreateDevice, ID3D11Device, D3D11_CREATE_DEVICE_FLAG, D3D11_SDK_VERSION, +}; +use windows::Win32::Graphics::Dxgi::{ + CreateDXGIFactory1, IDXGIAdapter, IDXGIDevice, IDXGIFactory1, +}; + use super::connection::Connection; use crate::egl; use crate::egl::types::{EGLAttrib, EGLDeviceEXT, EGLDisplay, EGLint}; @@ -15,18 +27,9 @@ use std::cell::{RefCell, RefMut}; use std::mem; use std::os::raw::c_void; use std::ptr; -use winapi::shared::dxgi::{self, IDXGIAdapter, IDXGIDevice, IDXGIFactory1}; -use winapi::shared::minwindef::UINT; -use winapi::shared::winerror::{self, S_OK}; -use winapi::um::d3d11::{D3D11CreateDevice, ID3D11Device, D3D11_SDK_VERSION}; -use winapi::um::d3dcommon::{ - D3D_DRIVER_TYPE, D3D_DRIVER_TYPE_UNKNOWN, D3D_DRIVER_TYPE_WARP, D3D_FEATURE_LEVEL_9_3, -}; -use winapi::Interface; -use wio::com::ComPtr; thread_local! { - static DXGI_FACTORY: RefCell>> = RefCell::new(None); + static DXGI_FACTORY: RefCell> = RefCell::new(None); } /// Represents a hardware display adapter that can be used for rendering (including the CPU). @@ -34,7 +37,7 @@ thread_local! { /// Adapters can be sent between threads. To render with an adapter, open a thread-local `Device`. #[derive(Clone)] pub struct Adapter { - pub(crate) dxgi_adapter: ComPtr, + pub(crate) dxgi_adapter: IDXGIAdapter, pub(crate) d3d_driver_type: D3D_DRIVER_TYPE, } @@ -45,15 +48,15 @@ unsafe impl Send for Adapter {} /// Devices contain most of the relevant surface management methods. pub struct Device { pub(crate) egl_display: EGLDisplay, - pub(crate) d3d11_device: ComPtr, + pub(crate) d3d11_device: ID3D11Device, pub(crate) d3d_driver_type: D3D_DRIVER_TYPE, pub(crate) display_is_owned: bool, } pub(crate) enum VendorPreference { None, - Prefer(UINT), - Avoid(UINT), + Prefer(u32), + Avoid(u32), } /// Wraps a Direct3D 11 device and its associated EGL display. @@ -62,7 +65,7 @@ pub struct NativeDevice { /// The ANGLE EGL display. pub egl_display: EGLDisplay, /// The Direct3D 11 device that the ANGLE EGL display was created with. - pub d3d11_device: *mut ID3D11Device, + pub d3d11_device: ID3D11Device, /// The Direct3D driver type that the device was created with. pub d3d_driver_type: D3D_DRIVER_TYPE, } @@ -74,54 +77,33 @@ impl Adapter { ) -> Result { unsafe { let dxgi_factory = DXGI_FACTORY.with(|dxgi_factory_slot| { - let mut dxgi_factory_slot: RefMut>> = - dxgi_factory_slot.borrow_mut(); - if dxgi_factory_slot.is_none() { - let mut dxgi_factory: *mut IDXGIFactory1 = ptr::null_mut(); - let result = dxgi::CreateDXGIFactory1( - &IDXGIFactory1::uuidof(), - &mut dxgi_factory as *mut *mut IDXGIFactory1 as *mut *mut c_void, - ); - if !winerror::SUCCEEDED(result) { - return Err(Error::Failed); - } - assert!(!dxgi_factory.is_null()); - *dxgi_factory_slot = Some(ComPtr::from_raw(dxgi_factory)); + let result = CreateDXGIFactory1::(); + if result.is_err() { + return Err(Error::Failed); } - Ok((*dxgi_factory_slot).clone().unwrap()) + Ok(result.unwrap()) })?; // Find the first adapter that matches the vendor preference. let mut adapter_index = 0; loop { - let mut dxgi_adapter_1 = ptr::null_mut(); - let result = (*dxgi_factory).EnumAdapters1(adapter_index, &mut dxgi_adapter_1); - if !winerror::SUCCEEDED(result) { + let result = (*dxgi_factory).EnumAdapters(adapter_index); + if result.is_err() { break; } - assert!(!dxgi_adapter_1.is_null()); - let dxgi_adapter_1 = ComPtr::from_raw(dxgi_adapter_1); - - let mut adapter_desc = mem::zeroed(); - let result = (*dxgi_adapter_1).GetDesc1(&mut adapter_desc); - assert_eq!(result, S_OK); + let dxgi_adapter_1 = result.unwrap(); + let result = dxgi_adapter_1.GetDesc(); + assert!(result.is_ok()); + let adapter_desc = result.unwrap(); let choose_this = match vendor_preference { VendorPreference::Prefer(vendor_id) => vendor_id == adapter_desc.VendorId, VendorPreference::Avoid(vendor_id) => vendor_id != adapter_desc.VendorId, VendorPreference::None => true, }; if choose_this { - let mut dxgi_adapter: *mut IDXGIAdapter = ptr::null_mut(); - let result = (*dxgi_adapter_1).QueryInterface( - &IDXGIAdapter::uuidof(), - &mut dxgi_adapter as *mut *mut IDXGIAdapter as *mut *mut c_void, - ); - assert_eq!(result, S_OK); - let dxgi_adapter = ComPtr::from_raw(dxgi_adapter); - return Ok(Adapter { - dxgi_adapter, + dxgi_adapter: dxgi_adapter_1, d3d_driver_type, }); } @@ -130,31 +112,21 @@ impl Adapter { } // Fallback: Go with the first adapter. - let mut dxgi_adapter_1 = ptr::null_mut(); - let result = (*dxgi_factory).EnumAdapters1(0, &mut dxgi_adapter_1); - if !winerror::SUCCEEDED(result) { + let result = (*dxgi_factory).EnumAdapters(0); + if result.is_err() { return Err(Error::NoAdapterFound); } - assert!(!dxgi_adapter_1.is_null()); - let dxgi_adapter_1 = ComPtr::from_raw(dxgi_adapter_1); - - let mut dxgi_adapter: *mut IDXGIAdapter = ptr::null_mut(); - let result = (*dxgi_adapter_1).QueryInterface( - &IDXGIAdapter::uuidof(), - &mut dxgi_adapter as *mut *mut IDXGIAdapter as *mut *mut c_void, - ); - assert!(winerror::SUCCEEDED(result)); - let dxgi_adapter = ComPtr::from_raw(dxgi_adapter); + let dxgi_adapter_1 = result.unwrap(); Ok(Adapter { - dxgi_adapter, + dxgi_adapter: dxgi_adapter_1, d3d_driver_type, }) } } /// Create an Adapter instance wrapping an existing DXGI adapter. - pub fn from_dxgi_adapter(adapter: ComPtr) -> Adapter { + pub fn from_dxgi_adapter(adapter: IDXGIAdapter) -> Adapter { Adapter { dxgi_adapter: adapter, d3d_driver_type: D3D_DRIVER_TYPE_UNKNOWN, @@ -167,34 +139,36 @@ impl Device { pub(crate) fn new(adapter: &Adapter) -> Result { let d3d_driver_type = adapter.d3d_driver_type; unsafe { - let mut d3d11_device = ptr::null_mut(); - let mut d3d11_feature_level = 0; - let d3d11_adapter = if d3d_driver_type == D3D_DRIVER_TYPE_WARP { - ptr::null_mut() + let mut d3d11_device = Default::default(); + let d3d11_feature_level = ptr::null_mut(); + let mut d3d11_device_context = Default::default(); + let d3d11_adapter: IDXGIAdapter = if d3d_driver_type == D3D_DRIVER_TYPE_WARP { + IDXGIAdapter::from_raw(ptr::null_mut()) } else { - adapter.dxgi_adapter.as_raw() + adapter.dxgi_adapter.clone() }; let result = D3D11CreateDevice( - d3d11_adapter, + &d3d11_adapter, d3d_driver_type, - ptr::null_mut(), - 0, - ptr::null_mut(), - 0, + HMODULE::default(), + D3D11_CREATE_DEVICE_FLAG(0), + None, D3D11_SDK_VERSION, - &mut d3d11_device, - &mut d3d11_feature_level, - ptr::null_mut(), + Some(&mut d3d11_device), + Some(d3d11_feature_level), + Some(&mut d3d11_device_context), ); - if !winerror::SUCCEEDED(result) { + + if result.is_err() { return Err(Error::DeviceOpenFailed); } - debug_assert!(d3d11_feature_level >= D3D_FEATURE_LEVEL_9_3); - let d3d11_device = ComPtr::from_raw(d3d11_device); + debug_assert!((*d3d11_feature_level).0 >= D3D_FEATURE_LEVEL_9_3.0); let eglCreateDeviceANGLE = EGL_EXTENSION_FUNCTIONS .CreateDeviceANGLE .expect("Where's the `EGL_ANGLE_device_creation` extension?"); + assert!(d3d11_device.is_some()); + let d3d11_device = d3d11_device.unwrap(); let egl_device = eglCreateDeviceANGLE( EGL_D3D11_DEVICE_ANGLE as EGLint, d3d11_device.as_raw() as *mut c_void, @@ -227,15 +201,12 @@ impl Device { } pub(crate) fn from_native_device(native_device: NativeDevice) -> Result { - unsafe { - (*native_device.d3d11_device).AddRef(); - Ok(Device { - egl_display: native_device.egl_display, - d3d11_device: ComPtr::from_raw(native_device.d3d11_device), - d3d_driver_type: native_device.d3d_driver_type, - display_is_owned: false, - }) - } + Ok(Device { + egl_display: native_device.egl_display, + d3d11_device: native_device.d3d11_device, + d3d_driver_type: native_device.d3d_driver_type, + display_is_owned: false, + }) } #[allow(non_snake_case)] @@ -264,13 +235,11 @@ impl Device { if result == egl::FALSE { return Err(Error::DeviceOpenFailed); } - let d3d11_device = device as *mut ID3D11Device; - unsafe { - (*d3d11_device).AddRef(); + let d3d11_device = ID3D11Device::from_raw(device as *mut c_void); Ok(Device { egl_display: egl_display, - d3d11_device: ComPtr::from_raw(d3d11_device), + d3d11_device: d3d11_device, d3d_driver_type: D3D_DRIVER_TYPE_UNKNOWN, display_is_owned: false, }) @@ -286,18 +255,13 @@ impl Device { /// Returns the adapter that this device was created with. pub fn adapter(&self) -> Adapter { unsafe { - let mut dxgi_device: *mut IDXGIDevice = ptr::null_mut(); - let result = (*self.d3d11_device).QueryInterface( - &IDXGIDevice::uuidof(), - &mut dxgi_device as *mut *mut IDXGIDevice as *mut *mut c_void, - ); - assert!(winerror::SUCCEEDED(result)); - let dxgi_device = ComPtr::from_raw(dxgi_device); + let result = (*self.d3d11_device).cast::(); + assert!(result.is_ok()); + let dxgi_device = result.unwrap(); - let mut dxgi_adapter = ptr::null_mut(); - let result = (*dxgi_device).GetAdapter(&mut dxgi_adapter); - assert!(winerror::SUCCEEDED(result)); - let dxgi_adapter = ComPtr::from_raw(dxgi_adapter); + let result = dxgi_device.GetAdapter(); + assert!(result.is_ok()); + let dxgi_adapter = result.unwrap(); Adapter { dxgi_adapter, @@ -313,7 +277,7 @@ impl Device { pub fn native_device(&self) -> NativeDevice { NativeDevice { egl_display: self.egl_display, - d3d11_device: self.d3d11_device.clone().into_raw(), + d3d11_device: self.d3d11_device.clone(), d3d_driver_type: self.d3d_driver_type, } } diff --git a/src/platform/windows/angle/surface.rs b/src/platform/windows/angle/surface.rs index 57932ec6..eb857c6a 100644 --- a/src/platform/windows/angle/surface.rs +++ b/src/platform/windows/angle/surface.rs @@ -24,15 +24,13 @@ use std::marker::PhantomData; use std::os::raw::c_void; use std::ptr; use std::thread; -use winapi::shared::dxgi::IDXGIKeyedMutex; -use winapi::shared::winerror::S_OK; -use winapi::um::d3d11; -use winapi::um::handleapi::INVALID_HANDLE_VALUE; -use winapi::um::winbase::INFINITE; -use winapi::um::winnt::HANDLE; -use wio::com::ComPtr; +use windows::core::Interface; +use windows::Win32::Foundation::{HANDLE, INVALID_HANDLE_VALUE}; +use windows::Win32::Graphics::Direct3D11::ID3D11Texture2D; +use windows::Win32::Graphics::Dxgi::IDXGIKeyedMutex; const SURFACE_GL_TEXTURE_TARGET: GLenum = gl::TEXTURE_2D; +const INFINITE: u32 = 0xFFFFFFFF; /// Represents a hardware buffer of pixels that can be rendered to via the CPU or GPU and either /// displayed in a native widget or bound to a texture for reading. @@ -70,7 +68,7 @@ pub struct Surface { pub struct SurfaceTexture { pub(crate) surface: Surface, pub(crate) local_egl_surface: EGLSurface, - pub(crate) local_keyed_mutex: Option>, + pub(crate) local_keyed_mutex: Option, pub(crate) gl_texture: GLuint, pub(crate) phantom: PhantomData<*const ()>, } @@ -103,12 +101,12 @@ pub(crate) enum Win32Objects { share_handle: HANDLE, synchronization: Synchronization, // We keep a reference to the ComPtr in order to keep its refcount from becoming zero - texture: Option>, + texture: Option, }, } pub(crate) enum Synchronization { - KeyedMutex(ComPtr), + KeyedMutex(IDXGIKeyedMutex), GLFinish, None, } @@ -146,7 +144,7 @@ impl Device { &mut self, context: &Context, size: &Size2D, - texture: Option>, + texture: Option, ) -> Result { let context_descriptor = self.context_descriptor(context); let egl_config = self.context_descriptor_to_egl_config(&context_descriptor); @@ -196,7 +194,7 @@ impl Device { self.egl_display, egl_surface, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE as EGLint, - &mut share_handle, + &mut share_handle as *mut HANDLE as *mut *mut c_void, ); assert_ne!(result, egl::FALSE); assert_ne!(share_handle, INVALID_HANDLE_VALUE); @@ -211,9 +209,7 @@ impl Device { &mut keyed_mutex as *mut *mut IDXGIKeyedMutex as *mut *mut c_void, ); let synchronization = if result != egl::FALSE && !keyed_mutex.is_null() { - let keyed_mutex = ComPtr::from_raw(keyed_mutex); - keyed_mutex.AddRef(); - Synchronization::KeyedMutex(keyed_mutex) + Synchronization::KeyedMutex((*keyed_mutex).clone()) } else if texture.is_none() { Synchronization::GLFinish } else { @@ -241,7 +237,7 @@ impl Device { &mut self, context: &Context, size: &Size2D, - texture: ComPtr, + texture: ID3D11Texture2D, ) -> Result { self.create_pbuffer_surface(context, size, Some(texture)) } @@ -336,7 +332,7 @@ impl Device { let local_egl_surface = egl.CreatePbufferFromClientBuffer( self.egl_display, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, - share_handle, + share_handle.0 as *const _, local_egl_config, pbuffer_attributes.as_ptr(), ); @@ -355,13 +351,10 @@ impl Device { &mut local_keyed_mutex as *mut *mut IDXGIKeyedMutex as *mut *mut c_void, ); let local_keyed_mutex = if result != egl::FALSE && !local_keyed_mutex.is_null() { - let local_keyed_mutex = ComPtr::from_raw(local_keyed_mutex); - local_keyed_mutex.AddRef(); + let result = (*local_keyed_mutex).AcquireSync(0, INFINITE); + assert!(result.is_ok()); - let result = local_keyed_mutex.AcquireSync(0, INFINITE); - assert_eq!(result, S_OK); - - Some(local_keyed_mutex) + Some((*local_keyed_mutex).clone()) } else { None }; @@ -380,7 +373,7 @@ impl Device { context: &Context, surface: Surface, local_egl_surface: EGLSurface, - local_keyed_mutex: Option>, + local_keyed_mutex: Option, ) -> Result { EGL_FUNCTIONS.with(|egl| { unsafe { @@ -442,7 +435,7 @@ impl Device { &mut self, context: &mut Context, size: &Size2D, - texture: ComPtr, + texture: ID3D11Texture2D, ) -> Result { let surface = self.create_pbuffer_surface(context, size, Some(texture))?; let local_egl_surface = surface.egl_surface; @@ -509,7 +502,7 @@ impl Device { if let Some(ref local_keyed_mutex) = surface_texture.local_keyed_mutex { let result = local_keyed_mutex.ReleaseSync(0); - assert_eq!(result, S_OK); + assert!(result.is_ok()); } EGL_FUNCTIONS.with(|egl| { diff --git a/src/platform/windows/wgl/connection.rs b/src/platform/windows/wgl/connection.rs index 17ccbe58..ab649b2b 100644 --- a/src/platform/windows/wgl/connection.rs +++ b/src/platform/windows/wgl/connection.rs @@ -13,7 +13,7 @@ use euclid::default::Size2D; use std::os::raw::c_void; -use winapi::shared::windef::HWND; +use windows::Win32::Foundation::HWND; /// Represents a connection to the display server. /// @@ -118,7 +118,7 @@ impl Connection { _size: Size2D, ) -> NativeWidget { NativeWidget { - window_handle: raw as HWND, + window_handle: HWND(raw), } } @@ -133,7 +133,7 @@ impl Connection { match raw_handle { Win32(handle) => Ok(NativeWidget { - window_handle: handle.hwnd as HWND, + window_handle: HWND(handle.hwnd), }), _ => Err(Error::IncompatibleNativeWidget), } @@ -150,7 +150,7 @@ impl Connection { match handle.as_raw() { Win32(handle) => Ok(NativeWidget { - window_handle: handle.hwnd.get() as HWND, + window_handle: HWND(handle.hwnd.get() as *mut c_void), }), _ => Err(Error::IncompatibleNativeWidget), } diff --git a/src/platform/windows/wgl/context.rs b/src/platform/windows/wgl/context.rs index 4f180163..a3876748 100644 --- a/src/platform/windows/wgl/context.rs +++ b/src/platform/windows/wgl/context.rs @@ -18,17 +18,28 @@ use std::mem; use std::os::raw::{c_char, c_int, c_void}; use std::ptr; use std::thread; -use winapi::shared::minwindef::{BOOL, FALSE, FLOAT, HMODULE, LPARAM, LPVOID, LRESULT, UINT}; -use winapi::shared::minwindef::{WORD, WPARAM}; -use winapi::shared::ntdef::{HANDLE, LPCSTR}; -use winapi::shared::windef::{HBRUSH, HDC, HGLRC, HWND}; -use winapi::um::libloaderapi; -use winapi::um::wingdi::{self, PFD_DOUBLEBUFFER, PFD_DRAW_TO_WINDOW, PFD_MAIN_PLANE}; -use winapi::um::wingdi::{wglCreateContext, wglDeleteContext, wglGetCurrentContext}; -use winapi::um::wingdi::{wglGetCurrentDC, wglGetProcAddress, wglMakeCurrent}; -use winapi::um::wingdi::{PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA, PIXELFORMATDESCRIPTOR}; -use winapi::um::winuser::{self, COLOR_BACKGROUND, CREATESTRUCTA, CS_OWNDC, WM_CREATE, WNDCLASSA}; -use winapi::um::winuser::{WS_OVERLAPPEDWINDOW, WS_VISIBLE}; +use windows::core::PCSTR; +use windows::Win32::Foundation::HANDLE; +use windows::Win32::Foundation::HINSTANCE; +use windows::Win32::Foundation::HWND; +use windows::Win32::Foundation::WPARAM; +use windows::Win32::Foundation::{BOOL, FALSE, HMODULE, LPARAM, LRESULT}; +use windows::Win32::Graphics::Gdi::GetDC; +use windows::Win32::Graphics::Gdi::COLOR_BACKGROUND; +use windows::Win32::Graphics::Gdi::{HBRUSH, HDC}; +use windows::Win32::Graphics::OpenGL::{wglCreateContext, wglDeleteContext, wglGetCurrentContext}; +use windows::Win32::Graphics::OpenGL::{wglGetCurrentDC, wglGetProcAddress, wglMakeCurrent}; +use windows::Win32::Graphics::OpenGL::{ChoosePixelFormat, GetPixelFormat, SetPixelFormat}; +use windows::Win32::Graphics::OpenGL::{DescribePixelFormat, HGLRC}; +use windows::Win32::Graphics::OpenGL::{PFD_DOUBLEBUFFER, PFD_DRAW_TO_WINDOW, PFD_MAIN_PLANE}; +use windows::Win32::Graphics::OpenGL::{PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA, PIXELFORMATDESCRIPTOR}; +use windows::Win32::System::LibraryLoader::{GetModuleHandleA, GetProcAddress, LoadLibraryA}; +use windows::Win32::UI::WindowsAndMessaging::{ + CreateWindowExA, DestroyWindow, RegisterClassA, HCURSOR, HICON, +}; +use windows::Win32::UI::WindowsAndMessaging::{DefWindowProcA, WINDOW_EX_STYLE}; +use windows::Win32::UI::WindowsAndMessaging::{CREATESTRUCTA, CS_OWNDC, WM_CREATE, WNDCLASSA}; +use windows::Win32::UI::WindowsAndMessaging::{WS_OVERLAPPEDWINDOW, WS_VISIBLE}; const WGL_DRAW_TO_WINDOW_ARB: GLenum = 0x2001; const WGL_ACCELERATION_ARB: GLenum = 0x2003; @@ -64,16 +75,16 @@ pub(crate) struct WGLPixelFormatExtensionFunctions { ChoosePixelFormatARB: unsafe extern "C" fn( hdc: HDC, piAttribIList: *const c_int, - pfAttribFList: *const FLOAT, - nMaxFormats: UINT, + pfAttribFList: *const f32, + nMaxFormats: u32, piFormats: *mut c_int, - nNumFormats: *mut UINT, + nNumFormats: *mut u32, ) -> BOOL, GetPixelFormatAttribivARB: unsafe extern "C" fn( hdc: HDC, iPixelFormat: c_int, iLayerPlane: c_int, - nAttributes: UINT, + nAttributes: u32, piAttributes: *const c_int, piValues: *mut c_int, ) -> BOOL, @@ -148,7 +159,7 @@ pub struct NativeContext(pub HGLRC); thread_local! { static OPENGL_LIBRARY: HMODULE = { unsafe { - libloaderapi::LoadLibraryA(&b"opengl32.dll\0"[0] as *const u8 as LPCSTR) + LoadLibraryA(PCSTR(&b"opengl32.dll\0"[0] as *const u8)).unwrap() } }; } @@ -283,17 +294,17 @@ impl Device { ]; glrc = wglCreateContextAttribsARB( dc, - share_with.map_or(ptr::null_mut(), |ctx| ctx.glrc), + share_with.map_or(HGLRC::default(), |ctx| ctx.glrc), wgl_attributes.as_ptr(), ); - if glrc.is_null() { + if glrc.is_invalid() { return Err(Error::ContextCreationFailed(WindowingApiError::Failed)); } // Temporarily make the context current. let _guard = CurrentContextGuard::new(); let ok = wglMakeCurrent(dc, glrc); - assert_ne!(ok, FALSE); + assert!(ok.is_ok()); // Load the GL functions. gl = Gl::load_with(get_proc_address); @@ -331,7 +342,7 @@ impl Device { let dc = hidden_window_dc.dc; let _guard = CurrentContextGuard::new(); let ok = wglMakeCurrent(dc, native_context.0); - assert_ne!(ok, FALSE); + assert!(ok.is_ok()); Gl::load_with(get_proc_address) }; @@ -361,7 +372,7 @@ impl Device { unsafe { if wglGetCurrentContext() == context.glrc { - wglMakeCurrent(ptr::null_mut(), ptr::null_mut()); + wglMakeCurrent(None, None); } if context.status == ContextStatus::Owned { @@ -369,7 +380,7 @@ impl Device { } } - context.glrc = ptr::null_mut(); + context.glrc = HGLRC::default(); context.status = ContextStatus::Destroyed; Ok(()) } @@ -378,7 +389,7 @@ impl Device { pub fn context_descriptor(&self, context: &Context) -> ContextDescriptor { unsafe { let dc_guard = self.get_context_dc(context); - let pixel_format = wingdi::GetPixelFormat(dc_guard.dc); + let pixel_format = GetPixelFormat(dc_guard.dc); let _guard = self.temporarily_make_context_current(context); @@ -422,7 +433,7 @@ impl Device { dc_guard.dc, context_descriptor.pixel_format, 0, - attrib_name_i_list.len() as UINT, + attrib_name_i_list.len() as u32, attrib_name_i_list.as_ptr(), attrib_value_i_list.as_mut_ptr(), ); @@ -479,7 +490,7 @@ impl Device { unsafe { let dc_guard = self.get_context_dc(context); let ok = wglMakeCurrent(dc_guard.dc, context.glrc); - if ok != FALSE { + if ok.is_ok() { Ok(()) } else { Err(Error::MakeCurrentFailed(WindowingApiError::Failed)) @@ -494,8 +505,8 @@ impl Device { #[inline] pub fn make_no_context_current(&self) -> Result<(), Error> { unsafe { - let ok = wglMakeCurrent(ptr::null_mut(), ptr::null_mut()); - if ok != FALSE { + let ok = wglMakeCurrent(None, None); + if ok.is_ok() { Ok(()) } else { Err(Error::MakeCurrentFailed(WindowingApiError::Failed)) @@ -582,7 +593,7 @@ impl Device { Framebuffer::Surface(Surface { win32_objects: Win32Objects::Widget { window_handle }, .. - }) => DCGuard::new(winuser::GetDC(window_handle), Some(window_handle)), + }) => DCGuard::new(GetDC(window_handle), Some(window_handle)), Framebuffer::Surface(Surface { win32_objects: Win32Objects::Texture { .. }, .. @@ -628,7 +639,7 @@ impl NativeContext { pub fn current() -> Result { unsafe { let glrc = wglGetCurrentContext(); - if glrc != ptr::null_mut() { + if !glrc.is_invalid() { Ok(NativeContext(glrc)) } else { Err(Error::NoCurrentContext) @@ -639,40 +650,42 @@ impl NativeContext { fn extension_loader_thread() -> WGLExtensionFunctions { unsafe { - let instance = libloaderapi::GetModuleHandleA(ptr::null_mut()); - let window_class_name = &b"SurfmanFalseWindow\0"[0] as *const u8 as LPCSTR; + let instance = GetModuleHandleA(None).unwrap(); + let window_class_name = PCSTR(&b"SurfmanFalseWindow\0"[0] as *const u8); let window_class = WNDCLASSA { style: CS_OWNDC, lpfnWndProc: Some(extension_loader_window_proc), cbClsExtra: 0, cbWndExtra: 0, - hInstance: instance, - hIcon: ptr::null_mut(), - hCursor: ptr::null_mut(), - hbrBackground: COLOR_BACKGROUND as HBRUSH, - lpszMenuName: ptr::null_mut(), + hInstance: HINSTANCE::from(instance), + hIcon: HICON::default(), + hCursor: HCURSOR::default(), + hbrBackground: HBRUSH(COLOR_BACKGROUND.0 as *mut c_void), + lpszMenuName: PCSTR::null(), lpszClassName: window_class_name, }; - let window_class_atom = winuser::RegisterClassA(&window_class); + let window_class_atom = RegisterClassA(&window_class); assert_ne!(window_class_atom, 0); let mut extension_functions = WGLExtensionFunctions::default(); - let window = winuser::CreateWindowExA( - 0, - window_class_atom as LPCSTR, + let window = CreateWindowExA( + WINDOW_EX_STYLE(0), + PCSTR(window_class_atom as *const u8), window_class_name, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 640, 480, - ptr::null_mut(), - ptr::null_mut(), + None, + None, instance, - &mut extension_functions as *mut WGLExtensionFunctions as LPVOID, + Some(&mut extension_functions as *mut WGLExtensionFunctions as *mut c_void), ); - winuser::DestroyWindow(window); + assert!(window.is_ok()); + + DestroyWindow(window.unwrap()); extension_functions } @@ -681,7 +694,7 @@ fn extension_loader_thread() -> WGLExtensionFunctions { #[allow(non_snake_case)] extern "system" fn extension_loader_window_proc( hwnd: HWND, - uMsg: UINT, + uMsg: u32, wParam: WPARAM, lParam: LPARAM, ) -> LRESULT { @@ -689,7 +702,7 @@ extern "system" fn extension_loader_window_proc( match uMsg { WM_CREATE => { let pixel_format_descriptor = PIXELFORMATDESCRIPTOR { - nSize: mem::size_of::() as WORD, + nSize: mem::size_of::() as u16, nVersion: 1, dwFlags: PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, iPixelType: PFD_TYPE_RGBA, @@ -710,7 +723,7 @@ extern "system" fn extension_loader_window_proc( cDepthBits: 24, cStencilBits: 8, cAuxBuffers: 0, - iLayerType: PFD_MAIN_PLANE, + iLayerType: PFD_MAIN_PLANE.0 as u8, bReserved: 0, dwLayerMask: 0, dwVisibleMask: 0, @@ -718,22 +731,23 @@ extern "system" fn extension_loader_window_proc( }; // Create a false GL context. - let dc = winuser::GetDC(hwnd); - let pixel_format = wingdi::ChoosePixelFormat(dc, &pixel_format_descriptor); + let dc = GetDC(hwnd); + let pixel_format = ChoosePixelFormat(dc, &pixel_format_descriptor); assert_ne!(pixel_format, 0); - let mut ok = wingdi::SetPixelFormat(dc, pixel_format, &pixel_format_descriptor); - assert_ne!(ok, FALSE); + let mut ok = SetPixelFormat(dc, pixel_format, &pixel_format_descriptor); + assert!(ok.is_ok()); let gl_context = wglCreateContext(dc); - assert!(!gl_context.is_null()); + assert!(gl_context.is_ok()); + let gl_context = gl_context.unwrap(); ok = wglMakeCurrent(dc, gl_context); - assert_ne!(ok, FALSE); + assert!(ok.is_ok()); // Detect extensions. - let create_struct = lParam as *mut CREATESTRUCTA; + let create_struct = lParam.0 as *mut CREATESTRUCTA; let wgl_extension_functions = (*create_struct).lpCreateParams as *mut WGLExtensionFunctions; (*wgl_extension_functions).GetExtensionsStringARB = mem::transmute( - wglGetProcAddress(&b"wglGetExtensionsStringARB\0"[0] as *const u8 as LPCSTR), + wglGetProcAddress(PCSTR(&b"wglGetExtensionsStringARB\0"[0] as *const u8)), ); let extensions = match (*wgl_extension_functions).GetExtensionsStringARB { Some(wglGetExtensionsStringARB) => { @@ -747,55 +761,55 @@ extern "system" fn extension_loader_window_proc( if extension == "WGL_ARB_pixel_format" { (*wgl_extension_functions).pixel_format_functions = Some(WGLPixelFormatExtensionFunctions { - ChoosePixelFormatARB: mem::transmute(wglGetProcAddress( - &b"wglChoosePixelFormatARB\0"[0] as *const u8 as LPCSTR, - )), + ChoosePixelFormatARB: mem::transmute(wglGetProcAddress(PCSTR( + &b"wglChoosePixelFormatARB\0"[0] as *const u8, + ))), GetPixelFormatAttribivARB: mem::transmute(wglGetProcAddress( - &b"wglGetPixelFormatAttribivARB\0"[0] as *const u8 as LPCSTR, + PCSTR(&b"wglGetPixelFormatAttribivARB\0"[0] as *const u8), )), }); continue; } if extension == "WGL_ARB_create_context" { (*wgl_extension_functions).CreateContextAttribsARB = - mem::transmute(wglGetProcAddress( - &b"wglCreateContextAttribsARB\0"[0] as *const u8 as LPCSTR, - )); + mem::transmute(wglGetProcAddress(PCSTR( + &b"wglCreateContextAttribsARB\0"[0] as *const u8, + ))); continue; } if extension == "WGL_NV_DX_interop" { (*wgl_extension_functions).dx_interop_functions = Some(WGLDXInteropExtensionFunctions { - DXCloseDeviceNV: mem::transmute(wglGetProcAddress( - &b"wglDXCloseDeviceNV\0"[0] as *const u8 as LPCSTR, - )), - DXLockObjectsNV: mem::transmute(wglGetProcAddress( - &b"wglDXLockObjectsNV\0"[0] as *const u8 as LPCSTR, - )), - DXOpenDeviceNV: mem::transmute(wglGetProcAddress( - &b"wglDXOpenDeviceNV\0"[0] as *const u8 as LPCSTR, - )), - DXRegisterObjectNV: mem::transmute(wglGetProcAddress( - &b"wglDXRegisterObjectNV\0"[0] as *const u8 as LPCSTR, - )), + DXCloseDeviceNV: mem::transmute(wglGetProcAddress(PCSTR( + &b"wglDXCloseDeviceNV\0"[0] as *const u8, + ))), + DXLockObjectsNV: mem::transmute(wglGetProcAddress(PCSTR( + &b"wglDXLockObjectsNV\0"[0] as *const u8, + ))), + DXOpenDeviceNV: mem::transmute(wglGetProcAddress(PCSTR( + &b"wglDXOpenDeviceNV\0"[0] as *const u8, + ))), + DXRegisterObjectNV: mem::transmute(wglGetProcAddress(PCSTR( + &b"wglDXRegisterObjectNV\0"[0] as *const u8, + ))), DXSetResourceShareHandleNV: mem::transmute(wglGetProcAddress( - &b"wglDXSetResourceShareHandleNV\0"[0] as *const u8 as LPCSTR, - )), - DXUnlockObjectsNV: mem::transmute(wglGetProcAddress( - &b"wglDXUnlockObjectsNV\0"[0] as *const u8 as LPCSTR, - )), - DXUnregisterObjectNV: mem::transmute(wglGetProcAddress( - &b"wglDXUnregisterObjectNV\0"[0] as *const u8 as LPCSTR, + PCSTR(&b"wglDXSetResourceShareHandleNV\0"[0] as *const u8), )), + DXUnlockObjectsNV: mem::transmute(wglGetProcAddress(PCSTR( + &b"wglDXUnlockObjectsNV\0"[0] as *const u8, + ))), + DXUnregisterObjectNV: mem::transmute(wglGetProcAddress(PCSTR( + &b"wglDXUnregisterObjectNV\0"[0] as *const u8, + ))), }); continue; } } wglDeleteContext(gl_context); - 0 + LRESULT(0) } - _ => winuser::DefWindowProcA(hwnd, uMsg, wParam, lParam), + _ => DefWindowProcA(hwnd, uMsg, wParam, lParam), } } } @@ -872,13 +886,13 @@ fn get_proc_address(symbol_name: &str) -> *const c_void { unsafe { // https://www.khronos.org/opengl/wiki/Load_OpenGL_Functions#Windows let symbol_name: CString = CString::new(symbol_name).unwrap(); - let symbol_ptr = symbol_name.as_ptr() as *const u8 as LPCSTR; - let addr = wglGetProcAddress(symbol_ptr) as *const c_void; - if !addr.is_null() { - return addr; + let symbol_ptr = PCSTR(symbol_name.as_ptr() as *const u8); + let addr = wglGetProcAddress(symbol_ptr); + if addr.is_some() { + return addr.unwrap() as *const c_void; } OPENGL_LIBRARY.with(|opengl_library| { - libloaderapi::GetProcAddress(*opengl_library, symbol_ptr) as *const c_void + GetProcAddress(*opengl_library, symbol_ptr).unwrap() as *const c_void }) } } @@ -886,14 +900,14 @@ fn get_proc_address(symbol_name: &str) -> *const c_void { pub(crate) fn set_dc_pixel_format(dc: HDC, pixel_format: c_int) { unsafe { let mut pixel_format_descriptor = mem::zeroed(); - let pixel_format_count = wingdi::DescribePixelFormat( + let pixel_format_count = DescribePixelFormat( dc, pixel_format, - mem::size_of::() as UINT, - &mut pixel_format_descriptor, + mem::size_of::() as u32, + Some(&mut pixel_format_descriptor), ); assert_ne!(pixel_format_count, 0); - let ok = wingdi::SetPixelFormat(dc, pixel_format, &mut pixel_format_descriptor); - assert_ne!(ok, FALSE); + let ok = SetPixelFormat(dc, pixel_format, &mut pixel_format_descriptor); + assert!(ok.is_ok()); } } diff --git a/src/platform/windows/wgl/device.rs b/src/platform/windows/wgl/device.rs index 64c8794a..a85edb2a 100644 --- a/src/platform/windows/wgl/device.rs +++ b/src/platform/windows/wgl/device.rs @@ -12,21 +12,29 @@ use std::os::raw::{c_int, c_void}; use std::ptr; use std::sync::mpsc::{self, Sender}; use std::thread::{self, JoinHandle}; -use winapi::shared::dxgi::{IDXGIAdapter, IDXGIDevice}; -use winapi::shared::minwindef::{self, FALSE, UINT}; -use winapi::shared::ntdef::{HANDLE, LPCSTR}; -use winapi::shared::windef::{HBRUSH, HDC, HWND}; -use winapi::shared::winerror::{self, S_OK}; -use winapi::um::d3d11::{D3D11CreateDevice, ID3D11Device, ID3D11DeviceContext, D3D11_SDK_VERSION}; -use winapi::um::d3dcommon::D3D_DRIVER_TYPE_HARDWARE; -use winapi::um::libloaderapi; -use winapi::um::winuser::{self, COLOR_BACKGROUND, CS_OWNDC, MSG, WM_CLOSE}; -use winapi::um::winuser::{WNDCLASSA, WS_OVERLAPPEDWINDOW}; -use wio::com::ComPtr; +use windows::core::{Interface, PCSTR}; +use windows::Win32::Foundation::HWND; +use windows::Win32::Foundation::{HANDLE, HINSTANCE, HMODULE, LPARAM, LRESULT, WPARAM}; +use windows::Win32::Graphics::Direct3D::D3D_DRIVER_TYPE_HARDWARE; +use windows::Win32::Graphics::Direct3D11::{ + D3D11CreateDevice, ID3D11Device, ID3D11DeviceContext, D3D11_CREATE_DEVICE_FLAG, + D3D11_SDK_VERSION, +}; +use windows::Win32::Graphics::Dxgi::{IDXGIAdapter, IDXGIDevice}; +use windows::Win32::Graphics::Gdi::ReleaseDC; +use windows::Win32::Graphics::Gdi::COLOR_BACKGROUND; +use windows::Win32::Graphics::Gdi::{GetDC, HBRUSH, HDC}; +use windows::Win32::System::LibraryLoader::{GetModuleHandleA, GetProcAddress}; +use windows::Win32::UI::WindowsAndMessaging::{ + CreateWindowExA, DefWindowProcA, DispatchMessageA, GetClassInfoA, GetMessageA, PostMessageA, + RegisterClassA, TranslateMessage, HCURSOR, HICON, HMENU, WINDOW_EX_STYLE, +}; +use windows::Win32::UI::WindowsAndMessaging::{CS_OWNDC, MSG, WM_CLOSE}; +use windows::Win32::UI::WindowsAndMessaging::{WNDCLASSA, WS_OVERLAPPEDWINDOW}; pub(crate) const HIDDEN_WINDOW_SIZE: c_int = 16; -const INTEL_PCI_ID: UINT = 0x8086; +const INTEL_PCI_ID: u32 = 0x8086; static NVIDIA_GPU_SELECT_SYMBOL: &[u8] = b"NvOptimusEnablement\0"; static AMD_GPU_SELECT_SYMBOL: &[u8] = b"AmdPowerXpressRequestHighPerformance\0"; @@ -52,8 +60,8 @@ unsafe impl Send for SendableHWND {} #[allow(dead_code)] pub struct Device { pub(crate) adapter: Adapter, - pub(crate) d3d11_device: ComPtr, - pub(crate) d3d11_device_context: ComPtr, + pub(crate) d3d11_device: ID3D11Device, + pub(crate) d3d11_device_context: ID3D11DeviceContext, pub(crate) gl_dx_interop_device: HANDLE, pub(crate) hidden_window: HiddenWindow, } @@ -62,7 +70,7 @@ pub struct Device { #[derive(Clone)] pub struct NativeDevice { /// The Direct3D 11 device. - pub d3d11_device: *mut ID3D11Device, + pub d3d11_device: ID3D11Device, /// The corresponding GL/DX interop device. /// @@ -74,17 +82,14 @@ pub struct NativeDevice { impl Adapter { pub(crate) fn set_exported_variables(&self) { unsafe { - let current_module = libloaderapi::GetModuleHandleA(ptr::null()); - assert!(!current_module.is_null()); - let nvidia_gpu_select_variable: *mut i32 = libloaderapi::GetProcAddress( - current_module, - NVIDIA_GPU_SELECT_SYMBOL.as_ptr() as LPCSTR, - ) as *mut i32; - let amd_gpu_select_variable: *mut i32 = libloaderapi::GetProcAddress( - current_module, - AMD_GPU_SELECT_SYMBOL.as_ptr() as LPCSTR, - ) as *mut i32; - if nvidia_gpu_select_variable.is_null() || amd_gpu_select_variable.is_null() { + let current_module = GetModuleHandleA(PCSTR::null()); + assert!(current_module.is_ok()); + let current_module = current_module.unwrap(); + let nvidia_gpu_select_variable = + GetProcAddress(current_module, PCSTR(NVIDIA_GPU_SELECT_SYMBOL.as_ptr())); + let amd_gpu_select_variable = + GetProcAddress(current_module, PCSTR(AMD_GPU_SELECT_SYMBOL.as_ptr())); + if nvidia_gpu_select_variable.is_none() || amd_gpu_select_variable.is_none() { println!( "surfman: Could not find the NVIDIA and/or AMD GPU selection symbols. \ Your application may end up using the wrong GPU (discrete vs. \ @@ -105,8 +110,14 @@ impl Adapter { Adapter::HighPerformance => 1, Adapter::LowPower => 0, }; - *nvidia_gpu_select_variable = value; - *amd_gpu_select_variable = value; + if nvidia_gpu_select_variable.is_some() { + let nvidia_gpu_select_variable = nvidia_gpu_select_variable.unwrap(); + *(nvidia_gpu_select_variable as *mut i32) = value; + } + if amd_gpu_select_variable.is_some() { + let amd_gpu_select_variable = amd_gpu_select_variable.unwrap(); + *(amd_gpu_select_variable as *mut i32) = value; + } } } } @@ -133,30 +144,29 @@ impl Device { }; unsafe { - let mut d3d11_device = ptr::null_mut(); - let mut d3d11_feature_level = 0; - let mut d3d11_device_context = ptr::null_mut(); + let mut d3d11_device = Default::default(); + let d3d11_feature_level = ptr::null_mut(); + let mut d3d11_device_context = Default::default(); let result = D3D11CreateDevice( - ptr::null_mut(), + None, D3D_DRIVER_TYPE_HARDWARE, - ptr::null_mut(), - 0, - ptr::null_mut(), - 0, + HMODULE::default(), + D3D11_CREATE_DEVICE_FLAG(0), + None, D3D11_SDK_VERSION, - &mut d3d11_device, - &mut d3d11_feature_level, - &mut d3d11_device_context, + Some(&mut d3d11_device), + Some(d3d11_feature_level), + Some(&mut d3d11_device_context), ); - if !winerror::SUCCEEDED(result) { + if result.is_err() { return Err(Error::DeviceOpenFailed); } - let d3d11_device = ComPtr::from_raw(d3d11_device); - let d3d11_device_context = ComPtr::from_raw(d3d11_device_context); + let d3d11_device = d3d11_device.unwrap(); + let d3d11_device_context = d3d11_device_context.unwrap(); let gl_dx_interop_device = (dx_interop_functions.DXOpenDeviceNV)(d3d11_device.as_raw() as *mut c_void); - assert!(!gl_dx_interop_device.is_null()); + assert!(!gl_dx_interop_device.is_invalid()); let hidden_window = HiddenWindow::new(); @@ -172,25 +182,23 @@ impl Device { pub(crate) fn from_native_device(native_device: NativeDevice) -> Result { unsafe { - (*native_device.d3d11_device).AddRef(); - let d3d11_device = ComPtr::from_raw(native_device.d3d11_device); - let dxgi_device: ComPtr = d3d11_device.cast().unwrap(); + let d3d11_device = native_device.d3d11_device; + let dxgi_device = d3d11_device.cast::(); + + assert!(dxgi_device.is_ok()); // Fetch the DXGI adapter. - let mut dxgi_adapter = ptr::null_mut(); - let result = dxgi_device.GetAdapter(&mut dxgi_adapter); - assert_eq!(result, S_OK); - assert!(!dxgi_adapter.is_null()); - let dxgi_adapter = ComPtr::from_raw(dxgi_adapter); + let result = dxgi_device.unwrap().GetAdapter(); + assert!(result.is_ok()); + let dxgi_adapter = result.unwrap(); // Turn that DXGI adapter into a `surfman` adapter. let adapter = Adapter::from_dxgi_adapter(&dxgi_adapter); // Fetch the device context. - let mut d3d11_device_context = ptr::null_mut(); - d3d11_device.GetImmediateContext(&mut d3d11_device_context); - assert!(!d3d11_device_context.is_null()); - let d3d11_device_context = ComPtr::from_raw(d3d11_device_context); + let d3d11_device_context = d3d11_device.GetImmediateContext(); + assert!(d3d11_device_context.is_ok()); + let d3d11_device_context = d3d11_device_context.unwrap(); let gl_dx_interop_device = native_device.gl_dx_interop_device; let hidden_window = HiddenWindow::new(); @@ -210,13 +218,10 @@ impl Device { /// The reference count on the D3D 11 device is increased before returning. #[inline] pub fn native_device(&self) -> NativeDevice { - unsafe { - let d3d11_device = self.d3d11_device.as_raw(); - (*d3d11_device).AddRef(); - NativeDevice { - d3d11_device, - gl_dx_interop_device: self.gl_dx_interop_device, - } + let d3d11_device = self.d3d11_device.clone(); + NativeDevice { + d3d11_device, + gl_dx_interop_device: self.gl_dx_interop_device, } } @@ -240,13 +245,12 @@ impl Device { } impl Adapter { - fn from_dxgi_adapter(dxgi_adapter: &ComPtr) -> Adapter { + fn from_dxgi_adapter(dxgi_adapter: &IDXGIAdapter) -> Adapter { unsafe { - let mut adapter_desc = mem::zeroed(); - let result = dxgi_adapter.GetDesc(&mut adapter_desc); - assert_eq!(result, S_OK); + let result = dxgi_adapter.GetDesc(); + assert!(result.is_ok()); - if adapter_desc.VendorId == INTEL_PCI_ID { + if result.unwrap().VendorId == INTEL_PCI_ID { Adapter::LowPower } else { Adapter::HighPerformance @@ -269,7 +273,7 @@ pub(crate) struct DCGuard<'a> { impl Drop for HiddenWindow { fn drop(&mut self) { unsafe { - winuser::PostMessageA(self.window, WM_CLOSE, 0, 0); + PostMessageA(self.window, WM_CLOSE, WPARAM(0), LPARAM(0)); if let Some(join_handle) = self.join_handle.take() { drop(join_handle.join()); } @@ -282,7 +286,7 @@ impl<'a> Drop for DCGuard<'a> { fn drop(&mut self) { unsafe { if let Some(window) = self.window { - winuser::ReleaseDC(window, self.dc); + ReleaseDC(window, self.dc); } } } @@ -299,36 +303,44 @@ impl HiddenWindow { } } + // From https://github.com/microsoft/windows-rs/blob/02c4f29d19fbe6d59b2ae0b42262e68d00438f0f/crates/samples/windows/direct2d/src/main.rs#L439 #[inline] pub(crate) fn get_dc(&self) -> DCGuard { - unsafe { DCGuard::new(winuser::GetDC(self.window), Some(self.window)) } + unsafe { DCGuard::new(GetDC(self.window), Some(self.window)) } + } + extern "system" fn wndproc( + window: HWND, + message: u32, + wparam: WPARAM, + lparam: LPARAM, + ) -> LRESULT { + unsafe { DefWindowProcA(window, message, wparam, lparam) } } - // The thread that creates the window for off-screen contexts. fn thread(sender: Sender) { unsafe { - let instance = libloaderapi::GetModuleHandleA(ptr::null_mut()); - let window_class_name = &b"SurfmanHiddenWindow\0"[0] as *const u8 as LPCSTR; + let instance = HINSTANCE::from(GetModuleHandleA(PCSTR::null()).unwrap()); + let window_class_name = PCSTR(&b"SurfmanHiddenWindow\0"[0] as *const u8); let mut window_class = mem::zeroed(); - if winuser::GetClassInfoA(instance, window_class_name, &mut window_class) == FALSE { + if GetClassInfoA(instance, window_class_name, &mut window_class).is_err() { window_class = WNDCLASSA { style: CS_OWNDC, - lpfnWndProc: Some(winuser::DefWindowProcA), + lpfnWndProc: Some(Self::wndproc), cbClsExtra: 0, cbWndExtra: 0, hInstance: instance, - hIcon: ptr::null_mut(), - hCursor: ptr::null_mut(), - hbrBackground: COLOR_BACKGROUND as HBRUSH, - lpszMenuName: ptr::null_mut(), + hIcon: HICON::default(), + hCursor: HCURSOR::default(), + hbrBackground: HBRUSH(COLOR_BACKGROUND.0 as *mut c_void), + lpszMenuName: PCSTR::null(), lpszClassName: window_class_name, }; - let window_class_atom = winuser::RegisterClassA(&window_class); + let window_class_atom = RegisterClassA(&window_class); assert_ne!(window_class_atom, 0); } - let window = winuser::CreateWindowExA( - 0, + let window = CreateWindowExA( + WINDOW_EX_STYLE(0), window_class_name, window_class_name, WS_OVERLAPPEDWINDOW, @@ -336,19 +348,23 @@ impl HiddenWindow { 0, HIDDEN_WINDOW_SIZE, HIDDEN_WINDOW_SIZE, - ptr::null_mut(), - ptr::null_mut(), + HWND::default(), + HMENU::default(), instance, - ptr::null_mut(), + None, ); + assert!(window.is_ok()); + + let window = window.unwrap(); + sender.send(SendableHWND(window)).unwrap(); let mut msg: MSG = mem::zeroed(); - while winuser::GetMessageA(&mut msg, window, 0, 0) != FALSE { - winuser::TranslateMessage(&msg); - winuser::DispatchMessageA(&msg); - if minwindef::LOWORD(msg.message) as UINT == WM_CLOSE { + while GetMessageA(&mut msg, window, 0, 0) != false { + TranslateMessage(&msg); + DispatchMessageA(&msg); + if msg.message == WM_CLOSE { break; } } diff --git a/src/platform/windows/wgl/surface.rs b/src/platform/windows/wgl/surface.rs index a8e2d6f5..e2eac7c0 100644 --- a/src/platform/windows/wgl/surface.rs +++ b/src/platform/windows/wgl/surface.rs @@ -16,23 +16,22 @@ use std::fmt::{self, Debug, Formatter}; use std::marker::PhantomData; use std::mem; use std::os::raw::c_void; -use std::ptr; use std::thread; -use winapi::shared::dxgi::IDXGIResource; -use winapi::shared::dxgiformat::DXGI_FORMAT_R8G8B8A8_UNORM; -use winapi::shared::dxgitype::DXGI_SAMPLE_DESC; -use winapi::shared::minwindef::{FALSE, UINT}; -use winapi::shared::ntdef::HANDLE; -use winapi::shared::windef::HWND; -use winapi::shared::winerror; -use winapi::um::d3d11::{ID3D11Texture2D, D3D11_USAGE_DEFAULT}; -use winapi::um::d3d11::{D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE}; -use winapi::um::d3d11::{D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX, D3D11_TEXTURE2D_DESC}; -use winapi::um::handleapi::INVALID_HANDLE_VALUE; -use winapi::um::wingdi; -use winapi::um::winuser; -use winapi::Interface; -use wio::com::ComPtr; +use windows::core::Interface; +use windows::Win32::Foundation::HANDLE; +use windows::Win32::Foundation::HWND; +use windows::Win32::Foundation::INVALID_HANDLE_VALUE; +use windows::Win32::Graphics::Direct3D11::{ID3D11Texture2D, D3D11_USAGE_DEFAULT}; +use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE}; +use windows::Win32::Graphics::Direct3D11::{ + D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX, D3D11_TEXTURE2D_DESC, +}; +use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R8G8B8A8_UNORM; +use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC; +use windows::Win32::Graphics::Dxgi::IDXGIResource; +use windows::Win32::Graphics::Gdi::{GetDC, ReleaseDC}; +use windows::Win32::Graphics::OpenGL::{GetPixelFormat, SwapBuffers}; +use windows::Win32::UI::WindowsAndMessaging::GetWindowRect; const SURFACE_GL_TEXTURE_TARGET: GLenum = gl::TEXTURE_2D; @@ -64,7 +63,7 @@ pub struct Surface { pub(crate) enum Win32Objects { Texture { - d3d11_texture: ComPtr, + d3d11_texture: ID3D11Texture2D, dxgi_share_handle: HANDLE, gl_dx_interop_object: HANDLE, gl_texture: GLuint, @@ -88,7 +87,7 @@ pub(crate) enum Win32Objects { pub struct SurfaceTexture { pub(crate) surface: Surface, #[allow(dead_code)] - pub(crate) local_d3d11_texture: ComPtr, + pub(crate) local_d3d11_texture: ID3D11Texture2D, local_gl_dx_interop_object: HANDLE, pub(crate) gl_texture: GLuint, pub(crate) phantom: PhantomData<*const ()>, @@ -158,8 +157,8 @@ impl Device { // Create the Direct3D 11 texture. let d3d11_texture2d_desc = D3D11_TEXTURE2D_DESC { - Width: size.width as UINT, - Height: size.height as UINT, + Width: size.width as u32, + Height: size.height as u32, MipLevels: 1, ArraySize: 1, Format: DXGI_FORMAT_R8G8B8A8_UNORM, @@ -168,45 +167,39 @@ impl Device { Quality: 0, }, Usage: D3D11_USAGE_DEFAULT, - BindFlags: D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, + BindFlags: (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET).0 as u32, CPUAccessFlags: 0, - MiscFlags: D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX, + MiscFlags: D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX.0 as u32, }; - let mut d3d11_texture = ptr::null_mut(); - let mut result = self.d3d11_device.CreateTexture2D( - &d3d11_texture2d_desc, - ptr::null(), - &mut d3d11_texture, - ); - if !winerror::SUCCEEDED(result) { + let d3d11_texture = Default::default(); + let result = + self.d3d11_device + .CreateTexture2D(&d3d11_texture2d_desc, None, d3d11_texture); + if !result.is_ok() { return Err(Error::SurfaceCreationFailed(WindowingApiError::Failed)); } - assert!(!d3d11_texture.is_null()); - let d3d11_texture = ComPtr::from_raw(d3d11_texture); - + assert!(d3d11_texture.is_some()); // Upcast it to a DXGI resource. - let mut dxgi_resource: *mut IDXGIResource = ptr::null_mut(); - result = d3d11_texture.QueryInterface( - &IDXGIResource::uuidof(), - &mut dxgi_resource as *mut *mut IDXGIResource as *mut *mut c_void, - ); - assert!(winerror::SUCCEEDED(result)); + let d3d11_texture = d3d11_texture.unwrap(); + let dxgi_resource = d3d11_texture.cast::(); + // assert!(result.is_ok()); assert!(!dxgi_resource.is_null()); - let dxgi_resource = ComPtr::from_raw(dxgi_resource); + // let dxgi_resource = ComPtr::from_raw(dxgi_resource); // Get the share handle. We'll need it both to bind to GL and to share the texture // across contexts. - let mut dxgi_share_handle = INVALID_HANDLE_VALUE; - result = dxgi_resource.GetSharedHandle(&mut dxgi_share_handle); - assert!(winerror::SUCCEEDED(result)); + let result = dxgi_resource.as_ref().unwrap().GetSharedHandle(); + assert!(result.is_ok()); + let dxgi_share_handle = result.unwrap(); assert_ne!(dxgi_share_handle, INVALID_HANDLE_VALUE); // Tell GL about the share handle. + let d3d11_texture = d3d11_texture; let ok = (dx_interop_functions.DXSetResourceShareHandleNV)( - d3d11_texture.as_raw() as *mut c_void, + d3d11_texture as *mut c_void, dxgi_share_handle, ); - assert_ne!(ok, FALSE); + assert_ne!(ok, false); // Make our texture object on the GL side. let mut gl_texture = 0; @@ -215,13 +208,13 @@ impl Device { // Bind the GL texture to the D3D11 texture. let gl_dx_interop_object = (dx_interop_functions.DXRegisterObjectNV)( self.gl_dx_interop_device, - d3d11_texture.as_raw() as *mut c_void, + d3d11_texture as *mut c_void, gl_texture, gl::TEXTURE_2D, WGL_ACCESS_READ_WRITE_NV, ); // Per the spec, and unlike other HANDLEs, null indicates an error. - if gl_dx_interop_object.is_null() { + if gl_dx_interop_object.is_invalid() { let msg = std::io::Error::last_os_error(); // Equivalent to GetLastError(). error!( "Unable to share surface between OpenGL and DirectX. OS error '{}'.", @@ -253,6 +246,8 @@ impl Device { // FIXME(pcwalton): Do we need to acquire the keyed mutex, or does the GL driver do // that? + let d3d11_texture = (*d3d11_texture).to_owned().unwrap(); + Ok(Surface { size: *size, context_id: context.id, @@ -277,16 +272,16 @@ impl Device { unsafe { // Get the bounds of the native HWND. let mut widget_rect = mem::zeroed(); - let ok = winuser::GetWindowRect(native_widget.window_handle, &mut widget_rect); - if ok == FALSE { + let ok = GetWindowRect(native_widget.window_handle, &mut widget_rect); + if ok.is_err() { return Err(Error::InvalidNativeWidget); } // Set its pixel format. { let context_dc_guard = self.get_context_dc(context); - let pixel_format = wingdi::GetPixelFormat(context_dc_guard.dc); - let window_dc = winuser::GetDC(native_widget.window_handle); + let pixel_format = GetPixelFormat(context_dc_guard.dc); + let window_dc = GetDC(native_widget.window_handle); context::set_dc_pixel_format(window_dc, pixel_format); } @@ -349,7 +344,7 @@ impl Device { self.gl_dx_interop_device, *gl_dx_interop_object, ); - assert_ne!(ok, FALSE); + assert_ne!(ok, false); *gl_dx_interop_object = INVALID_HANDLE_VALUE; } Win32Objects::Widget { window_handle: _ } => {} @@ -395,26 +390,23 @@ impl Device { unsafe { // Create a new texture wrapping the shared handle. - let mut local_d3d11_texture = ptr::null_mut(); - let result = self.d3d11_device.OpenSharedResource( - dxgi_share_handle, - &ID3D11Texture2D::uuidof(), - &mut local_d3d11_texture, - ); - if !winerror::SUCCEEDED(result) || local_d3d11_texture.is_null() { + let mut local_d3d11_texture = Default::default(); + let result = self + .d3d11_device + .OpenSharedResource(dxgi_share_handle, &mut local_d3d11_texture); + if result.is_err() || local_d3d11_texture.is_none() { return Err(( Error::SurfaceImportFailed(WindowingApiError::Failed), surface, )); } - let local_d3d11_texture = ComPtr::from_raw(local_d3d11_texture as *mut ID3D11Texture2D); - + let local_d3d11_texture: ID3D11Texture2D = local_d3d11_texture.unwrap(); // Make GL aware of the connection between the share handle and the texture. let ok = (dx_interop_functions.DXSetResourceShareHandleNV)( local_d3d11_texture.as_raw() as *mut c_void, dxgi_share_handle, ); - assert_ne!(ok, FALSE); + assert_ne!(ok, false); // Create a GL texture. let mut gl_texture = 0; @@ -435,7 +427,7 @@ impl Device { 1, &mut local_gl_dx_interop_object, ); - assert_ne!(ok, FALSE); + assert_ne!(ok, false); // Initialize the texture, for convenience. // FIXME(pcwalton): We should probably reset the bound texture after this. @@ -456,7 +448,6 @@ impl Device { gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as GLint, ); - // Finish up. Ok(SurfaceTexture { surface, @@ -497,14 +488,14 @@ impl Device { 1, &mut surface_texture.local_gl_dx_interop_object, ); - assert_ne!(ok, FALSE); + assert_ne!(ok, false); // Unregister the texture from GL/DX interop. let ok = (dx_interop_functions.DXUnregisterObjectNV)( self.gl_dx_interop_device, surface_texture.local_gl_dx_interop_object, ); - assert_ne!(ok, FALSE); + assert_ne!(ok, false); surface_texture.local_gl_dx_interop_object = INVALID_HANDLE_VALUE; // Destroy the GL texture. @@ -535,7 +526,7 @@ impl Device { 1, &mut gl_dx_interop_object, ); - assert_ne!(ok, FALSE); + assert_ne!(ok, false); } } @@ -559,7 +550,7 @@ impl Device { 1, &mut gl_dx_interop_object, ); - assert_ne!(ok, FALSE); + assert_ne!(ok, false); } } @@ -594,10 +585,10 @@ impl Device { }; unsafe { - let dc = winuser::GetDC(window_handle); - let ok = wingdi::SwapBuffers(dc); - assert_ne!(ok, FALSE); - winuser::ReleaseDC(window_handle, dc); + let dc = GetDC(window_handle); + let ok = SwapBuffers(dc); + assert!(ok.is_ok()); + ReleaseDC(window_handle, dc); Ok(()) } } @@ -647,7 +638,7 @@ impl Surface { Win32Objects::Texture { ref d3d11_texture, .. } => SurfaceID((*d3d11_texture).as_raw() as usize), - Win32Objects::Widget { window_handle } => SurfaceID(window_handle as usize), + Win32Objects::Widget { window_handle } => SurfaceID(window_handle.0 as usize), } } }