use glow::{Context, HasContext};
use std::rc::Rc;
use std::borrow::Cow;
use crate::access::{AccessLock, UnitAccessLock};
#[derive(Debug)]
pub(crate) struct InnerShader {
pub(crate) context: Rc<Context>,
pub(crate) access: UnitAccessLock,
pub(crate) shader: <Context as HasContext>::Shader,
}
impl Drop for InnerShader {
fn drop(&mut self) {
unsafe {
let _atom = self.access.acquire_write_guarded();
self.context.delete_shader(self.shader)
}
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum ShaderSource<'a> {
Glsl(Cow<'a, str>)
}
macro_rules! instance_shaders {
(
$(
$(#[$outer:meta])*
pub struct $name:ident: $kind:expr;
)+
) => {$(
$(#[$outer])*
pub struct $name {
pub(crate) inner: Rc<InnerShader>,
}
impl $name {
#[allow(dead_code)]
pub(crate) const GL_TYPE: u32 = $kind;
#[allow(dead_code)]
pub unsafe fn as_raw_handle(&self) -> <Context as HasContext>::Shader {
self.inner.shader
}
}
impl AccessLock for $name {
fn write_locks(&self) -> usize { self.inner.access.write_locks() }
fn read_locks(&self) -> usize { self.inner.access.read_locks() }
fn acquire_write(&self) { self.inner.access.acquire_write() }
fn release_write(&self) { self.inner.access.release_write() }
fn acquire_read(&self) { self.inner.access.acquire_read() }
fn release_read(&self) { self.inner.access.release_read() }
}
)+}
}
instance_shaders! {
#[doc = "An instanced and successfully compiled vertex shader object."]
#[derive(Debug)]
pub struct VertexShader: glow::VERTEX_SHADER;
#[doc = "An instanced and successfully compiled fragment shader object."]
#[derive(Debug)]
pub struct FragmentShader: glow::FRAGMENT_SHADER;
#[doc = "An instanced and successfully compiled compute shader object."]
#[doc = ""]
#[doc = "# Support"]
#[doc = "Keep in mind that compute shaders are only supported in OpenGL "]
#[doc = "ES 3.1 and above."]
#[derive(Debug)]
pub struct ComputeShader: glow::COMPUTE_SHADER;
}
#[derive(Debug, thiserror::Error)]
pub enum ShaderError {
#[error("could not create shader object: {what}")]
CreationFailed {
what: String
},
#[error("could not compile shader object: {what}")]
CompilationFailed {
what: String
}
}