Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

egui-wgpu: only depend on epaint (not entire egui) #2438

Merged
merged 3 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 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 crates/egui-wgpu/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ All notable changes to the `egui-wgpu` integration will be noted in this file.
## Unreleased
* Return `Err` instead of panic if we can't find a device ([#2428](https://github.com/emilk/egui/pull/2428)).
* `winit::Painter::set_window` is now `async` ([#2434](https://github.com/emilk/egui/pull/2434)).
* `egui-wgpu` now only depends on `epaint` instead of the entire `egui` ([#2438](https://github.com/emilk/egui/pull/2438)).


## 0.20.0 - 2022-12-08 - web support
Expand Down
2 changes: 1 addition & 1 deletion crates/egui-wgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ winit = ["dep:winit"]


[dependencies]
egui = { version = "0.20.0", path = "../egui", default-features = false, features = [
epaint = { version = "0.20.0", path = "../epaint", default-features = false, features = [
"bytemuck",
] }

Expand Down
7 changes: 4 additions & 3 deletions crates/egui-wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@

pub use wgpu;

/// Low-level painting of [`egui`] on [`wgpu`].
/// Low-level painting of [`egui`](https://github.com/emilk/egui) on [`wgpu`].
pub mod renderer;
pub use renderer::CallbackFn;
pub use renderer::Renderer;

/// Module for painting [`egui`] with [`wgpu`] on [`winit`].
/// Module for painting [`egui`](https://github.com/emilk/egui) with [`wgpu`] on [`winit`].
#[cfg(feature = "winit")]
pub mod winit;

use egui::mutex::RwLock;
use std::sync::Arc;

use epaint::mutex::RwLock;

/// Access to the render state for egui.
#[derive(Clone)]
pub struct RenderState {
Expand Down
68 changes: 35 additions & 33 deletions crates/egui-wgpu/src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ use std::num::NonZeroU64;
use std::ops::Range;
use std::{borrow::Cow, collections::HashMap, num::NonZeroU32};

use egui::epaint::Vertex;
use egui::NumExt;
use egui::{epaint::Primitive, PaintCallbackInfo};
use type_map::concurrent::TypeMap;
use wgpu;
use wgpu::util::DeviceExt as _;

/// A callback function that can be used to compose an [`egui::PaintCallback`] for custom WGPU
use epaint::{emath::NumExt, PaintCallbackInfo, Primitive, Vertex};

/// A callback function that can be used to compose an [`epaint::PaintCallback`] for custom WGPU
/// rendering.
///
/// The callback is composed of two functions: `prepare` and `paint`:
Expand Down Expand Up @@ -154,11 +153,11 @@ pub struct Renderer {
/// Map of egui texture IDs to textures and their associated bindgroups (texture view +
/// sampler). The texture may be None if the TextureId is just a handle to a user-provided
/// sampler.
textures: HashMap<egui::TextureId, (Option<wgpu::Texture>, wgpu::BindGroup)>,
textures: HashMap<epaint::TextureId, (Option<wgpu::Texture>, wgpu::BindGroup)>,
next_user_texture_id: u64,
samplers: HashMap<egui::TextureOptions, wgpu::Sampler>,
samplers: HashMap<epaint::textures::TextureOptions, wgpu::Sampler>,

/// Storage for use by [`egui::PaintCallback`]'s that need to store resources such as render
/// Storage for use by [`epaint::PaintCallback`]'s that need to store resources such as render
/// pipelines that must have the lifetime of the renderpass.
pub paint_callback_resources: TypeMap,
}
Expand Down Expand Up @@ -346,7 +345,7 @@ impl Renderer {
pub fn render<'rp>(
&'rp self,
render_pass: &mut wgpu::RenderPass<'rp>,
paint_jobs: &[egui::epaint::ClippedPrimitive],
paint_jobs: &[epaint::ClippedPrimitive],
screen_descriptor: &ScreenDescriptor,
) {
crate::profile_function!();
Expand All @@ -361,7 +360,7 @@ impl Renderer {
let mut index_buffer_slices = self.index_buffer.slices.iter();
let mut vertex_buffer_slices = self.vertex_buffer.slices.iter();

for egui::ClippedPrimitive {
for epaint::ClippedPrimitive {
clip_rect,
primitive,
} in paint_jobs
Expand Down Expand Up @@ -475,8 +474,8 @@ impl Renderer {
&mut self,
device: &wgpu::Device,
queue: &wgpu::Queue,
id: egui::TextureId,
image_delta: &egui::epaint::ImageDelta,
id: epaint::TextureId,
image_delta: &epaint::ImageDelta,
) {
crate::profile_function!();

Expand All @@ -490,15 +489,15 @@ impl Renderer {
};

let data_color32 = match &image_delta.image {
egui::ImageData::Color(image) => {
epaint::ImageData::Color(image) => {
assert_eq!(
width as usize * height as usize,
image.pixels.len(),
"Mismatch between texture size and texel count"
);
Cow::Borrowed(&image.pixels)
}
egui::ImageData::Font(image) => {
epaint::ImageData::Font(image) => {
assert_eq!(
width as usize * height as usize,
image.pixels.len(),
Expand Down Expand Up @@ -582,23 +581,23 @@ impl Renderer {
};
}

pub fn free_texture(&mut self, id: &egui::TextureId) {
pub fn free_texture(&mut self, id: &epaint::TextureId) {
self.textures.remove(id);
}

/// Get the WGPU texture and bind group associated to a texture that has been allocated by egui.
///
/// This could be used by custom paint hooks to render images that have been added through with
/// [`egui_extras::RetainedImage`](https://docs.rs/egui_extras/latest/egui_extras/image/struct.RetainedImage.html)
/// or [`egui::Context::load_texture`].
/// or [`epaint::Context::load_texture`](https://docs.rs/egui/latest/egui/struct.Context.html#method.load_texture).
pub fn texture(
&self,
id: &egui::TextureId,
id: &epaint::TextureId,
) -> Option<&(Option<wgpu::Texture>, wgpu::BindGroup)> {
self.textures.get(id)
}

/// Registers a `wgpu::Texture` with a `egui::TextureId`.
/// Registers a `wgpu::Texture` with a `epaint::TextureId`.
///
/// This enables the application to reference the texture inside an image ui element.
/// This effectively enables off-screen rendering inside the egui UI. Texture must have
Expand All @@ -609,7 +608,7 @@ impl Renderer {
device: &wgpu::Device,
texture: &wgpu::TextureView,
texture_filter: wgpu::FilterMode,
) -> egui::TextureId {
) -> epaint::TextureId {
self.register_native_texture_with_sampler_options(
device,
texture,
Expand All @@ -622,15 +621,15 @@ impl Renderer {
)
}

/// Registers a `wgpu::Texture` with an existing `egui::TextureId`.
/// Registers a `wgpu::Texture` with an existing `epaint::TextureId`.
///
/// This enables applications to reuse `TextureId`s.
pub fn update_egui_texture_from_wgpu_texture(
&mut self,
device: &wgpu::Device,
texture: &wgpu::TextureView,
texture_filter: wgpu::FilterMode,
id: egui::TextureId,
id: epaint::TextureId,
) {
self.update_egui_texture_from_wgpu_texture_with_sampler_options(
device,
Expand All @@ -645,7 +644,7 @@ impl Renderer {
);
}

/// Registers a `wgpu::Texture` with a `egui::TextureId` while also accepting custom
/// Registers a `wgpu::Texture` with a `epaint::TextureId` while also accepting custom
/// `wgpu::SamplerDescriptor` options.
///
/// This allows applications to specify individual minification/magnification filters as well as
Expand All @@ -660,7 +659,7 @@ impl Renderer {
device: &wgpu::Device,
texture: &wgpu::TextureView,
sampler_descriptor: wgpu::SamplerDescriptor<'_>,
) -> egui::TextureId {
) -> epaint::TextureId {
crate::profile_function!();

let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
Expand All @@ -683,14 +682,14 @@ impl Renderer {
],
});

let id = egui::TextureId::User(self.next_user_texture_id);
let id = epaint::TextureId::User(self.next_user_texture_id);
self.textures.insert(id, (None, bind_group));
self.next_user_texture_id += 1;

id
}

/// Registers a `wgpu::Texture` with an existing `egui::TextureId` while also accepting custom
/// Registers a `wgpu::Texture` with an existing `epaint::TextureId` while also accepting custom
/// `wgpu::SamplerDescriptor` options.
///
/// This allows applications to reuse `TextureId`s created with custom sampler options.
Expand All @@ -700,7 +699,7 @@ impl Renderer {
device: &wgpu::Device,
texture: &wgpu::TextureView,
sampler_descriptor: wgpu::SamplerDescriptor<'_>,
id: egui::TextureId,
id: epaint::TextureId,
) {
crate::profile_function!();

Expand Down Expand Up @@ -741,7 +740,7 @@ impl Renderer {
device: &wgpu::Device,
queue: &wgpu::Queue,
encoder: &mut wgpu::CommandEncoder,
paint_jobs: &[egui::epaint::ClippedPrimitive],
paint_jobs: &[epaint::ClippedPrimitive],
screen_descriptor: &ScreenDescriptor,
) -> Vec<wgpu::CommandBuffer> {
crate::profile_function!();
Expand Down Expand Up @@ -801,7 +800,7 @@ impl Renderer {
let mut user_cmd_bufs = Vec::new(); // collect user command buffers

crate::profile_scope!("primitives");
for egui::ClippedPrimitive { primitive, .. } in paint_jobs.iter() {
for epaint::ClippedPrimitive { primitive, .. } in paint_jobs.iter() {
match primitive {
Primitive::Mesh(mesh) => {
{
Expand Down Expand Up @@ -844,14 +843,17 @@ impl Renderer {
}
}

fn create_sampler(options: egui::TextureOptions, device: &wgpu::Device) -> wgpu::Sampler {
fn create_sampler(
options: epaint::textures::TextureOptions,
device: &wgpu::Device,
) -> wgpu::Sampler {
let mag_filter = match options.magnification {
egui::TextureFilter::Nearest => wgpu::FilterMode::Nearest,
egui::TextureFilter::Linear => wgpu::FilterMode::Linear,
epaint::textures::TextureFilter::Nearest => wgpu::FilterMode::Nearest,
epaint::textures::TextureFilter::Linear => wgpu::FilterMode::Linear,
};
let min_filter = match options.minification {
egui::TextureFilter::Nearest => wgpu::FilterMode::Nearest,
egui::TextureFilter::Linear => wgpu::FilterMode::Linear,
epaint::textures::TextureFilter::Nearest => wgpu::FilterMode::Nearest,
epaint::textures::TextureFilter::Linear => wgpu::FilterMode::Linear,
};
device.create_sampler(&wgpu::SamplerDescriptor {
label: Some(&format!(
Expand Down Expand Up @@ -893,7 +895,7 @@ struct ScissorRect {
}

impl ScissorRect {
fn new(clip_rect: &egui::Rect, pixels_per_point: f32, target_size: [u32; 2]) -> Self {
fn new(clip_rect: &epaint::Rect, pixels_per_point: f32, target_size: [u32; 2]) -> Self {
// Transform clip rect to physical pixels:
let clip_min_x = pixels_per_point * clip_rect.min.x;
let clip_min_y = pixels_per_point * clip_rect.min.y;
Expand Down
9 changes: 5 additions & 4 deletions crates/egui-wgpu/src/winit.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::sync::Arc;

use egui::mutex::RwLock;
use tracing::error;
use wgpu::{Adapter, Instance, Surface};

use epaint::mutex::RwLock;

use crate::{renderer, RenderState, Renderer, SurfaceErrorAction, WgpuConfiguration};

struct SurfaceState {
Expand Down Expand Up @@ -249,9 +250,9 @@ impl Painter {
pub fn paint_and_update_textures(
&mut self,
pixels_per_point: f32,
clear_color: egui::Rgba,
clipped_primitives: &[egui::ClippedPrimitive],
textures_delta: &egui::TexturesDelta,
clear_color: epaint::Rgba,
clipped_primitives: &[epaint::ClippedPrimitive],
textures_delta: &epaint::textures::TexturesDelta,
) {
crate::profile_function!();

Expand Down