use crate::base::egl::ffi::EGLImageKHR;
use crate::context::ContextID;
use crate::{Context, Device, Error};
use crate::base::egl::device::EGL_FUNCTIONS;
use euclid::default::Size2D;
use glow::Texture;
use std::fmt::{self, Debug, Formatter};
use std::marker::PhantomData;
use std::thread;
pub use crate::base::egl::context::ContextDescriptor;
#[cfg(android_platform)]
mod android_surface;
#[cfg(android_platform)]
pub use android_surface::*;
#[cfg(ohos_platform)]
mod ohos_surface;
#[cfg(ohos_platform)]
pub use ohos_surface::*;
pub struct Surface {
pub(crate) context_id: ContextID,
pub(crate) size: Size2D<i32>,
pub(crate) objects: SurfaceObjects,
pub(crate) destroyed: bool,
}
pub struct SurfaceTexture {
pub(crate) surface: Surface,
pub(crate) local_egl_image: EGLImageKHR,
pub(crate) texture_object: Option<Texture>,
pub(crate) phantom: PhantomData<*const ()>,
}
unsafe impl Send for Surface {}
impl Debug for Surface {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
write!(formatter, "Surface({:x})", self.id().0)
}
}
impl Drop for Surface {
fn drop(&mut self) {
if !self.destroyed && !thread::panicking() {
panic!("Should have destroyed the surface first with `destroy_surface()`!")
}
}
}
impl Surface {
pub(crate) fn resize(&mut self, size: Size2D<i32>) {
self.size = size;
}
}
impl Debug for SurfaceTexture {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
write!(f, "SurfaceTexture({:?})", self.surface)
}
}
impl Device {
pub fn present_surface(&self, context: &Context, surface: &mut Surface) -> Result<(), Error> {
self.present_surface_inner(context, surface)
}
pub(crate) fn present_surface_inner(
&self,
context: &Context,
surface: &Surface,
) -> Result<(), Error> {
if context.id != surface.context_id {
return Err(Error::IncompatibleSurface);
}
EGL_FUNCTIONS.with(|egl| unsafe {
match surface.objects {
SurfaceObjects::Window { egl_surface } => {
egl.SwapBuffers(self.egl_display, egl_surface);
Ok(())
}
_ => Err(Error::NoWidgetAttached),
}
})
}
pub fn resize_surface(
&self,
_context: &Context,
surface: &mut Surface,
size: Size2D<i32>,
) -> Result<(), Error> {
surface.resize(size);
Ok(())
}
}