-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
gl_glue.rs
123 lines (106 loc) · 3.93 KB
/
gl_glue.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#![allow(bare_trait_objects)] // Until https://github.com/brendanzab/gl-rs/pull/493
pub type ServoGl = std::rc::Rc<dyn servo::gl::Gl>;
#[cfg(any(target_os = "android", target_os = "windows"))]
#[allow(non_camel_case_types)]
pub mod egl {
use servo::gl::GlesFns;
use std::ffi::CString;
use std::os::raw::c_void;
pub type EGLNativeWindowType = *const libc::c_void;
pub type khronos_utime_nanoseconds_t = khronos_uint64_t;
pub type khronos_uint64_t = libc::uint64_t;
pub type khronos_ssize_t = libc::c_long;
pub type EGLint = libc::int32_t;
pub type EGLNativeDisplayType = *const libc::c_void;
pub type EGLNativePixmapType = *const libc::c_void;
pub type NativeDisplayType = EGLNativeDisplayType;
pub type NativePixmapType = EGLNativePixmapType;
pub type NativeWindowType = EGLNativeWindowType;
include!(concat!(env!("OUT_DIR"), "/egl_bindings.rs"));
pub fn init() -> Result<crate::gl_glue::ServoGl, &'static str> {
info!("Loading EGL...");
unsafe {
let egl = Egl;
let d = egl.GetCurrentDisplay();
egl.SwapInterval(d, 1);
let egl = GlesFns::load_with(|addr| {
let addr = CString::new(addr.as_bytes()).unwrap();
let addr = addr.as_ptr();
let egl = Egl;
egl.GetProcAddress(addr) as *const c_void
});
info!("EGL loaded");
Ok(egl)
}
}
}
#[cfg(target_os = "windows")]
pub mod gl {
pub fn init() -> Result<crate::gl_glue::ServoGl, &'static str> {
unimplemented!();
}
}
#[cfg(target_os = "macos")]
pub mod gl {
use core_foundation::base::TCFType;
use core_foundation::bundle::{
CFBundleGetBundleWithIdentifier, CFBundleGetFunctionPointerForName,
};
use core_foundation::string::CFString;
use servo::gl::GlFns;
use std::os::raw::c_void;
use std::str;
pub fn init() -> Result<crate::gl_glue::ServoGl, &'static str> {
info!("Loading OpenGL...");
let gl = unsafe {
GlFns::load_with(|addr| {
let symbol_name: CFString = str::FromStr::from_str(addr).unwrap();
let framework_name: CFString = str::FromStr::from_str("com.apple.opengl").unwrap();
let framework =
CFBundleGetBundleWithIdentifier(framework_name.as_concrete_TypeRef());
let symbol =
CFBundleGetFunctionPointerForName(framework, symbol_name.as_concrete_TypeRef());
symbol as *const c_void
})
};
info!("OpenGL loaded");
Ok(gl)
}
}
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "openbsd"
))]
pub mod gl {
use libloading::{Library, Symbol};
use servo::gl::GlFns;
use std::ffi::CString;
use std::os::raw::c_void;
pub fn init() -> Result<crate::gl_glue::ServoGl, &'static str> {
info!("Loading OpenGL");
pub mod glx {
include!(concat!(env!("OUT_DIR"), "/glx_bindings.rs"));
}
let lib = match Library::new("libGL.so.1").or_else(|_| Library::new("libGL.so")) {
Ok(lib) => lib,
Err(_) => return Err("Can't find libGL.so, OpenGL isn't configured/installed"),
};
let glx = glx::Glx::load_with(|sym| unsafe {
let symbol: Symbol<*const c_void> = lib.get(sym.as_bytes()).unwrap();
*symbol.into_raw()
});
let gl = unsafe {
GlFns::load_with(|addr| {
let addr = CString::new(addr.as_bytes()).unwrap();
glx.GetProcAddress(addr.as_ptr() as *const _) as *const _
})
};
info!("OpenGL is loaded");
Ok(gl)
}
}