Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVG rendering upgrade/generalization #51

Open
7 tasks
redhog opened this issue Feb 23, 2020 · 28 comments
Open
7 tasks

SVG rendering upgrade/generalization #51

redhog opened this issue Feb 23, 2020 · 28 comments

Comments

@redhog
Copy link
Owner

redhog commented Feb 23, 2020

Goals for a new SVG rendering platform

  • Use OpenGL as the back-end
  • Render to an OpenGL texture.
  • Possibility of accessing the SVG DOM and sending diffs/updates over X properties, so that changing the SVG would not require a re-parsing of the whole document from text
  • Being able to add CSS classes dynamically
    • Update the SVG efficiently when window properties changes
    • Set classes on root DOM node for each property name/value pair
      • Example: if _NET_WM_WINDOW_TYPE is set to _NET_WM_WINDOW_TYPE_DESKTOP, set a class _NET_WM_WINDOW_TYPE___NET_WM_WINDOW_TYPE_DESKTOP on the root DOM node
  • Allow positioning of the SVG with relation to the window based on parameters inside the SVG

Current platform:

Need to investigate

OpenVG stuff

Other

@IanTrudel IanTrudel mentioned this issue Feb 23, 2020
5 tasks
@redhog
Copy link
Owner Author

redhog commented Feb 23, 2020

Solution for communicating the placement: If an SVG document contains a group with id "#window", the full image is scaled and moved such that this group exactly overlays the window, whatever its dimensions. This way, elements can be placed outside of the window box itself (e.g. to draw border elements).

@redhog
Copy link
Owner Author

redhog commented Feb 24, 2020

@backorder So I'm having this problem where reading out the coordinates of an element of an svg (see above) in the current version of librsvg (2.40.20-2) only gives integers (and for width/height for which there are float values, they're still rounded to whole numbers). The newest version of librsvg seems to maybe be able to give the raw floats, but that version depends on new versions of libcairo and basically the whole universe... Any ideas? Alternative svg implementations? Hacks for librsvg? Something else?
The alternative is to wrap the svg in json or msgpack or something to send these parameters, but that is both uglier and harder to parse (remember that glass-renderer is pure C code)...

@IanTrudel
Copy link
Collaborator

Are you using libcairo provided by the system or includes your own along InfiniteGlass? On another FOSS project, we used to provide dependencies including libcairo with the releases.

@redhog
Copy link
Owner Author

redhog commented Feb 24, 2020

I use the system libraries for everything... And librsvg + libcairo has a pretty long list of deps, and if you ship/build one, you'll have to ship all... Dependency hell is an ugly place to be...

@redhog
Copy link
Owner Author

redhog commented Feb 24, 2020

And at some point just wrapping the data becomes way easier... It's just too bad when svg itself does have space for the data I need... I just can't get it out.

Oh, and I thought briefly about using an xml lib to just read out the values, but the problem is, you then have to handle transforms...

@IanTrudel
Copy link
Collaborator

RE: Dependency hell

I hear you! I can probably look during the weekend. Busy week.

@redhog
Copy link
Owner Author

redhog commented Feb 24, 2020

