1*c8dee2aaSAndroid Build Coastguard Worker // Copyright 2023 Google LLC
2*c8dee2aaSAndroid Build Coastguard Worker //
3*c8dee2aaSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*c8dee2aaSAndroid Build Coastguard Worker // found in the LICENSE file.
5*c8dee2aaSAndroid Build Coastguard Worker
6*c8dee2aaSAndroid Build Coastguard Worker use crate::ffi;
7*c8dee2aaSAndroid Build Coastguard Worker use {
8*c8dee2aaSAndroid Build Coastguard Worker peniko::{
9*c8dee2aaSAndroid Build Coastguard Worker kurbo::{Affine, Cap, Join, PathEl, Point, Stroke},
10*c8dee2aaSAndroid Build Coastguard Worker Brush, Color, Fill, Mix,
11*c8dee2aaSAndroid Build Coastguard Worker },
12*c8dee2aaSAndroid Build Coastguard Worker std::pin::Pin,
13*c8dee2aaSAndroid Build Coastguard Worker vello_encoding::{
14*c8dee2aaSAndroid Build Coastguard Worker BumpEstimator, Encoding as VelloEncoding, PathEncoder, RenderConfig, Transform,
15*c8dee2aaSAndroid Build Coastguard Worker },
16*c8dee2aaSAndroid Build Coastguard Worker };
17*c8dee2aaSAndroid Build Coastguard Worker
18*c8dee2aaSAndroid Build Coastguard Worker pub(crate) struct Encoding {
19*c8dee2aaSAndroid Build Coastguard Worker encoding: VelloEncoding,
20*c8dee2aaSAndroid Build Coastguard Worker estimator: BumpEstimator,
21*c8dee2aaSAndroid Build Coastguard Worker }
22*c8dee2aaSAndroid Build Coastguard Worker
new_encoding() -> Box<Encoding>23*c8dee2aaSAndroid Build Coastguard Worker pub(crate) fn new_encoding() -> Box<Encoding> {
24*c8dee2aaSAndroid Build Coastguard Worker Box::new(Encoding::new())
25*c8dee2aaSAndroid Build Coastguard Worker }
26*c8dee2aaSAndroid Build Coastguard Worker
27*c8dee2aaSAndroid Build Coastguard Worker impl Encoding {
new() -> Encoding28*c8dee2aaSAndroid Build Coastguard Worker fn new() -> Encoding {
29*c8dee2aaSAndroid Build Coastguard Worker // An encoding blob that doesn't represent a scene fragment (i.e. a reused blob that is
30*c8dee2aaSAndroid Build Coastguard Worker // appended to a root encoding), then we need to initialize the transform and linewidth
31*c8dee2aaSAndroid Build Coastguard Worker // streams with first entries (an identity transform and -1 linewidth value). Resetting
32*c8dee2aaSAndroid Build Coastguard Worker // the encoding as non-fragment achieves this.
33*c8dee2aaSAndroid Build Coastguard Worker let mut encoding = VelloEncoding::new();
34*c8dee2aaSAndroid Build Coastguard Worker encoding.reset();
35*c8dee2aaSAndroid Build Coastguard Worker Encoding { encoding, estimator: BumpEstimator::new(), }
36*c8dee2aaSAndroid Build Coastguard Worker }
37*c8dee2aaSAndroid Build Coastguard Worker
is_empty(&self) -> bool38*c8dee2aaSAndroid Build Coastguard Worker pub fn is_empty(&self) -> bool {
39*c8dee2aaSAndroid Build Coastguard Worker self.encoding.is_empty()
40*c8dee2aaSAndroid Build Coastguard Worker }
41*c8dee2aaSAndroid Build Coastguard Worker
reset(&mut self)42*c8dee2aaSAndroid Build Coastguard Worker pub fn reset(&mut self) {
43*c8dee2aaSAndroid Build Coastguard Worker self.encoding.reset();
44*c8dee2aaSAndroid Build Coastguard Worker self.estimator.reset();
45*c8dee2aaSAndroid Build Coastguard Worker }
46*c8dee2aaSAndroid Build Coastguard Worker
fill( &mut self, style: ffi::Fill, transform: ffi::Affine, brush: &ffi::Brush, path_iter: Pin<&mut ffi::PathIterator>, )47*c8dee2aaSAndroid Build Coastguard Worker pub fn fill(
48*c8dee2aaSAndroid Build Coastguard Worker &mut self,
49*c8dee2aaSAndroid Build Coastguard Worker style: ffi::Fill,
50*c8dee2aaSAndroid Build Coastguard Worker transform: ffi::Affine,
51*c8dee2aaSAndroid Build Coastguard Worker brush: &ffi::Brush,
52*c8dee2aaSAndroid Build Coastguard Worker path_iter: Pin<&mut ffi::PathIterator>,
53*c8dee2aaSAndroid Build Coastguard Worker ) {
54*c8dee2aaSAndroid Build Coastguard Worker let t = Transform::from_kurbo(&transform.into());
55*c8dee2aaSAndroid Build Coastguard Worker self.encoding.encode_transform(t);
56*c8dee2aaSAndroid Build Coastguard Worker self.encoding.encode_fill_style(style.into());
57*c8dee2aaSAndroid Build Coastguard Worker if self.encode_path(path_iter, &t, None) {
58*c8dee2aaSAndroid Build Coastguard Worker self.encoding.encode_brush(&Brush::from(brush), 1.0)
59*c8dee2aaSAndroid Build Coastguard Worker }
60*c8dee2aaSAndroid Build Coastguard Worker }
61*c8dee2aaSAndroid Build Coastguard Worker
stroke( &mut self, style: &ffi::Stroke, transform: ffi::Affine, brush: &ffi::Brush, path_iter: Pin<&mut ffi::PathIterator>, )62*c8dee2aaSAndroid Build Coastguard Worker pub fn stroke(
63*c8dee2aaSAndroid Build Coastguard Worker &mut self,
64*c8dee2aaSAndroid Build Coastguard Worker style: &ffi::Stroke,
65*c8dee2aaSAndroid Build Coastguard Worker transform: ffi::Affine,
66*c8dee2aaSAndroid Build Coastguard Worker brush: &ffi::Brush,
67*c8dee2aaSAndroid Build Coastguard Worker path_iter: Pin<&mut ffi::PathIterator>,
68*c8dee2aaSAndroid Build Coastguard Worker ) {
69*c8dee2aaSAndroid Build Coastguard Worker let t = Transform::from_kurbo(&transform.into());
70*c8dee2aaSAndroid Build Coastguard Worker self.encoding.encode_transform(t);
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker // TODO: process any dash pattern here using kurbo's dash expander unless Graphite
73*c8dee2aaSAndroid Build Coastguard Worker // handles dashing already.
74*c8dee2aaSAndroid Build Coastguard Worker let stroke = style.into();
75*c8dee2aaSAndroid Build Coastguard Worker self.encoding.encode_stroke_style(&stroke);
76*c8dee2aaSAndroid Build Coastguard Worker if self.encode_path(path_iter, &t, Some(&stroke)) {
77*c8dee2aaSAndroid Build Coastguard Worker self.encoding.encode_brush(&Brush::from(brush), 1.0);
78*c8dee2aaSAndroid Build Coastguard Worker }
79*c8dee2aaSAndroid Build Coastguard Worker }
80*c8dee2aaSAndroid Build Coastguard Worker
begin_clip(&mut self, transform: ffi::Affine, path_iter: Pin<&mut ffi::PathIterator>)81*c8dee2aaSAndroid Build Coastguard Worker pub fn begin_clip(&mut self, transform: ffi::Affine, path_iter: Pin<&mut ffi::PathIterator>) {
82*c8dee2aaSAndroid Build Coastguard Worker let t = Transform::from_kurbo(&transform.into());
83*c8dee2aaSAndroid Build Coastguard Worker self.encoding.encode_transform(t);
84*c8dee2aaSAndroid Build Coastguard Worker self.encoding.encode_fill_style(Fill::NonZero);
85*c8dee2aaSAndroid Build Coastguard Worker self.encode_path(path_iter, &t, None);
86*c8dee2aaSAndroid Build Coastguard Worker self.encoding.encode_begin_clip(Mix::Clip.into(), /*alpha=*/ 1.0);
87*c8dee2aaSAndroid Build Coastguard Worker }
88*c8dee2aaSAndroid Build Coastguard Worker
end_clip(&mut self)89*c8dee2aaSAndroid Build Coastguard Worker pub fn end_clip(&mut self) {
90*c8dee2aaSAndroid Build Coastguard Worker self.encoding.encode_end_clip();
91*c8dee2aaSAndroid Build Coastguard Worker }
92*c8dee2aaSAndroid Build Coastguard Worker
append(&mut self, other: &Encoding)93*c8dee2aaSAndroid Build Coastguard Worker pub fn append(&mut self, other: &Encoding) {
94*c8dee2aaSAndroid Build Coastguard Worker self.encoding.append(&other.encoding, &None);
95*c8dee2aaSAndroid Build Coastguard Worker self.estimator.append(&other.estimator, None);
96*c8dee2aaSAndroid Build Coastguard Worker }
97*c8dee2aaSAndroid Build Coastguard Worker
prepare_render( &self, width: u32, height: u32, background: &ffi::Color, ) -> Box<RenderConfiguration>98*c8dee2aaSAndroid Build Coastguard Worker pub fn prepare_render(
99*c8dee2aaSAndroid Build Coastguard Worker &self,
100*c8dee2aaSAndroid Build Coastguard Worker width: u32,
101*c8dee2aaSAndroid Build Coastguard Worker height: u32,
102*c8dee2aaSAndroid Build Coastguard Worker background: &ffi::Color,
103*c8dee2aaSAndroid Build Coastguard Worker ) -> Box<RenderConfiguration> {
104*c8dee2aaSAndroid Build Coastguard Worker let mut packed_scene = Vec::new();
105*c8dee2aaSAndroid Build Coastguard Worker let layout = vello_encoding::resolve_solid_paths_only(&self.encoding, &mut packed_scene);
106*c8dee2aaSAndroid Build Coastguard Worker let mut config = RenderConfig::new(&layout, width, height, &background.into());
107*c8dee2aaSAndroid Build Coastguard Worker
108*c8dee2aaSAndroid Build Coastguard Worker let bump_estimate = self.estimator.tally(None);
109*c8dee2aaSAndroid Build Coastguard Worker //println!("bump: {bump_estimate}");
110*c8dee2aaSAndroid Build Coastguard Worker config.buffer_sizes.bin_data = bump_estimate.binning;
111*c8dee2aaSAndroid Build Coastguard Worker config.buffer_sizes.seg_counts = bump_estimate.seg_counts;
112*c8dee2aaSAndroid Build Coastguard Worker config.buffer_sizes.segments = bump_estimate.segments;
113*c8dee2aaSAndroid Build Coastguard Worker config.buffer_sizes.lines = bump_estimate.lines;
114*c8dee2aaSAndroid Build Coastguard Worker config.gpu.binning_size = bump_estimate.binning.len();
115*c8dee2aaSAndroid Build Coastguard Worker config.gpu.seg_counts_size = bump_estimate.seg_counts.len();
116*c8dee2aaSAndroid Build Coastguard Worker config.gpu.segments_size = bump_estimate.segments.len();
117*c8dee2aaSAndroid Build Coastguard Worker config.gpu.lines_size = bump_estimate.lines.len();
118*c8dee2aaSAndroid Build Coastguard Worker
119*c8dee2aaSAndroid Build Coastguard Worker Box::new(RenderConfiguration {
120*c8dee2aaSAndroid Build Coastguard Worker packed_scene,
121*c8dee2aaSAndroid Build Coastguard Worker config,
122*c8dee2aaSAndroid Build Coastguard Worker })
123*c8dee2aaSAndroid Build Coastguard Worker }
124*c8dee2aaSAndroid Build Coastguard Worker
encode_path( &mut self, iter: Pin<&mut ffi::PathIterator>, transform: &Transform, stroke: Option<&Stroke>, ) -> bool125*c8dee2aaSAndroid Build Coastguard Worker fn encode_path(
126*c8dee2aaSAndroid Build Coastguard Worker &mut self,
127*c8dee2aaSAndroid Build Coastguard Worker iter: Pin<&mut ffi::PathIterator>,
128*c8dee2aaSAndroid Build Coastguard Worker transform: &Transform,
129*c8dee2aaSAndroid Build Coastguard Worker stroke: Option<&Stroke>,
130*c8dee2aaSAndroid Build Coastguard Worker ) -> bool {
131*c8dee2aaSAndroid Build Coastguard Worker let mut encoder = self.encoding.encode_path(/*is_fill=*/ stroke.is_none());
132*c8dee2aaSAndroid Build Coastguard Worker
133*c8dee2aaSAndroid Build Coastguard Worker // Wrap the input iterator inside a custom iterator, so that the path gets
134*c8dee2aaSAndroid Build Coastguard Worker // encoded as the estimator runs through it.
135*c8dee2aaSAndroid Build Coastguard Worker let path = IterablePathEncoder { iter, encoder: &mut encoder };
136*c8dee2aaSAndroid Build Coastguard Worker self.estimator.count_path(path, transform, stroke);
137*c8dee2aaSAndroid Build Coastguard Worker encoder.finish(/*insert_path_marker=*/ true) != 0
138*c8dee2aaSAndroid Build Coastguard Worker }
139*c8dee2aaSAndroid Build Coastguard Worker }
140*c8dee2aaSAndroid Build Coastguard Worker
141*c8dee2aaSAndroid Build Coastguard Worker // This is path element iterator that encodes path elements as it gets polled.
142*c8dee2aaSAndroid Build Coastguard Worker struct IterablePathEncoder<'a, 'b> {
143*c8dee2aaSAndroid Build Coastguard Worker iter: Pin<&'a mut ffi::PathIterator>,
144*c8dee2aaSAndroid Build Coastguard Worker encoder: &'a mut PathEncoder<'b>,
145*c8dee2aaSAndroid Build Coastguard Worker }
146*c8dee2aaSAndroid Build Coastguard Worker
147*c8dee2aaSAndroid Build Coastguard Worker impl Iterator for IterablePathEncoder<'_, '_> {
148*c8dee2aaSAndroid Build Coastguard Worker type Item = PathEl;
149*c8dee2aaSAndroid Build Coastguard Worker
next(&mut self) -> Option<Self::Item>150*c8dee2aaSAndroid Build Coastguard Worker fn next(&mut self) -> Option<Self::Item> {
151*c8dee2aaSAndroid Build Coastguard Worker let mut path_el = ffi::PathElement::default();
152*c8dee2aaSAndroid Build Coastguard Worker if !unsafe { self.iter.as_mut().next_element(&mut path_el) } {
153*c8dee2aaSAndroid Build Coastguard Worker return None;
154*c8dee2aaSAndroid Build Coastguard Worker }
155*c8dee2aaSAndroid Build Coastguard Worker Some(match path_el.verb {
156*c8dee2aaSAndroid Build Coastguard Worker ffi::PathVerb::MoveTo => {
157*c8dee2aaSAndroid Build Coastguard Worker let p = &path_el.points[0];
158*c8dee2aaSAndroid Build Coastguard Worker self.encoder.move_to(p.x, p.y);
159*c8dee2aaSAndroid Build Coastguard Worker PathEl::MoveTo(p.into())
160*c8dee2aaSAndroid Build Coastguard Worker }
161*c8dee2aaSAndroid Build Coastguard Worker ffi::PathVerb::LineTo => {
162*c8dee2aaSAndroid Build Coastguard Worker let p = &path_el.points[1];
163*c8dee2aaSAndroid Build Coastguard Worker self.encoder.line_to(p.x, p.y);
164*c8dee2aaSAndroid Build Coastguard Worker PathEl::LineTo(p.into())
165*c8dee2aaSAndroid Build Coastguard Worker }
166*c8dee2aaSAndroid Build Coastguard Worker ffi::PathVerb::QuadTo => {
167*c8dee2aaSAndroid Build Coastguard Worker let p0 = &path_el.points[1];
168*c8dee2aaSAndroid Build Coastguard Worker let p1 = &path_el.points[2];
169*c8dee2aaSAndroid Build Coastguard Worker self.encoder.quad_to(p0.x, p0.y, p1.x, p1.y);
170*c8dee2aaSAndroid Build Coastguard Worker PathEl::QuadTo(p0.into(), p1.into())
171*c8dee2aaSAndroid Build Coastguard Worker }
172*c8dee2aaSAndroid Build Coastguard Worker ffi::PathVerb::CurveTo => {
173*c8dee2aaSAndroid Build Coastguard Worker let p0 = &path_el.points[1];
174*c8dee2aaSAndroid Build Coastguard Worker let p1 = &path_el.points[2];
175*c8dee2aaSAndroid Build Coastguard Worker let p2 = &path_el.points[3];
176*c8dee2aaSAndroid Build Coastguard Worker self.encoder.cubic_to(p0.x, p0.y, p1.x, p1.y, p2.x, p2.y);
177*c8dee2aaSAndroid Build Coastguard Worker PathEl::CurveTo(p0.into(), p1.into(), p2.into())
178*c8dee2aaSAndroid Build Coastguard Worker }
179*c8dee2aaSAndroid Build Coastguard Worker ffi::PathVerb::Close => {
180*c8dee2aaSAndroid Build Coastguard Worker self.encoder.close();
181*c8dee2aaSAndroid Build Coastguard Worker PathEl::ClosePath
182*c8dee2aaSAndroid Build Coastguard Worker }
183*c8dee2aaSAndroid Build Coastguard Worker _ => panic!("invalid path verb"),
184*c8dee2aaSAndroid Build Coastguard Worker })
185*c8dee2aaSAndroid Build Coastguard Worker }
186*c8dee2aaSAndroid Build Coastguard Worker }
187*c8dee2aaSAndroid Build Coastguard Worker
188*c8dee2aaSAndroid Build Coastguard Worker pub(crate) struct RenderConfiguration {
189*c8dee2aaSAndroid Build Coastguard Worker packed_scene: Vec<u8>,
190*c8dee2aaSAndroid Build Coastguard Worker config: RenderConfig,
191*c8dee2aaSAndroid Build Coastguard Worker }
192*c8dee2aaSAndroid Build Coastguard Worker
193*c8dee2aaSAndroid Build Coastguard Worker impl RenderConfiguration {
config_uniform_buffer_size(self: &RenderConfiguration) -> usize194*c8dee2aaSAndroid Build Coastguard Worker pub fn config_uniform_buffer_size(self: &RenderConfiguration) -> usize {
195*c8dee2aaSAndroid Build Coastguard Worker std::mem::size_of::<vello_encoding::ConfigUniform>()
196*c8dee2aaSAndroid Build Coastguard Worker }
197*c8dee2aaSAndroid Build Coastguard Worker
scene_buffer_size(self: &RenderConfiguration) -> usize198*c8dee2aaSAndroid Build Coastguard Worker pub fn scene_buffer_size(self: &RenderConfiguration) -> usize {
199*c8dee2aaSAndroid Build Coastguard Worker self.packed_scene.len()
200*c8dee2aaSAndroid Build Coastguard Worker }
201*c8dee2aaSAndroid Build Coastguard Worker
write_config_uniform_buffer(self: &RenderConfiguration, out_buffer: &mut [u8]) -> bool202*c8dee2aaSAndroid Build Coastguard Worker pub fn write_config_uniform_buffer(self: &RenderConfiguration, out_buffer: &mut [u8]) -> bool {
203*c8dee2aaSAndroid Build Coastguard Worker let bytes = bytemuck::bytes_of(&self.config.gpu);
204*c8dee2aaSAndroid Build Coastguard Worker if out_buffer.len() < bytes.len() {
205*c8dee2aaSAndroid Build Coastguard Worker return false;
206*c8dee2aaSAndroid Build Coastguard Worker }
207*c8dee2aaSAndroid Build Coastguard Worker out_buffer.copy_from_slice(bytes);
208*c8dee2aaSAndroid Build Coastguard Worker true
209*c8dee2aaSAndroid Build Coastguard Worker }
210*c8dee2aaSAndroid Build Coastguard Worker
write_scene_buffer(self: &RenderConfiguration, out_buffer: &mut [u8]) -> bool211*c8dee2aaSAndroid Build Coastguard Worker pub fn write_scene_buffer(self: &RenderConfiguration, out_buffer: &mut [u8]) -> bool {
212*c8dee2aaSAndroid Build Coastguard Worker if out_buffer.len() < self.packed_scene.len() {
213*c8dee2aaSAndroid Build Coastguard Worker return false;
214*c8dee2aaSAndroid Build Coastguard Worker }
215*c8dee2aaSAndroid Build Coastguard Worker out_buffer.copy_from_slice(&self.packed_scene);
216*c8dee2aaSAndroid Build Coastguard Worker true
217*c8dee2aaSAndroid Build Coastguard Worker }
218*c8dee2aaSAndroid Build Coastguard Worker
workgroup_counts(self: &RenderConfiguration) -> ffi::DispatchInfo219*c8dee2aaSAndroid Build Coastguard Worker pub fn workgroup_counts(self: &RenderConfiguration) -> ffi::DispatchInfo {
220*c8dee2aaSAndroid Build Coastguard Worker (&self.config.workgroup_counts).into()
221*c8dee2aaSAndroid Build Coastguard Worker }
222*c8dee2aaSAndroid Build Coastguard Worker
buffer_sizes(self: &RenderConfiguration) -> ffi::BufferSizes223*c8dee2aaSAndroid Build Coastguard Worker pub fn buffer_sizes(self: &RenderConfiguration) -> ffi::BufferSizes {
224*c8dee2aaSAndroid Build Coastguard Worker (&self.config.buffer_sizes).into()
225*c8dee2aaSAndroid Build Coastguard Worker }
226*c8dee2aaSAndroid Build Coastguard Worker }
227*c8dee2aaSAndroid Build Coastguard Worker
228*c8dee2aaSAndroid Build Coastguard Worker impl Iterator for Pin<&mut ffi::PathIterator> {
229*c8dee2aaSAndroid Build Coastguard Worker type Item = PathEl;
230*c8dee2aaSAndroid Build Coastguard Worker
next(&mut self) -> Option<PathEl>231*c8dee2aaSAndroid Build Coastguard Worker fn next(&mut self) -> Option<PathEl> {
232*c8dee2aaSAndroid Build Coastguard Worker let mut path_el = ffi::PathElement::default();
233*c8dee2aaSAndroid Build Coastguard Worker if !unsafe { self.as_mut().next_element(&mut path_el) } {
234*c8dee2aaSAndroid Build Coastguard Worker return None;
235*c8dee2aaSAndroid Build Coastguard Worker }
236*c8dee2aaSAndroid Build Coastguard Worker Some(match path_el.verb {
237*c8dee2aaSAndroid Build Coastguard Worker ffi::PathVerb::MoveTo => {
238*c8dee2aaSAndroid Build Coastguard Worker let p = &path_el.points[0];
239*c8dee2aaSAndroid Build Coastguard Worker PathEl::MoveTo(p.into())
240*c8dee2aaSAndroid Build Coastguard Worker }
241*c8dee2aaSAndroid Build Coastguard Worker ffi::PathVerb::LineTo => {
242*c8dee2aaSAndroid Build Coastguard Worker let p = &path_el.points[1];
243*c8dee2aaSAndroid Build Coastguard Worker PathEl::LineTo(p.into())
244*c8dee2aaSAndroid Build Coastguard Worker }
245*c8dee2aaSAndroid Build Coastguard Worker ffi::PathVerb::QuadTo => {
246*c8dee2aaSAndroid Build Coastguard Worker let p0 = &path_el.points[1];
247*c8dee2aaSAndroid Build Coastguard Worker let p1 = &path_el.points[2];
248*c8dee2aaSAndroid Build Coastguard Worker PathEl::QuadTo(p0.into(), p1.into())
249*c8dee2aaSAndroid Build Coastguard Worker }
250*c8dee2aaSAndroid Build Coastguard Worker ffi::PathVerb::CurveTo => {
251*c8dee2aaSAndroid Build Coastguard Worker let p0 = &path_el.points[1];
252*c8dee2aaSAndroid Build Coastguard Worker let p1 = &path_el.points[2];
253*c8dee2aaSAndroid Build Coastguard Worker let p2 = &path_el.points[3];
254*c8dee2aaSAndroid Build Coastguard Worker PathEl::CurveTo(p0.into(), p1.into(), p2.into())
255*c8dee2aaSAndroid Build Coastguard Worker }
256*c8dee2aaSAndroid Build Coastguard Worker ffi::PathVerb::Close => PathEl::ClosePath,
257*c8dee2aaSAndroid Build Coastguard Worker _ => panic!("invalid path verb"),
258*c8dee2aaSAndroid Build Coastguard Worker })
259*c8dee2aaSAndroid Build Coastguard Worker }
260*c8dee2aaSAndroid Build Coastguard Worker }
261*c8dee2aaSAndroid Build Coastguard Worker
262*c8dee2aaSAndroid Build Coastguard Worker impl From<&ffi::Point> for Point {
from(src: &ffi::Point) -> Self263*c8dee2aaSAndroid Build Coastguard Worker fn from(src: &ffi::Point) -> Self {
264*c8dee2aaSAndroid Build Coastguard Worker Self::new(src.x.into(), src.y.into())
265*c8dee2aaSAndroid Build Coastguard Worker }
266*c8dee2aaSAndroid Build Coastguard Worker }
267*c8dee2aaSAndroid Build Coastguard Worker
268*c8dee2aaSAndroid Build Coastguard Worker impl Default for ffi::PathVerb {
default() -> Self269*c8dee2aaSAndroid Build Coastguard Worker fn default() -> Self {
270*c8dee2aaSAndroid Build Coastguard Worker Self::MoveTo
271*c8dee2aaSAndroid Build Coastguard Worker }
272*c8dee2aaSAndroid Build Coastguard Worker }
273*c8dee2aaSAndroid Build Coastguard Worker
274*c8dee2aaSAndroid Build Coastguard Worker impl From<ffi::Affine> for Affine {
from(src: ffi::Affine) -> Self275*c8dee2aaSAndroid Build Coastguard Worker fn from(src: ffi::Affine) -> Self {
276*c8dee2aaSAndroid Build Coastguard Worker Self::new([
277*c8dee2aaSAndroid Build Coastguard Worker src.matrix[0] as f64,
278*c8dee2aaSAndroid Build Coastguard Worker src.matrix[1] as f64,
279*c8dee2aaSAndroid Build Coastguard Worker src.matrix[2] as f64,
280*c8dee2aaSAndroid Build Coastguard Worker src.matrix[3] as f64,
281*c8dee2aaSAndroid Build Coastguard Worker src.matrix[4] as f64,
282*c8dee2aaSAndroid Build Coastguard Worker src.matrix[5] as f64,
283*c8dee2aaSAndroid Build Coastguard Worker ])
284*c8dee2aaSAndroid Build Coastguard Worker }
285*c8dee2aaSAndroid Build Coastguard Worker }
286*c8dee2aaSAndroid Build Coastguard Worker
287*c8dee2aaSAndroid Build Coastguard Worker impl From<&ffi::Color> for Color {
from(src: &ffi::Color) -> Self288*c8dee2aaSAndroid Build Coastguard Worker fn from(src: &ffi::Color) -> Self {
289*c8dee2aaSAndroid Build Coastguard Worker Self {
290*c8dee2aaSAndroid Build Coastguard Worker r: src.r,
291*c8dee2aaSAndroid Build Coastguard Worker g: src.g,
292*c8dee2aaSAndroid Build Coastguard Worker b: src.b,
293*c8dee2aaSAndroid Build Coastguard Worker a: src.a,
294*c8dee2aaSAndroid Build Coastguard Worker }
295*c8dee2aaSAndroid Build Coastguard Worker }
296*c8dee2aaSAndroid Build Coastguard Worker }
297*c8dee2aaSAndroid Build Coastguard Worker
298*c8dee2aaSAndroid Build Coastguard Worker impl From<&ffi::Brush> for Brush {
from(src: &ffi::Brush) -> Self299*c8dee2aaSAndroid Build Coastguard Worker fn from(src: &ffi::Brush) -> Self {
300*c8dee2aaSAndroid Build Coastguard Worker match src.kind {
301*c8dee2aaSAndroid Build Coastguard Worker ffi::BrushKind::Solid => Brush::Solid(Color::from(&src.data.solid)),
302*c8dee2aaSAndroid Build Coastguard Worker _ => panic!("invalid brush kind"),
303*c8dee2aaSAndroid Build Coastguard Worker }
304*c8dee2aaSAndroid Build Coastguard Worker }
305*c8dee2aaSAndroid Build Coastguard Worker }
306*c8dee2aaSAndroid Build Coastguard Worker
307*c8dee2aaSAndroid Build Coastguard Worker impl From<ffi::Fill> for Fill {
from(src: ffi::Fill) -> Self308*c8dee2aaSAndroid Build Coastguard Worker fn from(src: ffi::Fill) -> Self {
309*c8dee2aaSAndroid Build Coastguard Worker match src {
310*c8dee2aaSAndroid Build Coastguard Worker ffi::Fill::NonZero => Self::NonZero,
311*c8dee2aaSAndroid Build Coastguard Worker ffi::Fill::EvenOdd => Self::EvenOdd,
312*c8dee2aaSAndroid Build Coastguard Worker _ => panic!("invalid fill type"),
313*c8dee2aaSAndroid Build Coastguard Worker }
314*c8dee2aaSAndroid Build Coastguard Worker }
315*c8dee2aaSAndroid Build Coastguard Worker }
316*c8dee2aaSAndroid Build Coastguard Worker
317*c8dee2aaSAndroid Build Coastguard Worker impl From<&ffi::Stroke> for Stroke {
from(src: &ffi::Stroke) -> Self318*c8dee2aaSAndroid Build Coastguard Worker fn from(src: &ffi::Stroke) -> Self {
319*c8dee2aaSAndroid Build Coastguard Worker let cap = match src.cap {
320*c8dee2aaSAndroid Build Coastguard Worker ffi::CapStyle::Butt => Cap::Butt,
321*c8dee2aaSAndroid Build Coastguard Worker ffi::CapStyle::Square => Cap::Square,
322*c8dee2aaSAndroid Build Coastguard Worker ffi::CapStyle::Round => Cap::Round,
323*c8dee2aaSAndroid Build Coastguard Worker _ => panic!("invalid cap style"),
324*c8dee2aaSAndroid Build Coastguard Worker };
325*c8dee2aaSAndroid Build Coastguard Worker Self {
326*c8dee2aaSAndroid Build Coastguard Worker width: src.width as f64,
327*c8dee2aaSAndroid Build Coastguard Worker join: match src.join {
328*c8dee2aaSAndroid Build Coastguard Worker ffi::JoinStyle::Bevel => Join::Bevel,
329*c8dee2aaSAndroid Build Coastguard Worker ffi::JoinStyle::Miter => Join::Miter,
330*c8dee2aaSAndroid Build Coastguard Worker ffi::JoinStyle::Round => Join::Round,
331*c8dee2aaSAndroid Build Coastguard Worker _ => panic!("invalid join style"),
332*c8dee2aaSAndroid Build Coastguard Worker },
333*c8dee2aaSAndroid Build Coastguard Worker miter_limit: src.miter_limit as f64,
334*c8dee2aaSAndroid Build Coastguard Worker start_cap: cap,
335*c8dee2aaSAndroid Build Coastguard Worker end_cap: cap,
336*c8dee2aaSAndroid Build Coastguard Worker // Skia expands a dash effect by transforming the encoded path, so don't need to handle
337*c8dee2aaSAndroid Build Coastguard Worker // that here.
338*c8dee2aaSAndroid Build Coastguard Worker dash_pattern: Default::default(),
339*c8dee2aaSAndroid Build Coastguard Worker dash_offset: 0.,
340*c8dee2aaSAndroid Build Coastguard Worker }
341*c8dee2aaSAndroid Build Coastguard Worker }
342*c8dee2aaSAndroid Build Coastguard Worker }
343*c8dee2aaSAndroid Build Coastguard Worker
344*c8dee2aaSAndroid Build Coastguard Worker impl From<&vello_encoding::WorkgroupSize> for ffi::WorkgroupSize {
from(src: &vello_encoding::WorkgroupSize) -> Self345*c8dee2aaSAndroid Build Coastguard Worker fn from(src: &vello_encoding::WorkgroupSize) -> Self {
346*c8dee2aaSAndroid Build Coastguard Worker Self {
347*c8dee2aaSAndroid Build Coastguard Worker x: src.0,
348*c8dee2aaSAndroid Build Coastguard Worker y: src.1,
349*c8dee2aaSAndroid Build Coastguard Worker z: src.2,
350*c8dee2aaSAndroid Build Coastguard Worker }
351*c8dee2aaSAndroid Build Coastguard Worker }
352*c8dee2aaSAndroid Build Coastguard Worker }
353*c8dee2aaSAndroid Build Coastguard Worker
354*c8dee2aaSAndroid Build Coastguard Worker impl From<&vello_encoding::WorkgroupCounts> for ffi::DispatchInfo {
from(src: &vello_encoding::WorkgroupCounts) -> Self355*c8dee2aaSAndroid Build Coastguard Worker fn from(src: &vello_encoding::WorkgroupCounts) -> Self {
356*c8dee2aaSAndroid Build Coastguard Worker Self {
357*c8dee2aaSAndroid Build Coastguard Worker use_large_path_scan: src.use_large_path_scan,
358*c8dee2aaSAndroid Build Coastguard Worker path_reduce: (&src.path_reduce).into(),
359*c8dee2aaSAndroid Build Coastguard Worker path_reduce2: (&src.path_reduce2).into(),
360*c8dee2aaSAndroid Build Coastguard Worker path_scan1: (&src.path_scan1).into(),
361*c8dee2aaSAndroid Build Coastguard Worker path_scan: (&src.path_scan).into(),
362*c8dee2aaSAndroid Build Coastguard Worker bbox_clear: (&src.bbox_clear).into(),
363*c8dee2aaSAndroid Build Coastguard Worker flatten: (&src.flatten).into(),
364*c8dee2aaSAndroid Build Coastguard Worker draw_reduce: (&src.draw_reduce).into(),
365*c8dee2aaSAndroid Build Coastguard Worker draw_leaf: (&src.draw_leaf).into(),
366*c8dee2aaSAndroid Build Coastguard Worker clip_reduce: (&src.clip_reduce).into(),
367*c8dee2aaSAndroid Build Coastguard Worker clip_leaf: (&src.clip_leaf).into(),
368*c8dee2aaSAndroid Build Coastguard Worker binning: (&src.binning).into(),
369*c8dee2aaSAndroid Build Coastguard Worker tile_alloc: (&src.tile_alloc).into(),
370*c8dee2aaSAndroid Build Coastguard Worker path_count_setup: (&src.path_count_setup).into(),
371*c8dee2aaSAndroid Build Coastguard Worker backdrop: (&src.backdrop).into(),
372*c8dee2aaSAndroid Build Coastguard Worker coarse: (&src.coarse).into(),
373*c8dee2aaSAndroid Build Coastguard Worker path_tiling_setup: (&src.path_tiling_setup).into(),
374*c8dee2aaSAndroid Build Coastguard Worker fine: (&src.fine).into(),
375*c8dee2aaSAndroid Build Coastguard Worker }
376*c8dee2aaSAndroid Build Coastguard Worker }
377*c8dee2aaSAndroid Build Coastguard Worker }
378*c8dee2aaSAndroid Build Coastguard Worker
379*c8dee2aaSAndroid Build Coastguard Worker impl From<&vello_encoding::BufferSizes> for ffi::BufferSizes {
from(src: &vello_encoding::BufferSizes) -> Self380*c8dee2aaSAndroid Build Coastguard Worker fn from(src: &vello_encoding::BufferSizes) -> Self {
381*c8dee2aaSAndroid Build Coastguard Worker Self {
382*c8dee2aaSAndroid Build Coastguard Worker path_reduced: src.path_reduced.size_in_bytes(),
383*c8dee2aaSAndroid Build Coastguard Worker path_reduced2: src.path_reduced2.size_in_bytes(),
384*c8dee2aaSAndroid Build Coastguard Worker path_reduced_scan: src.path_reduced_scan.size_in_bytes(),
385*c8dee2aaSAndroid Build Coastguard Worker path_monoids: src.path_monoids.size_in_bytes(),
386*c8dee2aaSAndroid Build Coastguard Worker path_bboxes: src.path_bboxes.size_in_bytes(),
387*c8dee2aaSAndroid Build Coastguard Worker draw_reduced: src.draw_reduced.size_in_bytes(),
388*c8dee2aaSAndroid Build Coastguard Worker draw_monoids: src.draw_monoids.size_in_bytes(),
389*c8dee2aaSAndroid Build Coastguard Worker info: src.info.size_in_bytes(),
390*c8dee2aaSAndroid Build Coastguard Worker clip_inps: src.clip_inps.size_in_bytes(),
391*c8dee2aaSAndroid Build Coastguard Worker clip_els: src.clip_els.size_in_bytes(),
392*c8dee2aaSAndroid Build Coastguard Worker clip_bics: src.clip_bics.size_in_bytes(),
393*c8dee2aaSAndroid Build Coastguard Worker clip_bboxes: src.clip_bboxes.size_in_bytes(),
394*c8dee2aaSAndroid Build Coastguard Worker draw_bboxes: src.draw_bboxes.size_in_bytes(),
395*c8dee2aaSAndroid Build Coastguard Worker bump_alloc: src.bump_alloc.size_in_bytes(),
396*c8dee2aaSAndroid Build Coastguard Worker indirect_count: src.indirect_count.size_in_bytes(),
397*c8dee2aaSAndroid Build Coastguard Worker bin_headers: src.bin_headers.size_in_bytes(),
398*c8dee2aaSAndroid Build Coastguard Worker paths: src.paths.size_in_bytes(),
399*c8dee2aaSAndroid Build Coastguard Worker lines: src.lines.size_in_bytes(),
400*c8dee2aaSAndroid Build Coastguard Worker bin_data: src.bin_data.size_in_bytes(),
401*c8dee2aaSAndroid Build Coastguard Worker tiles: src.tiles.size_in_bytes(),
402*c8dee2aaSAndroid Build Coastguard Worker seg_counts: src.seg_counts.size_in_bytes(),
403*c8dee2aaSAndroid Build Coastguard Worker segments: src.segments.size_in_bytes(),
404*c8dee2aaSAndroid Build Coastguard Worker ptcl: src.ptcl.size_in_bytes(),
405*c8dee2aaSAndroid Build Coastguard Worker }
406*c8dee2aaSAndroid Build Coastguard Worker }
407*c8dee2aaSAndroid Build Coastguard Worker }
408