• GUI implementation

    From apam@21:1/182 to tenser on Tue May 23 16:45:13 2023
    Hi

    I was wondering do you know much about GUI implementation?

    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.

    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.

    I am drawing on a buffer, then flipping it onto the framebuffer at the
    end.

    Do you know a good resource for learning this?

    Thanks,
    Andrew


    --- Talisman v0.47-dev (Windows/x64)
    * Origin: Smuggler's Cove - Private BBS (21:1/182)
  • From fusion@21:1/616 to apam on Tue May 23 04:46:24 2023
    On 23 May 2023, apam said the following...

    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.

    just spitballing here but:

    as a window moves, have a function for each window to tell it what is happening. follow the z-order from top to bottom. if your new window's right side is now 420 and your next window down in the z-order used to be overlapped from 421-430 that window's expose function is called and can redraw itself that tiny bit. what the message might look like for each window:

    window zorder1: i'm exposing 421w-430w
    window zo2: okay i'll redisplay that but part of it isn't in my window. i'll tell the next window down
    window zo3: you're telling me 421w-430w 510h-515h is now exposed. i'm there so i'll redraw that little bit. 5 lines arent in my window though. i'll tell the next window down
    window zo4: i'm nowhere near you guys. i'll pass it along unchanged
    window zo5: those are my lines. i'll redraw them.
    xx no further unclaimed exposures xx

    cheat and force the icons on the bottom of the z-order of the window list, or make the desktop a window

    for updating a window (text scrolling in the bg or something) probably just send an expose message to the whole window rectangle.. but then you might
    need code for exposing 4 rectangles in one go (like if a small window like a calculator is right on top in the middle of a text editor)

    i duno. never implemented that type of thing myself, but seems like a reasonable method to me.

    --- Mystic BBS v1.12 A47 2021/12/25 (Windows/32)
    * Origin: cold fusion - cfbbs.net - grand rapids, mi (21:1/616)
  • From Vorlon@21:1/195.5 to apam on Wed May 24 16:55:27 2023
    Hi Apam,

    On Tuesday May 23 2023, Apam said to tenser:

    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.

    Vesa mode will be one reason your gui is slow. Before I got the Matrox G550 goin in my Amilathion system I was using vesa mode. It was slow.

    Once the drivers for the Matrox loaded in, I was also able to switch to a 1024x768 16Bit screen mode.

    It was night and day the speed up.



    \/orlon
    aka
    Stephen

    Rocking FSXnet with an Amiga 4000 and Zeus BBS.

    --- Zeus BBS 1.5
    * Origin: -:-- Dragon's Lair --:- dragon.vk3heg.net Prt: 6800 (21:1/195.5)
  • From hollowone@21:2/150 to fusion on Wed May 24 04:43:31 2023
    Two hints:
    - Redrawing whole screen definitively doesn't sound like the most optimal
    way to compose your GUI system. This thing should be easy to layer and signal only those fragments of the screen that requires redrawing
    - check your buffering options on the card, try to avoid updating whole screen between RAM (CPU memory) and VRAM on the card. VESA 2.0+ supports double and triple buffering on the card. that should accelerate the whole thing especially if the DATA BUS on your computer is slow to copy memory between cpu and gpu

    What's the complete hardware you're targeting this development effort for?

    -h1

    ... Xerox Alto was the thing. Anything after we use is just a mere copy.

    --- Mystic BBS v1.12 A48 (Linux/64)
    * Origin: 2o fOr beeRS bbs>>>20ForBeers.com:1337 (21:2/150)
  • From tenser@21:1/101 to apam on Thu May 25 01:24:17 2023
    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)