Nearly everything, esp OpenVG stuff, seems to be abandonware :(

@IanTrudel
Copy link
Collaborator

I had evaluated possible replacements for Cairo and SVG libraries in the past and one of the best candidate is https://skia.org/.

Take a look and see if it would be something fit for InfiniteGlass.

@redhog
Copy link
Owner Author

redhog commented Feb 25, 2020

So I decided to do something completely else to solve the window decorations. This will still be interesting to look into / fix later though. What I did was allow rendering extra windows with positions/sizes relative to the main window. So each button is an actual window. Might even make input handling easier. I'm not done yet, but the initial work is at #53

@IanTrudel
Copy link
Collaborator

IanTrudel commented Feb 25, 2020

I will give it a try but the pull doesn't work here.

By the way, switching Cairo/SVG to Skia would be a very good move. Cairo and libsvg are hard to deal with despite how useful they are. I would be interested in assisting you in coding and testing.

@redhog
Copy link
Owner Author

redhog commented Feb 26, 2020

Cool! I couldn't immediately see any SVG parser in Skia, only the drawing primitives, but I didn't look very hard.

All the svg rendering is in glass-renderer/property_svg.c. It's not that much code, but there is one small tricky aspect: The SVG is zoomed and cropped while being rendered, so that you can zoom in infinitely on an SVG on the screen without losing resolution, or running out of RAM. This coordinate calculation isn't exactly obvious. Luckily I don't see why that part of the code would need to change at all :)

Maybe have a look and see if you can figure out how to port it?

@IanTrudel
Copy link
Collaborator

Yes, I can take a look during the weekend. My understanding is that Skia is also performing better. So that would be interesting to see how it goes. Any other places Cairo or SVG is used?

@redhog
Copy link
Owner Author

redhog commented Feb 26, 2020

Something that uses OpenGL as the back-end would be ideal from a performance point of view I guess, esp if it can render directly to an OpenGL texture...

Nope, it's all in one place. The rendering model is like this:

Each window corresponds to a single glDrawArrays() call, where window properties are mapped to uniforms, arrays and/or textures depending on their type. This is done in the property_TYPE.c modules. SVG:s are mapped to textures, in property_svg.c, in such a way that only the part of the SVG that will be visible will be rendered. To make that possible, those properties set an extra uniform with the data needed to scale and shift the texture back to the right place in the shader code.

Any complexity is handled by setting up properties and / or shader code. I'm trying to keep the C code as small and generic as possible, as that's where the hairy stuff ends up if you're not careful...

@IanTrudel
Copy link
Collaborator

I checked property_svg.c today. It gives me a good idea what to look for. Need to check the equivalent in Skia now.

@redhog
Copy link
Owner Author

redhog commented Mar 1, 2020

Cool!

Some other cool features to look for:

  • Imagine if we could have a DOM-tree of the SVG both server and client side and exchange diffs/updates, so that changing the SVG would not require a re-parsing of the whole document from text?
  • Being able to add CSS classes dynamically
    • Update the SVG efficiently when window properties changes
    • Set classes on root DOM node for each property name/value pair
      • Example: if _NET_WM_WINDOW_TYPE is set to _NET_WM_WINDOW_TYPE_DESKTOP, set a class _NET_WM_WINDOW_TYPE___NET_WM_WINDOW_TYPE_DESKTOP on the root DOM node.

@IanTrudel
Copy link
Collaborator

Fantastic idea ! There are a lot of things we can do with SVG that would be too resources intensive with images.

By the way, we got a new fan. I'm 9th who starred the project and now there is a mysterious 10th! Congrats!

@redhog
Copy link
Owner Author

redhog commented Mar 1, 2020

Yeah. The problem with doing nearly all of those things with the current implementation is that reparsing the XML of the SVG and rebuilding the DOM tree on every update is pretty slow. Example: The title search functionality (every time you press a key I update the content of a line of text in the SVG).

New fans are super cool! Would be even cooler if more people started giving feedback too! I feel like the WM is moving forward so much quicker with your input!

@redhog
Copy link
Owner Author

redhog commented Mar 2, 2020

Btw, sorry that everything is a bit slow right now - I'm working on #53 and it's taking quite a bit of time to get right...

@IanTrudel
Copy link
Collaborator

No problem. A bit of slow down here too. Sick last week and work is piling up. But the dream of InfiniteGlass is still present. :)

@redhog redhog changed the title SVG positioning SVG rendering upgrade/generalization Mar 6, 2020
@redhog
Copy link
Owner Author

redhog commented Mar 31, 2020

Try out SVG-to-SDF-topixmap

@IanTrudel
Copy link
Collaborator

RE: Skia rasterization

https://github.com/google/skia/blob/master/example/SkiaSDLExample.cpp#L248

Skia can use CPU, SDL, OpenGL and Vulkan to do the rasterization.

@IanTrudel
Copy link
Collaborator

RE: Signed Distance Function (SDF)

Paper presented at SIGGRAPH 2007:
Improved Alpha-Tested Magnification for Vector Textures and Special Effects
https://steamcdn-a.akamaihd.net/apps/valve/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf

https://en.wikipedia.org/wiki/Signed_distance_function

@IanTrudel
Copy link
Collaborator

IanTrudel commented Apr 1, 2020

RE: Accessing DOM

resvg seems to support DOM through xmlparser/roxmltree and Skia has some SkSVG and SkDOM.

https://github.com/RazrFalcon/resvg/blob/master/README.md

@IanTrudel
Copy link
Collaborator

Chromium Embedded Framework could work as a solution. It provides a renderer that use Skia when it comes to SVG. It obviously support the full features including SVG animation.

https://en.m.wikipedia.org/wiki/Chromium_Embedded_Framework

https://www.reddit.com/r/vulkan/comments/85xjp8/cef_ui_integration_in_vulkan/

@redhog
Copy link
Owner Author

redhog commented Apr 6, 2020

Does it support using the OpenGL skia backend? It would be a very big performance advantage to not render the image to RAM and then copy it to a texture, but keep it in texture/gpu ram all the time...

@IanTrudel
Copy link
Collaborator

Yes, it supports multiple backends including OpenGL and Vulkan. CEF provides the core features of a web browser but it's been trimmed down compared to Chromium. There shouldn't be bloat, memory footprint and CPU usage should be within acceptable limits.

@IanTrudel
Copy link
Collaborator

Additional reference:

Python bindings for the Chromium Embedded Framework (CEF) at https://github.com/cztomczak/cefpython.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants