Skip to content

Commit

Permalink
backends: Use CStr literals everywhere possible
Browse files Browse the repository at this point in the history
This addition to the 2021 edition makes it possible to generate a &CStr
at compile-time, with no need for unwrap()/expect() or unsafe, making it
much more ergonomic to pass to C APIs.
  • Loading branch information
linkmauve committed Jun 30, 2024
1 parent e3b6eb1 commit e91165e
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 64 deletions.
8 changes: 2 additions & 6 deletions examples/buffer_test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{ffi::CStr, fmt, fs::File, os::unix::io::OwnedFd, path::PathBuf};
use std::{fmt, fs::File, os::unix::io::OwnedFd, path::PathBuf};

use clap::{Args, Parser, Subcommand, ValueEnum};
use smithay::{
Expand Down Expand Up @@ -189,11 +189,7 @@ fn buffer_test(args: TestArgs) {
Instance::new(Version::VERSION_1_2, None).expect("Unable to create vulkan instance");
let physical_device = PhysicalDevice::enumerate(&instance)
.expect("Failed to enumerate physical devices")
.filter(|phd| {
phd.has_device_extension(unsafe {
CStr::from_bytes_with_nul_unchecked(b"VK_EXT_physical_device_drm\0")
})
})
.filter(|phd| phd.has_device_extension(c"VK_EXT_physical_device_drm"))
.find(|phd| {
phd.primary_node().unwrap() == Some(node) || phd.render_node().unwrap() == Some(node)
})
Expand Down
39 changes: 16 additions & 23 deletions src/backend/renderer/gles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1848,36 +1848,28 @@ impl GlesRenderer {
let debug_shader = format!("#version 100\n#define {}\n{}", shaders::DEBUG_FLAGS, src.as_ref());
let debug_program = unsafe { link_program(&self.gl, shaders::VERTEX_SHADER, &debug_shader)? };

let vert = CStr::from_bytes_with_nul(b"vert\0").expect("NULL terminated");
let vert_position = CStr::from_bytes_with_nul(b"vert_position\0").expect("NULL terminated");
let matrix = CStr::from_bytes_with_nul(b"matrix\0").expect("NULL terminated");
let tex_matrix = CStr::from_bytes_with_nul(b"tex_matrix\0").expect("NULL terminated");
let size = CStr::from_bytes_with_nul(b"size\0").expect("NULL terminated");
let alpha = CStr::from_bytes_with_nul(b"alpha\0").expect("NULL terminated");
let tint = CStr::from_bytes_with_nul(b"tint\0").expect("NULL terminated");

unsafe {
Ok(GlesPixelProgram(Rc::new(GlesPixelProgramInner {
normal: GlesPixelProgramInternal {
program,
uniform_matrix: self
.gl
.GetUniformLocation(program, matrix.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(program, c"matrix".as_ptr() as *const ffi::types::GLchar),
uniform_tex_matrix: self
.gl
.GetUniformLocation(program, tex_matrix.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(program, c"tex_matrix".as_ptr() as *const ffi::types::GLchar),
uniform_alpha: self
.gl
.GetUniformLocation(program, alpha.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(program, c"alpha".as_ptr() as *const ffi::types::GLchar),
uniform_size: self
.gl
.GetUniformLocation(program, size.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(program, c"size".as_ptr() as *const ffi::types::GLchar),
attrib_vert: self
.gl
.GetAttribLocation(program, vert.as_ptr() as *const ffi::types::GLchar),
.GetAttribLocation(program, c"vert".as_ptr() as *const ffi::types::GLchar),
attrib_position: self
.gl
.GetAttribLocation(program, vert_position.as_ptr() as *const ffi::types::GLchar),
.GetAttribLocation(program, c"vert_position".as_ptr() as *const ffi::types::GLchar),
additional_uniforms: additional_uniforms
.iter()
.map(|uniform| {
Expand All @@ -1899,22 +1891,23 @@ impl GlesRenderer {
program: debug_program,
uniform_matrix: self
.gl
.GetUniformLocation(debug_program, matrix.as_ptr() as *const ffi::types::GLchar),
uniform_tex_matrix: self
.gl
.GetUniformLocation(debug_program, tex_matrix.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(debug_program, c"matrix".as_ptr() as *const ffi::types::GLchar),
uniform_tex_matrix: self.gl.GetUniformLocation(
debug_program,
c"tex_matrix".as_ptr() as *const ffi::types::GLchar,
),
uniform_alpha: self
.gl
.GetUniformLocation(debug_program, alpha.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(debug_program, c"alpha".as_ptr() as *const ffi::types::GLchar),
uniform_size: self
.gl
.GetUniformLocation(debug_program, size.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(debug_program, c"size".as_ptr() as *const ffi::types::GLchar),
attrib_vert: self
.gl
.GetAttribLocation(debug_program, vert.as_ptr() as *const ffi::types::GLchar),
.GetAttribLocation(debug_program, c"vert".as_ptr() as *const ffi::types::GLchar),
attrib_position: self.gl.GetAttribLocation(
debug_program,
vert_position.as_ptr() as *const ffi::types::GLchar,
c"vert_position".as_ptr() as *const ffi::types::GLchar,
),
additional_uniforms: additional_uniforms
.iter()
Expand All @@ -1937,7 +1930,7 @@ impl GlesRenderer {
destruction_callback_sender: self.destruction_callback_sender.clone(),
uniform_tint: self
.gl
.GetUniformLocation(debug_program, tint.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(debug_program, c"tint".as_ptr() as *const ffi::types::GLchar),
})))
}
}
Expand Down
54 changes: 23 additions & 31 deletions src/backend/renderer/gles/shaders/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,25 +142,18 @@ pub(super) unsafe fn texture_program(
let program = unsafe { link_program(gl, shaders::VERTEX_SHADER, &shader)? };
let debug_program = unsafe { link_program(gl, shaders::VERTEX_SHADER, debug_shader.as_ref())? };

let vert = CStr::from_bytes_with_nul(b"vert\0").expect("NULL terminated");
let vert_position = CStr::from_bytes_with_nul(b"vert_position\0").expect("NULL terminated");
let tex = CStr::from_bytes_with_nul(b"tex\0").expect("NULL terminated");
let matrix = CStr::from_bytes_with_nul(b"matrix\0").expect("NULL terminated");
let tex_matrix = CStr::from_bytes_with_nul(b"tex_matrix\0").expect("NULL terminated");
let alpha = CStr::from_bytes_with_nul(b"alpha\0").expect("NULL terminated");
let tint = CStr::from_bytes_with_nul(b"tint\0").expect("NULL terminated");

Ok(GlesTexProgramVariant {
normal: GlesTexProgramInternal {
program,
uniform_tex: gl.GetUniformLocation(program, tex.as_ptr() as *const ffi::types::GLchar),
uniform_matrix: gl.GetUniformLocation(program, matrix.as_ptr() as *const ffi::types::GLchar),
uniform_tex: gl.GetUniformLocation(program, c"tex".as_ptr() as *const ffi::types::GLchar),
uniform_matrix: gl
.GetUniformLocation(program, c"matrix".as_ptr() as *const ffi::types::GLchar),
uniform_tex_matrix: gl
.GetUniformLocation(program, tex_matrix.as_ptr() as *const ffi::types::GLchar),
uniform_alpha: gl.GetUniformLocation(program, alpha.as_ptr() as *const ffi::types::GLchar),
attrib_vert: gl.GetAttribLocation(program, vert.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(program, c"tex_matrix".as_ptr() as *const ffi::types::GLchar),
uniform_alpha: gl.GetUniformLocation(program, c"alpha".as_ptr() as *const ffi::types::GLchar),
attrib_vert: gl.GetAttribLocation(program, c"vert".as_ptr() as *const ffi::types::GLchar),
attrib_vert_position: gl
.GetAttribLocation(program, vert_position.as_ptr() as *const ffi::types::GLchar),
.GetAttribLocation(program, c"vert_position".as_ptr() as *const ffi::types::GLchar),
additional_uniforms: additional_uniforms
.iter()
.map(|uniform| {
Expand All @@ -179,16 +172,20 @@ pub(super) unsafe fn texture_program(
},
debug: GlesTexProgramInternal {
program: debug_program,
uniform_tex: gl.GetUniformLocation(debug_program, tex.as_ptr() as *const ffi::types::GLchar),
uniform_tex: gl
.GetUniformLocation(debug_program, c"tex".as_ptr() as *const ffi::types::GLchar),
uniform_matrix: gl
.GetUniformLocation(debug_program, matrix.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(debug_program, c"matrix".as_ptr() as *const ffi::types::GLchar),
uniform_tex_matrix: gl
.GetUniformLocation(debug_program, tex_matrix.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(debug_program, c"tex_matrix".as_ptr() as *const ffi::types::GLchar),
uniform_alpha: gl
.GetUniformLocation(debug_program, alpha.as_ptr() as *const ffi::types::GLchar),
attrib_vert: gl.GetAttribLocation(debug_program, vert.as_ptr() as *const ffi::types::GLchar),
attrib_vert_position: gl
.GetAttribLocation(debug_program, vert_position.as_ptr() as *const ffi::types::GLchar),
.GetUniformLocation(debug_program, c"alpha".as_ptr() as *const ffi::types::GLchar),
attrib_vert: gl
.GetAttribLocation(debug_program, c"vert".as_ptr() as *const ffi::types::GLchar),
attrib_vert_position: gl.GetAttribLocation(
debug_program,
c"vert_position".as_ptr() as *const ffi::types::GLchar,
),
additional_uniforms: additional_uniforms
.iter()
.map(|uniform| {
Expand All @@ -206,7 +203,7 @@ pub(super) unsafe fn texture_program(
.collect(),
},
// debug flags
uniform_tint: gl.GetUniformLocation(debug_program, tint.as_ptr() as *const ffi::types::GLchar),
uniform_tint: gl.GetUniformLocation(debug_program, c"tint".as_ptr() as *const ffi::types::GLchar),
})
};

Expand All @@ -223,16 +220,11 @@ pub(super) unsafe fn texture_program(
pub(super) unsafe fn solid_program(gl: &ffi::Gles2) -> Result<GlesSolidProgram, GlesError> {
let program = link_program(gl, shaders::VERTEX_SHADER_SOLID, shaders::FRAGMENT_SHADER_SOLID)?;

let matrix = CStr::from_bytes_with_nul(b"matrix\0").expect("NULL terminated");
let color = CStr::from_bytes_with_nul(b"color\0").expect("NULL terminated");
let vert = CStr::from_bytes_with_nul(b"vert\0").expect("NULL terminated");
let position = CStr::from_bytes_with_nul(b"position\0").expect("NULL terminated");

Ok(GlesSolidProgram {
program,
uniform_matrix: gl.GetUniformLocation(program, matrix.as_ptr() as *const ffi::types::GLchar),
uniform_color: gl.GetUniformLocation(program, color.as_ptr() as *const ffi::types::GLchar),
attrib_vert: gl.GetAttribLocation(program, vert.as_ptr() as *const ffi::types::GLchar),
attrib_position: gl.GetAttribLocation(program, position.as_ptr() as *const ffi::types::GLchar),
uniform_matrix: gl.GetUniformLocation(program, c"matrix".as_ptr() as *const ffi::types::GLchar),
uniform_color: gl.GetUniformLocation(program, c"color".as_ptr() as *const ffi::types::GLchar),
attrib_vert: gl.GetAttribLocation(program, c"vert".as_ptr() as *const ffi::types::GLchar),
attrib_position: gl.GetAttribLocation(program, c"position".as_ptr() as *const ffi::types::GLchar),
})
}
6 changes: 2 additions & 4 deletions src/backend/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,7 @@ impl Instance {

// Enable debug layers if present and debug assertions are enabled.
if cfg!(debug_assertions) {
const VALIDATION: &CStr =
unsafe { CStr::from_bytes_with_nul_unchecked(b"VK_LAYER_KHRONOS_validation\0") };
const VALIDATION: &CStr = c"VK_LAYER_KHRONOS_validation";

if available_layers
.iter()
Expand Down Expand Up @@ -256,8 +255,7 @@ impl Instance {
app_info.map(|info| CString::new(info.name).expect("app name contains null terminator"));
let mut app_info = vk::ApplicationInfo::default()
.api_version(api_version.to_raw())
// SAFETY: null terminated with no interior null bytes.
.engine_name(unsafe { CStr::from_bytes_with_nul_unchecked(b"Smithay\0") })
.engine_name(c"Smithay")
.engine_version(Version::SMITHAY.to_raw());

if let Some(app_version) = app_version {
Expand Down

0 comments on commit e91165e

Please sign in to comment.