phronmophobic/membrane

Use Skija bindings for Skia?

tonsky opened this issue · 7 comments

Hi Adrian!

Great project, happy to see native Clojure getting some UI love.

My name is Nikita, I maintain Skija, a high-quality JVM bindings for Skia. I noticed you are using Skia as well.

Do you think Skija might be a good fit for membrane? If yes, I will be glad to offer assistance on Skija side, if anything you need is missing.

If not, no worries, I wish you a success either way :)

Here’s the link: https://github.com/jetbrains/skija

Hi Adrian, I agree, and for me it'd be great if this worked together with Skija since I'm doing some other graphics work using that library but it'd be nice if I could use it together with membrane to add these very nice UI elements to it.

Best regards,
Darrick

Hey, I was excited to see the announcement of Skija and I do think it might be a good fit for membrane. I haven't completely figured all the tradeoffs might be, but here are some of my thoughts so far:

  • It looks like Skija has a better, automatic process for building skia. As long as Skija is maintained, that would make it easier for membrane to upgrade to newer versions of skia
  • Currently, membrane's skia bindings also include some glue c++ glue code. Using Skija wouldn't rule out c++ glue code for specific optimizations, but it may make glue code harder to include.
  • Skija has a Windows build (membrane currently does not)!
  • Skija includes skia's paragraph text shaping!
  • Using Skija would make it easier to not bundle skia in membrane's jar. It currently adds a lot of bloat for users who are using membrane while not targeting skia
  • membrane is graalvm compatible. I've been thinking about how to leverage some combination of sci, graalvm, and skia for building mobile apps. I'm not sure how skija would fit into that plan.
  • The boundary between c++ code and jvm code does add overhead. It seems like Skija wraps individual calls to the skia library which may add extra overhead compared to being able to write higher level procedures in c++ that can reduce the overhead of calling into c++ code.

Anyway, a skija graphics backend can live along side another skia implementation (assuming you don't load both at the same time. That seems like a recipe for trouble). I think writing a skija+lwgl backend is definitely worth a shot.

RE: graalvm, Skija should be compatible, but LWJGL is not :) Thus, I have never run Skija under GraalVM (yet). But I plan to.

RE: skia's paragraph text shaping. Warning! It’s very new and buggy still (on Skia side) https://bugs.chromium.org/p/skia/issues/list?q=paragraph&can=2. But we have decent TextBlobs + Shaper which work much better

I'm now pretty close to a fully implemented Skija backend for membrane. You can check it out in membrane version 0.9.18-beta. I would love to hear your feedback.

There's an example project at https://github.com/phronmophobic/membrane-skija-example, but it's pretty minimal. I'm happy to answer any questions (@phronmophobic on clojurian's slack).

There are some features I used in my Skia backend directly that either weren't available in Skija or I couldn't find. Not sure where the best place to report them was. Should I make an issue for each or one big issue with all of them? Anyway, here's a list before I forget:

  • Skia allows you to clone a SkPaint object from another Paint. This is useful for pushing and popping paints as you draw the UI tree.
  • It would be great to have helpers for setting colors on a Paint. Writing colors as ints isn't so bad, but working with them programmatically is a pain, especially since clojure's bit manipulation is a real pain. Membrane's colors are RGB or RGBA with floats from [0,1.0f]. You can see how I interfaced with .setColor at https://github.com/phronmophobic/membrane/blob/master/src/membrane/skija.clj#L294
  • calling .drawString with a Null Paint will crash the jvm
  • SkPaint has a .setAlpha method that would be nice to have. There is a workaround though, https://github.com/phronmophobic/membrane/blob/master/src/membrane/skija.clj#L479
  • Is there any reason not to compile with "-target" "1.8" "-source" "1.8"
  • Skia let's you use the default system font by providing a null typeface. This works on mac osx, but crashes the JVM on linux.

Check out the membrane todo app running on Skija!

skija-example

Wow that looks cool!

Should I make an issue for each or one big issue with all of them?

Yes, please open an issue per requrest (unless requests are closely related that would be most likely added together, e.g. color-manipulation functions).

It would be great to have helpers for setting colors on a Paint

There’s Color4f that is 4 floats underneath, with getters and setters (immutable, so it’s more of withR/G/B/A than setR/G/B/A). It also has function to convert to and from int. Would those do?

Is there any reason not to compile with "-target" "1.8" "-source" "1.8"

We depend on Java 9 API (java.lang.ref.Cleaner, java.lang.ref.Reference::reachabilityFence), possibly can go as low as 9.

Out of curiosity, what’s so magical about Java 8? Many people have asked me about backwards compatibility, and all had 8 in mind. Nobody has ever asked about any other version.

Awesome. I'll file the issues later today.

There’s Color4f that is 4 floats underneath, with getters and setters (immutable, so it’s more of withR/G/B/A than setR/G/B/A). It also has function to convert to and from int. Would those do?

Perfect! I'm not sure how I missed this.

We depend on Java 9 API (java.lang.ref.Cleaner, java.lang.ref.Reference::reachabilityFence), possibly can go as low as 9.

Out of curiosity, what’s so magical about Java 8? Many people have asked me about backwards compatibility, and all had 8 in mind. Nobody has ever asked about any other version.

Sounds like a pretty good reason to not support Java 8. I think the biggest reason Java 8 is more popular is that Java 9 is non-LTS and java 8 will supported for much longer. Many deployments that were easy to update have since moved to Java 11 or newer. If they weren't easy to update, they stayed on Java 8. See https://www.oracle.com/java/technologies/java-se-support-roadmap.html
Screen Shot 2020-12-29 at 10 33 14 AM