On 23 May 2023 at 04:45p, apam pondered and said...
I was wondering do you know much about GUI implementation?
Not my area of specialty, I'm afraid, but I know a
little bit.
I would probably look at an existing example; the
plan 9 /dev/draw code and the window system may
count.
I'd start here:
https://github.com/0intro/plan9/tree/main/sys/src/libdraw https://github.com/0intro/plan9/blob/main/sys/src/9/port/devdraw.c https://github.com/0intro/plan9/tree/main/sys/src/libframe
(look for `frdrawsel0` in `frdraw.c` here)
https://github.com/0intro/plan9/tree/main/sys/src/cmd/rio
(look for `wrefresh` in `wind.c` here)
I've been working on my OS, and I'm trying to improve the speed. I
*think* the GUI is a bottleneck.
Presently, the "window manager" is built into the kernel, and every 5 ticks (jiffies if you like) it processes input and redraws the frame buffer.
Does this mean that it unconditionally redraws the frame
buffer? It strikes me that you could keep a flag telling
you whether the buffer needs to be redrawn based on what
events you see (either input or a program writing to a
window). That alone would probably give you a fairly
substantial improvement.
The framebuffer is a vesa 1024x768 framebuffer (32bit), and I am
redrawing the desktop, then each of the icons, then the windows then drawing the mouse pointer.
So essentially everything is getting redrawn whether it's changed or not.
I think I should only be drawing things that are either visible or changed, but I just can't wrap my head around how to do this without making it just as complex as just redrawing everything.
Yeah, that sounds like it's going to be a performance
bottleneck.
With the caveat that I'm not a front-end person, it strikes
me that each graphical object, as managed by the window
system, could have some notion of whether it has updated or
not by tacking a boolean onto each datum. The in your refresh
routine, you could simply test all of those; if none have
changed, you have nothing to do.
If they _have_ changed, you could then look at the changed
objects; for example windows. If they have not moved or
resized, you simply render the updated contents and bitblt
them into the frame buffer.
If they _have_ moved or resized, it's a little more complex:
drawing the updated contents is fairly straight forward
(just render into a local buffer and bitblt to the frame
buffer), but the complication is that you _also_ have to
redraw anything that was under the old object that has now
been exposed. For that, you've got to know the intersection
of old and new graphical objects to compute the area that
needs to be updated. I can think of a few different ways
that I might try to approach this problem, but this is where
I admit to being out of my depth and I'd look at something
like the plan9 code (which I would turn to because I am
familiar with that system overall and it tends to be both
reasonably simple and fairly readable).
I hope this helps! We're going to have to redo the graphics
primitives from plan9 in r9 in a few months, so perhaps
something interesting will come out of that.
--- Mystic BBS v1.12 A48 (Linux/64)
* Origin: Agency BBS | Dunedin, New Zealand | agency.bbs.nz (21:1/101)