autocommit 2022-01-28 19:46:23 CET
This commit is contained in:
parent
a5573b8a3a
commit
b11a36729c
45 changed files with 1646 additions and 2171 deletions
72
src/render/egl/context.rs
Normal file
72
src/render/egl/context.rs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
use crate::render::egl::display::EglDisplay;
|
||||
use crate::render::egl::sys::{
|
||||
eglDestroyContext, eglMakeCurrent, EGLContext, EGLSurface, EGL_FALSE, EGL_TRUE,
|
||||
};
|
||||
use crate::render::ext::GlExt;
|
||||
use crate::render::gl::sys::{GLint, GLuint};
|
||||
use crate::render::RenderError;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EglContext {
|
||||
pub dpy: Rc<EglDisplay>,
|
||||
pub ext: GlExt,
|
||||
pub ctx: EGLContext,
|
||||
|
||||
pub tex_prog: GLuint,
|
||||
pub tex_tex: GLint,
|
||||
pub tex_texcoord: GLint,
|
||||
pub tex_pos: GLint,
|
||||
}
|
||||
|
||||
impl Drop for EglContext {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if eglDestroyContext(self.dpy.dpy, self.ctx) != EGL_TRUE {
|
||||
log::warn!("`eglDestroyContext` failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[thread_local]
|
||||
static mut CURRENT: EGLContext = EGLContext::none();
|
||||
|
||||
impl EglContext {
|
||||
#[inline]
|
||||
pub fn with_current<T, F: FnOnce() -> Result<T, RenderError>>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> Result<T, RenderError> {
|
||||
unsafe {
|
||||
if CURRENT == self.ctx {
|
||||
return f();
|
||||
}
|
||||
self.with_current_slow(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cold]
|
||||
unsafe fn with_current_slow<T, F: FnOnce() -> Result<T, RenderError>>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> Result<T, RenderError> {
|
||||
if eglMakeCurrent(
|
||||
self.dpy.dpy,
|
||||
EGLSurface::none(),
|
||||
EGLSurface::none(),
|
||||
self.ctx,
|
||||
) == EGL_FALSE
|
||||
{
|
||||
return Err(RenderError::MakeCurrent);
|
||||
}
|
||||
let prev = CURRENT;
|
||||
CURRENT = self.ctx;
|
||||
let res = f();
|
||||
if eglMakeCurrent(self.dpy.dpy, EGLSurface::none(), EGLSurface::none(), prev) == EGL_FALSE {
|
||||
panic!("Could not restore EGLContext");
|
||||
}
|
||||
CURRENT = prev;
|
||||
res
|
||||
}
|
||||
}
|
||||
99
src/render/egl/device.rs
Normal file
99
src/render/egl/device.rs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
use crate::format::{formats, Format};
|
||||
use crate::render::egl::display::EglDisplay;
|
||||
use crate::render::egl::sys::{
|
||||
eglInitialize, EGLDeviceEXT, EGLDisplay, EGLint, EGL_PLATFORM_DEVICE_EXT, EGL_TRUE,
|
||||
};
|
||||
use crate::render::egl::PROCS;
|
||||
use crate::render::ext::{get_display_ext, DeviceExt, DisplayExt};
|
||||
use crate::render::RenderError;
|
||||
use ahash::AHashMap;
|
||||
use std::ffi::CStr;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct EglDevice {
|
||||
pub exts: DeviceExt,
|
||||
pub dev: EGLDeviceEXT,
|
||||
}
|
||||
|
||||
impl EglDevice {
|
||||
pub fn query_string(&self, name: EGLint) -> Result<&'static CStr, RenderError> {
|
||||
unsafe {
|
||||
let res = PROCS.eglQueryDeviceStringEXT(self.dev, name);
|
||||
if res.is_null() {
|
||||
return Err(RenderError::DeviceQueryString);
|
||||
}
|
||||
Ok(CStr::from_ptr(res))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_display(&self) -> Result<Rc<EglDisplay>, RenderError> {
|
||||
unsafe {
|
||||
let dpy = PROCS.eglGetPlatformDisplayEXT(
|
||||
EGL_PLATFORM_DEVICE_EXT as _,
|
||||
self.dev.0,
|
||||
ptr::null(),
|
||||
);
|
||||
if dpy.is_none() {
|
||||
return Err(RenderError::GetDisplay);
|
||||
}
|
||||
let mut dpy = EglDisplay {
|
||||
exts: DisplayExt::empty(),
|
||||
formats: AHashMap::new(),
|
||||
dev: *self,
|
||||
dpy,
|
||||
};
|
||||
let mut major = 0;
|
||||
let mut minor = 0;
|
||||
if eglInitialize(dpy.dpy, &mut major, &mut minor) != EGL_TRUE {
|
||||
return Err(RenderError::Initialize);
|
||||
}
|
||||
dpy.exts = get_display_ext(dpy.dpy);
|
||||
if !dpy.exts.intersects(DisplayExt::KHR_IMAGE_BASE) {
|
||||
return Err(RenderError::ImageBase);
|
||||
}
|
||||
if !dpy
|
||||
.exts
|
||||
.intersects(DisplayExt::EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS)
|
||||
{
|
||||
return Err(RenderError::DmaBufImport);
|
||||
}
|
||||
if !dpy
|
||||
.exts
|
||||
.intersects(DisplayExt::KHR_NO_CONFIG_CONTEXT | DisplayExt::MESA_CONFIGLESS_CONTEXT)
|
||||
{
|
||||
return Err(RenderError::ConfiglessContext);
|
||||
}
|
||||
if !dpy.exts.intersects(DisplayExt::KHR_SURFACELESS_CONTEXT) {
|
||||
return Err(RenderError::SurfacelessContext);
|
||||
}
|
||||
dpy.formats = query_formats(dpy.dpy)?;
|
||||
|
||||
Ok(Rc::new(dpy))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn query_formats(dpy: EGLDisplay) -> Result<AHashMap<u32, &'static Format>, RenderError> {
|
||||
let mut vec = vec![];
|
||||
let mut num = 0;
|
||||
let res = PROCS.eglQueryDmaBufFormatsEXT(dpy, num, ptr::null_mut(), &mut num);
|
||||
if res != EGL_TRUE {
|
||||
return Err(RenderError::QueryDmaBufFormats);
|
||||
}
|
||||
vec.reserve_exact(num as usize);
|
||||
let res = PROCS.eglQueryDmaBufFormatsEXT(dpy, num, vec.as_mut_ptr(), &mut num);
|
||||
if res != EGL_TRUE {
|
||||
return Err(RenderError::QueryDmaBufFormats);
|
||||
}
|
||||
vec.set_len(num as usize);
|
||||
let mut res = AHashMap::new();
|
||||
let formats = formats();
|
||||
for fmt in vec {
|
||||
if let Some(format) = formats.get(&(fmt as u32)) {
|
||||
res.insert(format.drm, *format);
|
||||
}
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
147
src/render/egl/display.rs
Normal file
147
src/render/egl/display.rs
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
use crate::drm::dma::DmaBuf;
|
||||
use crate::drm::INVALID_MODIFIER;
|
||||
use crate::format::Format;
|
||||
use crate::render::egl::context::EglContext;
|
||||
use crate::render::egl::device::EglDevice;
|
||||
use crate::render::egl::image::EglImage;
|
||||
use crate::render::egl::sys::{
|
||||
eglCreateContext, eglTerminate, EGLClientBuffer, EGLConfig, EGLContext, EGLDisplay, EGLint,
|
||||
EGL_CONTEXT_CLIENT_VERSION, EGL_DMA_BUF_PLANE0_FD_EXT, EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT,
|
||||
EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE0_OFFSET_EXT,
|
||||
EGL_DMA_BUF_PLANE0_PITCH_EXT, EGL_DMA_BUF_PLANE1_FD_EXT, EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT,
|
||||
EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE1_OFFSET_EXT,
|
||||
EGL_DMA_BUF_PLANE1_PITCH_EXT, EGL_DMA_BUF_PLANE2_FD_EXT, EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT,
|
||||
EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE2_OFFSET_EXT,
|
||||
EGL_DMA_BUF_PLANE2_PITCH_EXT, EGL_DMA_BUF_PLANE3_FD_EXT, EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT,
|
||||
EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE3_OFFSET_EXT,
|
||||
EGL_DMA_BUF_PLANE3_PITCH_EXT, EGL_HEIGHT, EGL_IMAGE_PRESERVED_KHR, EGL_LINUX_DMA_BUF_EXT,
|
||||
EGL_LINUX_DRM_FOURCC_EXT, EGL_NONE, EGL_TRUE, EGL_WIDTH,
|
||||
};
|
||||
use crate::render::egl::PROCS;
|
||||
use crate::render::ext::{get_gl_ext, DisplayExt, GlExt};
|
||||
use crate::render::RenderError;
|
||||
use ahash::AHashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EglDisplay {
|
||||
pub exts: DisplayExt,
|
||||
pub formats: AHashMap<u32, &'static Format>,
|
||||
pub dev: EglDevice,
|
||||
pub dpy: EGLDisplay,
|
||||
}
|
||||
|
||||
impl EglDisplay {
|
||||
pub fn create_context(self: &Rc<Self>) -> Result<Rc<EglContext>, RenderError> {
|
||||
let attrib = [EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE];
|
||||
unsafe {
|
||||
let ctx = eglCreateContext(
|
||||
self.dpy,
|
||||
EGLConfig::none(),
|
||||
EGLContext::none(),
|
||||
attrib.as_ptr(),
|
||||
);
|
||||
if ctx.is_none() {
|
||||
return Err(RenderError::CreateContext);
|
||||
}
|
||||
let mut ctx = EglContext {
|
||||
dpy: self.clone(),
|
||||
ext: GlExt::empty(),
|
||||
ctx,
|
||||
tex_prog: 0,
|
||||
tex_tex: 0,
|
||||
tex_texcoord: 0,
|
||||
tex_pos: 0,
|
||||
};
|
||||
ctx.ext = ctx.with_current(|| Ok(get_gl_ext()))?;
|
||||
// if !ctx.ext.contains(GlExt::GL_OES_EGL_IMAGE) {
|
||||
// return Err(GlesError::OesEglImage);
|
||||
// }
|
||||
Ok(Rc::new(ctx))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn import_dmabuf(self: &Rc<Self>, buf: &DmaBuf) -> Result<Rc<EglImage>, RenderError> {
|
||||
struct PlaneKey {
|
||||
fd: EGLint,
|
||||
offset: EGLint,
|
||||
pitch: EGLint,
|
||||
mod_lo: EGLint,
|
||||
mod_hi: EGLint,
|
||||
}
|
||||
const PLANE_KEYS: [PlaneKey; 4] = [
|
||||
PlaneKey {
|
||||
fd: EGL_DMA_BUF_PLANE0_FD_EXT,
|
||||
offset: EGL_DMA_BUF_PLANE0_OFFSET_EXT,
|
||||
pitch: EGL_DMA_BUF_PLANE0_PITCH_EXT,
|
||||
mod_lo: EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT,
|
||||
mod_hi: EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT,
|
||||
},
|
||||
PlaneKey {
|
||||
fd: EGL_DMA_BUF_PLANE1_FD_EXT,
|
||||
offset: EGL_DMA_BUF_PLANE1_OFFSET_EXT,
|
||||
pitch: EGL_DMA_BUF_PLANE1_PITCH_EXT,
|
||||
mod_lo: EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
|
||||
mod_hi: EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT,
|
||||
},
|
||||
PlaneKey {
|
||||
fd: EGL_DMA_BUF_PLANE2_FD_EXT,
|
||||
offset: EGL_DMA_BUF_PLANE2_OFFSET_EXT,
|
||||
pitch: EGL_DMA_BUF_PLANE2_PITCH_EXT,
|
||||
mod_lo: EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT,
|
||||
mod_hi: EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT,
|
||||
},
|
||||
PlaneKey {
|
||||
fd: EGL_DMA_BUF_PLANE3_FD_EXT,
|
||||
offset: EGL_DMA_BUF_PLANE3_OFFSET_EXT,
|
||||
pitch: EGL_DMA_BUF_PLANE3_PITCH_EXT,
|
||||
mod_lo: EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT,
|
||||
mod_hi: EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT,
|
||||
},
|
||||
];
|
||||
|
||||
let mut attribs = vec![];
|
||||
attribs.extend_from_slice(&[EGL_WIDTH, buf.width]);
|
||||
attribs.extend_from_slice(&[EGL_HEIGHT, buf.height]);
|
||||
attribs.extend_from_slice(&[EGL_LINUX_DRM_FOURCC_EXT, buf.format.drm as _]);
|
||||
attribs.extend_from_slice(&[EGL_IMAGE_PRESERVED_KHR, EGL_TRUE as _]);
|
||||
for (key, plane) in PLANE_KEYS.iter().zip(buf.planes.iter()) {
|
||||
attribs.extend_from_slice(&[key.fd, plane.fd.raw()]);
|
||||
attribs.extend_from_slice(&[key.pitch, plane.stride as _]);
|
||||
attribs.extend_from_slice(&[key.offset, plane.offset as _]);
|
||||
if buf.modifier != INVALID_MODIFIER {
|
||||
attribs.extend_from_slice(&[key.mod_lo, buf.modifier as i32]);
|
||||
attribs.extend_from_slice(&[key.mod_hi, (buf.modifier >> 32) as i32]);
|
||||
}
|
||||
}
|
||||
attribs.push(EGL_NONE);
|
||||
let img = unsafe {
|
||||
PROCS.eglCreateImageKHR(
|
||||
self.dpy,
|
||||
EGLContext::none(),
|
||||
EGL_LINUX_DMA_BUF_EXT as _,
|
||||
EGLClientBuffer::none(),
|
||||
attribs.as_ptr(),
|
||||
)
|
||||
};
|
||||
if img.is_none() {
|
||||
return Err(RenderError::CreateImage);
|
||||
}
|
||||
Ok(Rc::new(EglImage {
|
||||
dpy: self.clone(),
|
||||
img,
|
||||
width: buf.width,
|
||||
height: buf.height,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EglDisplay {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if eglTerminate(self.dpy) != EGL_TRUE {
|
||||
log::warn!("`eglTerminate` failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/render/egl/image.rs
Normal file
21
src/render/egl/image.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
use crate::render::egl::display::EglDisplay;
|
||||
use crate::render::egl::sys::{EGLImageKHR, EGL_FALSE};
|
||||
use crate::render::egl::PROCS;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct EglImage {
|
||||
pub dpy: Rc<EglDisplay>,
|
||||
pub img: EGLImageKHR,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
}
|
||||
|
||||
impl Drop for EglImage {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if PROCS.eglDestroyImageKHR(self.dpy.dpy, self.img) == EGL_FALSE {
|
||||
log::warn!("`eglDestroyImageKHR` failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
171
src/render/egl/mod.rs
Normal file
171
src/render/egl/mod.rs
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
use crate::drm::drm::Drm;
|
||||
use crate::render::egl::device::EglDevice;
|
||||
use crate::render::egl::sys::{
|
||||
eglBindAPI, EGLAttrib, EGLLabelKHR, EGLenum, EGLint, EGL_DEBUG_MSG_CRITICAL_KHR,
|
||||
EGL_DEBUG_MSG_ERROR_KHR, EGL_DEBUG_MSG_INFO_KHR, EGL_DEBUG_MSG_WARN_KHR,
|
||||
EGL_DRM_DEVICE_FILE_EXT, EGL_NONE, EGL_OPENGL_ES_API, EGL_TRUE,
|
||||
};
|
||||
use crate::render::ext::{get_client_ext, get_device_ext, ClientExt, DeviceExt};
|
||||
use crate::render::proc::ExtProc;
|
||||
use crate::render::RenderError;
|
||||
use bstr::ByteSlice;
|
||||
use log::Level;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::ffi::CStr;
|
||||
use std::ptr;
|
||||
use sys::{
|
||||
EGL_BAD_ACCESS, EGL_BAD_ALLOC, EGL_BAD_ATTRIBUTE, EGL_BAD_CONFIG, EGL_BAD_CONTEXT,
|
||||
EGL_BAD_CURRENT_SURFACE, EGL_BAD_DEVICE_EXT, EGL_BAD_DISPLAY, EGL_BAD_MATCH,
|
||||
EGL_BAD_NATIVE_PIXMAP, EGL_BAD_NATIVE_WINDOW, EGL_BAD_PARAMETER, EGL_BAD_SURFACE,
|
||||
EGL_CONTEXT_LOST, EGL_NOT_INITIALIZED, EGL_SUCCESS,
|
||||
};
|
||||
use uapi::c;
|
||||
|
||||
pub mod context;
|
||||
pub mod device;
|
||||
pub mod display;
|
||||
pub mod image;
|
||||
pub mod sys;
|
||||
|
||||
pub(super) static PROCS: Lazy<ExtProc> = Lazy::new(|| ExtProc::load());
|
||||
|
||||
pub(super) static EXTS: Lazy<ClientExt> = Lazy::new(|| get_client_ext());
|
||||
|
||||
pub fn init() -> Result<(), RenderError> {
|
||||
if !EXTS.contains(ClientExt::EXT_PLATFORM_BASE) {
|
||||
return Err(RenderError::ExtPlatformBase);
|
||||
}
|
||||
if !EXTS.device_query() {
|
||||
return Err(RenderError::DeviceQuery);
|
||||
}
|
||||
if !EXTS.device_enumeration() {
|
||||
return Err(RenderError::DeviceEnumeration);
|
||||
}
|
||||
if EXTS.contains(ClientExt::KHR_DEBUG) {
|
||||
let attrib: &[EGLAttrib] = &[
|
||||
EGL_DEBUG_MSG_CRITICAL_KHR as _,
|
||||
EGL_TRUE as _,
|
||||
EGL_DEBUG_MSG_ERROR_KHR as _,
|
||||
EGL_TRUE as _,
|
||||
EGL_DEBUG_MSG_WARN_KHR as _,
|
||||
EGL_TRUE as _,
|
||||
EGL_DEBUG_MSG_INFO_KHR as _,
|
||||
EGL_TRUE as _,
|
||||
EGL_NONE as _,
|
||||
];
|
||||
unsafe {
|
||||
PROCS.eglDebugMessageControlKHR(egl_log, attrib.as_ptr());
|
||||
}
|
||||
}
|
||||
if unsafe { eglBindAPI(EGL_OPENGL_ES_API) } != EGL_TRUE {
|
||||
return Err(RenderError::BindFailed);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn find_drm_device(drm: &Drm) -> Result<Option<EglDevice>, RenderError> {
|
||||
let drm_dev = drm.get_device()?;
|
||||
for device in query_devices()? {
|
||||
if device.exts.contains(DeviceExt::EXT_DEVICE_DRM) {
|
||||
let device_file = device.query_string(EGL_DRM_DEVICE_FILE_EXT)?;
|
||||
for (_, name) in drm_dev.nodes() {
|
||||
if device_file == name {
|
||||
return Ok(Some(device));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn query_devices() -> Result<Vec<EglDevice>, RenderError> {
|
||||
if !EXTS.device_enumeration() {
|
||||
return Err(RenderError::DeviceEnumeration);
|
||||
}
|
||||
unsafe {
|
||||
let mut devices = vec![];
|
||||
let mut num_devices = 0;
|
||||
let res = PROCS.eglQueryDevicesEXT(num_devices, ptr::null_mut(), &mut num_devices);
|
||||
if res != EGL_TRUE {
|
||||
return Err(RenderError::QueryDevices);
|
||||
}
|
||||
devices.reserve_exact(num_devices as usize);
|
||||
let res = PROCS.eglQueryDevicesEXT(num_devices, devices.as_mut_ptr(), &mut num_devices);
|
||||
if res != EGL_TRUE {
|
||||
return Err(RenderError::QueryDevices);
|
||||
}
|
||||
devices.set_len(num_devices as usize);
|
||||
Ok(devices
|
||||
.into_iter()
|
||||
.map(|d| EglDevice {
|
||||
exts: get_device_ext(d),
|
||||
dev: d,
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn egl_log(
|
||||
error: EGLenum,
|
||||
command: *const c::c_char,
|
||||
message_type: EGLint,
|
||||
_thread_label: EGLLabelKHR,
|
||||
_object_label: EGLLabelKHR,
|
||||
message: *const c::c_char,
|
||||
) {
|
||||
let level = match message_type {
|
||||
EGL_DEBUG_MSG_CRITICAL_KHR => Level::Error,
|
||||
EGL_DEBUG_MSG_ERROR_KHR => Level::Error,
|
||||
EGL_DEBUG_MSG_WARN_KHR => Level::Warn,
|
||||
EGL_DEBUG_MSG_INFO_KHR => Level::Info,
|
||||
_ => Level::Warn,
|
||||
};
|
||||
let command = if !command.is_null() {
|
||||
CStr::from_ptr(command).to_bytes()
|
||||
} else {
|
||||
b"none"
|
||||
};
|
||||
let message = if !message.is_null() {
|
||||
CStr::from_ptr(message).to_bytes()
|
||||
} else {
|
||||
b"none"
|
||||
};
|
||||
let err_name = error_name(error);
|
||||
log::log!(
|
||||
level,
|
||||
"EGL: command: {}, error: {} (0x{:x}), message: {}",
|
||||
command.as_bstr(),
|
||||
err_name,
|
||||
error,
|
||||
message.as_bstr()
|
||||
);
|
||||
}
|
||||
|
||||
fn error_name(error: EGLenum) -> &'static str {
|
||||
macro_rules! en {
|
||||
($($name:ident,)*) => {
|
||||
match error as _ {
|
||||
$($name => stringify!($name),)*
|
||||
_ => "unknown",
|
||||
}
|
||||
}
|
||||
}
|
||||
en! {
|
||||
EGL_SUCCESS,
|
||||
EGL_NOT_INITIALIZED,
|
||||
EGL_BAD_ACCESS,
|
||||
EGL_BAD_ALLOC,
|
||||
EGL_BAD_ATTRIBUTE,
|
||||
EGL_BAD_CONTEXT,
|
||||
EGL_BAD_CONFIG,
|
||||
EGL_BAD_CURRENT_SURFACE,
|
||||
EGL_BAD_DISPLAY,
|
||||
EGL_BAD_DEVICE_EXT,
|
||||
EGL_BAD_SURFACE,
|
||||
EGL_BAD_MATCH,
|
||||
EGL_BAD_PARAMETER,
|
||||
EGL_BAD_NATIVE_PIXMAP,
|
||||
EGL_BAD_NATIVE_WINDOW,
|
||||
EGL_CONTEXT_LOST,
|
||||
}
|
||||
}
|
||||
102
src/render/egl/sys.rs
Normal file
102
src/render/egl/sys.rs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
use uapi::c;
|
||||
|
||||
pub type EGLint = i32;
|
||||
pub type EGLenum = c::c_uint;
|
||||
pub type EGLBoolean = c::c_uint;
|
||||
pub type EGLuint64KHR = u64;
|
||||
pub type EGLAttrib = isize;
|
||||
|
||||
egl_transparent!(EGLDisplay);
|
||||
egl_transparent!(EGLSurface);
|
||||
egl_transparent!(EGLConfig);
|
||||
egl_transparent!(EGLImageKHR);
|
||||
egl_transparent!(EGLContext);
|
||||
egl_transparent!(EGLClientBuffer);
|
||||
egl_transparent!(EGLLabelKHR);
|
||||
egl_transparent!(EGLDeviceEXT);
|
||||
|
||||
pub type EGLDEBUGPROCKHR = unsafe extern "C" fn(
|
||||
error: EGLenum,
|
||||
command: *const c::c_char,
|
||||
message_type: EGLint,
|
||||
thread_label: EGLLabelKHR,
|
||||
object_label: EGLLabelKHR,
|
||||
message: *const c::c_char,
|
||||
);
|
||||
|
||||
pub const EGL_EXTENSIONS: EGLint = 0x3055;
|
||||
pub const EGL_DEBUG_MSG_CRITICAL_KHR: EGLint = 0x33B9;
|
||||
pub const EGL_DEBUG_MSG_ERROR_KHR: EGLint = 0x33BA;
|
||||
pub const EGL_DEBUG_MSG_WARN_KHR: EGLint = 0x33BB;
|
||||
pub const EGL_DEBUG_MSG_INFO_KHR: EGLint = 0x33BC;
|
||||
pub const EGL_TRUE: EGLBoolean = 1;
|
||||
pub const EGL_FALSE: EGLBoolean = 0;
|
||||
pub const EGL_NONE: EGLint = 0x3038;
|
||||
pub const EGL_SUCCESS: EGLint = 0x3000;
|
||||
pub const EGL_NOT_INITIALIZED: EGLint = 0x3001;
|
||||
pub const EGL_BAD_ACCESS: EGLint = 0x3002;
|
||||
pub const EGL_BAD_ALLOC: EGLint = 0x3003;
|
||||
pub const EGL_BAD_ATTRIBUTE: EGLint = 0x3004;
|
||||
pub const EGL_BAD_CONFIG: EGLint = 0x3005;
|
||||
pub const EGL_BAD_CONTEXT: EGLint = 0x3006;
|
||||
pub const EGL_BAD_CURRENT_SURFACE: EGLint = 0x3007;
|
||||
pub const EGL_BAD_DISPLAY: EGLint = 0x3008;
|
||||
pub const EGL_BAD_MATCH: EGLint = 0x3009;
|
||||
pub const EGL_BAD_NATIVE_PIXMAP: EGLint = 0x300A;
|
||||
pub const EGL_BAD_NATIVE_WINDOW: EGLint = 0x300B;
|
||||
pub const EGL_BAD_PARAMETER: EGLint = 0x300C;
|
||||
pub const EGL_BAD_SURFACE: EGLint = 0x300D;
|
||||
pub const EGL_CONTEXT_LOST: EGLint = 0x300E;
|
||||
pub const EGL_BAD_DEVICE_EXT: EGLint = 0x322B;
|
||||
pub const EGL_OPENGL_ES_API: EGLenum = 0x30A0;
|
||||
pub const EGL_DRM_DEVICE_FILE_EXT: EGLint = 0x3233;
|
||||
pub const EGL_PLATFORM_DEVICE_EXT: EGLint = 0x313F;
|
||||
pub const EGL_CONTEXT_CLIENT_VERSION: EGLint = 0x3098;
|
||||
|
||||
pub const EGL_WIDTH: EGLint = 0x3057;
|
||||
pub const EGL_HEIGHT: EGLint = 0x3056;
|
||||
pub const EGL_LINUX_DRM_FOURCC_EXT: EGLint = 0x3271;
|
||||
pub const EGL_DMA_BUF_PLANE0_FD_EXT: EGLint = 0x3272;
|
||||
pub const EGL_DMA_BUF_PLANE0_OFFSET_EXT: EGLint = 0x3273;
|
||||
pub const EGL_DMA_BUF_PLANE0_PITCH_EXT: EGLint = 0x3274;
|
||||
pub const EGL_DMA_BUF_PLANE1_FD_EXT: EGLint = 0x3275;
|
||||
pub const EGL_DMA_BUF_PLANE1_OFFSET_EXT: EGLint = 0x3276;
|
||||
pub const EGL_DMA_BUF_PLANE1_PITCH_EXT: EGLint = 0x3277;
|
||||
pub const EGL_DMA_BUF_PLANE2_FD_EXT: EGLint = 0x3278;
|
||||
pub const EGL_DMA_BUF_PLANE2_OFFSET_EXT: EGLint = 0x3279;
|
||||
pub const EGL_DMA_BUF_PLANE2_PITCH_EXT: EGLint = 0x327A;
|
||||
pub const EGL_DMA_BUF_PLANE3_FD_EXT: EGLint = 0x3440;
|
||||
pub const EGL_DMA_BUF_PLANE3_OFFSET_EXT: EGLint = 0x3441;
|
||||
pub const EGL_DMA_BUF_PLANE3_PITCH_EXT: EGLint = 0x3442;
|
||||
pub const EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT: EGLint = 0x3443;
|
||||
pub const EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT: EGLint = 0x3444;
|
||||
pub const EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT: EGLint = 0x3445;
|
||||
pub const EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT: EGLint = 0x3446;
|
||||
pub const EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT: EGLint = 0x3447;
|
||||
pub const EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT: EGLint = 0x3448;
|
||||
pub const EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT: EGLint = 0x3449;
|
||||
pub const EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT: EGLint = 0x344A;
|
||||
pub const EGL_IMAGE_PRESERVED_KHR: EGLint = 0x30D2;
|
||||
pub const EGL_LINUX_DMA_BUF_EXT: EGLint = 0x3270;
|
||||
|
||||
#[link(name = "EGL")]
|
||||
extern "C" {
|
||||
pub fn eglQueryString(dpy: EGLDisplay, name: EGLint) -> *const c::c_char;
|
||||
pub fn eglGetProcAddress(procname: *const c::c_char) -> *mut u8;
|
||||
pub fn eglBindAPI(api: EGLenum) -> EGLBoolean;
|
||||
pub fn eglTerminate(dpy: EGLDisplay) -> EGLBoolean;
|
||||
pub fn eglInitialize(dpy: EGLDisplay, major: *mut EGLint, minor: *mut EGLint) -> EGLBoolean;
|
||||
pub fn eglCreateContext(
|
||||
dpy: EGLDisplay,
|
||||
config: EGLConfig,
|
||||
share_context: EGLContext,
|
||||
attrib_list: *const EGLint,
|
||||
) -> EGLContext;
|
||||
pub fn eglDestroyContext(dpy: EGLDisplay, ctx: EGLContext) -> EGLBoolean;
|
||||
pub fn eglMakeCurrent(
|
||||
dpy: EGLDisplay,
|
||||
draw: EGLSurface,
|
||||
read: EGLSurface,
|
||||
ctx: EGLContext,
|
||||
) -> EGLBoolean;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue