Closed RazrFalcon closed 2 years ago
hi, thank you nice work 🙂. Looks promising I will try to create a tiny-skia
render backend.
tiny-skia
is looking great. Would this mean no text on Canvas
widgets? As far as I can tell, raqote
does support (some) text while tiny-skia
doesn't/won't for quite some time support any.
@arctic-alpaca with the text drawing should be not problem, we uses for raqote also a custom implementation based on rusttype
.
@arctic-alpaca raqote has a very rudimentary text support which relies on system libraries. I plan to use a pure Rust implementation eventually.
Thanks for the explanations!
@FloVanGH Out of interest and to understand OrbTk better, what needs to be done to implement a new drawing backend? Is it enough to implement RenderContext2D
and modify the renderer/src/lib.rs
file?
@arctic-alpaca you are welcome. Yes that is the main effort of implement a new render backend. What you have to do then is to connect you RenderContext2D with a window. That is done inside of the shell crate.
But with alpha-5
I want to decouple that parts more from the other crates. My goal is that you can inject render context and events from outside. This will make it possible to use OrbTk also I use of a game engine.
maybe it is worth to creating a RenderBackend trait.
@kivimango yes that's the plan 🙂. And I want to separate each render and window backend in a own crate. This will reduce a lot of cfg
code.
With the upcoming milestone alpha5 I want to do same further performance improvements. And I will also start an experimental tiny-skia render backend.
Glad to here. After 3 weeks, I'm still at 90%. This is just how software development works. =)
The library become 20-50% faster and there are only two things left: stroke dashing (easy) and clipping (hard). Once again, I hope to finish in two weeks. But we'll see.
From the performance prospective, tiny-skia is 2-3x faster than cairo in most cases, but there are still weird cases when cairo is faster. And compared to raqote, we are 4-7x faster, depending on a task. Also, unlike raqote, tiny-skia supports bicubic bitmaps transformation and hairline stroking (stroke-width < 1px).
Glad to here. After 3 weeks, I'm still at 90%. This is just how software development works. =)
That's true ;-)
The library become 20-50% faster and there are only two things left: stroke dashing (easy) and clipping (hard). Once again, I hope to finish in two weeks. But we'll see.
That's great I think clippling is the last part we currently need from tiny skia.
Here is an implementation of the tiny-skia backend, currently is not complete but is understandable for the majority of the widgets, missing functionalities needed to finish it:
Also, I have a problem with the gradients, for some reason they don't work, and LinearGradient::new
returns me None
Yes, clipping with path will be supported in the release.
Support for draw arcs, with beziers you only can approximate them but never match it!.
Skia converts Arcs to conic curves and then into quads. So it still not as perfect, I guess. tiny-skia skips arcs completely for now.
LinearGradient::new returns me None
Can you provide the input values you are using?
Can you provide the input values you are using?
I think is better with the context, I checked the input in which it fails is not empty and its two points are separated, also it fails in points_to_unit_ts
but I do not understand that function!
Yes, clipping with path will be supported in the release.
I saw the roadmap thank you!
tiny-skia skips arcs completely for now
Well, then I will implement them with beziers, thanks Tell me if I'm wrong: for a gradient, the coordinates to pass are the ones of the two ends, right?
Yes, I saw this code. I'm asking about the actual values/number, so I can try to reproduce it myself.
points_to_unit_ts
Looks like a malformed transform for me.
Sorry, here is the input values for one of the gradients of the calculator example:
[crates/render/src/tiny-skia/mod.rs:89] tstart = Point {
x: 132.0,
y: 332.0,
}
[crates/render/src/tiny-skia/mod.rs:89] tend = Point {
x: 132.0,
y: 284.0,
}
[crates/render/src/tiny-skia/mod.rs:89] &g_stops = [
GradientStop {
position: 0,
color: Color {
r: 0.47843137,
g: 0.56078434,
b: 0.6392157,
a: 1,
},
},
GradientStop {
position: 1,
color: Color {
r: 0.39215687,
g: 0.48235294,
b: 0.5686275,
a: 1,
},
},
]
[crates/render/src/tiny-skia/mod.rs:89] spread = Pad
Looks like a malformed transform for me.
I'm using Transform::identity()
directly in the argument
Thanks. I was able to reproduce it. Will see what's wrong.
PS: this is because start_x and end_x are the same. Not sure why this is a problem.
It wasn't a trivial fix, but it's fixed now.
Thank you very much, your crate is pretty fast
Does it visually noticeable compared to raqote?
Very, I don't know if I'm oversensitive but for me is a great speed up. You can check yourself.
Also, can you give a manner to modifying the alpha channel of a Color
after its creation, please? I need to apply for the global alpha.
Nice to hear.
I will add set_*
methods to Color
.
@sandmor I've added set_*
methods as well as Color::apply_opacity
, which should be handy.
Thanks, but you don't have to run so much :smile:, this of anyway will not get merged until at least rectangular clipping gets supported.
@sandmor I've just added clipping.
@RazrFalcon Thank you, currently I'm working in the arcs, draw the extremes is a bit complex but with the help of Stack Overflow I expect to soon have the function ended then I will look into the path and if there is another bugs on my implementation, if not I will do a pull request, Thanks!
@RazrFalcon is set_clip_path
stackable? so, I can cut a region, build another path and stack it over, so the two ones clip the following operations? that is not require for the UI but so is as RenderContext2d
would work... well, that is a corner case(I think) so don't worry very much about.
Also, can you setup a boundings check when a path is traced? I hit various "unreachable" errors in my experiments when I attempt to draw off-boundings, that is very annoying when you just want to see why your operation is doing that, also I think that can be trigger by OrbTk
itself in some cases attempting to draw the UI, so can you fix that, please?
EDIT: OrbTk uses save
and restore
methods to deal with multiple paths if you are interested although I will do a PR of anyway at least as an experimental backend
@sandmor I can port Skia's implementation of arc if you like. It's very robust.
No, tiny-skia
is intentionally doesn't have "layers". Maybe it would change someday, but for now is just a single layer.
I hit various "unreachable" errors in my experiments when I attempt to draw off-boundings
This must not happen. Could you provide a minimal example?
OrbTk uses save and restore methods to deal with multiple paths
What paths? Clip paths?
This must not happen. Could you provide a minimal example? Is weird I can not reproduce it out of my code and the thing I was used to test was one of my recently started projects that I modify to use as canvas to draw arcs, I'd prefer not show it although I trigger one the errors here, apparently you have a bunch of unreachable functions that are called. No, tiny-skia is intentionally doesn't have "layers". Maybe it would change someday, but for now is just a single layer. I don't need layers and OrbTk don't use it neither, but works as next:
- You have a not clipped canvas
- You build a path
- You save the current canvas state
- You use the path to clip the desire area
- You draw some stuff
- You build another path
- You use the new path to clip the desire area, this results in a clipped area that is the overlaps of the already apply paths
- Then you can call
restore
and restore the clipped area to the last save state. For example, I apply a square mask using clipping, then I clip another time but with a circular mask, I expect the next result if I paint the whole area: Like you see, I don't need multiple layers, only the capability of save the clipping mask whenRenderContext2D.save
is called and the capability of overlap the new clipping path(or clipping mask) with the previous one. I can useset_clip_mask
or something then to restore the saved clipping mask. I can port Skia's implementation of arc if you like
Don't worry I already implemented it, although I'd appreciate if you can view some obvious optimization on my code.... I think it have too many conditions I tried to decrease them but I don't have many experience with this.
Yes, tiny-skia
doesn't support save/restore either. At this point I guess it would be easier to re-implement in on the orbtk side. So you will need to store the last/current transform and clip mask. And I can make the clip mask public.
I'm trying too keep tiny-skia
as simple as possible.
This is the one I'm using in resvg
. It works fine.
Skia uses a different algorithm.
And don't worry about performance. Compared to actual rendering it's nothing.
I trigger one the errors here
It was already fixed. At least on my tests.
it would be easier to re-implement in on the orbtk side
Yeah, good idea, but then I need some tools: The capability of get and set the clippping mask, and the capability to overlap a path area over a clipping mask or if you can maintain simple the things at cost of some performance then only the power of generate a clipping mask from a path and then I manually merge the result with the current clipping mask
This is the one I'm using in resvg. It works fine.
So... I can not see how it draws an arc, only calculates some parameters, I can do that with sin/cos, the problem is calculate the bezier control points needed to trace the arc contour but don't worry you have reason, the performance is negligible in this case I only like to make the things as efficiently as possible... even if somethings sacrifice some code prettiness
Merged in.
Since you're already using
raqote
, I though you might be interest in a faster, more actively developed alternative.tiny-skia is a direct
raqote
rival. It's basically a Skia CPU subset ported to pure Rust. And it's usually 2-6x faster thanraqote
, while still 2-3 times slower than Skia (it's mainly SIMD issues). In many cases it's even faster thancairo
.Is still in development (90% is done) and I plan to use it in resvg very soon. And I'm interested in any kind of feedback.