nandi/jolt-nativepublic Fork 0
98daca12963d585049dc7c4cd5d6032343cc2be8
Commits
Clone
git clone https://git.rickub.com/nandi/jolt-native.git
git clone ssh://git@rickub.com/nandi/jolt-native.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Take the eight tags a client still had nowhere to put d5dfd53 · on 98daca12963d585049dc7c4cd5d6032343cc2be8 · nandi · 9d ago
video_check.clj · 81 lines · 3.9 KBClojure Blame HistoryRaw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
(ns glimmer-jvui.video-check
  "An :image node with a live :feed, painted, and the pixels checked.

  :image and not a :video tag of its own, because that is how libvidya has
  it and how frq writes it: a feed and a file differ in where the pixels
  come from and in nothing downstream of that.

  The layout tests run headless and cannot see this: with no renderer every
  frame is dropped and a video tile is an empty rectangle that lays out
  correctly. What is actually at stake is the CHANNEL ORDER — a buffer whose
  bytes run R,G,B,A is the 32-bit word 0xAABBGGRR, so SDL wants ABGR8888 and
  the obvious-looking ARGB8888 rotates every channel and turns skin blue. A
  test that only asked whether a texture existed would pass either way.

  So: a window under SDL's dummy driver, a frame with a RED left half and a
  BLUE right half, a screenshot, and a look at what came out."
  (:require [glimmer.core :as ui]
            [glimmer.ratom :as ra]
            [glimmer-jvui.core :as backend]
            [jvui.sdl :as sdl]
            [jolt.ffi :as ffi]))

(defn- red-blue
  "w by h RGBA: red left, blue right, opaque."
  [w h]
  (let [p (ffi/alloc (* 4 w h))]
    (dotimes [y h]
      (dotimes [x w]
        (let [o (* 4 (+ (* y w) x))
              left? (< x (quot w 2))]
          (ffi/write (+ p o 0) :uint8 (if left? 230 10))   ; R
          (ffi/write (+ p o 1) :uint8 10)                  ; G
          (ffi/write (+ p o 2) :uint8 (if left? 10 230))   ; B
          (ffi/write (+ p o 3) :uint8 255))))              ; A
    p))

;; A BMP from SDL is bottom-up and 24bpp, with rows padded to a four-byte
;; boundary and the pixel array offset in the header at byte 10. Every one of
;; those was got wrong first time round — 32bpp and no padding — and the
;; result was not an error but plausible-looking numbers from the wrong
;; addresses, which is exactly how a pixel test lies to you.
(defn- bmp-pixel [path x y]
  (let [b (java.nio.file.Files/readAllBytes (java.nio.file.Path/of path (into-array String [])))
        u (fn [i] (bit-and (int (aget b i)) 255))
        le (fn [i] (+ (u i) (bit-shift-left (u (+ i 1)) 8)
                      (bit-shift-left (u (+ i 2)) 16) (bit-shift-left (u (+ i 3)) 24)))
        off (le 10)
        w (le 18)
        h (le 22)
        stride (* 4 (quot (+ (* w 3) 3) 4))
        i (+ off (* (- h 1 y) stride) (* 3 x))]
    {:b (u i) :g (u (+ i 1)) :r (u (+ i 2))}))

(defn -main [& _]
  (let [px   (red-blue 64 64)
        shot (str (System/getProperty "java.io.tmpdir") "/jvui-video-check.bmp")
        n    (ra/atom 0)]
    (try
      ;; Pushed from a TIMER, which is how frq does it — av.clj drives its
      ;; whole media plane from (every! 16 pump!). Pushing from the
      ;; component body instead is what the first version of this test did,
      ;; and it silently proved nothing: a component with no state renders
      ;; once, at mount, before the window exists — so the frame was
      ;; dropped for want of a renderer and the tile was empty for a
      ;; reason that had nothing to do with the picture.
      (backend/every! 16 (fn [] (backend/frame-rgba! "peer" 64 64 px)))
      (ui/run (fn [] [:image {:feed "peer" :size [120.0 120.0]}])
              {:title "video" :width 160 :height 160 :frames 6 :shot shot})
      (finally (ffi/free px)))
    (let [left  (bmp-pixel shot 40 80)
          right (bmp-pixel shot 120 80)
          ok-l  (and (> (:r left) 150) (< (:b left) 100))
          ok-r  (and (> (:b right) 150) (< (:r right) 100))]
      (println "  left pixel " (pr-str left))
      (println "  right pixel" (pr-str right))
      (println (if ok-l "- the red half is red" "FAIL the red half is not red"))
      (println (if ok-r "- the blue half is blue" "FAIL the blue half is not blue"))
      (if (and ok-l ok-r)
        (println "all 2 checks passed")
        (do (println "channel order is wrong — see the ABGR note in jvui.sdl")
            (System/exit 1))))))