1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
/* SPDX-License-Identifier: LGPL-2.1-or-later
Copyright (c) 2022 Purism, SPC
*/
/*! OpenGL procedures.
The Shader binds the surfaces on every call.
It might be that there is performance to be gained by only doing it once
for every shader/input/output surface triple.
Or even by doing binding/import once per texture individually.
*/
pub mod egl;
pub mod egl_ext;
mod glerr;
pub mod shaders;
mod raw;
mod uniforms;
pub use cgmath;
use egl::Dimensions;
use egl::Texture;
pub use egl::{ContextRef, CurrentContext};
pub use gbm::Format;
use gl;
pub use glium;
use glium::GlObject;
use glium::texture::UnsignedTexture2d;
pub use raw::Facade;
pub use shaders::bayer;
pub use shaders::yuv;
/// Initializes the GL texture.
// For unknown reasons, passing a texture obtained this way to uniforms with the relevant filters doesn't do anything to initialize it.
// Instead, this does the necessary setup.
fn import_bind_texture<F: glium::backend::Facade>(
facade: &F,
tex: Texture,
) -> Result<UnsignedTexture2d, glerr::Error> {
let Dimensions { width, height } = tex.dimensions();
let imported = unsafe {
use glium::texture::*;
UnsignedTexture2d::from_id(
facade,
UncompressedUintFormat::U8U8U8U8,
tex.id().as_gl_id(),
// This unbinds the texture when dropped.
// The ownership pertains to the ID, not the backing image
true,
MipmapsOption::NoMipmap,
Dimensions::Texture2d { width, height },
)
};
// Can't get Backend directly out of Facade, so we access it behind glium's back.
gl::load_with(|s| unsafe {raw::Backend::get_proc_address(s)});
// Excuse me while I cargo-cult
// whatever is happening in Texture2d::with_mipmaps.
unsafe {
let bind_point = gl::TEXTURE_2D;
let id = imported.get_id();
glerr::check(
gl::BindTexture(bind_point, id)
)?;
glerr::check(
gl::TexParameteri(bind_point, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_BORDER as i32)
)?;
glerr::check(
gl::TexParameteri(bind_point, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32)
)?;
glerr::check(
gl::TexParameteri(bind_point, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_BORDER as i32)
)?;
glerr::check(
gl::TexParameteri(bind_point, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32)
)?;
glerr::check(
gl::TexParameteri(bind_point, gl::TEXTURE_BASE_LEVEL, 0)
)?;
glerr::check(
gl::TexParameteri(bind_point, gl::TEXTURE_MAX_LEVEL, 0)
)?;
// Here glium uses format RGBA8.
// Somehow the texture is immutable. This call fails. Leaving it as commented to provide clues in case something goes wrong in the future.
// Update: with this uncommented, the texture is blank
//glerr::check(
//gl::TexStorage2D(bind_point, 1, gl::R8, width as i32, height as i32)
//)?;
}
Ok(imported)
}