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

write pixel graphics directly to linux console framebuffer #1369

Closed
dankamongmen opened this issue Feb 27, 2021 · 15 comments
Closed

write pixel graphics directly to linux console framebuffer #1369

dankamongmen opened this issue Feb 27, 2021 · 15 comments
Assignees
Labels
bitmaps bitmapped graphics (sixel, kitty, mmap) documentation Improvements or additions to documentation enhancement New feature or request
Milestone

Comments

@dankamongmen
Copy link
Owner

w3m appears capable of rendering pixel images in the linux console sans fbterm. i didn't know this was possible -- i thought you had to use fbterm or something similar to get sub-cell (maybe it's actually bringing the console into framebuffer mode?). figure out what's going on, and use it for our NCBLIT_PIXEL implementation on TERM=linux.

@dankamongmen dankamongmen added enhancement New feature or request question/research Further information is requested labels Feb 27, 2021
@dankamongmen dankamongmen self-assigned this Feb 27, 2021
@dankamongmen dankamongmen added documentation Improvements or additions to documentation and removed question/research Further information is requested labels Mar 1, 2021
@dankamongmen
Copy link
Owner Author

looks like oyu just need permissions to open the appropriate framebuffer device, and then you can mmap() it and scribble to your heart's content.

@dankamongmen dankamongmen changed the title figure out what w3m is doing in the linux console, and rip it off write pixel graphics directly to linux console framebuffer Mar 5, 2021
@WSLUser
Copy link

WSLUser commented Mar 8, 2021

Hey while you're at this, I just thought about this project supporting IO_URING as well. It has to be enabled in the kernel but it's enabled by default in the latest kernel stable and mainline. Framebuffer support is the same, needs to be enabled but typically it is for linux. This is only not the case for certain devices/situations including WSL2 (where when I enable the framebuffer devices, io_uring, and other perf options (compliments to Clear Linux for making those easy to determine), things speed up a bit.)

@ghost
Copy link

ghost commented Mar 10, 2021

Curious: Do you have GPM mouse support when running on the raw console?

@dankamongmen
Copy link
Owner Author

Hey while you're at this, I just thought about this project supporting IO_URING as well. It has to be enabled in the kernel but it's enabled by default in the latest kernel stable and mainline. Framebuffer support is the same, needs to be enabled but typically it is for linux. This is only not the case for certain devices/situations including WSL2 (where when I enable the framebuffer devices, io_uring, and other perf options (compliments to Clear Linux for making those easy to determine), things speed up a bit.)

i'm quite familiar with io_uring, and it's great stuff, but i don't quite see how it would apply to Notcurses? i'm unafraid of new, esoteric, linux-only APIs; we use pidfd already in src/lib/fd.c.

@dankamongmen
Copy link
Owner Author

Curious: Do you have GPM mouse support when running on the raw console?

I believe so! I claim it, so I assume I tested it at some point =].

@WSLUser
Copy link

WSLUser commented Mar 12, 2021

I wasn't sure how much it might play into this project either hence seeing if it has any viability or if it's just not something that is applicable to this type of project.

@dankamongmen
Copy link
Owner Author

it looks like we can detect a raw framebuffer with the FBIOGET_VSCREENINFO ioctl. this will also provide cell-pixel geometry.

@dankamongmen
Copy link
Owner Author

it looks like we can detect a raw framebuffer with the FBIOGET_VSCREENINFO ioctl. this will also provide cell-pixel geometry.

but i think this needs be performed using the framebuffer device, not the tty.

@dankamongmen
Copy link
Owner Author

i'm not sure how/if DRM Dumb Buffers need play a role https://manpages.debian.org/testing/libdrm-dev/drm-memory.7.en.html

@dankamongmen
Copy link
Owner Author

i'm also unsure how one determines which framebuffer is relevant if several are present. CON2FBMAP looks like it might be what we want here, or even just /proc/fb.

@dankamongmen
Copy link
Owner Author

there's also /sys/class/vtconsole/*/name:

[schwarzgerat](0) $ cat /sys/class/vtconsole/vtcon1/name
(M) frame buffer device
[schwarzgerat](0) $ cat /sys/class/vtconsole/vtcon0/name 
(S) dummy device
[schwarzgerat](0) $ 

@dankamongmen
Copy link
Owner Author

i think the thing to do here might be to rerun FBIOGET_VSCREENINFO whenever we run a TIOCGWINSZ (i.e., at startup and on SIGWINCH). this way we always know the number of rows and columns, which we need since the fb ioctl only gives us the screen geometry in pixels (and we need to divide it out), and we also update whenever the video mode is changed. we'll only do this if we're a linux framebuffer, of course. so we probably just keep an fd open if that's the case?

@dankamongmen
Copy link
Owner Author

we now open the framebuffer device and apply the ioctl, extracting pixel geometry. the name in the banner is then Linux framebuffer as opposed to Linux console.

@dankamongmen dankamongmen added the bitmaps bitmapped graphics (sixel, kitty, mmap) label Jun 29, 2021
@dankamongmen dankamongmen added this to the 3.0.0 milestone Jun 29, 2021
@dankamongmen
Copy link
Owner Author

so an interesting element here is that our method of drawing is fundamentally different. for everything else, we provide rectangular data, and it's laid out for us, written as a large glyph. here, we need lay down the lines ourselves, and they're done via mmap direct writes.

that latter is a wrinkle -- it changes up the ordering of things. we purposefully do bitmap phase 1, glyph phase 1, bitmap phase 2, glyph phase 2, as that's necessary for wipe/restore logic. if we draw directly from sprixel_draw(), that's functionally going to work like bitmap phase 1, bitmap phase 2, glyph phase 1, glyph phase 2...hrmm.

@dankamongmen
Copy link
Owner Author

this is pretty much working now, at the level of iterm anyway -- we can draw, but no wiping/rebuilding yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bitmaps bitmapped graphics (sixel, kitty, mmap) documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants