render: hide graphics API behind traits
This commit is contained in:
parent
d650b3375d
commit
24e410a5b5
40 changed files with 601 additions and 246 deletions
|
|
@ -18,13 +18,15 @@ macro_rules! egl_transparent {
|
|||
};
|
||||
}
|
||||
|
||||
pub use renderer::*;
|
||||
use {
|
||||
crate::{
|
||||
format::Format,
|
||||
gfx_api::{BufferPoints, CopyTexture, FillRect, GfxApiOpt},
|
||||
gfx_api::{
|
||||
BufferPoints, CopyTexture, FillRect, GfxApiOpt, GfxContext, GfxError, GfxTexture,
|
||||
},
|
||||
gfx_apis::gl::{
|
||||
gl::texture::image_target,
|
||||
renderer::{context::GlRenderContext, framebuffer::Framebuffer, texture::Texture},
|
||||
sys::{
|
||||
glActiveTexture, glBindTexture, glClear, glClearColor, glDisable,
|
||||
glDisableVertexAttribArray, glDrawArrays, glEnable, glEnableVertexAttribArray,
|
||||
|
|
@ -35,10 +37,14 @@ use {
|
|||
},
|
||||
theme::Color,
|
||||
utils::{rc_eq::rc_eq, vecstorage::VecStorage},
|
||||
video::{drm::DrmError, gbm::GbmError},
|
||||
video::{
|
||||
drm::{Drm, DrmError},
|
||||
gbm::GbmError,
|
||||
},
|
||||
},
|
||||
isnt::std_1::vec::IsntVecExt,
|
||||
std::cell::RefCell,
|
||||
once_cell::sync::Lazy,
|
||||
std::{cell::RefCell, rc::Rc, sync::Arc},
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
|
|
@ -52,12 +58,19 @@ pub mod sys {
|
|||
pub use super::{egl::sys::*, gl::sys::*};
|
||||
}
|
||||
|
||||
pub fn init() -> Result<(), RenderError> {
|
||||
egl::init()
|
||||
static INIT: Lazy<Result<(), Arc<RenderError>>> = Lazy::new(|| egl::init().map_err(Arc::new));
|
||||
|
||||
pub(super) fn create_gfx_context(drm: &Drm) -> Result<Rc<dyn GfxContext>, GfxError> {
|
||||
if let Err(e) = &*INIT {
|
||||
return Err(GfxError(Box::new(e.clone())));
|
||||
}
|
||||
GlRenderContext::from_drm_device(drm)
|
||||
.map(|v| Rc::new(v) as Rc<dyn GfxContext>)
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum RenderError {
|
||||
enum RenderError {
|
||||
#[error("EGL library does not support `EGL_EXT_platform_base`")]
|
||||
ExtPlatformBase,
|
||||
#[error("Could not compile a shader")]
|
||||
|
|
@ -117,13 +130,13 @@ pub enum RenderError {
|
|||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct GfxGlState {
|
||||
struct GfxGlState {
|
||||
triangles: RefCell<Vec<f32>>,
|
||||
fill_rect: VecStorage<&'static FillRect>,
|
||||
copy_tex: VecStorage<&'static CopyTexture>,
|
||||
}
|
||||
|
||||
pub fn run_ops(fb: &Framebuffer, ops: &[GfxApiOpt]) {
|
||||
fn run_ops(fb: &Framebuffer, ops: &[GfxApiOpt]) {
|
||||
let mut state = fb.ctx.gl_state.borrow_mut();
|
||||
let state = &mut *state;
|
||||
let mut fill_rect = state.fill_rect.take();
|
||||
|
|
@ -207,7 +220,16 @@ pub fn run_ops(fb: &Framebuffer, ops: &[GfxApiOpt]) {
|
|||
let y1 = 2.0 * (tex.target.y1 / height) - 1.0;
|
||||
let x2 = 2.0 * (tex.target.x2 / width) - 1.0;
|
||||
let y2 = 2.0 * (tex.target.y2 / height) - 1.0;
|
||||
render_texture(&fb.ctx, &tex.tex, tex.format, x1, y1, x2, y2, &tex.source)
|
||||
render_texture(
|
||||
&fb.ctx,
|
||||
&tex.tex.as_gl(),
|
||||
tex.format,
|
||||
x1,
|
||||
y1,
|
||||
x2,
|
||||
y2,
|
||||
&tex.source,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -219,7 +241,7 @@ fn clear(c: &Color) {
|
|||
}
|
||||
}
|
||||
|
||||
fn fill_boxes3(ctx: &RenderContext, boxes: &[f32], color: &Color) {
|
||||
fn fill_boxes3(ctx: &GlRenderContext, boxes: &[f32], color: &Color) {
|
||||
unsafe {
|
||||
glUseProgram(ctx.fill_prog.prog);
|
||||
glUniform4f(ctx.fill_prog_color, color.r, color.g, color.b, color.a);
|
||||
|
|
@ -238,7 +260,7 @@ fn fill_boxes3(ctx: &RenderContext, boxes: &[f32], color: &Color) {
|
|||
}
|
||||
|
||||
fn render_texture(
|
||||
ctx: &RenderContext,
|
||||
ctx: &GlRenderContext,
|
||||
texture: &Texture,
|
||||
format: &Format,
|
||||
x1: f32,
|
||||
|
|
@ -320,3 +342,17 @@ fn render_texture(
|
|||
glBindTexture(target, 0);
|
||||
}
|
||||
}
|
||||
|
||||
impl dyn GfxTexture {
|
||||
fn as_gl(&self) -> &Texture {
|
||||
self.as_any()
|
||||
.downcast_ref()
|
||||
.expect("Non-gl texture passed into gl")
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RenderError> for GfxError {
|
||||
fn from(value: RenderError) -> Self {
|
||||
Self(Box::new(value))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ pub(crate) static PROCS: Lazy<ExtProc> = Lazy::new(ExtProc::load);
|
|||
|
||||
pub(crate) static EXTS: Lazy<ClientExt> = Lazy::new(get_client_ext);
|
||||
|
||||
pub fn init() -> Result<(), RenderError> {
|
||||
pub(in crate::gfx_apis::gl) fn init() -> Result<(), RenderError> {
|
||||
if !EXTS.contains(ClientExt::EXT_PLATFORM_BASE) {
|
||||
return Err(RenderError::ExtPlatformBase);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,21 @@
|
|||
use {
|
||||
crate::gfx_apis::gl::{
|
||||
egl::{
|
||||
display::EglDisplay,
|
||||
sys::{eglDestroyContext, eglMakeCurrent, EGLContext, EGLSurface, EGL_FALSE, EGL_TRUE},
|
||||
PROCS,
|
||||
crate::{
|
||||
gfx_api::ResetStatus,
|
||||
gfx_apis::gl::{
|
||||
egl::{
|
||||
display::EglDisplay,
|
||||
sys::{
|
||||
eglDestroyContext, eglMakeCurrent, EGLContext, EGLSurface, EGL_FALSE, EGL_TRUE,
|
||||
},
|
||||
PROCS,
|
||||
},
|
||||
ext::{DisplayExt, GlExt},
|
||||
sys::{
|
||||
GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB,
|
||||
GL_UNKNOWN_CONTEXT_RESET_ARB,
|
||||
},
|
||||
RenderError,
|
||||
},
|
||||
ext::{DisplayExt, GlExt},
|
||||
sys::{
|
||||
GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB,
|
||||
GL_UNKNOWN_CONTEXT_RESET_ARB,
|
||||
},
|
||||
RenderError, ResetStatus,
|
||||
},
|
||||
std::rc::Rc,
|
||||
};
|
||||
|
|
@ -58,7 +63,7 @@ impl EglContext {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_current<T, F: FnOnce() -> Result<T, RenderError>>(
|
||||
pub(in crate::gfx_apis::gl) fn with_current<T, F: FnOnce() -> Result<T, RenderError>>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> Result<T, RenderError> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use {
|
||||
crate::{
|
||||
format::{formats, Format},
|
||||
gfx_api::{GfxFormat, GfxModifier},
|
||||
gfx_apis::gl::{
|
||||
egl::{
|
||||
context::EglContext,
|
||||
|
|
@ -35,29 +36,16 @@ use {
|
|||
std::{ptr, rc::Rc},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EglFormat {
|
||||
pub format: &'static Format,
|
||||
pub implicit_external_only: bool,
|
||||
pub modifiers: AHashMap<u64, EglModifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EglModifier {
|
||||
pub modifier: u64,
|
||||
pub external_only: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EglDisplay {
|
||||
pub exts: DisplayExt,
|
||||
pub formats: Rc<AHashMap<u32, EglFormat>>,
|
||||
pub formats: Rc<AHashMap<u32, GfxFormat>>,
|
||||
pub gbm: Rc<GbmDevice>,
|
||||
pub dpy: EGLDisplay,
|
||||
}
|
||||
|
||||
impl EglDisplay {
|
||||
pub fn create(drm: &Drm) -> Result<Rc<Self>, RenderError> {
|
||||
pub(in crate::gfx_apis::gl) fn create(drm: &Drm) -> Result<Rc<Self>, RenderError> {
|
||||
unsafe {
|
||||
let gbm = match GbmDevice::new(drm) {
|
||||
Ok(gbm) => gbm,
|
||||
|
|
@ -107,7 +95,9 @@ impl EglDisplay {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_context(self: &Rc<Self>) -> Result<Rc<EglContext>, RenderError> {
|
||||
pub(in crate::gfx_apis::gl) fn create_context(
|
||||
self: &Rc<Self>,
|
||||
) -> Result<Rc<EglContext>, RenderError> {
|
||||
let mut attrib = vec![EGL_CONTEXT_CLIENT_VERSION, 2];
|
||||
if self
|
||||
.exts
|
||||
|
|
@ -142,7 +132,10 @@ impl EglDisplay {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn import_dmabuf(self: &Rc<Self>, buf: &DmaBuf) -> Result<Rc<EglImage>, RenderError> {
|
||||
pub(in crate::gfx_apis::gl) fn import_dmabuf(
|
||||
self: &Rc<Self>,
|
||||
buf: &DmaBuf,
|
||||
) -> Result<Rc<EglImage>, RenderError> {
|
||||
let format = match self.formats.get(&buf.format.drm) {
|
||||
Some(fmt) => match fmt.modifiers.get(&buf.modifier) {
|
||||
Some(fmt) => fmt,
|
||||
|
|
@ -235,7 +228,7 @@ impl Drop for EglDisplay {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe fn query_formats(dpy: EGLDisplay) -> Result<AHashMap<u32, EglFormat>, RenderError> {
|
||||
unsafe fn query_formats(dpy: EGLDisplay) -> Result<AHashMap<u32, GfxFormat>, RenderError> {
|
||||
let mut vec = vec![];
|
||||
let mut num = 0;
|
||||
let res = PROCS.eglQueryDmaBufFormatsEXT(dpy, num, ptr::null_mut(), &mut num);
|
||||
|
|
@ -255,7 +248,7 @@ unsafe fn query_formats(dpy: EGLDisplay) -> Result<AHashMap<u32, EglFormat>, Ren
|
|||
let (modifiers, external_only) = query_modifiers(dpy, fmt, format)?;
|
||||
res.insert(
|
||||
format.drm,
|
||||
EglFormat {
|
||||
GfxFormat {
|
||||
format,
|
||||
implicit_external_only: external_only,
|
||||
modifiers,
|
||||
|
|
@ -270,7 +263,7 @@ unsafe fn query_modifiers(
|
|||
dpy: EGLDisplay,
|
||||
gl_format: EGLint,
|
||||
format: &'static Format,
|
||||
) -> Result<(AHashMap<u64, EglModifier>, bool), RenderError> {
|
||||
) -> Result<(AHashMap<u64, GfxModifier>, bool), RenderError> {
|
||||
let mut mods = vec![];
|
||||
let mut ext_only = vec![];
|
||||
let mut num = 0;
|
||||
|
|
@ -304,7 +297,7 @@ unsafe fn query_modifiers(
|
|||
for (modifier, ext_only) in mods.iter().copied().zip(ext_only.iter().copied()) {
|
||||
res.insert(
|
||||
modifier as _,
|
||||
EglModifier {
|
||||
GfxModifier {
|
||||
modifier: modifier as _,
|
||||
external_only: ext_only == EGL_TRUE,
|
||||
},
|
||||
|
|
@ -316,7 +309,7 @@ unsafe fn query_modifiers(
|
|||
}
|
||||
res.insert(
|
||||
INVALID_MODIFIER,
|
||||
EglModifier {
|
||||
GfxModifier {
|
||||
modifier: INVALID_MODIFIER,
|
||||
external_only,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ pub struct GlProgram {
|
|||
}
|
||||
|
||||
impl GlProgram {
|
||||
pub unsafe fn from_shaders(
|
||||
pub(in crate::gfx_apis::gl) unsafe fn from_shaders(
|
||||
ctx: &Rc<EglContext>,
|
||||
vert: &str,
|
||||
frag: &str,
|
||||
|
|
@ -31,7 +31,10 @@ impl GlProgram {
|
|||
Self::link(&vert, &frag)
|
||||
}
|
||||
|
||||
pub unsafe fn link(vert: &GlShader, frag: &GlShader) -> Result<Self, RenderError> {
|
||||
pub(in crate::gfx_apis::gl) unsafe fn link(
|
||||
vert: &GlShader,
|
||||
frag: &GlShader,
|
||||
) -> Result<Self, RenderError> {
|
||||
let res = GlProgram {
|
||||
_ctx: vert.ctx.clone(),
|
||||
prog: glCreateProgram(),
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ pub struct GlRenderBuffer {
|
|||
}
|
||||
|
||||
impl GlRenderBuffer {
|
||||
pub unsafe fn from_image(
|
||||
pub(in crate::gfx_apis::gl) unsafe fn from_image(
|
||||
img: &Rc<EglImage>,
|
||||
ctx: &Rc<EglContext>,
|
||||
) -> Result<Rc<GlRenderBuffer>, RenderError> {
|
||||
|
|
@ -41,7 +41,9 @@ impl GlRenderBuffer {
|
|||
}))
|
||||
}
|
||||
|
||||
pub unsafe fn create_framebuffer(self: &Rc<Self>) -> Result<GlFrameBuffer, RenderError> {
|
||||
pub(in crate::gfx_apis::gl) unsafe fn create_framebuffer(
|
||||
self: &Rc<Self>,
|
||||
) -> Result<GlFrameBuffer, RenderError> {
|
||||
let mut fbo = 0;
|
||||
glGenFramebuffers(1, &mut fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub struct GlShader {
|
|||
}
|
||||
|
||||
impl GlShader {
|
||||
pub unsafe fn compile(
|
||||
pub(in crate::gfx_apis::gl) unsafe fn compile(
|
||||
ctx: &Rc<EglContext>,
|
||||
ty: GLenum,
|
||||
src: &str,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,10 @@ pub fn image_target(external_only: bool) -> GLenum {
|
|||
}
|
||||
|
||||
impl GlTexture {
|
||||
pub fn import_img(ctx: &Rc<EglContext>, img: &Rc<EglImage>) -> Result<GlTexture, RenderError> {
|
||||
pub(in crate::gfx_apis::gl) fn import_img(
|
||||
ctx: &Rc<EglContext>,
|
||||
img: &Rc<EglImage>,
|
||||
) -> Result<GlTexture, RenderError> {
|
||||
if !ctx.ext.contains(GlExt::GL_OES_EGL_IMAGE_EXTERNAL) {
|
||||
return Err(RenderError::ExternalUnsupported);
|
||||
}
|
||||
|
|
@ -58,7 +61,7 @@ impl GlTexture {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn import_shm(
|
||||
pub(in crate::gfx_apis::gl) fn import_shm(
|
||||
ctx: &Rc<EglContext>,
|
||||
data: &[Cell<u8>],
|
||||
format: &'static Format,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
pub use {context::*, framebuffer::*, image::*, texture::*};
|
||||
|
||||
mod context;
|
||||
mod framebuffer;
|
||||
mod image;
|
||||
mod texture;
|
||||
pub(super) mod context;
|
||||
pub(super) mod framebuffer;
|
||||
pub(super) mod image;
|
||||
pub(super) mod texture;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue