KHR_composition_layer_color_scale_bias instead of raster alpha (#407)

This commit is contained in:
galister
2026-02-04 09:39:57 +09:00
committed by GitHub
parent e1c72fa446
commit a22bb2bf1a
7 changed files with 15 additions and 71 deletions

View File

@@ -314,7 +314,7 @@ pub fn openvr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
let tgt = RenderTarget { let tgt = RenderTarget {
views: smallvec![o.ensure_staging_image(&mut app, meta.extent)?], views: smallvec![o.ensure_staging_image(&mut app, meta.extent)?],
}; };
let mut rdr = RenderResources::new(app.gfx.clone(), tgt, &meta, 1.0)?; let mut rdr = RenderResources::new(app.gfx.clone(), tgt, &meta)?;
o.render(&mut app, &mut rdr)?; o.render(&mut app, &mut rdr)?;
o.data.image_dirty = true; o.data.image_dirty = true;
futures.execute_results(rdr.end()?)?; futures.execute_results(rdr.end()?)?;

View File

@@ -363,14 +363,14 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
for o in overlays.values_mut() { for o in overlays.values_mut() {
o.data.cur_visible = false; o.data.cur_visible = false;
let Some(alpha) = o.config.active_state.as_ref().map(|x| x.alpha) else { if o.config
.active_state
.as_ref()
.is_none_or(|s| s.alpha < 0.01)
{
log::trace!("{}: hidden, skip render", o.config.name); log::trace!("{}: hidden, skip render", o.config.name);
continue; continue;
}; };
if alpha < 0.01 {
log::trace!("{}: alpha too low, skip render", o.config.name);
continue;
}
if !o.data.init { if !o.data.init {
log::trace!("{}: init", o.config.name); log::trace!("{}: init", o.config.name);
@@ -378,11 +378,7 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
o.data.init = true; o.data.init = true;
} }
let should_render = match o.should_render(&mut app)? { let should_render = matches!(o.should_render(&mut app)?, ShouldRender::Should);
ShouldRender::Should => true,
ShouldRender::Can => (o.data.last_alpha - alpha).abs() > f32::EPSILON,
ShouldRender::Unable => false, //try show old image if exists
};
log::trace!("{}: should_render returned: {should_render}", o.config.name); log::trace!("{}: should_render returned: {should_render}", o.config.name);
if should_render { if should_render {
@@ -391,9 +387,8 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
let stereo = !matches!(meta.stereo, StereoMode::None); let stereo = !matches!(meta.stereo, StereoMode::None);
let wsi = o.ensure_swapchain_acquire(&app, &xr_state, meta.extent, stereo)?; let wsi = o.ensure_swapchain_acquire(&app, &xr_state, meta.extent, stereo)?;
let tgt = RenderTarget { views: wsi.views }; let tgt = RenderTarget { views: wsi.views };
let mut rdr = RenderResources::new(app.gfx.clone(), tgt, &meta, alpha)?; let mut rdr = RenderResources::new(app.gfx.clone(), tgt, &meta)?;
o.render(&mut app, &mut rdr)?; o.render(&mut app, &mut rdr)?;
o.data.last_alpha = alpha;
futures.execute_results(rdr.end()?)?; futures.execute_results(rdr.end()?)?;
} else if o.data.swapchain.is_none() { } else if o.data.swapchain.is_none() {
log::trace!("{}: not showing due to missing swapchain", o.config.name); log::trace!("{}: not showing due to missing swapchain", o.config.name);

View File

@@ -17,7 +17,6 @@ pub struct OpenXrOverlayData {
pub(super) swapchain: Option<WlxSwapchain>, pub(super) swapchain: Option<WlxSwapchain>,
pub(super) init: bool, pub(super) init: bool,
pub(super) cur_visible: bool, pub(super) cur_visible: bool,
pub(super) last_alpha: f32,
color_bias_khr: Option<Box<xr::sys::CompositionLayerColorScaleBiasKHR>>, color_bias_khr: Option<Box<xr::sys::CompositionLayerColorScaleBiasKHR>>,
} }

View File

@@ -53,7 +53,6 @@ pub struct ScreenPipeline {
mouse: BufPass, mouse: BufPass,
pass: SmallVec<[BufPass; 2]>, pass: SmallVec<[BufPass; 2]>,
pipeline: Arc<WGfxPipeline<Vert2Uv>>, pipeline: Arc<WGfxPipeline<Vert2Uv>>,
buf_alpha: Subbuffer<[f32]>,
extentf: [f32; 2], extentf: [f32; 2],
offsetf: [f32; 2], offsetf: [f32; 2],
stereo: StereoMode, stereo: StereoMode,
@@ -76,29 +75,12 @@ impl ScreenPipeline {
.use_updatable_descriptors(smallvec![0]), .use_updatable_descriptors(smallvec![0]),
)?; )?;
let buf_alpha = app
.gfx
.empty_buffer(BufferUsage::TRANSFER_DST | BufferUsage::UNIFORM_BUFFER, 1)?;
let mut me = Self { let mut me = Self {
pass: smallvec![Self::create_pass( pass: smallvec![Self::create_pass(app, pipeline.clone(), extentf, offsetf,)?],
app, mouse: Self::create_mouse_pass(app, pipeline.clone(), extentf, offsetf)?,
pipeline.clone(),
extentf,
offsetf,
buf_alpha.clone()
)?],
mouse: Self::create_mouse_pass(
app,
pipeline.clone(),
extentf,
offsetf,
buf_alpha.clone(),
)?,
pipeline, pipeline,
extentf, extentf,
offsetf, offsetf,
buf_alpha,
stereo, stereo,
}; };
me.ensure_stereo(stereo); me.ensure_stereo(stereo);
@@ -121,7 +103,6 @@ impl ScreenPipeline {
self.pipeline.clone(), self.pipeline.clone(),
self.extentf, self.extentf,
self.offsetf, self.offsetf,
self.buf_alpha.clone(),
)?); )?);
} }
@@ -146,13 +127,7 @@ impl ScreenPipeline {
self.offsetf = offsetf; self.offsetf = offsetf;
self.pass.clear(); self.pass.clear();
self.mouse = Self::create_mouse_pass( self.mouse = Self::create_mouse_pass(app, self.pipeline.clone(), extentf, offsetf)?;
app,
self.pipeline.clone(),
extentf,
offsetf,
self.buf_alpha.clone(),
)?;
Ok(()) Ok(())
} }
@@ -161,14 +136,12 @@ impl ScreenPipeline {
pipeline: Arc<WGfxPipeline<Vert2Uv>>, pipeline: Arc<WGfxPipeline<Vert2Uv>>,
extentf: [f32; 2], extentf: [f32; 2],
offsetf: [f32; 2], offsetf: [f32; 2],
buf_alpha: Subbuffer<[f32]>,
) -> anyhow::Result<BufPass> { ) -> anyhow::Result<BufPass> {
let set0 = pipeline.uniform_sampler( let set0 = pipeline.uniform_sampler(
0, 0,
app.gfx_extras.fallback_image.clone(), app.gfx_extras.fallback_image.clone(),
app.gfx.texture_filter, app.gfx.texture_filter,
)?; )?;
let set1 = pipeline.buffer(1, buf_alpha)?;
let buf_vert = app let buf_vert = app
.gfx .gfx
.empty_buffer(BufferUsage::TRANSFER_DST | BufferUsage::VERTEX_BUFFER, 4)?; .empty_buffer(BufferUsage::TRANSFER_DST | BufferUsage::VERTEX_BUFFER, 4)?;
@@ -179,7 +152,7 @@ impl ScreenPipeline {
buf_vert.clone(), buf_vert.clone(),
0..4, 0..4,
0..1, 0..1,
vec![set0, set1], vec![set0],
&Default::default(), &Default::default(),
)?; )?;
@@ -191,7 +164,6 @@ impl ScreenPipeline {
pipeline: Arc<WGfxPipeline<Vert2Uv>>, pipeline: Arc<WGfxPipeline<Vert2Uv>>,
extentf: [f32; 2], extentf: [f32; 2],
offsetf: [f32; 2], offsetf: [f32; 2],
buf_alpha: Subbuffer<[f32]>,
) -> anyhow::Result<BufPass> { ) -> anyhow::Result<BufPass> {
#[rustfmt::skip] #[rustfmt::skip]
let mouse_bytes = [ let mouse_bytes = [
@@ -215,14 +187,13 @@ impl ScreenPipeline {
.empty_buffer(BufferUsage::TRANSFER_DST | BufferUsage::VERTEX_BUFFER, 4)?; .empty_buffer(BufferUsage::TRANSFER_DST | BufferUsage::VERTEX_BUFFER, 4)?;
let set0 = pipeline.uniform_sampler(0, view, Filter::Nearest)?; let set0 = pipeline.uniform_sampler(0, view, Filter::Nearest)?;
let set1 = pipeline.buffer(1, buf_alpha)?;
let pass = pipeline.create_pass( let pass = pipeline.create_pass(
extentf, extentf,
offsetf, offsetf,
buf_vert.clone(), buf_vert.clone(),
0..4, 0..4,
0..1, 0..1,
vec![set0, set1], vec![set0],
&Default::default(), &Default::default(),
)?; )?;
@@ -239,8 +210,6 @@ impl ScreenPipeline {
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
self.ensure_depth(app, rdr.cmd_bufs.len())?; self.ensure_depth(app, rdr.cmd_bufs.len())?;
self.buf_alpha.write()?[0] = rdr.alpha;
for (eye, cmd_buf) in rdr.cmd_bufs.iter_mut().enumerate() { for (eye, cmd_buf) in rdr.cmd_bufs.iter_mut().enumerate() {
let current = &mut self.pass[eye]; let current = &mut self.pass[eye];
@@ -270,10 +239,6 @@ impl ScreenPipeline {
Ok(()) Ok(())
} }
pub fn get_alpha_buf(&self) -> Subbuffer<[f32]> {
self.buf_alpha.clone()
}
} }
fn stereo_mode_to_verts(stereo: StereoMode, array_index: usize) -> [Vert2Uv; 4] { fn stereo_mode_to_verts(stereo: StereoMode, array_index: usize) -> [Vert2Uv; 4] {

View File

@@ -451,17 +451,13 @@ impl OverlayBackend for WvrWindowBackend {
popup_img.clone(), popup_img.clone(),
app.gfx.texture_filter, app.gfx.texture_filter,
)?; )?;
let set1 = self
.popups_pipeline
.buffer(1, self.pipeline.as_ref().unwrap().get_alpha_buf())?;
let pass = self.popups_pipeline.create_pass( let pass = self.popups_pipeline.create_pass(
extentf, extentf,
[BORDER_SIZE as _, (BAR_SIZE + BORDER_SIZE) as _], [BORDER_SIZE as _, (BAR_SIZE + BORDER_SIZE) as _],
buf_vert, buf_vert,
0..4, 0..4,
0..1, 0..1,
vec![set0, set1], vec![set0],
&Default::default(), &Default::default(),
)?; )?;

View File

@@ -5,13 +5,9 @@ layout (location = 0) in vec2 in_uv;
layout (location = 0) out vec4 out_color; layout (location = 0) out vec4 out_color;
layout (set = 0, binding = 0) uniform sampler2D in_texture; layout (set = 0, binding = 0) uniform sampler2D in_texture;
layout (set = 1, binding = 0) uniform AlphaBlock {
uniform float alpha;
};
void main() void main()
{ {
out_color = texture(in_texture, in_uv); out_color = texture(in_texture, in_uv);
out_color.a = alpha;
} }

View File

@@ -47,18 +47,12 @@ pub struct RenderTarget {
} }
pub struct RenderResources { pub struct RenderResources {
pub alpha: f32,
pub cmd_bufs: SmallVec<[GfxCommandBuffer; 2]>, pub cmd_bufs: SmallVec<[GfxCommandBuffer; 2]>,
pub extent: [u32; 2], pub extent: [u32; 2],
} }
impl RenderResources { impl RenderResources {
pub fn new( pub fn new(gfx: Arc<WGfx>, target: RenderTarget, meta: &FrameMeta) -> anyhow::Result<Self> {
gfx: Arc<WGfx>,
target: RenderTarget,
meta: &FrameMeta,
alpha: f32,
) -> anyhow::Result<Self> {
let mut cmd_bufs = SmallVec::new_const(); let mut cmd_bufs = SmallVec::new_const();
for tgt in target.views { for tgt in target.views {
@@ -70,7 +64,6 @@ impl RenderResources {
Ok(Self { Ok(Self {
cmd_bufs, cmd_bufs,
alpha,
extent: meta.extent, extent: meta.extent,
}) })
} }