1
0
Fork 0
forked from wry/wry

render: hide graphics API behind traits

This commit is contained in:
Julian Orth 2023-10-22 20:00:32 +02:00
parent d650b3375d
commit 24e410a5b5
40 changed files with 601 additions and 246 deletions

View file

@ -1,12 +1,12 @@
use {
crate::{
format::{Format, XRGB8888},
gfx_api::GfxApiOpt,
gfx_api::{
GfxApiOpt, GfxContext, GfxError, GfxFormat, GfxFramebuffer, GfxImage, GfxTexture,
ResetStatus,
},
gfx_apis::gl::{
egl::{
context::EglContext,
display::{EglDisplay, EglFormat},
},
egl::{context::EglContext, display::EglDisplay},
ext::GlExt,
gl::{
program::GlProgram, render_buffer::GlRenderBuffer, sys::GLint, texture::GlTexture,
@ -25,6 +25,7 @@ use {
cell::{Cell, RefCell},
ffi::CString,
fmt::{Debug, Formatter},
mem,
rc::Rc,
},
uapi::ustr,
@ -53,7 +54,7 @@ pub(crate) struct TexProgs {
pub solid: TexProg,
}
pub struct RenderContext {
pub(in crate::gfx_apis::gl) struct GlRenderContext {
pub(crate) ctx: Rc<EglContext>,
pub gbm: Rc<GbmDevice>,
@ -67,24 +68,16 @@ pub struct RenderContext {
pub(crate) fill_prog_color: GLint,
pub(crate) gfx_ops: RefCell<Vec<GfxApiOpt>>,
pub(crate) gl_state: RefCell<GfxGlState>,
pub(in crate::gfx_apis::gl) gl_state: RefCell<GfxGlState>,
}
impl Debug for RenderContext {
impl Debug for GlRenderContext {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RenderContext").finish_non_exhaustive()
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ResetStatus {
Guilty,
Innocent,
Unknown,
Other(u32),
}
impl RenderContext {
impl GlRenderContext {
pub fn reset_status(&self) -> Option<ResetStatus> {
self.ctx.reset_status()
}
@ -93,7 +86,7 @@ impl RenderContext {
self.ctx.ext.contains(GlExt::GL_OES_EGL_IMAGE_EXTERNAL)
}
pub fn from_drm_device(drm: &Drm) -> Result<Self, RenderError> {
pub(in crate::gfx_apis::gl) fn from_drm_device(drm: &Drm) -> Result<Self, RenderError> {
let nodes = drm.get_nodes()?;
let node = match nodes
.get(&NodeType::Render)
@ -167,11 +160,11 @@ impl RenderContext {
self.render_node.clone()
}
pub fn formats(&self) -> Rc<AHashMap<u32, EglFormat>> {
pub fn formats(&self) -> Rc<AHashMap<u32, GfxFormat>> {
self.ctx.dpy.formats.clone()
}
pub fn dmabuf_fb(self: &Rc<Self>, buf: &DmaBuf) -> Result<Rc<Framebuffer>, RenderError> {
fn dmabuf_fb(self: &Rc<Self>, buf: &DmaBuf) -> Result<Rc<Framebuffer>, RenderError> {
self.ctx.with_current(|| unsafe {
let img = self.ctx.dpy.import_dmabuf(buf)?;
let rb = GlRenderBuffer::from_image(&img, &self.ctx)?;
@ -183,7 +176,7 @@ impl RenderContext {
})
}
pub fn dmabuf_img(self: &Rc<Self>, buf: &DmaBuf) -> Result<Rc<Image>, RenderError> {
fn dmabuf_img(self: &Rc<Self>, buf: &DmaBuf) -> Result<Rc<Image>, RenderError> {
self.ctx.with_current(|| {
let img = self.ctx.dpy.import_dmabuf(buf)?;
Ok(Rc::new(Image {
@ -193,7 +186,7 @@ impl RenderContext {
})
}
pub fn shmem_texture(
fn shmem_texture(
self: &Rc<Self>,
data: &[Cell<u8>],
format: &'static Format,
@ -208,3 +201,57 @@ impl RenderContext {
}))
}
}
impl GfxContext for GlRenderContext {
fn take_render_ops(&self) -> Vec<GfxApiOpt> {
mem::take(&mut self.gfx_ops.borrow_mut())
}
fn reset_status(&self) -> Option<ResetStatus> {
self.reset_status()
}
fn supports_external_texture(&self) -> bool {
self.supports_external_texture()
}
fn render_node(&self) -> Rc<CString> {
self.render_node()
}
fn formats(&self) -> Rc<AHashMap<u32, GfxFormat>> {
self.formats()
}
fn dmabuf_fb(self: Rc<Self>, buf: &DmaBuf) -> Result<Rc<dyn GfxFramebuffer>, GfxError> {
(&self)
.dmabuf_fb(buf)
.map(|w| w as Rc<dyn GfxFramebuffer>)
.map_err(|e| e.into())
}
fn dmabuf_img(self: Rc<Self>, buf: &DmaBuf) -> Result<Rc<dyn GfxImage>, GfxError> {
(&self)
.dmabuf_img(buf)
.map(|w| w as Rc<dyn GfxImage>)
.map_err(|e| e.into())
}
fn shmem_texture(
self: Rc<Self>,
data: &[Cell<u8>],
format: &'static Format,
width: i32,
height: i32,
stride: i32,
) -> Result<Rc<dyn GfxTexture>, GfxError> {
(&self)
.shmem_texture(data, format, width, height, stride)
.map(|w| w as Rc<dyn GfxTexture>)
.map_err(|e| e.into())
}
fn gbm(&self) -> &GbmDevice {
&self.gbm
}
}

View file

@ -3,6 +3,7 @@ use {
cursor::Cursor,
fixed::Fixed,
format::{Format, ARGB8888, XRGB8888},
gfx_api::{GfxFramebuffer, GfxTexture},
gfx_apis::gl::{
gl::{
frame_buffer::GlFrameBuffer,
@ -11,10 +12,9 @@ use {
GL_FRAMEBUFFER,
},
},
renderer::context::RenderContext,
renderer::context::GlRenderContext,
run_ops,
sys::{glBlendFunc, glFlush, glReadnPixels, GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
Texture,
},
rect::Rect,
renderer::{renderer_base::RendererBase, RenderResult, Renderer},
@ -23,6 +23,7 @@ use {
tree::Node,
},
std::{
any::Any,
cell::Cell,
fmt::{Debug, Formatter},
rc::Rc,
@ -30,8 +31,8 @@ use {
};
pub struct Framebuffer {
pub(crate) ctx: Rc<RenderContext>,
pub(crate) gl: GlFrameBuffer,
pub(in crate::gfx_apis::gl) ctx: Rc<GlRenderContext>,
pub(in crate::gfx_apis::gl) gl: GlFrameBuffer,
}
impl Debug for Framebuffer {
@ -57,7 +58,14 @@ impl Framebuffer {
});
}
pub fn copy_texture(&self, state: &State, texture: &Rc<Texture>, x: i32, y: i32, alpha: bool) {
pub fn copy_texture(
&self,
state: &State,
texture: &Rc<dyn GfxTexture>,
x: i32,
y: i32,
alpha: bool,
) {
let mut ops = self.ctx.gfx_ops.borrow_mut();
ops.clear();
let scale = Scale::from_int(1);
@ -129,7 +137,7 @@ impl Framebuffer {
});
}
pub fn render_custom(&self, scale: Scale, f: impl FnOnce(&mut RendererBase)) {
pub fn render_custom(&self, scale: Scale, f: &mut dyn FnMut(&mut RendererBase)) {
let mut ops = self.ctx.gfx_ops.borrow_mut();
ops.clear();
let mut renderer = RendererBase {
@ -255,3 +263,69 @@ impl Framebuffer {
});
}
}
impl GfxFramebuffer for Framebuffer {
fn as_any(&self) -> &dyn Any {
self
}
fn clear(&self) {
self.clear()
}
fn clear_with(&self, r: f32, g: f32, b: f32, a: f32) {
self.clear_with(r, g, b, a)
}
fn copy_texture(
&self,
state: &State,
texture: &Rc<dyn GfxTexture>,
x: i32,
y: i32,
alpha: bool,
) {
self.copy_texture(state, texture, x, y, alpha)
}
fn copy_to_shm(
&self,
x: i32,
y: i32,
width: i32,
height: i32,
format: &Format,
shm: &[Cell<u8>],
) {
self.copy_to_shm(x, y, width, height, format, shm)
}
fn render_custom(&self, scale: Scale, f: &mut dyn FnMut(&mut RendererBase)) {
self.render_custom(scale, f)
}
fn render(
&self,
node: &dyn Node,
state: &State,
cursor_rect: Option<Rect>,
on_output: bool,
result: &mut RenderResult,
scale: Scale,
render_hardware_cursor: bool,
) {
self.render(
node,
state,
cursor_rect,
on_output,
result,
scale,
render_hardware_cursor,
)
}
fn render_hardware_cursor(&self, cursor: &dyn Cursor, state: &State, scale: Scale) {
self.render_hardware_cursor(cursor, state, scale)
}
}

View file

@ -1,15 +1,18 @@
use {
crate::gfx_apis::gl::{
egl::image::EglImage,
gl::{render_buffer::GlRenderBuffer, texture::GlTexture},
Framebuffer, RenderContext, RenderError, Texture,
crate::{
gfx_api::{GfxError, GfxFramebuffer, GfxImage, GfxTexture},
gfx_apis::gl::{
egl::image::EglImage,
gl::{render_buffer::GlRenderBuffer, texture::GlTexture},
Framebuffer, GlRenderContext, RenderError, Texture,
},
},
std::rc::Rc,
};
pub struct Image {
pub(crate) ctx: Rc<RenderContext>,
pub(crate) gl: Rc<EglImage>,
pub(in crate::gfx_apis::gl) ctx: Rc<GlRenderContext>,
pub(in crate::gfx_apis::gl) gl: Rc<EglImage>,
}
impl Image {
@ -21,14 +24,14 @@ impl Image {
self.gl.height
}
pub fn to_texture(self: &Rc<Self>) -> Result<Rc<Texture>, RenderError> {
fn to_texture(self: &Rc<Self>) -> Result<Rc<Texture>, RenderError> {
Ok(Rc::new(Texture {
ctx: self.ctx.clone(),
gl: GlTexture::import_img(&self.ctx.ctx, &self.gl)?,
}))
}
pub fn to_framebuffer(&self) -> Result<Rc<Framebuffer>, RenderError> {
fn to_framebuffer(&self) -> Result<Rc<Framebuffer>, RenderError> {
self.ctx.ctx.with_current(|| unsafe {
let rb = GlRenderBuffer::from_image(&self.gl, &self.ctx.ctx)?;
let fb = rb.create_framebuffer()?;
@ -39,3 +42,27 @@ impl Image {
})
}
}
impl GfxImage for Image {
fn to_framebuffer(self: Rc<Self>) -> Result<Rc<dyn GfxFramebuffer>, GfxError> {
(*self)
.to_framebuffer()
.map(|v| v as Rc<dyn GfxFramebuffer>)
.map_err(|e| e.into())
}
fn to_texture(self: Rc<Self>) -> Result<Rc<dyn GfxTexture>, GfxError> {
(&self)
.to_texture()
.map(|v| v as Rc<dyn GfxTexture>)
.map_err(|e| e.into())
}
fn width(&self) -> i32 {
self.width()
}
fn height(&self) -> i32 {
self.height()
}
}

View file

@ -1,14 +1,18 @@
use {
crate::gfx_apis::gl::{gl::texture::GlTexture, renderer::context::RenderContext},
crate::{
gfx_api::GfxTexture,
gfx_apis::gl::{gl::texture::GlTexture, renderer::context::GlRenderContext},
},
std::{
any::Any,
fmt::{Debug, Formatter},
rc::Rc,
},
};
pub struct Texture {
pub(crate) ctx: Rc<RenderContext>,
pub(crate) gl: GlTexture,
pub(in crate::gfx_apis::gl) ctx: Rc<GlRenderContext>,
pub(in crate::gfx_apis::gl) gl: GlTexture,
}
impl Debug for Texture {
@ -26,3 +30,17 @@ impl Texture {
self.gl.height
}
}
impl GfxTexture for Texture {
fn width(&self) -> i32 {
self.width()
}
fn height(&self) -> i32 {
self.height()
}
fn as_any(&self) -> &dyn Any {
self
}
}