Automattic / node-canvas

Node canvas is a Cairo backed Canvas implementation for NodeJS.
10.2k stars 1.17k forks source link

fbdev backend #533

Open piranna opened 9 years ago

piranna commented 9 years ago

Add support to use fbdev as a backend to paint directly on Linux console. It will not be the fastest one (it will be software rasterized), but it's easy to implement and could be a starting point to move to better ones. The most simple implementation would be to just paint the canvas pixels to the framebuffer device each time a frame event is dispatched. This could allow to have basic graphics support on NodeOS.

ReneHollander commented 9 years ago

I hacked something together: https://github.com/Automattic/node-canvas/compare/master...ReneHollander:master Its not good nor should it be used, but its a starting point. I will work on it a little more...

Edit: One problem with drawing to fbdev directly is, the size of the surface more or less gets set with the screen size. You can't specify the size in any way, it will just create a surface that is as big as the screen.

Edit 2: Link updated

piranna commented 9 years ago

Wow, awesome! :-D Maybe it's not production ready as you say, but it's a huge work, thank you! :-D

I've review the code and have three questions:

2015-03-08 22:47 GMT+01:00 Rene Hollander notifications@github.com:

I hacked something together: ReneHollander@7a6d345 https://github.com/ReneHollander/node-canvas/commit/7a6d3455f2d447b902fd443d6a468937b90e659c Its not good nor should it be used, but its a starting point. I will work on it a little more...

— Reply to this email directly or view it on GitHub https://github.com/Automattic/node-canvas/issues/533#issuecomment-77776532 .

"Si quieres viajar alrededor del mundo y ser invitado a hablar en un monton de sitios diferentes, simplemente escribe un sistema operativo Unix." – Linus Tordvals, creador del sistema operativo Linux

ReneHollander commented 9 years ago

Writing to the file is just for testing. The third Parameter is not w3c, but in this project also used for PDF and SVG output. A global variable could be defined, but that should be adressed in another issue. Cairo doesnt need to be compiled with any support enabled for it. But my Fork currently only works on Linux, because FB support is hardcoded ATM.

If you want more information on how I am actually drawing to the screen, I can describe it further tomorrow. Typing this in Nexus 5...

piranna commented 9 years ago

Writing to the file is just for testing.

Ok.

The third Parameter is not w3c, but in this project also used for PDF and SVG output.

Ok, fair enought.

A global variable could be defined, but that should be adressed in another issue.

Ok, I'll do it.

Cairo doesnt need to be compiled with any support enabled for it. But my Fork currently only works on Linux, because FB support is hardcoded ATM.

Cool! :-D I asked for this only for NodeOS that's Linux based, so no problem here, specially since it doesn't require any special compilation flag :-)

If you want more information on how I am actually drawing to the screen, I can describe it further tomorrow. Typing this in Nexus 5...

Don't worry ;-)

"Si quieres viajar alrededor del mundo y ser invitado a hablar en un monton de sitios diferentes, simplemente escribe un sistema operativo Unix." – Linus Tordvals, creador del sistema operativo Linux

ReneHollander commented 9 years ago

To make it easier to add new backends I put together a small system. Its not implemented into actual node-canvas yet. First I have to figure out what closures are and what they do in this context :D I made that system, because I also want to add support for egl and be able to draw to simple windows for debugging purposes. If I would just add it, it would produce a huge clusterfuck of if and select statements all in one class.

piranna commented 9 years ago

EGL would be awesome! :-D

ReneHollander commented 9 years ago

I just wanted to inform you, that I implemented my backend system with https://github.com/ReneHollander/node-canvas/commit/454691b5f322b034c52dc6cb5d831e48a3be572d successfully. You can now draw to either fbdev or an image buffer. Things to mention:

It should be good to use for now. If you try it and find some bugs, please report them on the issues page of my fork (https://github.com/ReneHollander/node-canvas/issues)

piranna commented 9 years ago

I just wanted to inform you, that I implemented my backend system with ReneHollander@454691b successfully. You can now draw to either fbdev or an image buffer.

Definitely the code looks cleaner, good job! :-D

Dropped SVG and PDF support for now

Reading your code this is about output format, isn't it?

Shitty way of accessing different backends from js

I've seen it worse... ;-) Just move it to a function and return a ImageBackend as default, and the code will improve ;-)

It should be good to use for now. If you try it and find some bugs, please report them on the issues page of my fork (https://github.com/ReneHollander/node-canvas/issues)

I'll try to find some time to test it on NodeOS ;-) Thank you for your work! :-)

ReneHollander commented 9 years ago

Dropped SVG and PDF support for now

Reading your code this is about output format, isn't it?

You could render to a PDF or SVG previously, but because I am still learning C++ and making nodejs addons, I decided to remove it for now and add these backends later.

Shitty way of accessing different backends from js

I've seen it worse... ;-) Just move it to a function and return a ImageBackend as default, and the code will improve ;-)

I want to make the backends accessible from javascript, so that you can create a backend, set for example framebuffer device or the egl surface you want to draw to and than pass it to the canvas. Canvas would have two constructors, one which takes an previously created backend and one that takes width and height and creates a ImageBackend.

piranna commented 9 years ago

You could render to a PDF or SVG previously, but because I am still learning C++ and making nodejs addons, I decided to remove it for now and add these backends later.

So it's only for output format, ok. I wasn't sure if it could be related to the output format or the posibility to draw SVG files on the canvas... :-)

I want to make the backends accessible from javascript, so that you can create a backend, set for example framebuffer device or the egl surface you want to draw to and than pass it to the canvas. Canvas would have two constructors, one which takes an previously created backend and one that takes width and height and creates a ImageBackend.

Oh, that would be really cool! :-D

piranna commented 9 years ago

@ReneHollander, it seems I'm getting it to work, but how could I be able to test to print on the screen? The simple-fbdev.js file only use fbdev as backend, how could I be able to actually see the result in the console?

By the way, I think by default it should get the actual size of the screen, not hardcoded 1024x1024... What I don't know what it should do is by setting some width and height. Ignore? Strech? Black margins down and right? Centered?

ReneHollander commented 9 years ago

Just run the simple-fbdev.js in a tty and it should work. The size is buggy right now, don't know why. See https://github.com/ReneHollander/node-canvas/issues/1 for further details.

piranna commented 9 years ago

I've test it from X11 and from a tty but got no result, both of them generate the demo file correctly (a green square on a transparent background) but I don't see it on the screen... :-/ How can I be able to test that framebuffer is working correctly and it's not a node-canvas problem?

By the way, I'm doing the tests on a MacBook Pro using EFI and don't see the framebuffer penguin at boot, if that matters...

ReneHollander commented 9 years ago

First check if /dev/fb0 exists. If this isn't the case, the framebuffer is no supported. But because the application doesn't crash, this should not be the case. Next check the output of fbset --show.

piranna commented 9 years ago
[piranna@Mabuk:~/Proyectos/node-canvas]
 (master) > sudo fbset --show

mode "1024x768"
    geometry 1024 768 1024 768 32
    timings 0 0 0 0 0 0 0
    accel true
    rgba 8/16,8/8,8/0,0/0
endmode

So yes, I have it :-)

