Skip to content

Commit

Permalink
address review feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
dfrg committed Nov 23, 2022
1 parent fc1a6e9 commit eccce74
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 25 deletions.
18 changes: 7 additions & 11 deletions piet-gpu/src/samples.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::PicoSvg;
use piet_scene::kurbo::{Affine, Ellipse, PathEl, Point, Rect};
use piet_scene::kurbo::{Affine, BezPath, Ellipse, PathEl, Point, Rect};
use piet_scene::*;

use crate::SimpleText;
Expand Down Expand Up @@ -104,7 +104,7 @@ fn render_cardioid(sb: &mut SceneBuilder) {
let dth = std::f64::consts::PI * 2.0 / (n as f64);
let center = Point::new(1024.0, 768.0);
let r = 750.0;
let mut path = vec![];
let mut path = BezPath::new();
for i in 1..n {
let mut p0 = center;
let a0 = i as f64 * dth;
Expand All @@ -122,7 +122,7 @@ fn render_cardioid(sb: &mut SceneBuilder) {
Affine::IDENTITY,
Color::rgb8(0, 0, 0),
None,
&&path[..],
&path,
);
}

Expand Down Expand Up @@ -169,26 +169,22 @@ fn render_alpha_test(sb: &mut SceneBuilder) {
Affine::IDENTITY,
Color::rgb8(255, 0, 0),
None,
&&make_diamond(1024.0, 100.0)[..],
&make_diamond(1024.0, 100.0),
);
sb.fill(
Fill::NonZero,
Affine::IDENTITY,
Color::rgba8(0, 255, 0, 0x80),
None,
&&make_diamond(1024.0, 125.0)[..],
);
sb.push_layer(
Mix::Clip,
Affine::IDENTITY,
&&make_diamond(1024.0, 150.0)[..],
&make_diamond(1024.0, 125.0),
);
sb.push_layer(Mix::Clip, Affine::IDENTITY, &make_diamond(1024.0, 150.0));
sb.fill(
Fill::NonZero,
Affine::IDENTITY,
Color::rgba8(0, 0, 255, 0x80),
None,
&&make_diamond(1024.0, 175.0)[..],
&make_diamond(1024.0, 175.0),
);
sb.pop_layer();
}
Expand Down
42 changes: 28 additions & 14 deletions piet-scene/src/scene/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
use super::{conv, Scene, SceneData, SceneFragment};
use crate::ResourcePatch;
use bytemuck::{Pod, Zeroable};
use peniko::kurbo::{Affine, PathEl, Shape};
use peniko::kurbo::{Affine, PathEl, Rect, Shape};
use peniko::{BlendMode, BrushRef, ColorStop, Fill, Stroke};
use smallvec::SmallVec;

/// Builder for constructing a scene or scene fragment.
pub struct SceneBuilder<'a> {
scene: &'a mut SceneData,
layers: SmallVec<[(BlendMode, bool); 8]>,
layers: SmallVec<[BlendMode; 8]>,
}

impl<'a> SceneBuilder<'a> {
Expand Down Expand Up @@ -60,23 +60,19 @@ impl<'a> SceneBuilder<'a> {
let blend = blend.into();
self.maybe_encode_transform(transform);
self.linewidth(-1.0);
if self.encode_path(shape, true) {
self.begin_clip(blend);
self.layers.push((blend, true));
} else {
// When the layer has an empty path, record an entry to prevent
// the stack from becoming unbalanced. This is handled in
// pop_layer.
self.layers.push((blend, false));
if !self.encode_path(shape, true) {

This comment has been minimized.

Copy link
@raphlinus

raphlinus Nov 23, 2022

Contributor

I was thinking of suppressing encoding until pop, but this is simpler and more local. And it's not something that any reasonable client should do, so correct but less efficient is reasonable. Thanks!

This comment has been minimized.

Copy link
@dfrg

dfrg Nov 23, 2022

Author Collaborator

I hadn't considered doing that. I agree with your assessment though, probably best to keep it simple. That solution also wouldn't catch the case of valid empty clips which would require deeper analysis of the path data and transforms.

// If the layer shape is invalid, encode a valid empty path. This suppresses
// all drawing until the layer is popped.
self.encode_path(&Rect::new(0.0, 0.0, 0.0, 0.0), true);
}
self.begin_clip(blend);
self.layers.push(blend);
}

/// Pops the current layer.
pub fn pop_layer(&mut self) {
if let Some((blend, active)) = self.layers.pop() {
if active {
self.end_clip(blend);
}
if let Some(blend) = self.layers.pop() {
self.end_clip(blend);
}
}

Expand Down Expand Up @@ -138,6 +134,10 @@ impl<'a> SceneBuilder<'a> {
}

impl<'a> SceneBuilder<'a> {
/// Encodes a path for the specified shape.
///
/// When the `is_fill` parameter is true, closes any open subpaths by inserting
/// a line to the start point of the subpath with the end segment bit set.
fn encode_path(&mut self, shape: &impl Shape, is_fill: bool) -> bool {
let mut b = PathBuilder::new(
&mut self.scene.tag_stream,
Expand Down Expand Up @@ -378,6 +378,12 @@ impl<'a> PathBuilder<'a> {

pub fn line_to(&mut self, x: f32, y: f32) {
if self.state == PathState::Start {
if self.n_pathseg == 0 {
// This copies the behavior of kurbo which treats an initial line, quad
// or curve as a move.
self.move_to(x, y);
return;
}
self.move_to(self.first_pt[0], self.first_pt[1]);
}
let buf = [x, y];
Expand All @@ -390,6 +396,10 @@ impl<'a> PathBuilder<'a> {

pub fn quad_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32) {
if self.state == PathState::Start {
if self.n_pathseg == 0 {
self.move_to(x2, y2);
return;
}
self.move_to(self.first_pt[0], self.first_pt[1]);
}
let buf = [x1, y1, x2, y2];
Expand All @@ -402,6 +412,10 @@ impl<'a> PathBuilder<'a> {

pub fn cubic_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x3: f32, y3: f32) {
if self.state == PathState::Start {
if self.n_pathseg == 0 {
self.move_to(x3, y3);
return;
}
self.move_to(self.first_pt[0], self.first_pt[1]);
}
let buf = [x1, y1, x2, y2, x3, y3];
Expand Down

0 comments on commit eccce74

Please sign in to comment.