Skip to content

Commit 5cce137

Browse files
committed
UI texture caching
1 parent b48e937 commit 5cce137

File tree

3 files changed

+55
-38
lines changed

3 files changed

+55
-38
lines changed

desktop/src/app.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,28 @@ use winit::window::WindowId;
1919
use crate::cef;
2020

2121
pub(crate) struct WinitApp {
22-
pub(crate) cef_context: cef::Context<cef::Initialized>,
23-
pub(crate) window: Option<Arc<Window>>,
24-
cef_schedule: Option<Instant>,
25-
_ui_frame_buffer: Option<wgpu::Texture>,
26-
window_size_sender: Sender<WindowSize>,
27-
_viewport_frame_buffer: Option<wgpu::Texture>,
22+
window: Option<Arc<Window>>,
23+
cef_context: cef::Context<cef::Initialized>,
24+
wgpu_context: WgpuContext,
25+
// Caches the resulting texture from CEF and the node graph output to render to the window
2826
graphics_state: Option<GraphicsState>,
27+
// Read back from the GPU, and will be used to check if inputs are sent to the browser
28+
// ui_overlay_frame_buffer: Option<FrameBuffer>,
29+
window_size_sender: Sender<WindowSize>,
30+
cef_schedule: Option<Instant>,
2931
event_loop_proxy: EventLoopProxy<CustomEvent>,
30-
wgpu_context: WgpuContext,
3132
}
3233

3334
impl WinitApp {
3435
pub(crate) fn new(cef_context: cef::Context<cef::Initialized>, window_size_sender: Sender<WindowSize>, event_loop_proxy: EventLoopProxy<CustomEvent>, wgpu_context: WgpuContext) -> Self {
3536
Self {
36-
cef_context,
3737
window: None,
38-
cef_schedule: Some(Instant::now()),
39-
_viewport_frame_buffer: None,
40-
_ui_frame_buffer: None,
38+
cef_context,
39+
wgpu_context,
4140
graphics_state: None,
4241
window_size_sender,
42+
cef_schedule: Some(Instant::now()),
4343
event_loop_proxy,
44-
wgpu_context,
4544
}
4645
}
4746
}
@@ -87,7 +86,7 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
8786
CustomEvent::UiUpdate((texture, width, height)) => {
8887
if let Some(graphics_state) = self.graphics_state.as_mut() {
8988
graphics_state.bind_texture(&texture);
90-
graphics_state.resize(width, height);
89+
graphics_state.try_resize(width, height);
9190
}
9291
if let Some(window) = &self.window {
9392
window.request_redraw();
@@ -96,6 +95,7 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
9695
CustomEvent::ScheduleBrowserWork(instant) => {
9796
if instant < Instant::now() {
9897
self.cef_context.work();
98+
// This seems pointless, it just schedules work in 10ms but doesnt loop
9999
let _ = self.event_loop_proxy.send_event(CustomEvent::ScheduleBrowserWork(Instant::now() + Duration::from_millis(10)));
100100
}
101101
self.cef_schedule = Some(instant);
@@ -134,6 +134,7 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
134134
_ => {}
135135
}
136136

137+
// Remove this since window events should not be tied to CEF
137138
// Notify cef of possible input events
138139
self.cef_context.work();
139140
}

desktop/src/cef.rs

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ pub(crate) struct CefHandler {
3838
window_size_receiver: Arc<Mutex<WindowSizeReceiver>>,
3939
event_loop_proxy: EventLoopProxy<CustomEvent>,
4040
wgpu_context: WgpuContext,
41+
cached_ui_texture: Arc<Mutex<Option<wgpu::Texture>>>,
4142
}
43+
4244
struct WindowSizeReceiver {
4345
receiver: Receiver<WindowSize>,
4446
window_size: WindowSize,
@@ -57,8 +59,37 @@ impl CefHandler {
5759
window_size_receiver: Arc::new(Mutex::new(WindowSizeReceiver::new(window_size_receiver))),
5860
event_loop_proxy,
5961
wgpu_context,
62+
cached_ui_texture: Arc::new(Mutex::new(None.into())),
6063
}
6164
}
65+
66+
fn try_resize_texture(&self, width: u32, height: u32) {
67+
let create_new_texture = self.cached_ui_texture.lock().unwrap().as_ref().map_or(true, |texture| {
68+
let size = texture.size();
69+
size.width != width || size.height != height
70+
});
71+
72+
if create_new_texture {
73+
self.create_texture(width, height);
74+
}
75+
}
76+
77+
fn create_texture(&self, width: u32, height: u32) {
78+
*self.cached_ui_texture.lock().unwrap() = Some(self.wgpu_context.device.create_texture(&wgpu::TextureDescriptor {
79+
label: Some("CEF Texture"),
80+
size: wgpu::Extent3d {
81+
width,
82+
height,
83+
depth_or_array_layers: 1,
84+
},
85+
mip_level_count: 1,
86+
sample_count: 1,
87+
dimension: wgpu::TextureDimension::D2,
88+
format: wgpu::TextureFormat::Bgra8UnormSrgb,
89+
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
90+
view_formats: &[],
91+
}));
92+
}
6293
}
6394

