User Tools

Site Tools


newsletters:2025-08

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
newsletters:2025-08 [2025/08/30 22:45] – [Performance experiment: per-thread value cache] osnrnewsletters:2025-08 [2025/09/01 01:46] (current) – [folk2 on the gadget] osnr
Line 1: Line 1:
-====== August 2025 newsletter (WIP) ======+====== August 2025 newsletter ======
  
 If you'd like to see the latest updates on Folk in person, **our next Folk open house is [[https://luma.com/wj4pshja|all afternoon (1pm-7pm) on Friday, September 26]], in East Williamsburg, Brooklyn.** You're welcome to come just to cowork, or use the afternoon to hack on your own project on our Folk system. If you'd like to see the latest updates on Folk in person, **our next Folk open house is [[https://luma.com/wj4pshja|all afternoon (1pm-7pm) on Friday, September 26]], in East Williamsburg, Brooklyn.** You're welcome to come just to cowork, or use the afternoon to hack on your own project on our Folk system.
Line 48: Line 48:
 === Anti-blinking: single-buffer canvases === === Anti-blinking: single-buffer canvases ===
  
-Since the spring, we've had this concept in folk2 of 'writable textures', or 'writable images', or (renamed this month, and I think this is now the final name, by analogy with HTML5) //canvases//. Canvases are GPU textures that you can use as a draw target for a shader, and that you can draw onto the screen (or onto other canvases) (just like any other GPU texture in Folk).+Since the spring, we've had this concept in folk2 of [[newsletters/2025-03#page-quads|'writable textures']], or [[newsletters/2025-04|'writable images']], or (renamed this month, and I think this is now the final name, by analogy with HTML5) //canvases//. Canvases are GPU textures that you can use as a draw target for a shader, and that you can draw onto the screen (or onto other canvases) (just like any other GPU texture in Folk).
  
 Canvases exist so that we can accurately transform page-local drawings as you lift up and skew the page, and so that we don't have to redraw page-local content when the display list doesn't change (we just use the existing texture contents). The explicit draw targets in page-local coordinates (as opposed to drawing everything onto the screen) also cut down on statement traffic, since they don't change even when the page moves, and they allow per-canvas display list settlement to work, reducing blinking/glitch states. Canvases exist so that we can accurately transform page-local drawings as you lift up and skew the page, and so that we don't have to redraw page-local content when the display list doesn't change (we just use the existing texture contents). The explicit draw targets in page-local coordinates (as opposed to drawing everything onto the screen) also cut down on statement traffic, since they don't change even when the page moves, and they allow per-canvas display list settlement to work, reducing blinking/glitch states.
  
-One problem, though, is that drawing to canvases has been a parallel process to drawing on the screen, which means that you need a way to synchronize so you don't draw a canvas to the screen while the canvas is itself being drawn onto. Until this month, we were double-buffering canvases, but this was really annoying to coordinate. I simplified everything to just run in a single loop on the GPU thread and render to canvases before then rendering to the screen. Then we can just have 1 buffer (GPU texture) per canvas, since textures are guaranteed to never be drawn to the screen in an inconsistent state. We have a decent amount of headroom on the GPU thread, so I'm hoping this is good enough for now.+One problem, though, is that drawing to canvases has been a parallel process to drawing on the screen, which means that you need a way to synchronize so you don't draw a canvas to the screen while the canvas is itself being drawn onto. Until this month, we were double-buffering canvases, but this was really annoying to coordinate (either you have independent locking which can mess up the scheduler and/or renderer and/or cause deadlock, or you coordinate through a statement [a claim about what the active/inactive buffer are] which introduces blink risk). 
 + 
 +I simplified everything (canvas render & screen render) to just run in a single loop on the GPU thread and render to canvases before then rendering to the screen. Then we can just have 1 buffer (GPU texture) per canvas, since textures are guaranteed to never be drawn to the screen in an inconsistent state. We have a decent amount of headroom on the GPU thread, so I'm hoping this is good enough for now.
 === Anti-blinking: display list settling === === Anti-blinking: display list settling ===
  
Line 65: Line 67:
 If you're familiar with folk2, you might anticipate blinking problems here, because there's a lacuna where the old clock time goes away, the new clock time comes in, but this When block hasn't been evaluated on the new clock time and so the new label statement hasn't appeared. The display subsystem might sample the DB during that lacuna, leading to a visible blink-out of the time: If you're familiar with folk2, you might anticipate blinking problems here, because there's a lacuna where the old clock time goes away, the new clock time comes in, but this When block hasn't been evaluated on the new clock time and so the new label statement hasn't appeared. The display subsystem might sample the DB during that lacuna, leading to a visible blink-out of the time:
  
-{{newsletters:img_3466.mp4?300px}}+{{:newsletters:pasted:20250901-013606.mp4?300px}} 
 + 
  
 You could have a bridge period here, where you ''Wish (keep 10ms) $this is labelled $t'', or use a ''Hold!'' instead, but then you have a different problem: you might see 2 clock times displayed, because the display subsystem happens to sample the DB in a period where both old and new label statements are in place. You could have a bridge period here, where you ''Wish (keep 10ms) $this is labelled $t'', or use a ''Hold!'' instead, but then you have a different problem: you might see 2 clock times displayed, because the display subsystem happens to sample the DB in a period where both old and new label statements are in place.
  
-But I don't want to resort to system-wide convergence where you don't see anything until everything in the universe has converged, so I'm trying this concept of per-canvas //settle time//. Basically, the Collect statement that figures out the display list for each canvas won't fire until the display list has been stable for 3ms. This prevents the user from seeing transient states with 0 or 2 label statements above.+But I don't want to resort to system-wide convergence where you don't see anything until everything in the universe has converged, so I'm trying this concept of per-canvas //settle time//
 + 
 +{{:newsletters:pasted:20250830-224637.png?400px}} 
 + 
 +Basically, the Collect statement above, which figures out the display list to render onto each canvas every frame, won're-fire/re-Collect until the display list has been stable for 3ms. This prevents the user from seeing those transient/glitch states with 0 or 2 label statements.
  
-TODOSign error+(among other things, had a [[https://github.com/FolkComputer/folk/commit/4e8133df9be4d1c0390cf7c24b08c1f03eed9feb|horrible sign error]] that I had to fix to get this to work)
 === Camera slice blinking fix: destructor inheritance in Collect === === Camera slice blinking fix: destructor inheritance in Collect ===
  
Line 196: Line 204:
 Omar: I've been [[https://github.com/FolkComputer/gadget2/commits/main/|updating]] the documentation for [[https://github.com/FolkComputer/gadget2|gadget2]] as Daniel Pipkin has worked on putting one together (he's needed clarification on what parts I've been using, how to set things up, etc). Omar: I've been [[https://github.com/FolkComputer/gadget2/commits/main/|updating]] the documentation for [[https://github.com/FolkComputer/gadget2|gadget2]] as Daniel Pipkin has worked on putting one together (he's needed clarification on what parts I've been using, how to set things up, etc).
  
 +=== Fasteners ===
 +
 +Spent some time looking into fasteners to try to keep the AnyBeam projector from swiveling/wiggling inside the gadget chassis. (because it's only attached by a single 1/4in bolt, because that's the only mount point in the projector)
 +
 +I got some threadlocker glue, and these washers, which I haven't gotten to try yet:
 +
 +{{:newsletters:pasted:img_3339.jpeg?250px}}
 +
 +=== folk2 on the gadget ===
 +
 +folk2 is a surprisingly nice improvement for the gadget. The text is scaled to be a constant real-world size no matter where you hold the gadget, and the whole critical path of Folk runs faster, so even on this mediocre calibration, it's easier to see how it's doing the same thing as the table:
 +
 +{{:newsletters:pasted:20250901-013703.mp4}}
 +
 +It's hacky and not 100% correct, but to give you an idea of the differences, I have this setup.folk to handle the trigger button and work on both folk1 and folk2:
 +
 +<details>
 +<summary>setup.folk</summary>
 +<code>
 +# Copy this file to ~/folk-live/setup.folk and edit it to make
 +# changes.
 +
 +if {[llength [info commands Assert!]] == 0} {
 +    # We're on folk1.
 +    proc Assert! args { tailcall Assert {*}$args }
 +
 +    set fd [open |[list python3 "/home/folk/UPS_Module_3S_Code/RaspberryPi/UPS Module 3S/INA219.py"] r]
 +    fconfigure $fd -buffering line
 +    fileevent $fd readable [list apply {{fd} {
 +        if {[gets $fd line] < 0} {
 +            if {[eof $fd]} {
 +                close $fd
 +            }
 +        }
 +
 +        if {[regexp {Percent:\s*([0-9\.]+)%} $line -> percent]} {
 +            Hold battery {Claim the battery percentage is $percent}
 +        }
 +    }} $fd]
 +
 +    When display /disp/ has width /w/ height /h/ {
 +        When the button is /state/ {
 +            When the clock time is /t/ {
 +                set color [expr {$state eq "pressed" ? "green" : "white"}]
 +                Wish to draw a dashed stroke with points \
 +                    [list [list 0 0] \
 +                         [list $w 0] \
 +                         [list $w $h] \
 +                         [list 0 $h] \
 +                         [list 0 0]] \
 +                    color $color width 10 dashlength 40 dashoffset [expr {fmod($t, 10)*-120}]
 +            }
 +        }
 +    }
 +
 +    set cc [c create]
 +    $cc include <wiringPi.h>
 +    $cc proc gpioInit {} void {
 +        // gpio mode 16 up
 +        FOLK_ENSURE(wiringPiSetup() != -1);
 +        pinMode(16, INPUT);
 +        pullUpDnControl(16, PUD_UP);
 +    }
 +    $cc proc gpioRead {} int {
 +        // gpio read 16
 +        return digitalRead(16);
 +    }
 +
 +    c loadlib /home/folk/wiringOP/wiringPi/libwiringPi.so.2.58
 +    $cc compile
 +    exec sudo chmod 666 /dev/mem
 +
 +    gpioInit
 +    When the clock time is /t/ {
 +        set pressed [expr {![gpioRead]}]
 +        Hold button \
 +            {Claim the button is [expr {$pressed ? "pressed" : "unpressed"}]}
 +    }
 +    puts stderr READY!
 +
 +} else {
 +    # We're on folk2.
 +
 +    exec v4l2-ctl --set-ctrl auto_exposure=1
 +    exec v4l2-ctl --set-ctrl exposure_time_absolute=1500
 +
 +    When {
 +        set fd [open |[list python3 "/home/folk/UPS_Module_3S_Code/RaspberryPi/UPS Module 3S/INA219.py"] r]
 +        fconfigure $fd -buffering line
 +        while {[gets $fd line] >= 0} {
 +            if {[eof $fd]} {
 +                close $fd
 +            }
 +
 +            if {[regexp {Percent:\s*([0-9\.]+)%} $line -> percent]} {
 +                Hold! -key battery \
 +                    Claim the battery percentage is $percent
 +            }
 +        }
 +    }
 +
 +    When display /disp/ has width /w/ height /h/ {
 +        When the button is /state/ {
 +            When the clock time is /t/ {
 +                set color [expr {$state eq "pressed" ? "green" : "white"}]
 +                Wish (keep 10ms) to draw a dashed line with points \
 +                    [list [list -1 -1] \
 +                         [list 1 -1] \
 +                         [list 1 1] \
 +                         [list -1 1] \
 +                         [list -1 -1]] \
 +                    color $color width 0.05 dashlength 0.1 dashoffset [expr {fmod($t, 10)*-0.4}]
 +            }
 +        }
 +    }
 +
 +    set cc [C]
 +    $cc include <wiringPi.h>
 +    $cc proc gpioInit {} void {
 +        // gpio mode 16 up
 +        FOLK_ENSURE(wiringPiSetup() != -1);
 +        pinMode(16, INPUT);
 +        pullUpDnControl(16, PUD_UP);
 +    }
 +    $cc proc gpioRead {} int {
 +        // gpio read 16
 +        return digitalRead(16);
 +    }
 +
 +    $cc endcflags -L/home/folk/wiringOP/wiringPi -lwiringPi
 +    set gpioLib [$cc compile]
 +    exec sudo chmod 666 /dev/mem
 +
 +    $gpioLib gpioInit
 +    When the clock time is /t/ {
 +        set pressed [expr {![$gpioLib gpioRead]}]
 +        Hold! -key button \
 +            Claim the button is [expr {$pressed ? "pressed" : "unpressed"}]
 +    }
 +}
 +
 +
 +
 +Assert! $this wishes $::thisNode uses camera "/dev/video0" with \
 +    width 3200 height 1200 \
 +    crop {x 500 y 0 width 1000 height 800}
 +
 +Assert! $this wishes $::thisNode uses display 0
 +
 +
 +When the battery percentage is /percent/ {
 +    Wish to draw text with text "$percent%" x 40 y 40
 +}
 +</code>
 +</details>
 ==== Mason's type proposal ==== ==== Mason's type proposal ====
 +
 +Mason has been [[https://discord.com/channels/956758212152025098/1400736329616068631/1401261049176526848|working on]] a [[https://gist.github.com/smj-edison/473297eacdbf80e3abaad0ca86c8f776|proposal for a type system in Folk]], for things like pixels, percentages, millimeters, stuff like that.
 +
 +{{newsletters:ff2f056b-ee9c-42df-9f2c-3aa107c0926b-84977-000007dcbb110ba9.png?440px}}
 ==== Projects ==== ==== Projects ====
  
-  * Rob Fielding created a full-fledged system for presenting slides that are fully controlled by programs in Folk:+  * Rob Fielding [[https://discord.com/channels/956758212152025098/956758650700046366/1402076995462107258|created a full-fledged system for presenting slides]] that are controlled by programs in Folk:
     * {{youtube>6Xy0YBTyZ3U?}}     * {{youtube>6Xy0YBTyZ3U?}}
  
Line 205: Line 372:
 ==== Outreach ==== ==== Outreach ====
  
-  * Omar hosted [[https://grjte.sh|grjte]], who'friend of a friend and has been interested in setting up a Folk instance:+  * Omar hosted his friend [[https://angeris.github.io|Guille Angeris]]'s colleague [[https://grjte.sh|grjte]], who was in New York for bit and has been interested in setting up a Folk instance:
     * {{newsletters:img_3341.jpeg?250px}}     * {{newsletters:img_3341.jpeg?250px}}
   * Andrés went to Taiwan and visited [[https://www.ultimems.com/|Ultimems]], the firm that develops the ultra-small laser projectors (the Ultimems Up projector). They were excited to hear about [[https://www.youtube.com/watch?v=hrXEtG3JILo|what we've been doing with the gadget]]. We had a great two-and-a-half hour talk walking through the use cases for Folk and our need (and gratefulness) for their small laser projectors for our work. We're excited to continue having a friendly relationship with them and maybe find space for a partnership some day.   * Andrés went to Taiwan and visited [[https://www.ultimems.com/|Ultimems]], the firm that develops the ultra-small laser projectors (the Ultimems Up projector). They were excited to hear about [[https://www.youtube.com/watch?v=hrXEtG3JILo|what we've been doing with the gadget]]. We had a great two-and-a-half hour talk walking through the use cases for Folk and our need (and gratefulness) for their small laser projectors for our work. We're excited to continue having a friendly relationship with them and maybe find space for a partnership some day.
Line 215: Line 382:
 === New installations === === New installations ===
  
-  * TODO: Fractal setup +  * The Fractal community here in Brooklyn had a "barn-raising" event to set up their Folk system. They had some trouble calibrating with their ultra-short-throw projector, but there seems to be a lot of excitement there 
-  * TODO: Baltimore setup +  * [[https://github.com/FolkComputer/folk/pull/225|Mike Subelsky set up a Folk system in Baltimore]] 
-  * TODO: Cambridge setup+  * Hamish Todd has been continuing to work on his Cambridge, UK installation and was asking questions about geometry and C API in Discord
  
 ===== What we'll be up to in September ===== ===== What we'll be up to in September =====
newsletters/2025-08.1756593920.txt.gz · Last modified: 2025/08/30 22:45 by osnr

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki