Skip to content

Commit

Permalink
wayland: implement alpha_modifier_v1
Browse files Browse the repository at this point in the history
  • Loading branch information
mahkoh committed Apr 9, 2024
1 parent 131f048 commit ff54a8a
Show file tree
Hide file tree
Showing 37 changed files with 654 additions and 88 deletions.
1 change: 1 addition & 0 deletions .builds/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ tasks:
- test: |
cd jay
export RUST_BACKTRACE=1
export GALLIUM_DRIVER=softpipe
./target/debug/jay run-tests
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ ash = "0.37.3"
gpu-alloc = "0.6.0"
gpu-alloc-ash = "0.6.0"
serde = { version = "1.0.196", features = ["derive"] }
enum-map = "2.7.3"

[build-dependencies]
repc = "0.1.1"
Expand Down
32 changes: 25 additions & 7 deletions build/vulkan.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,40 @@
use {
crate::open,
anyhow::{bail, Context},
shaderc::CompileOptions,
std::{io::Write, path::Path},
};

const ROOT: &str = "src/gfx_apis/vulkan/shaders";

pub fn main() -> anyhow::Result<()> {
println!("cargo:rerun-if-changed={}", ROOT);
for shader in std::fs::read_dir(ROOT)? {
let shader = shader?;
let name = shader.file_name().to_string_lossy().into_owned();
compile_shader(&name).context(name)?;
compile_simple("fill.frag")?;
compile_simple("fill.vert")?;
compile_simple("tex.vert")?;
compile_tex_frag("tex.frag.spv", false, false)?;
compile_tex_frag("tex.frag.mult+opaque.spv", false, true)?;
compile_tex_frag("tex.frag.mult+alpha.spv", true, true)?;
Ok(())
}

fn compile_tex_frag(out: &str, alpha: bool, alpha_multiplier: bool) -> anyhow::Result<()> {
let mut opts = CompileOptions::new().unwrap();
if alpha {
opts.add_macro_definition("ALPHA", None);
}
if alpha_multiplier {
opts.add_macro_definition("ALPHA_MULTIPLIER", None);
}
compile_shader("tex.frag", out, Some(&opts)).with_context(|| out.to_string())?;
Ok(())
}

fn compile_shader(name: &str) -> anyhow::Result<()> {
fn compile_simple(name: &str) -> anyhow::Result<()> {
compile_shader(name, &format!("{name}.spv"), None).with_context(|| name.to_string())
}

fn compile_shader(name: &str, out: &str, options: Option<&CompileOptions>) -> anyhow::Result<()> {
let stage = match Path::new(name)
.extension()
.and_then(|e| e.to_str())
Expand All @@ -29,9 +47,9 @@ fn compile_shader(name: &str) -> anyhow::Result<()> {
let src = std::fs::read_to_string(format!("{}/{}", ROOT, name))?;
let compiler = shaderc::Compiler::new().unwrap();
let binary = compiler
.compile_into_spirv(&src, stage, name, "main", None)
.compile_into_spirv(&src, stage, name, "main", options)
.unwrap();
let mut file = open(&format!("{}.spv", name))?;
let mut file = open(out)?;
file.write_all(binary.as_binary_u8())?;
file.flush()?;
Ok(())
Expand Down
4 changes: 4 additions & 0 deletions src/backends/metal/video.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,10 @@ impl MetalConnector {
}
return None;
};
if ct.alpha.is_some() {
// Direct scanout with alpha factor is not supported.
return None;
}
if !ct.tex.format().has_alpha && ct.target.is_covering() {
// Texture covers the entire screen and is opaque.
break 'ct ct;
Expand Down
3 changes: 3 additions & 0 deletions src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ fn render_img(image: &InstantiatedCursorImage, renderer: &mut Renderer, x: Fixed
if extents.intersects(&renderer.pixel_extents()) {
renderer.base.render_texture(
&img.tex,
None,
extents.x1(),
extents.y1(),
None,
Expand All @@ -399,6 +400,7 @@ impl Cursor for StaticCursor {
if let Some(img) = self.image.scales.get(&renderer.scale()) {
renderer.base.render_texture(
&img.tex,
None,
0,
0,
None,
Expand Down Expand Up @@ -438,6 +440,7 @@ impl Cursor for AnimatedCursor {
if let Some(img) = img.scales.get(&renderer.scale()) {
renderer.base.render_texture(
&img.tex,
None,
0,
0,
None,
Expand Down
2 changes: 2 additions & 0 deletions src/gfx_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ pub struct CopyTexture {
pub buffer_resv: Option<Rc<dyn BufferResv>>,
pub acquire_sync: AcquireSync,
pub release_sync: ReleaseSync,
pub alpha: Option<f32>,
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -292,6 +293,7 @@ impl dyn GfxFramebuffer {
let mut renderer = self.renderer_base(&mut ops, scale, Transform::None);
renderer.render_texture(
texture,
None,
x,
y,
None,
Expand Down
32 changes: 22 additions & 10 deletions src/gfx_apis/gl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ use {
},
gfx_apis::gl::{
gl::texture::image_target,
renderer::{context::GlRenderContext, framebuffer::Framebuffer, texture::Texture},
renderer::{
context::{GlRenderContext, TexCopyType, TexSourceType},
framebuffer::Framebuffer,
texture::Texture,
},
sys::{
GL_BLEND, GL_FALSE, GL_FLOAT, GL_LINEAR, GL_TEXTURE0, GL_TEXTURE_MIN_FILTER,
GL_TRIANGLES, GL_TRIANGLE_STRIP,
Expand Down Expand Up @@ -336,16 +340,20 @@ fn render_texture(ctx: &GlRenderContext, tex: &CopyTexture) {
},
false => &ctx.tex_internal,
};
let prog = match texture.gl.format.has_alpha {
true => {
(gles.glEnable)(GL_BLEND);
&progs.alpha
}
false => {
(gles.glDisable)(GL_BLEND);
&progs.solid
}
let copy_type = match tex.alpha.is_some() {
true => TexCopyType::Multiply,
false => TexCopyType::Identity,
};
let source_type = match texture.gl.format.has_alpha {
true => TexSourceType::HasAlpha,
false => TexSourceType::Opaque,
};
if (copy_type, source_type) == (TexCopyType::Identity, TexSourceType::Opaque) {
(gles.glDisable)(GL_BLEND);
} else {
(gles.glEnable)(GL_BLEND);
}
let prog = &progs[copy_type][source_type];

(gles.glUseProgram)(prog.prog.prog);

Expand All @@ -354,6 +362,10 @@ fn render_texture(ctx: &GlRenderContext, tex: &CopyTexture) {
let texcoord = tex.source.to_points();
let pos = tex.target.to_points();

if let Some(alpha) = tex.alpha {
(gles.glUniform1f)(prog.alpha, alpha);
}

(gles.glVertexAttribPointer)(
prog.texcoord as _,
2,
Expand Down
82 changes: 51 additions & 31 deletions src/gfx_apis/gl/renderer/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use {
},
},
ahash::AHashMap,
enum_map::{enum_map, Enum, EnumMap},
jay_config::video::GfxApi,
std::{
cell::{Cell, RefCell},
Expand All @@ -36,22 +37,35 @@ pub(crate) struct TexProg {
pub(crate) pos: GLint,
pub(crate) texcoord: GLint,
pub(crate) tex: GLint,
pub(crate) alpha: GLint,
}

impl TexProg {
unsafe fn from(prog: GlProgram) -> Self {
unsafe fn from(prog: GlProgram, alpha_multiplier: bool) -> Self {
let alpha = match alpha_multiplier {
true => prog.get_uniform_location(ustr!("alpha")),
false => 0,
};
Self {
pos: prog.get_attrib_location(ustr!("pos")),
texcoord: prog.get_attrib_location(ustr!("texcoord")),
tex: prog.get_uniform_location(ustr!("tex")),
alpha,
prog,
}
}
}

pub(crate) struct TexProgs {
pub alpha: TexProg,
pub solid: TexProg,
#[derive(Copy, Clone, PartialEq, Enum)]
pub(in crate::gfx_apis::gl) enum TexCopyType {
Identity,
Multiply,
}

#[derive(Copy, Clone, PartialEq, Enum)]
pub(in crate::gfx_apis::gl) enum TexSourceType {
Opaque,
HasAlpha,
}

pub(in crate::gfx_apis::gl) struct GlRenderContext {
Expand All @@ -61,8 +75,8 @@ pub(in crate::gfx_apis::gl) struct GlRenderContext {

pub(crate) render_node: Rc<CString>,

pub(crate) tex_internal: TexProgs,
pub(crate) tex_external: Option<TexProgs>,
pub(crate) tex_internal: EnumMap<TexCopyType, EnumMap<TexSourceType, TexProg>>,
pub(crate) tex_external: Option<EnumMap<TexCopyType, EnumMap<TexSourceType, TexProg>>>,

pub(crate) fill_prog: GlProgram,
pub(crate) fill_prog_pos: GLint,
Expand Down Expand Up @@ -100,28 +114,37 @@ impl GlRenderContext {

unsafe fn new(ctx: &Rc<EglContext>, node: &Rc<CString>) -> Result<Self, RenderError> {
let tex_vert = include_str!("../shaders/tex.vert.glsl");
let tex_prog =
GlProgram::from_shaders(ctx, tex_vert, include_str!("../shaders/tex.frag.glsl"))?;
let tex_alpha_prog = GlProgram::from_shaders(
ctx,
tex_vert,
include_str!("../shaders/tex-alpha.frag.glsl"),
)?;
let tex_external = if ctx.ext.contains(GL_OES_EGL_IMAGE_EXTERNAL) {
let solid = GlProgram::from_shaders(
ctx,
tex_vert,
include_str!("../shaders/tex-external.frag.glsl"),
)?;
let alpha = GlProgram::from_shaders(
ctx,
tex_vert,
include_str!("../shaders/tex-external-alpha.frag.glsl"),
)?;
Some(TexProgs {
alpha: TexProg::from(alpha),
solid: TexProg::from(solid),
let tex_frag = include_str!("../shaders/tex.frag.glsl");
let create_programs = |external: bool| {
let create_program = |alpha_multiplier: bool, alpha: bool| {
let mut tex_frac_src = String::new();
if external {
tex_frac_src.push_str("#define EXTERNAL\n");
}
if alpha_multiplier {
tex_frac_src.push_str("#define ALPHA_MULTIPLIER\n");
}
if alpha {
tex_frac_src.push_str("#define ALPHA\n");
}
tex_frac_src.push_str(tex_frag);
let prog = GlProgram::from_shaders(ctx, tex_vert, &tex_frac_src)?;
Ok::<_, RenderError>(TexProg::from(prog, alpha_multiplier))
};
Ok::<_, RenderError>(enum_map! {
TexCopyType::Identity => enum_map! {
TexSourceType::Opaque => create_program(false, false)?,
TexSourceType::HasAlpha => create_program(false, true)?,
},
TexCopyType::Multiply => enum_map! {
TexSourceType::Opaque => create_program(true, false)?,
TexSourceType::HasAlpha => create_program(true, true)?,
},
})
};
let tex_internal = create_programs(false)?;
let tex_external = if ctx.ext.contains(GL_OES_EGL_IMAGE_EXTERNAL) {
Some(create_programs(true)?)
} else {
None
};
Expand All @@ -137,10 +160,7 @@ impl GlRenderContext {

render_node: node.clone(),

tex_internal: TexProgs {
solid: TexProg::from(tex_prog),
alpha: TexProg::from(tex_alpha_prog),
},
tex_internal,
tex_external,

fill_prog_pos: fill_prog.get_attrib_location(ustr!("pos")),
Expand Down
7 changes: 0 additions & 7 deletions src/gfx_apis/gl/shaders/tex-alpha.frag.glsl

This file was deleted.

9 changes: 0 additions & 9 deletions src/gfx_apis/gl/shaders/tex-external-alpha.frag.glsl

This file was deleted.

9 changes: 0 additions & 9 deletions src/gfx_apis/gl/shaders/tex-external.frag.glsl

This file was deleted.

Loading

0 comments on commit ff54a8a

Please sign in to comment.