piranna commented 9 years ago

I've been able to compile node-canvas statically and make it work on NodeOS :-D And also, I've been able to fix the problem with the height, seems you did a bad copy&paste :-P

fbdev

piranna commented 9 years ago

I don't know why the square is shown three times, but maybe it's due to a bad hard-coded configuration of the framebuffer, isn't it?

ReneHollander commented 9 years ago

The error could be because of a bad configuration of the framebuffer code as you stated. I will look into the issues. Also I want to tidy up the backends, add an option to select the backends that should be supported at compile time and something to select the actually used backend during runtime. I want to do it in the next weeks. I hope I can reproduce the stated issue on a PC of mine, otherwise its going to be hard to fix...

I also did some research on hardware acceleration a while back. On an Raspberry PI it should not be too hard, but for normal devices, the drivers require a running X server, but not an actual window manager. It may be possible to get that working...

ReneHollander commented 9 years ago

And how did you fix the height issue?

piranna commented 9 years ago

The error could be because of a bad configuration of the framebuffer code as you stated. I will look into the issues. Also I want to tidy up the backends, add an option to select the backends that should be supported at compile time and something to select the actually used backend during runtime. I want to do it in the next weeks. I hope I can reproduce the stated issue on a PC of mine, otherwise its going to be hard to fix...

Cool :-) For the backends maybe only could make sense for the "hardware ones" (framebuffer, X11...) while the "software ones" (image, pdf...) maybe should be always enabled, what do you think?

I also did some research on hardware acceleration a while back. On an Raspberry PI it should not be too hard, but for normal devices, the drivers require a running X server, but not an actual window manager. It may be possible to get that working...

For Raspberry Pi there's node-openvg-canvas that's backed by OpenVG framework, or are you talking about EGL backend? In that case X server should not be needed at all.

piranna commented 9 years ago

And how did you fix the height issue?

It was easy, since I needed to add an implementation of the Backend destructor, I moved all the implementations to a backend.cc file and then I saw that the code of the width and height methods were the same :-P

ReneHollander commented 9 years ago

Cool :-) For the backends maybe only could make sense for the "hardware ones" (framebuffer, X11...) while the "software ones" (image, pdf...) maybe should be always enabled, what do you think?

The software backends will be enabled all the time, only platform specific backends should be toggable during runtime.

For Raspberry Pi there's node-openvg-canvas that's backed by OpenVG framework, or are you talking about EGL backend? In that case X server should not be needed at all.

I want to make a Raspberry PI backend based on EGL. For any other device i suspect that a running X server is needed to achieve hardware acceleration.

It was easy, since I needed to add an implementation of the Backend destructor, I moved all the implementations to a backend.cc file and then I saw that the code of the width and height methods were the same :-P

Stupid copy&paste errors...

piranna commented 9 years ago

The software backends will be enabled all the time, only platform specific backends should be toggable during runtime.

:+1: Maybe also hardware backends should be disabled by default, since node-canvas is mostly focused for server side apps so there wouldn't be screen at all.

I want to make a Raspberry PI backend based on EGL. For any other device i suspect that a running X server is needed to achieve hardware acceleration.

EGL is also available on desktop platforms, only problem is how to enable it, that there's almost no info :-P On NodeOS we are already investigating how to do it for CEF, maybe we can join forces here since would be done the same way in both cases :-)

Stupid copy&paste errors...

Yep ;-)

piranna commented 9 years ago

@ReneHollander, I've just updated my fork to latest code from @Automattic master, maybe you could be interested on merge/rebase it and work from there... :-)

ReneHollander commented 9 years ago

I will do that :)

piranna commented 9 years ago

Good ;-)

piranna commented 9 years ago

My pull-request now have full support for FbDev, both on real hardware and QEmu. On QEmu it needs to be used with the stdvga graphic card instead of the default Cirrus one, since by default it uses 24 bits color depth and Cairo don't support it (it uses 32 bits ignoring alpha channel).