update cushy + improved layout

This commit is contained in:
Daniel Bulant 2024-11-25 15:23:12 +01:00
parent ffaef580df
commit d2123ba96e
No known key found for this signature in database
4 changed files with 88 additions and 61 deletions

24
Cargo.lock generated
View file

@ -823,7 +823,7 @@ checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991"
[[package]]
name = "cushy"
version = "0.4.0"
source = "git+https://github.com/khonsulabs/cushy.git?branch=main#57f0c06b12f51cd7ef133794119bf1ba163e88d8"
source = "git+https://github.com/khonsulabs/cushy.git?branch=main#5e2819a98386a4d1f7485de23acd6603e43b6368"
dependencies = [
"ahash",
"alot",
@ -852,7 +852,7 @@ dependencies = [
[[package]]
name = "cushy-macros"
version = "0.4.0"
source = "git+https://github.com/khonsulabs/cushy.git?branch=main#57f0c06b12f51cd7ef133794119bf1ba163e88d8"
source = "git+https://github.com/khonsulabs/cushy.git?branch=main#5e2819a98386a4d1f7485de23acd6603e43b6368"
dependencies = [
"attribute-derive",
"manyhow",
@ -1576,9 +1576,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.15.1"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
[[package]]
name = "heck"
@ -1798,7 +1798,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
dependencies = [
"equivalent",
"hashbrown 0.15.1",
"hashbrown 0.15.2",
]
[[package]]
@ -1926,7 +1926,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
name = "kludgine"
version = "0.11.0"
source = "git+https://github.com/khonsulabs/kludgine#1964cea13c1da08fb06d93c5101f3cd1f748c930"
source = "git+https://github.com/khonsulabs/kludgine#af4e6450c3bff3b2b6a6a3d7e9c0c2471b622578"
dependencies = [
"ahash",
"alot",
@ -4129,9 +4129,9 @@ checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
[[package]]
name = "wgpu"
version = "23.0.0"
version = "23.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76ab52f2d3d18b70d5ab8dd270a1cff3ebe6dbe4a7d13c1cc2557138a9777fdc"
checksum = "80f70000db37c469ea9d67defdc13024ddf9a5f1b89cb2941b812ad7cde1735a"
dependencies = [
"arrayvec",
"cfg_aliases 0.1.1",
@ -4154,9 +4154,9 @@ dependencies = [
[[package]]
name = "wgpu-core"
version = "23.0.0"
version = "23.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e0c68e7b6322a03ee5b83fcd92caeac5c2a932f6457818179f4652ad2a9c065"
checksum = "d63c3c478de8e7e01786479919c8769f62a22eec16788d8c2ac77ce2c132778a"
dependencies = [
"arrayvec",
"bit-vec",
@ -4179,9 +4179,9 @@ dependencies = [
[[package]]
name = "wgpu-hal"
version = "23.0.0"
version = "23.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de6e7266b869de56c7e3ed72a954899f71d14fec6cc81c102b7530b92947601b"
checksum = "89364b8a0b211adc7b16aeaf1bd5ad4a919c1154b44c9ce27838213ba05fd821"
dependencies = [
"android_system_properties",
"arrayvec",

View file

@ -7,7 +7,10 @@ use std::{
};
use cushy::{
figures::{units::UPx, Rect},
figures::{
units::{Px, UPx},
IntoUnsigned, Rect,
},
kludgine::{self, wgpu},
RenderOperation,
};
@ -304,7 +307,7 @@ impl VideoPipeline {
}
}
fn prepare(&mut self, queue: &wgpu::Queue, video_id: u64, bounds: Rect<UPx>) {
fn prepare(&mut self, queue: &wgpu::Queue, video_id: u64, bounds: Rect<Px>) {
if let Some(video) = self.videos.get(&video_id) {
let uniforms = Uniforms {
rect: [
@ -327,38 +330,23 @@ impl VideoPipeline {
fn draw(&self, pass: &mut wgpu::RenderPass, viewport: Rect<UPx>, video_id: u64) {
if let Some(video) = self.videos.get(&video_id) {
// let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
// label: Some("iced_video_player render pass"),
// color_attachments: &[Some(wgpu::RenderPassColorAttachment {
// view: target,
// resolve_target: None,
// ops: wgpu::Operations {
// load: wgpu::LoadOp::Load,
// store: wgpu::StoreOp::Store,
// },
// })],
// depth_stencil_attachment: None,
// timestamp_writes: None,
// occlusion_query_set: None,
// });
pass.set_pipeline(&self.pipeline);
pass.set_bind_group(0, &video.bg0, &[]);
// pass.set_viewport(
// viewport.origin.x as _,
// viewport.origin.y as _,
// viewport.size.width as _,
// viewport.size.height as _,
// 0.0,
// 1.0,
// );
pass.set_viewport(
viewport.origin.x.get() as _,
viewport.origin.y.get() as _,
viewport.size.width.get() as f32,
viewport.size.height.get() as f32,
0.0,
1.0,
);
pass.draw(0..4, 0..1);
}
}
}
pub(crate) struct VideoRO {
pipeline: Option<VideoPipeline>,
pipeline: VideoPipeline,
}
impl RenderOperation for VideoRO {
@ -366,21 +354,19 @@ impl RenderOperation for VideoRO {
type Prepared = VideoPrimitive;
fn new(graphics: &mut cushy::kludgine::Graphics<'_>) -> Self {
VideoRO { pipeline: None }
VideoRO {
pipeline: VideoPipeline::new(graphics),
}
}
fn prepare(
&mut self,
context: Self::DrawInfo,
origin: cushy::figures::Point<cushy::figures::units::Px>,
rect: Rect<Px>,
graphics: &mut cushy::kludgine::Graphics<'_>,
) -> Self::Prepared {
let pipeline = self
.pipeline
.get_or_insert_with(|| VideoPipeline::new(graphics));
if context.upload_frame {
pipeline.upload(
self.pipeline.upload(
graphics.device(),
graphics.queue(),
context.video_id,
@ -389,26 +375,22 @@ impl RenderOperation for VideoRO {
context.frame.lock().expect("lock frame mutex").as_slice(),
);
}
pipeline.prepare(graphics.queue(), context.video_id, graphics.clip_rect());
self.pipeline
.prepare(graphics.queue(), context.video_id, rect);
context
}
fn render(
&self,
prepared: &Self::Prepared,
origin: cushy::figures::Point<cushy::figures::units::Px>,
opacity: f32,
_rect: Rect<Px>,
_opacity: f32,
graphics: &mut cushy::kludgine::RenderingGraphics<'_, '_>,
) {
let pipeline = self.pipeline.as_ref().expect("prepare sets pipeline");
let rect = graphics.clip_rect();
pipeline.draw(
// target,
graphics.pass_mut(),
rect,
prepared.video_id,
);
dbg!(rect);
self.pipeline
.draw(graphics.pass_mut(), rect.into_unsigned(), prepared.video_id);
}
}

View file

@ -5,15 +5,19 @@ use std::{
use cushy::{
context::{GraphicsContext, LayoutContext},
figures::{units::UPx, Size},
value::{Destination, Dynamic, DynamicReader, Generation, Source},
figures::{
units::{Px, UPx},
FloatConversion, IntoSigned, IntoUnsigned, Point, Rect, Size,
},
value::{Destination, Dynamic, DynamicReader, Generation, Source, Value},
widget::Widget,
widgets::image::{Aspect, ImageScaling},
ConstraintLimit,
};
use crate::{
pipeline::{VideoPrimitive, VideoRO},
video::Video,
video::{Internal, Video},
Error,
};
@ -26,6 +30,7 @@ pub struct VideoPlayer {
subtitles: Dynamic<Option<String>>,
frame: Dynamic<()>,
last_frame: Generation,
scaling: Value<ImageScaling>,
}
impl VideoPlayer {
@ -37,6 +42,7 @@ impl VideoPlayer {
video,
last_frame: Generation::default(),
frame,
scaling: Default::default(),
}
}
@ -61,6 +67,41 @@ impl VideoPlayer {
pub fn video(&self) -> &Video {
&self.video
}
fn calculate_video_rect(
&self,
video: &Internal,
within_size: Size<UPx>,
context: &mut GraphicsContext<'_, '_, '_, '_>,
) -> Rect<Px> {
let within_size = within_size.into_signed();
let size = Size {
width: Px::new(video.width),
height: Px::new(video.height),
};
match self.scaling.get_tracking_invalidate(context) {
ImageScaling::Aspect { mode, orientation } => {
let scale_width = within_size.width.into_float() / size.width.into_float();
let scale_height = within_size.height.into_float() / size.height.into_float();
let effective_scale = match mode {
Aspect::Fill => scale_width.max(scale_height),
Aspect::Fit => scale_width.min(scale_height),
};
let scaled = size * effective_scale;
let x = (within_size.width - scaled.width) * *orientation.width;
let y = (within_size.height - scaled.height) * *orientation.height;
Rect::new(Point::new(x, y), scaled)
}
ImageScaling::Stretch => within_size.into(),
ImageScaling::Scale(factor) => {
let size = size.map(|px| px * factor);
size.into()
}
}
}
}
impl Widget for VideoPlayer {
@ -93,8 +134,11 @@ impl Widget for VideoPlayer {
fn layout(
&mut self,
available_space: Size<ConstraintLimit>,
_context: &mut LayoutContext<'_, '_, '_, '_>,
context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> {
available_space.map(ConstraintLimit::max)
let inner = self.video.read();
let rect =
self.calculate_video_rect(&inner, available_space.map(ConstraintLimit::max), context);
rect.size.into_unsigned()
}
}

View file

@ -1,6 +1,7 @@
// This file is taken nearly one to one from https://github.com/jazzfool/iced_video_player
use crate::Error;
use cushy::value::{Destination, Dynamic};
use glib::property::PropertyGet;
use gstreamer as gst;
use gstreamer_app as gst_app;
use gstreamer_app::prelude::*;