Live data from Hacker News

Minimal Cross-Platform Graphics

zserge.com

31–40 of 67 posts

Re: Minimal Cross-Platform Graphics

#31
post #8

Earlier quoted context omitted.

No direct access to the command buffers of the GPU? No matrix transform routines? No colorspaces besides RGB? Absolute non-starter.

There’s simple and there’s naive. SDL already walked this path. So did pygame. It turns out without shaders, and all their complexity, you basically can’t do anything useful at high resolutions. /shrug It’s too slow; compositing, transformations, all the things people want to do are very much harder to implement in software on top of a naive graphics stack. Simple doesn’t mean naive; you can have a simple api that is…

For any graphic intensive application it would be obviously be necessary to use a GPU.

But for quick hacking / porting old demos / writing emulators and also text based UI it can be fast enough.

With the added benefit of small footprint, high compatibility and fast startup time.

The Lite editor https://github.com/rxi/lite is using pure software rendering (on top of SDL) in a rather naïve fashion but it still renders full 32bit colors at full resolution at more than 60FPS on my computer, not the best solution but still surprisingly fast given the simplicity of the renderer.

This is typically a case where simple/naïve can beat a juggernaut like Electron.

Re: Minimal Cross-Platform Graphics

#32
post #24

Earlier quoted context omitted.

That's a silly statement. If you want to place single pixels, a GPU won't help in any way. The most efficient way would be to write pixels with the CPU into a mapped GPU texture, and then render this texture as fullscreen quad. That's hardly more efficient than going through the system's windowing system. For applications like emulators, or making vintage games (like Doom) run on modern platforms, that approach makes…

>That's hardly more efficient than going through the system's windowing system. My intuition says otherwise but I admit I don't have math on hand to back it up.

Ok it's most likely slightly slower, but not enough that it matters. Frame latency might actually be lower though if the result doesn't need to go through a swapchain AND the window system composer.

Re: Minimal Cross-Platform Graphics

#33
post #20

Earlier quoted context omitted.

2d graphics are rendered on the GPU nowadays, and rightly so. Even SDL uses the GPU wherever it can, by default.

That's a silly statement. If you want to place single pixels, a GPU won't help in any way. The most efficient way would be to write pixels with the CPU into a mapped GPU texture, and then render this texture as fullscreen quad. That's hardly more efficient than going through the system's windowing system. For applications like emulators, or making vintage games (like Doom) run on modern platforms, that approach makes…

But wouldn't the GPU help if you were mapping e.g. 256x192 virtual pixels to say 1024x768? I.e., each of the pixels from the low-res space being represented by a NxM patch of actual screen pixels, like a Win32 GDI StretchBlt() call.

If you had a frame buffer for the actual screen and you tried to do even a 1 to 2x2 expansion on the CPU's time, that'd have to be a serious speed hit. Presumably GPU hardware can do that sort of thing.

Re: Minimal Cross-Platform Graphics

#34
post #12

I used to use a timer to limit the frame rate to 60 Hz too. But on Windows, I found that DwmFlush() seems to act like WaitVSync(), so I've been using that in preference for years now. I think this is undocumented behaviour. I guess what it actually does is wait until the compositor is ready for another frame. To be able to call that function, I LoadLibrary("dwmapi.dll"), and then GetProcAddress(dwm, "DwmFlush").

Why not just use VSync?

How would I do that? I think there is any such function in the Win32 API.

Re: Minimal Cross-Platform Graphics

#35

Earlier quoted context omitted.

Most vintage systems use something way more complex than a pure CPU-controlled framebuffer for graphics. They generally have some sorts of pre-defined "tiles" used to implement a fixed-width character mode, with the addition of a limited number of "sprites" overlaid in hardware. These video modes could be implemented efficiently by modern GPU's.

Only if you don't have a cycle correct emulator inbetween. Those old school system relied on hard real time timings down to the clock cycle to let the CPU control the color palette, sprite properties etc... at the right raster position within a frame. Modern GPUs don't allow such a tight synchronization between the CPU and GPU, so the best way is to run the entire emulation single-threaded on the CPU, including the v…

It depends what you mean by "hard real time". In theory, user input you get while scanning out pixel x might change pixel x + 1, and this leaves you with no choice but rendering single pixels in a strictly serial way. In practice, no existing emulator cares about that.

Re: Minimal Cross-Platform Graphics

#36

This is extremely useful, and the page is beautifully written. Some people write absurd electron behemoths, and then there's this jewel of elegance. Could this be compiled as an αpε? Such a thing would make many heads explode.

I think the Xlib dependency would prevent compilation as an αpε. I put some effort into doing X11 from scratch (without Xlib or Xcb) to make this possible. Or at least, my aim was to be able to build with musl libc and generate a single executable that would run on many different Linuxes.

https://github.com/abainbridge/deadfrog-lib/blob/master/src/.... It is janky though.

Re: Minimal Cross-Platform Graphics

#37

Earlier quoted context omitted.

That's a silly statement. If you want to place single pixels, a GPU won't help in any way. The most efficient way would be to write pixels with the CPU into a mapped GPU texture, and then render this texture as fullscreen quad. That's hardly more efficient than going through the system's windowing system. For applications like emulators, or making vintage games (like Doom) run on modern platforms, that approach makes…

But wouldn't the GPU help if you were mapping e.g. 256x192 virtual pixels to say 1024x768? I.e., each of the pixels from the low-res space being represented by a NxM patch of actual screen pixels, like a Win32 GDI StretchBlt() call. If you had a frame buffer for the actual screen and you tried to do even a 1 to 2x2 expansion on the CPU's time, that'd have to be a serious speed hit. Presumably GPU hardware can do that…

Yes, for fancy upscaling or applying pixel shader effects like CRT filters, doing the final pass on the GPU definitely makes sense. This would no longer be a "minimal" library though.

Window system composers should also be able to upscale bitmaps on their own though, and nothing prevents them to use the GPU for this.

Re: Minimal Cross-Platform Graphics

#38

Earlier quoted context omitted.

Only if you don't have a cycle correct emulator inbetween. Those old school system relied on hard real time timings down to the clock cycle to let the CPU control the color palette, sprite properties etc... at the right raster position within a frame. Modern GPUs don't allow such a tight synchronization between the CPU and GPU, so the best way is to run the entire emulation single-threaded on the CPU, including the v…

It depends what you mean by "hard real time". In theory, user input you get while scanning out pixel x might change pixel x + 1, and this leaves you with no choice but rendering single pixels in a strictly serial way. In practice, no existing emulator cares about that.

It's not about user input, but the CPU writing video hardware registers at just the right raster position mid-frame (to recycle sprites, change the color palette, or even the resolution). Home computer emulators for systems like the C64 or the Amstrad CPC need to do this at exactly the right clock cycle, otherwise modern (demo scene) demos wouldn't render correctly.

PS: of course one could build a GPU command list to render such a video frame somehow, but I bet just building this command list is more expensive then just doing the video decode with the CPU. It would basically come down to one draw command per (emulated system) pixel in the worst case.

Re: Minimal Cross-Platform Graphics

#39
post #28

Wonderful. I really wanted something like this to do Graphic the "hard way", also the most fun way... I was trying to use Tcl-TK for that but this seems a lot lower level, perfect for what I wanted to do which is to write a small GUI toolkit for tiny apps.

Writing pixels into an RGBA framebuffer in main memory is fun, but it's also the easy and slow way to do graphics. The hard way these days is to figure out how to use a modern GPU to do the rendering you need. It's almost always several orders of magnitude faster.
Post reply on HN