[HN Gopher] Show HN: Skia-canvas, a browserless implementation o...
       ___________________________________________________________________
        
       Show HN: Skia-canvas, a browserless implementation of the Canvas
       API for Node.js
        
       Author : _samizdat
       Score  : 144 points
       Date   : 2020-09-03 14:58 UTC (8 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | LAMike wrote:
       | Anyone have a demo, or "Hello World" for this library?
        
       | untog wrote:
       | If you're already using Rust, an alternative might be raqote,
       | which would avoid the need to interface with C++ at all... and
       | it's the canvas library used by Firefox's Servo:
       | 
       | https://github.com/jrmuizel/raqote
        
         | gardaani wrote:
         | The good things about raqote is that it's a Rust library so it
         | may be safer than Skia. Raqote is also easier to compile than
         | Skia.
         | 
         | The downside is that it's slower than Skia [1].
         | 
         | But, it should be possible to modify skia-canvas to work with
         | raqote. The JS API would stay the same.
         | 
         | [1] https://twitter.com/pcwalton/status/1252281006263988224
        
           | muizelaar wrote:
           | Raqote is also noticeably faster than it was in April. Still
           | not as fast as Skia but getting closer.
        
       | Sophistifunk wrote:
       | Ugh, there's like ten of these. When will I be able to open a
       | damned window and draw on it?
        
         | runbyfruity wrote:
         | 1973, with the Xerox PARC-developed Alto personal computer.
         | It's still possible to do today.
        
         | dylan604 wrote:
         | Wouldn't that require a browser? What point is the browserless
         | feature? Are non-browser UI applications being used that take
         | advantage of Node.js? Is it for apps?
        
       | gfxgirl wrote:
       | I'm curious, what if anything is different from node-canvas? Not
       | that I'm complaining in any way, just curious.
        
         | Keverw wrote:
         | Wonder if maybe it has less dependencies, that would be a win.
         | like for example on Mac you need cairo pango libpng jpeg giflib
         | librsvg for Node Canvas. So got to note it down for devs to put
         | on their machines, and then remember to also add the same
         | packages to the containers for deployment or if not using
         | containers install on the server directly. I was playing with
         | Node Canvas ages ago to create placeholder profile pics pngs
         | using a random color background and letter.
        
         | wffurr wrote:
         | This uses the Skia backend instead of Cairo. It will give
         | results closer to Chrome's Canvas implementation.
         | 
         | It also doesn't appear to support Windows yet, whereas node-
         | canvas does.
         | 
         | There's probably other differences, e.g. performance, size,
         | etc. but you'd have to measure them.
        
       | pier25 wrote:
       | How does text rendering on images work on different platforms? Do
       | you always get the same result regardless of the platform?
       | 
       | I'm asking because usually Skia produces different aliasing
       | results on different platforms (eg: Windows vs macOS).
        
         | c-smile wrote:
         | If by "on different platforms" you mean "on different server
         | platforms" then result will be different but close enough.
         | 
         | On Windows, for example, Skia will render text closer to
         | Direct2D/DirectWrite. On MacOS to CoreText.
         | 
         | For the reference, here is rendering of the same UI (HTML/CSS)
         | in Sciter using Direct2D (left) and Skia/OpenGl (right):
         | 
         | https://sciter.com/wp-content/uploads/2020/09/d2d-vs-skia.pn...
        
           | pier25 wrote:
           | > _On Windows, for example, Skia will render text closer to
           | Direct2D /DirectWrite. On MacOS to CoreText._
           | 
           | So what you're saying is that Skia changes the aliasing to
           | look like the platform it's running on?
           | 
           | Damn, I wish I could make Chrome on Windows render text like
           | it does macOS.
        
             | [deleted]
        
             | c-smile wrote:
             | I do not see any significant difference (other than
             | different system fonts):
             | 
             | Here is MacOS rendering https://sciter.com/wp-
             | content/uploads/2020/09/mac-os-front.p...
        
               | pier25 wrote:
               | Maybe not when using Sciter, but on Chrome the
               | differences are massive. I will try to make some
               | screenshots later.
        
           | paraboul wrote:
           | Also depends what you mean by rendering. Skia also uses
           | system library for font shaping (CoreText on macOS and
           | direct2d on windows), but also has support for using harfbuzz
           | instead (which works on any platform, even for WebAssembly).
        
             | pier25 wrote:
             | > _Skia also uses system library for font shaping (CoreText
             | on macOS and direct2d on windows)_
             | 
             | Maybe that's why Chrome looks so different on both
             | platforms.
        
         | paraboul wrote:
         | Not the author, but user of Skia on daily basis.
         | 
         | It depends. Skia can either be used as software or GPU
         | renderer.
         | 
         | GPU AA rendering can slightly differs when using MSAA. When
         | MSAA is turned on, Skia has different path renderer strategies
         | (that could be CPU-based, like SDF, or GPU-based using coverage
         | counting). In that case (msaa turned off), AA result _should_
         | be identical on all platforms, at the cost of performance.
        
           | mtklein wrote:
           | Having looked at Skia against a lot of different
           | OS/GPU/driver combinations, I would be surprised to see bit
           | identical results from GPU rendering except perhaps across
           | different nvidia cards. I wouldn't even necessarily expect
           | identical results in replicated runs on the same machine.
           | 
           | Worth keeping in mind that what Skia's GPU backend decides to
           | do depends on GPU features, and sometimes on GPU workarounds.
           | There's no guaranteed way to force it to render identically
           | on all platforms short of something like swiftshader.
        
             | [deleted]
        
             | Dork1234 wrote:
             | Can you force CPU only and control MSAA or are you always
             | restricted by the hardware of the host system in some ways?
        
               | paraboul wrote:
               | you can force CPU only and also disable MSAA on the GPU
               | renderer. Enabling the GPU renderer doesn't guarantee
               | that everything will be generated on the GPU. Skia can
               | still decide to rasterize a path on the CPU before
               | uploading it on the GPU.
        
               | Dork1234 wrote:
               | But if you force CPU everything should be on CPU? or do
               | things get offloaded the developer doesn't know about?
        
               | paraboul wrote:
               | If you use the Software renderer, then yes, it's fully
               | rasterized on the CPU. You can even build skia without
               | any on the GPU source code.
        
             | paraboul wrote:
             | hey thanks for answering! You're one of the main skia
             | contributor right?
             | 
             | I thought GrGlCaps was supposed to fallback _most of the
             | time_ to equivalents. Also thought that golden images
             | baseline where pixel tested against a large set of
             | different hardware.
             | 
             | But yeah, Skia blacklists MSAA for Intel GPU, so if you
             | opt-in for sampling, you're not guaranted it's going to be
             | enabled and therefore observe differences
        
       | sitkack wrote:
       | Are there server side webgl implementations as well? Either GPU
       | accelerated or pure software.
        
         | dhritzkiv wrote:
         | There's headless-gl (https://github.com/stackgl/headless-gl).
         | Note: I'm a maintainer
        
           | modeless wrote:
           | This looks great! You actually pass conformance? Any plans
           | for WebGL 2, or SwiftShader?
        
       | adamnemecek wrote:
       | If you are looking for a Rust native, not too complicated
       | implementation of canvas api, check out
       | https://github.com/cytecbg/gpucanvas. It's a rust port of nanovg.
       | 
       | Check the demo by running 'cargo run --example demo'.
        
         | adamnemecek wrote:
         | I'll be adding more backends to this. I'm almost done with a
         | metal backend (https://github.com/adamnemecek/gpucanvas), I'll
         | add vulkan and wgpu next. If you want to get involved, we are
         | definitely looking for contributors!
         | 
         | It's a really good way to understand 2d graphics.
        
       | aloer wrote:
       | What are the differences between this and canvaskit, the official
       | wasm version (?) of skia?
       | 
       | https://www.npmjs.com/package/canvaskit-wasm
       | 
       | Can be used with node as well
        
         | esrauch wrote:
         | This is a native dependency where that's compiling skia itself
         | to wasm. The native dependency should be able to be faster by a
         | wide margin by taking advantage of hardware acceleration but
         | it's not obvious if it does (similarly skia compiled to wasm
         | must be much slower than using the proper canvas API in the
         | browser)
        
           | aloer wrote:
           | Why is wasm necessarily slower than the browser if the
           | browser is already implementing canvas via skia? Just the
           | hardware acceleration? Does that mean only gpu access or
           | something more?
           | 
           | Not that that would make much sense. I've not been very
           | successful at understanding what kind of problem canvaskit is
           | trying to solve
           | 
           | What I am trying to do is the same as it was more than a year
           | ago (https://news.ycombinator.com/item?id=20339574): A tile
           | based, web based view with prerendered image tiles from the
           | server and on the fly rendered tiles on the client. Ideally
           | the client side rendering is super fast, whether that means
           | gpu is enough or multi threaded cpu I don't know yet
           | 
           | So what I understand so far is that I can't have anything
           | multithreaded (yet?) in the web client and probably native
           | canvas is the most performant. Even canvaskit with webgl
           | won't reach that performance (not sure here)
           | 
           | Otoh canvaskit could possibly be used in other browsers if
           | they don't natively implement canvas via skia itself to
           | minimize render diffs
           | 
           | And lastly this project here could be the backend renderer
           | instead of either headless browser via canvas api (hacky) or
           | canvaskit in node (slow because cpu only)
           | 
           | But none of these offer and kind of performance increase over
           | native canvas which is limited to single thread because of
           | spectre and meltdown
        
             | c-smile wrote:
             | > Why is wasm necessarily slower
             | 
             | Usually wasm is twice slower than native code:
             | https://www.usenix.org/conference/atc19/presentation/jangda
             | 
             | WebAssembly is essentially a bytecode that needs to be
             | JITted before running. That's pretty much the same
             | situation as with Java, you may have comparable performance
             | but usually comparable Java code runs slower that native.
        
       | tenaciousDaniel wrote:
       | Calling it "server-side canvas" really throws me off. Why would a
       | drawing API be needed on a server? For headless rendering?
       | 
       | If the benefit is to use the drawing API in a Node context
       | _outside of_ a server environment, that makes more sense to me.
        
         | chrisco255 wrote:
         | For outputting to static files, like JPEG or PDF.
        
         | untog wrote:
         | > Why would a drawing API be needed on a server?
         | 
         | There are plenty of reasons to want to generate an image
         | dynamically on a server. Dynamic image resizing to fit client
         | requirements is one that immediately comes to mind.
        
           | pier25 wrote:
           | Or dynamic images for emails
        
             | Keverw wrote:
             | Reminds me of how some games or other sites had an image
             | you could put in your forum signatures. I think Steam had
             | one or some third party built it. Would show like the games
             | you were playing and if in game and not... I think Skype
             | and MSN had icons too that was a image but used your
             | profile id in it.
        
         | andrewaylett wrote:
         | I once set up a large bank (you've probably heard of the bank,
         | you've almost certainly not used this specific project though)
         | with server-side Adobe Flex. We were using Flex to display
         | charts on the client, and needed a way to render the same
         | charts for use in reports.
         | 
         | This would be really useful for similar modern projects.
        
         | dwhitney wrote:
         | Server Side Rendering is a good use case. If you want to pre-
         | render a data visualization that can be loaded with a web page,
         | you can use something like this in place of the browser's
         | canvas, but use the same code to generate the data
         | visualization
        
         | pier25 wrote:
         | I can totally see myself using it to render PDFs server side
         | (invoices, reports, etc).
        
         | core-questions wrote:
         | > Why would a drawing API be needed on a server? For headless
         | rendering?
         | 
         | 15 years ago I was driving GD and ImageMagick from PHP to
         | render things like staff ID cards, barcode labels for things,
         | etc.
         | 
         | It was trivial to write a script that would render something
         | quickly and just output raw image data, so you could <img
         | src="whatever.php?name=Joe&department=Meat" /> and the image
         | would be dynamically created and sent with the right MIME type.
         | 
         | Plenty of great use cases for this.
        
         | scrollaway wrote:
         | I previously worked on an in-browser Hearthstone card renderer
         | that uses Canvas. The rendering needed to be client-side for
         | dynamic use cases (where the card would receive various effects
         | thus change its look).
         | 
         | However I also needed to implement a server-side version of it
         | that prerendered all the cards to PNG so that they're browsable
         | without having clients consume excessive cpu/battery. Doing it
         | using a separate codebase would have been hell to reconcile.
         | Hence node-canvas.
        
         | jperras wrote:
         | I have definitely needed this exact functionality in the recent
         | past.
         | 
         | We had an application where a canvas-based editor was used to
         | create diagrams, and then these diagrams were saved to a
         | library. We wanted to have each saved diagram to have a preview
         | image to better visually distinguish between them while
         | scrolling. The ability to render a png on the server from the
         | canvas would have saved us a _lot_ of trouble.
        
         | iamdbtoo wrote:
         | I once built a simple website for a Netflix show where you
         | could enter some text and it'd be played in an animation, but
         | you could also save/share a video of it.
         | 
         | It was so much easier to build the animation in canvas for the
         | site and just replay it to get frames for a video on the server
         | than to try to make the video in some other environment and
         | then show it in the browser.
        
         | sergeykish wrote:
         | To render all sort of dynamic information:
         | 
         | * visitors counter
         | 
         | * request IP
         | 
         | * game stats in forum signature (implemented this with gd and
         | ruby)
        
         | enobrev wrote:
         | I have built quite a few rendering servers for various use
         | using canvas.js and nodejs. I also built a prototype for a
         | dynamic video rendering server once - also based upon nodejs
         | and canvas.js. It was slow but worked out as a proof of concept
         | that became a fairly successful startup.
        
         | giovannibonetti wrote:
         | I was thinking on creating a turn-based multiplayer game for
         | group chat in an app like Telegram. Then, whenever a player
         | gave a command the server would draw the board and send the
         | updated image to the chat.
         | 
         | It could start with something simple like tic-tac-toe and only
         | two players. A player would tell the app a number between 1 and
         | 9 corresponding to the place he/she chose. Then the server/bot
         | would send the updated image to the conversation.
         | 
         | What do you think? :)
        
           | mufufu wrote:
           | Not sure why that would have to be done server side though,
           | couldn't the server only be used for coordination/maintain
           | state and then submit the current state/positions to the
           | client and the client would render the board?
        
             | julienb_sea wrote:
             | In his example, there is no client browser. The users are
             | just sending commands into a telegram chat, the app is
             | presumably only able to send API calls based on chat events
             | responses. Its unlikely the app would be sufficiently
             | featured to do the board rendering itself, although I am
             | not really familiar with this space so I'm making
             | assumptions.
             | 
             | As such, the backend would do the heavy lifting of
             | rendering the board, and send the rendered board back into
             | the message group.
        
             | imjasonmiller wrote:
             | I think one's constrained by the chat application's
             | functionalities. Telegram doesn't allow a bot to perform
             | such operations on the client, last time I built one at
             | least.
             | 
             | Of course one might be able to use emoji or text as a
             | representation of said state if the game allows for it.
        
           | deft wrote:
           | Someone I know is doing exactly this (well for discord) and I
           | thought it was genius.
        
       ___________________________________________________________________
       (page generated 2020-09-03 23:00 UTC)