Skip to content

Commit b8cccd5

Browse files
committed
coderabbit bits
1 parent 12f42d8 commit b8cccd5

File tree

5 files changed

+117
-77
lines changed

5 files changed

+117
-77
lines changed

apps/desktop/src/routes/screenshot-editor/Preview.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,27 @@ export function Preview(props: { zoom: number; setZoom: (z: number) => void }) {
3939

4040
const [pan, setPan] = createSignal({ x: 0, y: 0 });
4141

42-
let previousBitmap: ImageBitmap | null = null;
42+
const [previousBitmap, setPreviousBitmap] = createSignal<ImageBitmap | null>(
43+
null,
44+
);
4345

4446
createEffect(() => {
4547
const frame = latestFrame();
4648
const currentBitmap = frame?.bitmap ?? null;
49+
const prevBitmap = previousBitmap();
4750

48-
if (previousBitmap && previousBitmap !== currentBitmap) {
49-
previousBitmap.close();
50-
previousBitmap = null;
51+
if (prevBitmap && prevBitmap !== currentBitmap) {
52+
prevBitmap.close();
5153
}
5254

53-
if (currentBitmap) {
54-
previousBitmap = currentBitmap;
55-
}
55+
setPreviousBitmap(currentBitmap);
5656
});
5757

5858
onCleanup(() => {
59-
if (previousBitmap) {
60-
previousBitmap.close();
61-
previousBitmap = null;
59+
const bitmap = previousBitmap();
60+
if (bitmap) {
61+
bitmap.close();
62+
setPreviousBitmap(null);
6263
}
6364
});
6465

apps/desktop/src/routes/screenshot-editor/context.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import { trackStore } from "@solid-primitives/deep";
33
import { debounce } from "@solid-primitives/scheduled";
44
import { makePersisted } from "@solid-primitives/storage";
55
import { convertFileSrc } from "@tauri-apps/api/core";
6-
import { createEffect, createResource, createSignal, on } from "solid-js";
6+
import {
7+
createEffect,
8+
createResource,
9+
createSignal,
10+
on,
11+
onCleanup,
12+
} from "solid-js";
713
import { createStore, reconcile, unwrap } from "solid-js/store";
814
import {
915
createImageDataWS,
@@ -149,12 +155,16 @@ function createScreenshotEditorContext() {
149155
img.onload = async () => {
150156
try {
151157
const bitmap = await createImageBitmap(img);
158+
const existing = latestFrame();
159+
if (existing?.bitmap) {
160+
existing.bitmap.close();
161+
}
152162
setLatestFrame({
153163
width: img.naturalWidth,
154164
height: img.naturalHeight,
155165
bitmap,
156166
});
157-
} catch (e) {
167+
} catch (e: unknown) {
158168
console.error("Failed to create ImageBitmap from fallback image:", e);
159169
}
160170
};
@@ -175,6 +185,21 @@ function createScreenshotEditorContext() {
175185
return instance;
176186
});
177187

188+
createEffect(
189+
on(latestFrame, (current, previous) => {
190+
if (previous?.bitmap && previous.bitmap !== current?.bitmap) {
191+
previous.bitmap.close();
192+
}
193+
}),
194+
);
195+
196+
onCleanup(() => {
197+
const frame = latestFrame();
198+
if (frame?.bitmap) {
199+
frame.bitmap.close();
200+
}
201+
});
202+
178203
const saveConfig = debounce((config: ProjectConfiguration) => {
179204
commands.updateScreenshotConfig(config, true);
180205
}, 1000);

crates/editor/src/editor_instance.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ impl EditorInstance {
350350
let decoders = prefetch_segment_media.decoders.clone();
351351
let cancel_token = new_cancel_token.clone();
352352
let playback_rx = playback_rx.clone();
353-
tokio::spawn(async move {
353+
let _ = tokio::spawn(async move {
354354
if cancel_token.is_cancelled() || *playback_rx.borrow() {
355355
return;
356356
}

crates/rendering/src/layers/camera.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl CameraLayer {
204204
},
205205
);
206206

207-
let _ = queue.submit(std::iter::once(encoder.finish()));
207+
let _submission_index = queue.submit(std::iter::once(encoder.finish()));
208208
}
209209
}
210210

crates/rendering/src/layers/display.rs

Lines changed: 77 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,16 @@
11
use cap_project::XY;
2+
use tracing;
23

34
use crate::{
45
DecodedSegmentFrames, PixelFormat,
56
composite_frame::{CompositeVideoFramePipeline, CompositeVideoFrameUniforms},
67
yuv_converter::YuvToRgbaConverter,
78
};
89

9-
fn copy_converted_texture(
10-
device: &wgpu::Device,
11-
queue: &wgpu::Queue,
12-
src_texture: &wgpu::Texture,
13-
dst_texture: &wgpu::Texture,
10+
struct PendingTextureCopy {
1411
width: u32,
1512
height: u32,
16-
) {
17-
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
18-
label: Some("YUV Copy Encoder"),
19-
});
20-
21-
encoder.copy_texture_to_texture(
22-
wgpu::TexelCopyTextureInfo {
23-
texture: src_texture,
24-
mip_level: 0,
25-
origin: wgpu::Origin3d::ZERO,
26-
aspect: wgpu::TextureAspect::All,
27-
},
28-
wgpu::TexelCopyTextureInfo {
29-
texture: dst_texture,
30-
mip_level: 0,
31-
origin: wgpu::Origin3d::ZERO,
32-
aspect: wgpu::TextureAspect::All,
33-
},
34-
wgpu::Extent3d {
35-
width,
36-
height,
37-
depth_or_array_layers: 1,
38-
},
39-
);
40-
41-
queue.submit(std::iter::once(encoder.finish()));
13+
dst_texture_index: usize,
4214
}
4315

4416
pub struct DisplayLayer {
@@ -50,6 +22,7 @@ pub struct DisplayLayer {
5022
bind_groups: [Option<wgpu::BindGroup>; 2],
5123
last_recording_time: Option<f32>,
5224
yuv_converter: YuvToRgbaConverter,
25+
pending_copy: Option<PendingTextureCopy>,
5326
}
5427

5528
impl DisplayLayer {
@@ -77,6 +50,7 @@ impl DisplayLayer {
7750
bind_groups: [bind_group_0, bind_group_1],
7851
last_recording_time: None,
7952
yuv_converter,
53+
pending_copy: None,
8054
}
8155
}
8256

@@ -88,6 +62,8 @@ impl DisplayLayer {
8862
frame_size: XY<u32>,
8963
uniforms: CompositeVideoFrameUniforms,
9064
) -> (bool, u32, u32) {
65+
self.pending_copy = None;
66+
9167
let frame_data = segment_frames.screen_frame.data();
9268
let actual_width = segment_frames.screen_frame.width();
9369
let actual_height = segment_frames.screen_frame.height();
@@ -149,27 +125,41 @@ impl DisplayLayer {
149125
if let (Some(y_data), Some(uv_data)) =
150126
(screen_frame.y_plane(), screen_frame.uv_plane())
151127
{
152-
if self
153-
.yuv_converter
154-
.convert_nv12(
155-
device,
156-
queue,
157-
y_data,
158-
uv_data,
159-
frame_size.x,
160-
frame_size.y,
161-
screen_frame.y_stride(),
162-
)
163-
.is_ok()
164-
{
165-
if let Some(output_texture) = self.yuv_converter.output_texture() {
166-
copy_converted_texture(
167-
device,
168-
queue,
169-
output_texture,
170-
&self.frame_textures[next_texture],
171-
frame_size.x,
172-
frame_size.y,
128+
let y_stride = screen_frame.y_stride();
129+
let convert_result = self.yuv_converter.convert_nv12(
130+
device,
131+
queue,
132+
y_data,
133+
uv_data,
134+
frame_size.x,
135+
frame_size.y,
136+
y_stride,
137+
);
138+
139+
match convert_result {
140+
Ok(_) => {
141+
if self.yuv_converter.output_texture().is_some() {
142+
self.pending_copy = Some(PendingTextureCopy {
143+
width: frame_size.x,
144+
height: frame_size.y,
145+
dst_texture_index: next_texture,
146+
});
147+
} else {
148+
tracing::debug!(
149+
width = frame_size.x,
150+
height = frame_size.y,
151+
y_stride,
152+
"NV12 conversion succeeded but output texture is None, skipping copy"
153+
);
154+
}
155+
}
156+
Err(e) => {
157+
tracing::debug!(
158+
error = ?e,
159+
width = frame_size.x,
160+
height = frame_size.y,
161+
y_stride,
162+
"NV12 to RGBA conversion failed"
173163
);
174164
}
175165
}
@@ -196,17 +186,13 @@ impl DisplayLayer {
196186
screen_frame.uv_stride(),
197187
)
198188
.is_ok()
189+
&& self.yuv_converter.output_texture().is_some()
199190
{
200-
if let Some(output_texture) = self.yuv_converter.output_texture() {
201-
copy_converted_texture(
202-
device,
203-
queue,
204-
output_texture,
205-
&self.frame_textures[next_texture],
206-
frame_size.x,
207-
frame_size.y,
208-
);
209-
}
191+
self.pending_copy = Some(PendingTextureCopy {
192+
width: frame_size.x,
193+
height: frame_size.y,
194+
dst_texture_index: next_texture,
195+
});
210196
}
211197
}
212198
}
@@ -220,7 +206,35 @@ impl DisplayLayer {
220206
(skipped, actual_width, actual_height)
221207
}
222208

223-
pub fn copy_to_texture(&mut self, _encoder: &mut wgpu::CommandEncoder) {}
209+
pub fn copy_to_texture(&mut self, encoder: &mut wgpu::CommandEncoder) {
210+
let Some(pending) = self.pending_copy.take() else {
211+
return;
212+
};
213+
214+
let Some(src_texture) = self.yuv_converter.output_texture() else {
215+
return;
216+
};
217+
218+
encoder.copy_texture_to_texture(
219+
wgpu::TexelCopyTextureInfo {
220+
texture: src_texture,
221+
mip_level: 0,
222+
origin: wgpu::Origin3d::ZERO,
223+
aspect: wgpu::TextureAspect::All,
224+
},
225+
wgpu::TexelCopyTextureInfo {
226+
texture: &self.frame_textures[pending.dst_texture_index],
227+
mip_level: 0,
228+
origin: wgpu::Origin3d::ZERO,
229+
aspect: wgpu::TextureAspect::All,
230+
},
231+
wgpu::Extent3d {
232+
width: pending.width,
233+
height: pending.height,
234+
depth_or_array_layers: 1,
235+
},
236+
);
237+
}
224238

225239
pub fn render(&self, pass: &mut wgpu::RenderPass<'_>) {
226240
if let Some(bind_group) = &self.bind_groups[self.current_texture] {

0 commit comments

Comments
 (0)