Skip to content

Commit

Permalink
Shrink size of RectShape from 72 bytes to 64 bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Jan 2, 2025
1 parent 65fbce1 commit ebb5136
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 49 deletions.
15 changes: 5 additions & 10 deletions crates/egui/src/widgets/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use epaint::{
use crate::{
load::{Bytes, SizeHint, SizedTexture, TextureLoadResult, TexturePoll},
pos2, Color32, Context, Id, Mesh, Painter, Rect, Response, Rounding, Sense, Shape, Spinner,
Stroke, TextStyle, TextureOptions, Ui, Vec2, Widget, WidgetInfo, WidgetType,
TextStyle, TextureOptions, Ui, Vec2, Widget, WidgetInfo, WidgetType,
};

/// A widget which displays an image.
Expand Down Expand Up @@ -822,15 +822,10 @@ pub fn paint_texture_at(
painter.add(Shape::mesh(mesh));
}
None => {
painter.add(RectShape {
rect,
rounding: options.rounding,
fill: options.tint,
stroke: Stroke::NONE,
blur_width: 0.0,
fill_texture_id: texture.id,
uv: options.uv,
});
painter.add(
RectShape::filled(rect, options.rounding, options.tint)
.with_texture(texture.id, options.uv),
);
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions crates/epaint/src/brush.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use crate::{Rect, TextureId};

/// Controls texturing of a [`crate::RectShape`].
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Brush {
/// If the rect should be filled with a texture, which one?
///
/// The texture is multiplied with [`crate::RectShape::fill`].
pub fill_texture_id: TextureId,

/// What UV coordinates to use for the texture?
///
/// To display a texture, set [`Self::fill_texture_id`],
/// and set this to `Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0))`.
///
/// Use [`Rect::ZERO`] to turn off texturing.
pub uv: Rect,
}
2 changes: 2 additions & 0 deletions crates/epaint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#![allow(clippy::float_cmp)]
#![allow(clippy::manual_range_contains)]

mod brush;
pub mod color;
pub mod image;
mod margin;
Expand All @@ -44,6 +45,7 @@ pub mod util;
mod viewport;

pub use self::{
brush::Brush,
color::ColorMode,
image::{ColorImage, FontImage, ImageData, ImageDelta},
margin::Margin,
Expand Down
3 changes: 1 addition & 2 deletions crates/epaint/src/shape_transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ pub fn adjust_colors(
fill,
stroke,
blur_width: _,
fill_texture_id: _,
uv: _,
brush: _,
}) => {
adjust_color(fill);
adjust_color(&mut stroke.color);
Expand Down
67 changes: 34 additions & 33 deletions crates/epaint/src/shapes/rect_shape.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::sync::Arc;

use crate::*;

/// How to paint a rectangle.
#[derive(Copy, Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct RectShape {
pub rect: Rect,
Expand All @@ -28,26 +30,23 @@ pub struct RectShape {
/// The blur is currently implemented using a simple linear blur in sRGBA gamma space.
pub blur_width: f32,

/// If the rect should be filled with a texture, which one?
///
/// The texture is multiplied with [`Self::fill`].
pub fill_texture_id: TextureId,

/// What UV coordinates to use for the texture?
/// Controls texturing, if any.
///
/// To display a texture, set [`Self::fill_texture_id`],
/// and set this to `Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0))`.
///
/// Use [`Rect::ZERO`] to turn off texturing.
pub uv: Rect,
/// Since most rectangles do not have a texture, this is optional and in an `Arc`,
/// so that [`RectShape`] is kept small..
pub brush: Option<Arc<Brush>>,
}

#[test]
fn rect_shape_size() {
assert_eq!(
std::mem::size_of::<RectShape>(), 72,
std::mem::size_of::<RectShape>(), 48,
"RectShape changed size! If it shrank - good! Update this test. If it grew - bad! Try to find a way to avoid it."
);
assert!(
std::mem::size_of::<RectShape>() <= 64,
"RectShape is getting way too big!"
);
}

impl RectShape {
Expand All @@ -65,8 +64,7 @@ impl RectShape {
fill: fill_color.into(),
stroke: stroke.into(),
blur_width: 0.0,
fill_texture_id: Default::default(),
uv: Rect::ZERO,
brush: Default::default(),
}
}

Expand All @@ -76,29 +74,14 @@ impl RectShape {
rounding: impl Into<Rounding>,
fill_color: impl Into<Color32>,
) -> Self {
Self {
rect,
rounding: rounding.into(),
fill: fill_color.into(),
stroke: Default::default(),
blur_width: 0.0,
fill_texture_id: Default::default(),
uv: Rect::ZERO,
}
Self::new(rect, rounding, fill_color, Stroke::NONE)
}

/// The stroke extends _outside_ the [`Rect`].
#[inline]
pub fn stroke(rect: Rect, rounding: impl Into<Rounding>, stroke: impl Into<Stroke>) -> Self {
Self {
rect,
rounding: rounding.into(),
fill: Default::default(),
stroke: stroke.into(),
blur_width: 0.0,
fill_texture_id: Default::default(),
uv: Rect::ZERO,
}
let fill = Color32::TRANSPARENT;
Self::new(rect, rounding, fill, stroke)
}

/// If larger than zero, the edges of the rectangle
Expand All @@ -113,6 +96,15 @@ impl RectShape {
self
}

/// Set the texture to use when painting this rectangle, if any.
pub fn with_texture(mut self, fill_texture_id: TextureId, uv: Rect) -> Self {
self.brush = Some(Arc::new(Brush {
fill_texture_id,
uv,
}));
self
}

/// The visual bounding rectangle (includes stroke width)
#[inline]
pub fn visual_bounding_rect(&self) -> Rect {
Expand All @@ -123,6 +115,15 @@ impl RectShape {
self.rect.expand(width + self.blur_width / 2.0)
}
}

/// The texture to use when painting this rectangle, if any.
///
/// If no texture is set, this will return [`TextureId::default`].
pub fn fill_texture_id(&self) -> TextureId {
self.brush
.as_ref()
.map_or_else(TextureId::default, |brush| brush.fill_texture_id)
}
}

impl From<RectShape> for Shape {
Expand Down
2 changes: 1 addition & 1 deletion crates/epaint/src/shapes/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ impl Shape {
if let Self::Mesh(mesh) = self {
mesh.texture_id
} else if let Self::Rect(rect_shape) = self {
rect_shape.fill_texture_id
rect_shape.fill_texture_id()
} else {
crate::TextureId::default()
}
Expand Down
10 changes: 7 additions & 3 deletions crates/epaint/src/tessellator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1693,14 +1693,14 @@ impl Tessellator {
/// * `rect`: the rectangle to tessellate.
/// * `out`: triangles are appended to this.
pub fn tessellate_rect(&mut self, rect: &RectShape, out: &mut Mesh) {
let brush = rect.brush.as_ref();
let RectShape {
mut rect,
mut rounding,
fill,
stroke,
mut blur_width,
fill_texture_id,
uv,
..
} = *rect;

if self.options.coarse_tessellation_culling
Expand Down Expand Up @@ -1775,7 +1775,11 @@ impl Tessellator {
path.add_line_loop(&self.scratchpad_points);
let path_stroke = PathStroke::from(stroke).outside();

if uv.is_positive() {
if let Some(brush) = brush {
let crate::Brush {
fill_texture_id,
uv,
} = **brush;
// Textured
let uv_from_pos = |p: Pos2| {
pos2(
Expand Down

0 comments on commit ebb5136

Please sign in to comment.