diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-04-13 11:07:23 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-04-13 11:07:23 +0400 |
| commit | 71be19b234d58f4ec447e921633506beb81a52c0 (patch) | |
| tree | a6b69d57a3e2edc9d8dac4c969548f227cbf341a /src/render_helpers/resources.rs | |
| parent | 4fd9300bdb07e90c26df28461f9bd6591c3d1d41 (diff) | |
| download | niri-71be19b234d58f4ec447e921633506beb81a52c0.tar.gz niri-71be19b234d58f4ec447e921633506beb81a52c0.tar.bz2 niri-71be19b234d58f4ec447e921633506beb81a52c0.zip | |
Implement window resize animations
Diffstat (limited to 'src/render_helpers/resources.rs')
| -rw-r--r-- | src/render_helpers/resources.rs | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/render_helpers/resources.rs b/src/render_helpers/resources.rs new file mode 100644 index 00000000..0aa1fed4 --- /dev/null +++ b/src/render_helpers/resources.rs @@ -0,0 +1,106 @@ +use std::cell::RefCell; +use std::rc::Rc; + +use smithay::backend::renderer::gles::{ffi, Capability, GlesError, GlesFrame, GlesRenderer}; + +pub struct Resources { + pub vertices: Vec<f32>, + pub vbos: [ffi::types::GLuint; 2], +} + +static INSTANCED_VERTS: [ffi::types::GLfloat; 8] = [ + 1.0, 0.0, // top right + 0.0, 0.0, // top left + 1.0, 1.0, // bottom right + 0.0, 1.0, // bottom left +]; + +/// Vertices for rendering individual triangles. +const MAX_RECTS_PER_DRAW: usize = 10; +const TRIANGLE_VERTS: [ffi::types::GLfloat; 12 * MAX_RECTS_PER_DRAW] = triangle_verts(); +const fn triangle_verts() -> [ffi::types::GLfloat; 12 * MAX_RECTS_PER_DRAW] { + let mut verts = [0.; 12 * MAX_RECTS_PER_DRAW]; + let mut i = 0; + loop { + // Top Left. + verts[i * 12] = 0.0; + verts[i * 12 + 1] = 0.0; + + // Bottom left. + verts[i * 12 + 2] = 0.0; + verts[i * 12 + 3] = 1.0; + + // Bottom right. + verts[i * 12 + 4] = 1.0; + verts[i * 12 + 5] = 1.0; + + // Top left. + verts[i * 12 + 6] = 0.0; + verts[i * 12 + 7] = 0.0; + + // Bottom right. + verts[i * 12 + 8] = 1.0; + verts[i * 12 + 9] = 1.0; + + // Top right. + verts[i * 12 + 10] = 1.0; + verts[i * 12 + 11] = 0.0; + + i += 1; + if i == MAX_RECTS_PER_DRAW { + break; + } + } + verts +} + +impl Resources { + fn create(renderer: &mut GlesRenderer) -> Result<Self, GlesError> { + let _span = tracy_client::span!("Resources::init"); + + let supports_instancing = renderer.capabilities().contains(&Capability::Instancing); + renderer.with_context(|gl| unsafe { + let vertices: &[ffi::types::GLfloat] = if supports_instancing { + &INSTANCED_VERTS + } else { + &TRIANGLE_VERTS + }; + + let mut vbos = [0; 2]; + gl.GenBuffers(vbos.len() as i32, vbos.as_mut_ptr()); + gl.BindBuffer(ffi::ARRAY_BUFFER, vbos[0]); + gl.BufferData( + ffi::ARRAY_BUFFER, + std::mem::size_of_val(vertices) as isize, + vertices.as_ptr() as *const _, + ffi::STATIC_DRAW, + ); + + gl.BindBuffer(ffi::ARRAY_BUFFER, 0); + + Self { + vertices: vec![], + vbos, + } + }) + } + + pub fn get(frame: &mut GlesFrame) -> Option<Rc<RefCell<Self>>> { + let data = frame.egl_context().user_data(); + data.get().cloned() + } +} + +pub fn init(renderer: &mut GlesRenderer) { + match Resources::create(renderer) { + Ok(resources) => { + let data = renderer.egl_context().user_data(); + if !data.insert_if_missing(|| Rc::new(RefCell::new(resources))) { + error!("resources were already initialized"); + } + } + Err(err) => { + warn!("error creating resources for rendering: {err:?}"); + } + } +} |