6495
impl CefEventHandler for CefHandler {
@@ -76,23 +107,12 @@ impl CefEventHandler for CefHandler {
76107
fn draw<'a>(&self, frame_buffer: FrameBufferRef<'a>) {
77108
let width = frame_buffer.width() as u32;
78109
let height = frame_buffer.height() as u32;
79-
let texture = self.wgpu_context.device.create_texture(&wgpu::TextureDescriptor {
80-
label: Some("CEF Texture"),
81-
size: wgpu::Extent3d {
82-
width,
83-
height,
84-
depth_or_array_layers: 1,
85-
},
86-
mip_level_count: 1,
87-
sample_count: 1,
88-
dimension: wgpu::TextureDimension::D2,
89-
format: wgpu::TextureFormat::Bgra8UnormSrgb,
90-
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
91-
view_formats: &[],
92-
});
110+
self.try_resize_texture(width, height);
111+
let binding = self.cached_ui_texture.lock().unwrap();
112+
let texture = binding.as_ref().expect("Texture must be initialized before drawing");
93113
self.wgpu_context.queue.write_texture(
94114
wgpu::TexelCopyTextureInfo {
95-
texture: &texture,
115+
texture,
96116
mip_level: 0,
97117
origin: wgpu::Origin3d::ZERO,
98118
aspect: wgpu::TextureAspect::All,
@@ -110,7 +130,7 @@ impl CefEventHandler for CefHandler {
110130
},
111131
);
112132

113-
let _ = self.event_loop_proxy.send_event(CustomEvent::UiUpdate((texture, width, height)));
133+
let _ = self.event_loop_proxy.send_event(CustomEvent::UiUpdate((texture.clone(), width, height)));
114134
}
115135

116136
fn schedule_cef_message_loop_work(&self, scheduled_time: std::time::Instant) {

desktop/src/render.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,7 @@ pub(crate) struct GraphicsState {
9999
surface: wgpu::Surface<'static>,
100100
context: WgpuContext,
101101
config: wgpu::SurfaceConfiguration,
102-
texture: Option<wgpu::Texture>,
103-
bind_group: Option<wgpu::BindGroup>,
102+
ui_overlay_bind_group: Option<wgpu::BindGroup>,
104103
render_pipeline: wgpu::RenderPipeline,
105104
sampler: wgpu::Sampler,
106105
}
@@ -211,14 +210,13 @@ impl GraphicsState {
211210
surface,
212211
context,
213212
config,
214-
texture: None,
215-
bind_group: None,
213+
ui_overlay_bind_group: None,
216214
render_pipeline,
217215
sampler,
218216
}
219217
}
220218

221-
pub(crate) fn resize(&mut self, width: u32, height: u32) {
219+
pub(crate) fn try_resize(&mut self, width: u32, height: u32) {
222220
if width > 0 && height > 0 && (self.config.width != width || self.config.height != height) {
223221
self.config.width = width;
224222
self.config.height = height;
@@ -228,9 +226,7 @@ impl GraphicsState {
228226

229227
pub(crate) fn bind_texture(&mut self, texture: &wgpu::Texture) {
230228
let bind_group = self.create_bindgroup(texture);
231-
self.texture = Some(texture.clone());
232-
233-
self.bind_group = Some(bind_group);
229+
self.ui_overlay_bind_group = Some(bind_group);
234230
}
235231

236232
fn create_bindgroup(&self, texture: &wgpu::Texture) -> wgpu::BindGroup {
@@ -275,7 +271,7 @@ impl GraphicsState {
275271
});
276272

277273
render_pass.set_pipeline(&self.render_pipeline);
278-
if let Some(bind_group) = &self.bind_group {
274+
if let Some(bind_group) = &self.ui_overlay_bind_group {
279275
render_pass.set_bind_group(0, bind_group, &[]);
280276
render_pass.draw(0..6, 0..1); // Draw 3 vertices for fullscreen triangle
281277
} else {

0 commit comments

Comments
 (0)