From 7655447233d2f068134e9df9ac71d42da652dd66 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Thu, 1 Oct 2026 00:26:14 -0400 Subject: [PATCH] T3: golden-image tests for the renderer + GPU parity; fix stale GPU uploads crates/golden (test-only, L3): nine procedural 320x180 scenes (transform and opacity, blend modes, Gaussian Blur, Lumetri basic, Crop, Cross Dissolve / Dip to Black / Wipe mid-transition, timecode/clip-name text) rendered on the CPU and compared with committed goldens (PSNR >= 45 dB, max <= 12, p99 <= 2); FILMCRAFT_BLESS=1 regenerates them with attribution sidecars. testkit::golden adds PNG I/O, diff metrics and failure images. The same scenes are composited on the GPU and compared with the CPU. GPU parity exposed a real bug: GpuCompositor cached uploads by pixel-buffer address without owning the buffer, so a new frame allocated at a freed frame's address was drawn with a stale texture (whole wrong frames, PSNR ~12 dB). The cache now keeps the buffer alive; regression test upload_cache_keeps_buffers_alive. Co-Authored-By: Claude Opus 5.5 --- ATTRIBUTION.md | 18 + Cargo.lock | 15 + crates/golden/Cargo.toml | 26 ++ crates/golden/goldens/blend_modes.png | Bin 0 -> 37912 bytes .../goldens/blend_modes.png.attribution | 8 + crates/golden/goldens/crop.png | Bin 0 -> 7677 bytes crates/golden/goldens/crop.png.attribution | 8 + crates/golden/goldens/gaussian_blur.png | Bin 0 -> 7937 bytes .../goldens/gaussian_blur.png.attribution | 8 + crates/golden/goldens/lumetri_basic.png | Bin 0 -> 25016 bytes .../goldens/lumetri_basic.png.attribution | 8 + crates/golden/goldens/text_burnin.png | Bin 0 -> 4528 bytes .../goldens/text_burnin.png.attribution | 8 + crates/golden/goldens/transform_opacity.png | Bin 0 -> 26637 bytes .../goldens/transform_opacity.png.attribution | 8 + .../goldens/transition_cross_dissolve.png | Bin 0 -> 29914 bytes .../transition_cross_dissolve.png.attribution | 8 + .../goldens/transition_dip_to_black.png | Bin 0 -> 17162 bytes .../transition_dip_to_black.png.attribution | 8 + crates/golden/goldens/transition_wipe.png | Bin 0 -> 26976 bytes .../goldens/transition_wipe.png.attribution | 8 + crates/golden/src/lib.rs | 8 + crates/golden/tests/golden.rs | 345 ++++++++++++++++++ crates/gpu/src/lib.rs | 11 +- crates/gpu/src/tests.rs | 18 + crates/testkit/src/golden.rs | 344 +++++++++++++++++ crates/testkit/src/lib.rs | 3 + docs/architecture.md | 3 +- docs/testing.md | 23 +- xtask/src/main.rs | 1 + 30 files changed, 879 insertions(+), 8 deletions(-) create mode 100644 crates/golden/Cargo.toml create mode 100644 crates/golden/goldens/blend_modes.png create mode 100644 crates/golden/goldens/blend_modes.png.attribution create mode 100644 crates/golden/goldens/crop.png create mode 100644 crates/golden/goldens/crop.png.attribution create mode 100644 crates/golden/goldens/gaussian_blur.png create mode 100644 crates/golden/goldens/gaussian_blur.png.attribution create mode 100644 crates/golden/goldens/lumetri_basic.png create mode 100644 crates/golden/goldens/lumetri_basic.png.attribution create mode 100644 crates/golden/goldens/text_burnin.png create mode 100644 crates/golden/goldens/text_burnin.png.attribution create mode 100644 crates/golden/goldens/transform_opacity.png create mode 100644 crates/golden/goldens/transform_opacity.png.attribution create mode 100644 crates/golden/goldens/transition_cross_dissolve.png create mode 100644 crates/golden/goldens/transition_cross_dissolve.png.attribution create mode 100644 crates/golden/goldens/transition_dip_to_black.png create mode 100644 crates/golden/goldens/transition_dip_to_black.png.attribution create mode 100644 crates/golden/goldens/transition_wipe.png create mode 100644 crates/golden/goldens/transition_wipe.png.attribution create mode 100644 crates/golden/src/lib.rs create mode 100644 crates/golden/tests/golden.rs create mode 100644 crates/testkit/src/golden.rs diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index abe06308d..394012f27 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -23,6 +23,24 @@ iconography, images or other Adobe assets; open licences only; every asset attri | `docs/images/filmcraft-effects.png` | FilmCraft contributors | Original work: FilmCraft screenshot crop; NASA Earth Views (US Government work, public domain) | MIT OR Apache-2.0; footage public domain | | `docs/images/filmcraft-timeline.png` | FilmCraft contributors | Original work: FilmCraft UI crop; thumbnails from Night of the Living Dead (1968) and Carnival of Souls (1962), CC0 Chopin waveform | MIT OR Apache-2.0; film frames public domain | +## Golden test images + +Reference frames for the renderer golden tests (`crates/golden`), rendered by FilmCraft itself from +procedural demo footage (`crates/media/src/generators.rs`); no external media. Regenerate with +`FILMCRAFT_BLESS=1 cargo test -p filmcraft-golden`. + +| Asset | Author | Source | Licence | +|---|---|---|---| +| `crates/golden/goldens/blend_modes.png` | FilmCraft contributors | Original work: golden reference rendered by FilmCraft (crates/golden/tests/golden.rs, scene `blend_modes`) from procedurally generated media | MIT OR Apache-2.0 | +| `crates/golden/goldens/crop.png` | FilmCraft contributors | Original work: golden reference rendered by FilmCraft (crates/golden/tests/golden.rs, scene `crop`) from procedurally generated media | MIT OR Apache-2.0 | +| `crates/golden/goldens/gaussian_blur.png` | FilmCraft contributors | Original work: golden reference rendered by FilmCraft (crates/golden/tests/golden.rs, scene `gaussian_blur`) from procedurally generated media | MIT OR Apache-2.0 | +| `crates/golden/goldens/lumetri_basic.png` | FilmCraft contributors | Original work: golden reference rendered by FilmCraft (crates/golden/tests/golden.rs, scene `lumetri_basic`) from procedurally generated media | MIT OR Apache-2.0 | +| `crates/golden/goldens/text_burnin.png` | FilmCraft contributors | Original work: golden reference rendered by FilmCraft (crates/golden/tests/golden.rs, scene `text_burnin`) from procedurally generated media | MIT OR Apache-2.0 | +| `crates/golden/goldens/transform_opacity.png` | FilmCraft contributors | Original work: golden reference rendered by FilmCraft (crates/golden/tests/golden.rs, scene `transform_opacity`) from procedurally generated media | MIT OR Apache-2.0 | +| `crates/golden/goldens/transition_cross_dissolve.png` | FilmCraft contributors | Original work: golden reference rendered by FilmCraft (crates/golden/tests/golden.rs, scene `transition_cross_dissolve`) from procedurally generated media | MIT OR Apache-2.0 | +| `crates/golden/goldens/transition_dip_to_black.png` | FilmCraft contributors | Original work: golden reference rendered by FilmCraft (crates/golden/tests/golden.rs, scene `transition_dip_to_black`) from procedurally generated media | MIT OR Apache-2.0 | +| `crates/golden/goldens/transition_wipe.png` | FilmCraft contributors | Original work: golden reference rendered by FilmCraft (crates/golden/tests/golden.rs, scene `transition_wipe`) from procedurally generated media | MIT OR Apache-2.0 | + ## Third-party media shown in screenshots The README screenshots show frames from these works. The media files themselves are not in the diff --git a/Cargo.lock b/Cargo.lock index c0c0ca828..9bc39411d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1451,6 +1451,21 @@ dependencies = [ "serde", ] +[[package]] +name = "filmcraft-golden" +version = "0.1.0" +dependencies = [ + "filmcraft-geom", + "filmcraft-gpu", + "filmcraft-media", + "filmcraft-project", + "filmcraft-render", + "filmcraft-testkit", + "filmcraft-time", + "pollster 0.4.0", + "wgpu", +] + [[package]] name = "filmcraft-gpu" version = "0.1.0" diff --git a/crates/golden/Cargo.toml b/crates/golden/Cargo.toml new file mode 100644 index 000000000..8ed401cb5 --- /dev/null +++ b/crates/golden/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "filmcraft-golden" +description = "Golden-image tests for the CPU renderer/compositor and GPU-vs-CPU parity (test-only crate)" +version.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true +publish = false + +[lints] +workspace = true + +# Test-only: the library is empty and everything is a dev-dependency, so the crate adds no edges +# to the layer graph. Goldens live in `goldens/` (see docs/testing.md §3). +[dependencies] + +[dev-dependencies] +filmcraft-testkit = { workspace = true } +filmcraft-time = { workspace = true } +filmcraft-geom = { workspace = true } +filmcraft-media = { workspace = true } +filmcraft-project = { workspace = true } +filmcraft-render = { workspace = true } +filmcraft-gpu = { workspace = true } +pollster = "0.4" +wgpu = { version = "30", features = ["wgsl", "metal", "vulkan", "dx12", "gles"] } diff --git a/crates/golden/goldens/blend_modes.png b/crates/golden/goldens/blend_modes.png new file mode 100644 index 0000000000000000000000000000000000000000..97ec12057ddc28d7b5f62a90dc99eb0dbfd4be4a GIT binary patch literal 37912 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 literal 0 HcmV?d00001 diff --git a/crates/golden/goldens/gaussian_blur.png.attribution b/crates/golden/goldens/gaussian_blur.png.attribution new file mode 100644 index 000000000..1e0c7bf7c --- /dev/null +++ b/crates/golden/goldens/gaussian_blur.png.attribution @@ -0,0 +1,8 @@ +asset: gaussian_blur.png +title: Gaussian Blur effect +author: FilmCraft contributors +source: original work (rendered by FilmCraft's own renderer from a procedurally generated project; no external media) +license: MIT OR Apache-2.0 +license-file: +added: 2026-10-01 by FilmCraft contributors (FILMCRAFT_BLESS=1) +notes: Golden reference image generated by crates/golden/tests/golden.rs (gaussian_blur). Regenerate with FILMCRAFT_BLESS=1. Contains no Adobe artwork. diff --git a/crates/golden/goldens/lumetri_basic.png b/crates/golden/goldens/lumetri_basic.png new file mode 100644 index 0000000000000000000000000000000000000000..7ae95cb90d0c78610517ba8581a822edf80077a3 GIT binary patch literal 25016 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

j3Q= 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 literal 0 HcmV?d00001 diff --git a/crates/golden/goldens/transform_opacity.png.attribution b/crates/golden/goldens/transform_opacity.png.attribution new file mode 100644 index 000000000..7d0e12b74 --- /dev/null +++ b/crates/golden/goldens/transform_opacity.png.attribution @@ -0,0 +1,8 @@ +asset: transform_opacity.png +title: Motion transform and opacity +author: FilmCraft contributors +source: original work (rendered by FilmCraft's own renderer from a procedurally generated project; no external media) +license: MIT OR Apache-2.0 +license-file: +added: 2026-10-01 by FilmCraft contributors (FILMCRAFT_BLESS=1) +notes: Golden reference image generated by crates/golden/tests/golden.rs (transform_opacity). Regenerate with FILMCRAFT_BLESS=1. Contains no Adobe artwork. diff --git a/crates/golden/goldens/transition_cross_dissolve.png b/crates/golden/goldens/transition_cross_dissolve.png new file mode 100644 index 0000000000000000000000000000000000000000..2ef34ac41d41d6fe1f894af98a494832afb37d83 GIT binary patch literal 29914 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 z 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 RSU~^)002ovPDHLkV1jc7UEBZw literal 0 HcmV?d00001 diff --git a/crates/golden/goldens/transition_dip_to_black.png.attribution b/crates/golden/goldens/transition_dip_to_black.png.attribution new file mode 100644 index 000000000..57ff8d19a --- /dev/null +++ b/crates/golden/goldens/transition_dip_to_black.png.attribution @@ -0,0 +1,8 @@ +asset: transition_dip_to_black.png +title: Dip to Black at 25% +author: FilmCraft contributors +source: original work (rendered by FilmCraft's own renderer from a procedurally generated project; no external media) +license: MIT OR Apache-2.0 +license-file: +added: 2026-10-01 by FilmCraft contributors (FILMCRAFT_BLESS=1) +notes: Golden reference image generated by crates/golden/tests/golden.rs (transition_dip_to_black). Regenerate with FILMCRAFT_BLESS=1. Contains no Adobe artwork. diff --git a/crates/golden/goldens/transition_wipe.png b/crates/golden/goldens/transition_wipe.png new file mode 100644 index 0000000000000000000000000000000000000000..2548e9ce91a3b232778e9ca391be880b8f47b900 GIT binary patch literal 26976 zcmV(`K-0g8P)APiFStq#OwfDI)D}ght5h6Xs~U&$p((ri>HgXuyFd0{(f>vF zQ~GF?Q){b*Q(1~Q0ZD=ugGebdBxFWT5pmDi>#g-pYrSg^=bU@v-iVvmvp7Vad(NKD z-s`u1@BH?0^_p-PS9DzKA9?dPysL}-?oIIw-%P&8)9$-_Q@qFh&v-Q#dW`cNeK?H6 z$O9Iq>hd@Kdu%qH+ZXq|09?GTdj-#V91FrZjB{KC4gkK&1MGE{i3N*W%zXps4=@Ln zT?;|jvhS8F+IFbzx8~fAb(ZIHUgH4Zt3KcqlXd6BLRj1#^dB65zhjrJ*R?O`PX~#8 zWr4Ge`zvH00DQ&A4hDv;lMr`p4%1!0{{_ouTsp

zeGo^&qGG(dT!^Pc!Zj@6pLw zhu6#I^>6>T|8<|u078AuZLuBp&F<}?cI^WGq^CQ@eh_GXCvLga)9MiqWQ9HZE3O{B ztUv8A?seQ)-F(ZdpIEj+Z(aRQWm3l3zwllUyK5sn%`wh)ipw@emw6DOulNumT9^gP z>S>q}R$*={|6Q}Cs=qT*_~;|p#{slJpuF!nAa6!jzYpU~7e2bo{_@He?f4fz_=ErH z5B}igajlnTEJ}~Cw0SeLaMtDwbMtVzC6xa(N89Ise&cP|8+M>>e{??>5S+(ZAs!t> z=qo!O>TiDYqfeYIkOOBwootMI91!=5(m0bWeNGg7>g%|`ajNqlMCdC%_O;(^=VV-z zu3>53IiY${_HL#0Z6f;oE)z}QT(CDQ5rq3UPDRZ9yrOa#S7H=n?5PJ%4mACA4zUXx z@En`l0H?dcwoAh8Tb(IpWuMu9X%)@>a$nv*#qqu$`QhLD(C?np!Qd1C#%99KK^7V+ zhTR8g|G?dt56faZjP^K#{OvY`9anKa<30p+#iPf~zL%z!iRwoXFadH~#W-?QtllPyn;3_Sa;mwH@w03XJ^j11tnz1A7A77(+KgLlTr zwM7bD{0g^z8JRq*@|?y4S{LFpR^^9&1!j4nS9_rEyV~-r&{I=IMZlt}Ed$+_l&3v_Wm!<8)8GKQD{DQM* zHDB1Azu?hd_+*50-RvAs4flMg%WwOeSfRI?c)g{liA}1B2hbb`br+obygA?a^Ds6e z&F3~uu6%n6#Fi&ApKg3Xv;IC#jQ#GM}VLh-v1DxiK;S_ zt=*NGC`b_aHe3mF8!vty>I#5+EilWQ?QuJsn{_#7{b?pb|MGGJ|Mb89nP2%2zkHEr zfCqO#IQMg9B~^6Sy(SFSq~3CXk$BPyzQ^ERnNNTiT%Ls+_OUgyzN3xW$f8=FL>ZT{GY^l)wP@NbO7Em|F%%s6u3C+ z#F_9H;+CV~*0an^Cp?AA_~NG38KXxo?vi@dkZPvLgpAK7icBFoCk5elBrn<5&J;0s zYOQn0YJHw{)-HDBE8QYO`=Bb(PCbmKKi72QnTG~gf}f#a2#U5*!Q z_ZnZzcGuqMzR%|7?dK(Y|4;wazT0n~0(-tj0FL&8u@83qirbvS_9sO10FS-LWrK;c zH%{i0e7NQFxZwG$8_ey##r+$XUd@*1Ug0vl;=)Te=x)4jeyuqTw|xIUfA63C=RZE( zzL&$5dR7a_X^%f63BZocPH|DNaFADDyZOW$pXj@OpI<&lePe+aC;u7A-lK2Af}Lqr zB3>5b=jHardwvgbmKS!4J)Y~C=3L*(9JnprV_B4K&>MECxUe|&_8;H--tYg@KlzhW zKZvb`i!WjnBH!+w8f~`yo`t;+LV-F=n2THE)Me}Q4jTOm$BWL4I1RQPF5Yt46UNmv z%*iy~IE-cNu**^d`{o0lU7>}Go;Q2Xfqv{4bI*0J15AI=&V-f4$rSeAaR$BNG;rK$ zMO#|G&RV~8zZw|lv!H-`EIZstz}oB7cnp3mVFeT&R%`4=)te_shRU3L4tq{cg5|m?qeH{xTPs3(i*qSb1K%J20C@A(w=)g$+aliRWZ^f$k;x&7rwJ=#JM< zO5**cUs{woVYCa5SM^g&-6nQ-x5H^hV{5;?|^0sZoQG%P8lx=hTT#Q zv{!)pe16JjJ8Q$+6Y!Jqp6~m4z=vZ8OsQBKYaT6{AJ?;WlU8c+-)a=Fux%3_{g9B z>FAhXZrjOm=HjLJXy{E6W{VbEm0y|FjEuo6%p)Fla}sfj^y45tV`|0)gG^}5Wnt?k z3-f8dE1u!qvg8t8f ze{h=1vY$3!!9&Gf3V_>{p|VR^*ed}}9x2q{ID4o)AK4{QF;C zJe0RST21G%5v!cb?T)P+Vb8yjlM(Fx)(`nf^crx{zIV{m!3%9jqREGXogqUo7vNZD;HjhM&^Srky(FXw%Cr zyI{LnV;qJZ_n{oe|DdfR89+O~ajSgh&|bGH_EMNR{=%Kcx!E`OlyIx?_d#n(Ox%B$j6DO?2lS*88&}~ksv)MU570uv9KTsBW|}o;iXXCth>qJ+|H*tn2B_NmL#Nz2h}q3}7mR1B3~NA^A0B;fklT)?--K z9e`;W#pZ%#7u(WP#r#4Os>!At(JwBr&B$yl*31Pc!tKnKOM=UcNbkh0M(l(UD2;(( zW&*V2h$RpJu?QvV{WWP>CIec?GX}e#jp<`-&}uKaehv%YR`AYo5#o{z+^BBT=W%Mp z!pvv)FwSW0+V1r1Ll;9rU<)Ir0w;b<2#ZOTX}o?e=aid9*i6OjvYQLu*?=w(}We(En;WY<3%us zCI1*M1zL@L*84(gm$4uAJIuw5-A9JwH-BpeFpAim-z3ccj)gHa(W=!b6h9G^gv+`v ze35k{5?gGY5`>w^@dKh06wT4Zv4I!ZM+4 z;V7T)oFF)V{o^_7Rgam=S<^RmAyI3qA)n8?!2 zM{dUuf|s(FPB*=_k?_4RpBHxC0}5vZ-8o?OeBs_h510TF&*+gE#Y;s+GLZ$@OTujE z3?^z-`VBkL(0SI#q|FH9?Pj3mx#U~_bd zVCGE6rA1saYOS(#C=^lY2JV!iXRdmB18{cdIdORFLAPS<98tHI^Z7IY z?g|a^#L3Sfi4Q`AHG;buZhj$^0pZmcG{ zvZN^F?8ucm(L#rDPPKO8fd2fEVy~xTs8zWD48b8mnSa4B zppyftDi}?8CXqNASuvUGy3CI}Rg;*-$ZtK=a`6t3a&Kjg z09EF}{|+dXHJb1>O&6?8p5*7~szh*$BJhQx3V&Zlv&U?h-PzdD-Rrwjr(B)%3 z3eHFNtuYmA_(y0At2if1&qP4a%E)_3#Pi{qXA)r-Me|eddR_qTLPy-2Va#%qJdx@U z*3VFF)Vf-gDM%t(17O8cQbQKB4kVgzeay5^SjuCAKk}nL`a8e*+iVGU54^E#JI?@A zEtF&jAz`e>Fi5R9m6TxxcwnMCZ7JeLYH0~8N>#F8i3A7MFA#MBQVSgDZGn-I*^ZVb zK}^9Q7ajKKAOOWDUL^dY^);mB>V~*AHS~G!NRfXl~9v%mRUgX znw!ip5CgTzY$iO@1YsVD$Dl#;!l%6j%S{?aF~u==2+tm z;sD=#gjK8z9Ft-g>&z5%A@iP|Q~)34b5Ryx6hc(!T2>Yop`$En4%omn&W8$<_$pBT zr%QseOjPt%3mkw7{~}4teHcsTs&}X!QY=+fQRnlO)1kr`c%3v68b&kQL}({48~I|< zo`RVY<}lpi*$i4^i?k=_2HUf!Lbn2jeU;&v4Z;?kcaMGRntn-;x&+{O++&9BM!Qv| z;>lOHs!XOJvk)o+%amdOuQ~>>`E~Pz9+Y&7HKdX@Z69@)Vx2->GGd$AV@6}U1_ywA z_MXps6g3$`ga}AJev>A8mXldH*Xt|*E}S@^)4erwHSA1G`a;5TkYJAqSfR)}b@cLc z)A?Vk8M+uN1FAcbVQCU|5vMCky-h1r1=y6~MqqBp8N9c6A6xViDVF=Z72f+ocg75c zmxgC|05}fV0Y+Z3#V8Cqt<9!V$wYr>-i`@M=`>@bGhCT9!qlB{b`*RrmN z5AsCpIy*D1E2NWm3dY#zz`>cVDh}+@8oo6Gh7AlT^$V7XP5k*~O!%PiqheW!NJaw}1n1Gi3{aR{~(d63vv3myCSgu4>X8q?t$@ z$kR-&GjAUaFomX*i(V2ojiwi@SWg{NnHjne^eoNFibnbZKVm6OmwV7uw>3= zJQgv$L;#9;0ZfTh?7aN1QEs{x#3;Hks$Ni!Kr(cU69A)2}}ZbJ~o>DVdHcBDJ`Sg-dxhM`E^K=X9PogI2{(>VtK1AOR0Z?#)=b z)(3IHY*O6t>Yoho0$`2PDA$0>PF650h7GX=!)Ca$ zs4SQZ#+~sb&EjC&pY0K*FvC;g>NF6%6mXpb@U@qKo%M171d5)%tjHm$B1mE z#^fwv5_(rXF>0Rc`3QOHm^7Z5FAa7}qhXSEp_69vWN{tBI;9Oyu7o8H31oqA3|t}^ z#qG>APU1s`83A~mw48pIO6->a12#M{3Gj4YVcf*3JJ$?723W6I4|1BM;Tnx@CrSO-FHFQPjgNsR5F z1_e5x#H0YN!g)bN5#1U2v`|Q#hQ(t9Xf@uNt5Qu?g^JCTRWaO%&=zr3jnZM3imOT5 z=PHF+l^7a>(zMyj_M8PgC6Vs<1}-yr6~HU9J7pphU@1? zM4hB}kkBr{9!++KPMQqwFz5`I1<~mp>I?@4B+2<%@hA2aR>x%c04VpFEp~YoP}2hK zE~pm8KHq=<@A}TiKlYa&C38l;@UH8E`Uea-er}dHjgmK|PG*%wP{FL|9bq_(%h#|-Sw3+aQ;0T`jP^{2h9OM6QRXv zTy^IBi{w7!;}QL`_>hmfP9$7&08Gu4Fm0bbYIG;rb3TAA4N+wfGob?+-XyS-&F~zw z8A&=owFrRfDMy@n!p15P5qcH%)v+D{kzK!}oXZc-pGP)SH#JOJL@Cp%vC5hJG2jHT zh+c9ICEZ)e*0v0-Al-=5ZK%dRBwW^+8QA&1W?fU;FuWDeFB2s9?EjS*D~V1LyC|rq z1+;-7TS^H?vWcRr=)gygfiv?;06<3XI;+jRy)ZD(HU4OZnD`M;2x!-FufS5bteJu(O><;+s*VVU z+afJDRLnB7*{fa5Ym=o^4n7IVn#XO$|9&LAXmeiBhtJQ-1*h8jVgO9hgv=5^Z#bAk z^4xtqQyrze5|m`ZNa40wR$~CO*^5NZtomg#&)^y?uvr**r3$bzaJD}m54akFnU&PE zuWnc|(q=I=s^}h>ehI*e4#SY@hAxJCW#ptz3-}#;2`4@lq zk^F`hjm@AxRE(Dc9 zn8VHY#*to$0L)eciKV1Sm!pnmh98F~v3R~Y+0RrOUh7>g~e?${j(@XLt_vICaVE4FdMfBOp$e9_T>~?odK9o z#h_BFelTxV6d%};x})f(4J?mHXc*Z7i$W1qPdPp!z$cDcDGYop&TUTWW*Setq%xBO z-9Zi*QQjL(Dl`PBv>b{mtoG*++y|k46>5bg$$JYA}iJ=ua@*)*k+uAzqSwdS&FwVEbn2daj|&?Qq2`Eck% zl0q{ND48psYf)OT?BXhrl`Y%AnA+8yp&)r<)@&VlX)t*~{?uK->S9R@bEFx}!Yl_R zfvJS_vq^20<)c)l)~W-N*x`$V0534Ix=5U7>H01eg?i2w()au(u>jBOBjKFmJ@RIv zLKFRF3@ZcYr6GoO$gd=52VvkOrPCIT=S&9f{mj$o9Z zTndJwlb}j51FWExbVaC<($%0z+nP^|e8V5b_zfp40<@&9dRc1T zpA#`870W^;qa9~t6w(?c>Z}$kmRyH?EH{)wlQZ7vMVc)cu}GtZm6{Alrx9U2pay~F zH7IY~t)O3#p@EG8Qt*n8){(H#akgW&xMiPO&)B8+>40>8o*&7JEBp;NM)o&qcc`!s3 z+9#Ed}Gq(p{lOt;4}W)xDJQ&Py)l| za)!f{T}MzK)dL^xcovNp_sVR1@Bm)Nm~}96iV_I(#Ci93eb1l$$)5^gfC;NAONW{> zN-}m*ATa~eY@;|L^0@HyBlL2BLU0Wq7{D+nfMHOf{jG0(`=>wkX(-Z6GCU_kQ4(T{ zLcGAxrEA_m(D$mz*J|VK_AAJP zl{Kls(6*pQuxhQOkg}+a@?xbqu`*4SjZzfRgsx8u0}=xhdRM?%*IFJx>g8x$OVoM; z615%ml^DR8yn6$%D_c-PI0`ty#cz~HtcATXm4J^>@=P(f07@_?u*uS;GVM(L9T?{} z;5L-jw8SY_c)DZ)3BkYAekp^c#c85gd#i$>7GugCGr?X#tcxWT{=C3=EwttEyE%tqCd$tjHCr z>2tdA>Zo72s&=*hq!nyH3!y|u!iwIcD|Jyv^iPXeSIkeck>(x31<9pEUU2oYTz*BB z6RP!OTJ{cc9$2GpYLl-P)m=Oz5>I7eK5w-5aor)qDWf+M@UlxON}cz&zx~@j{WqV9 zBa4w1uH!X1F@P1rBsWU@a~8<+G3kAh$4?O&Qm#pyC1P=FyE_Wg&`BW;F5WPC3=e) zm;uaDHY!3(Mg=b%l2bt!F6bpSm;l@E>Z87Vf*0gKUtW-1rl$sXD@A1lLn z0A4tP8o*`Hq@kF8lEs5)wp!~o3X5*&71yx>m_H!^mmUg~5+JfeP_%5Ke9i#QC>lT{ zVSX;}e8)RK`Q#^SX-F~V1=iBV#x9JVcwY{^uwW%+;Lm>g^Vvp)wMA=`ol)Ijm4O+< zr0D{SAsi*bIr*HR99d3IqBf8SOz~^^U&p|u#gvw-l)`1w42jm;j`S3Y>At=?=AtEI znoY$U&~!vAMSCPQF+x!wB*Dw<5+zqD1`Dw?@f(Znx)kF9%QhYru$@OmExG5nYRytb z_iemIuoJTFcd*a|*FGFe=a+9}0QWcy4#0WZbe3ob>@!t)FPg=LYoZStyhlvZcS9GL zfhpV}QBX#nk;oKk=`0+UKss^a0(#8AA&3(zh5hZG&`2a;YloHS}R{YVSFc%fAYXOFyAXF6EDRpII4!OPXJ7oC?eq_mW-j6 z(Tg<*o6T#SdKJxC)`hN%#~HwV3?tdtI96Cz7FPa*30S_Ow=MUgf6t*h`XQ>lUx1xz zk6PF4(p3nypfJ}Syi{^Pto6mP0d9-PM**r@msQCBgwoj3iZN+Rva}bJP*l#9~6;L<#89N0b*CVp^7i zSxktVj#rJ2Wdw$z>UZL%iZ*Z9d(FOa3u^(bQNz+N3BV*mLkadTI&cLreH2CLM-Fce z>R)C#f~@x-He&+tU;tJN8nXI9l{#Wa!5<(msuSDB!bunm*VIWI{DKVNNRDUZtCmiYKMqi5oW*+1Wm8_;wU9 z;%M1R)Cyy4;fj7WumdawK(~4m+!K&?WLsPu19zJhIUXhDh-A)QtD@0Vik(z;%Os4Q zV3^rzU@jsL5v4K_11o?*G6_im9(aCBdkOiTh2 zmYo43b41hmGa5HUr&)n#nUO4TfzX@3s@heM6bL#-UTAt+YZ$;B7a8dwsZU~CW&s`0 zb!TFRVFr$7z>}DhPJ|9-U@f#^c2c5cK9J~xX59h~y^xv!;Nnk{IEg7v6BH#S&#xGYH3w{vc?WvB$z%EsUO$F>nS|-)YfjqGARx<>pY#F)6Z08>Cf!g+b!*El49t zMllt+30#Be)RU4jz;tC>#nMq!qtEMeWvQUt|ryQg&RThc!35^Wkj^@vX zQWq(sAwhBS^TDO95d(Nw<-H^YDj$I^Mgmq!j2A@J)x;DgPA_86P7|K98Grv5s=7a z#j#dQ@*MZfQDc3)! z1g2Q+$ExJZm3>6h(c<3898OpQ=|jW1!8JH5QnM@7q1|dq1rdN5oH#jptelRUui(6H zd}_>Kcpw_^9+#Z~yaL5nD7HtQY7HkpY|v1A`d3XF?#!>jAZ)t$tna=^am-r`5ccv_UKo?@)Zi#?4q@b zWcy59l_&k)fAf>_=8yl~uTu0l86#N2*IFk+!t5?+|22~Ul=usYdP$P7Qs@@7JWtRd zpJn15i@2q6hdsDb9&l7w9dLxYSZ>eXqhLgw_uE)Gu5$x~;;rDucCFA;A?$H~CxdoS{qT%`jeRzC<#j%7-8T!`HrkE5kdm(;hXDn`b+<_8u?e@BO)- z`tZ;HDjy~Z)LCv%T1QK(k5vp8m#;X*Suhh>nhhqA4VQyR&@AqxcHYAnx)VX#!AH2) z{ado(+Pq(!L9Cae=i@%YPMTf(bWaYy?>O&!T;*w^#YBrqkx7uVfmVIcP6`TO_GDUM zWu9~yct;t)oZg-!zz_t$>TVEk=^)7okH6#XAN$NlDU@QvA}cGR8J0%%>Jec(nIbn@ zDMZqfGkO!}3Jt6L${5b_Vv?*q1u&M1iQ=b0jelg?Occq)Dmuquu_slM{YaN){x9BJ z?N+4d?bY}cR{BB#Fmr2U&kFc;le@hZ7CSt&6yXAWPn zx|c|`#Ztsulk`NsMBjnE!OXyd-pHqr1%i27eA5!rD_YgSwzQ1Hm2iG! z472+RIi&&EaBAUE?6iWKsMIkDckE})5aUc>=H|CQ{_RhF@+nXk5mPV*i&+st*p+Vu z12FWGh$IOVJdd*hsb}Gu9Y{#o1uS1!<01)yQ~)Oyp;`Ioa545d4O*Uz$(Txt&|-B2 zt7BLlRREjShYr`FG@v0_oDKE#=Kx~O&ra#3DfONYW(@y|#hhrAj)yT75s4a|kp#M8 zxGZ+8pl`^s##$DwknBWE9L6L67U!_1VhFQM!@w+mpw|JD%lF=>7RKXn3)q`)C;W_a zN57nd_!HDNVS1O|jKrxfEJAbL=bo!SNXEK~+B9V{a|*B{3scdw8A&N8CXvA9Y;h*( zE3Da%iag20BP!^X`V_r17iXDxlS-bxrXsQYoHx##PgZ3HFqvLa0;ftPK3;vq=hSJH zS}6h)qKNZU!vi#$_^=Z!_wT-o>;EGb>s9?@Yf~QFI|&V zL?{X9I-x=+@U~Q&Q0_%L>v6#hwN)9$?O1{{lkyq1o%BSt1!QD#?-6T^O?fZR#1g$* z@4c3X)*EXXI~s6d@j)G%VcA%!9drjZiv}+DOcrS^KO^XkMB_&tx9&u)QpavhakHR^ zbS%UQ)Q?z-CK9GuO9$StE|^LUHi<+cK^NHl6s3~2M0k;Q+i^rDktBOwKrGC}ivyMK z!DQWiwU(EduOemk9T6duQ%3;IX@4EE%RFCNJ}3VI@zL-v;utkHYngHhoVw7F4y$4U z`-S-x$-Eq?;1=oBum7eueficc=vQ=bsOq7bXk#)6KuyF&tLdFaDXrw{ABG`qhJiA` z)A~;STZ6E;@GS;QX)2-IY6n!~lyAfsbB~0z!&bzkl-7cFC7zMd`Vb>TASY;Q{k>6Bb5zql>PeRt3+qNI3rNrd z2PsAtiF?_SV9c_&3UdU*Ar(cFjXWJ!mnIcW033VigTTGn$cI8DI(l)rbXv@cidwKQ zH5+6!fPC>kjQP{Bp{SsypY)b zP7K^B19N_6zIg+ba0Dtj{pElBDqOz?RYVH4%v7*WHzg`cP5z~KUa<)+oy#aj^s}gj#5N zG~taBK?Qs;C95s7po`^cxo|mc5Kna&XsL5{At?AX7~7oz4JHq+nAO~s_1qdn&9~-< zuju7ZB)1SPMTVF~#6kT~NDZ{6KU;4s1FU4)x$IgCnFA{mP%3bVfGMt7_S#4toQ%NK z3CyCH#N&}Vw{R7t01amt1LyHb@HIPMxe;h2j8Gkn$m%ExfD?l{#9r#^48p)HLKF4D zu;I$i$TZ97B{i5Bn8PZ_sY3uJtvO$5%B;)gt-Q8muxBUPz?Sw%Hulhgm18yCf=Yr= zFemB2T}K9Owykk)heSG7`>U_8AF&FnXoSd~ZiRXn}U$MOfMu9n+ z=x6?Tu=**Zni^O;Kzl!yYzZ(rJK~IJ>7ebh?W-kC1D?>6Z z%|fxNj)Tdp66`tT>^E`QNSLz58ERomiQWj&x*2gDMPXcPQ=n^!f);A_zSxj0mBqZU z!tYVeXAfH2(u;wr^ahO4`r49jIg-UITjCVJ9cMD2)T&CP{buy8Sk6}wdPQn!l=zP| z2Pk8Zf*AQLk`9>03A$9^MivE@Bq$b?TSHI@S5(!Ft!T(feid1?Fks|dOAyjUTVc@} z4vRTuCAcTWp$0Qn4()0$ON{So#pP zf}i1{l%xzZd^?gROWt{CHELh|W45$SJ-%khh1wp{co<-`Wf-L{Su-5NJXqP6V8+I+ zNQM2`d$O|%ijua%KEq^6Dek#I@ag)23LNt4&5lPi87BQuoInQPfzyR}%OqYK0x(ZT zGDv|%bFpZr5EG%A=C_$K%iSuqbfRTIXn%3x_TpodTF0r*At>oW>R{EVNDMU_!b)+8 zb(!s1Y@dtl{9<~~^oMx`>w0PWAhshmjIbe?R8)47uo(;`Ll{b^pJN>6#=D+6APtob$pyys zMuUY5fXgomW{XCr0M|99^6f-IZsBeFCU+xEsWxG>wkC&pOnTm)cQDP6IXFw$xOg^< z)nxFdEYSI-(>b(ycyLQh(H9DCl`Zv+3MxBAbC?&Qv-FvUP!TIyF-HIj>yjTRiJU1R zj^cCWfWQI7nUMrn$x=fZv`%c{J)0*@==SVRVN(VY97re|F(aEmU6 zCFn{n@yGn9=!e}v<{x^dybEp2K8y&=z)}k$xtucq4`4P#X~EGTrJxvvP-tloX5|DV zW@CPJR_~2-?^CLX)%Ii|>Xw#HE7OBqAexoKivq{8Ew!F#a-kYDWMfO@qf0k(G1X(oE<&s z%8q7|#Tm%Ut3F0uFyVo`TlqKl^NYi%4$*o0Do zqc&%$`l^;0;vbq+Hydmy?hDurx4m)c z*B2#oEO3STrXk_N`A)wKngllnu&|b<88CpOG!ILK+(fnJ7$p&>2UGyl%1l%e$p<0~ zOiMBWn8N!-dO{170jrvlCE=lCrHxg-pa6~%^dxLJh~Fx3+g@d0R82KSPOLLumzu6Q z=}(KyrdrHc1zxTc2WmY-j_+r^k^s!@21VdZmWr;TxfpMeZMmXnDvWV3aaW)fOBq!G zd5|RMHA^KMu356-TA#=OR?D!Y8xJfPZ|IPNt~WZ#QM`JZu|)^ZH)^vXb2k=`kzqux zL`CR9UfIv90A6pxGJrq#o4;Or;Q%_NS9A(BbBAIOM3ZJgV>zm|xkL+KqX(1h!pYGa zlX3t`Np_fI7?l~U!f`Qzf)Ng?15;G~)`)d#{=7#qSWO08Yl`1k@kjDQs6ngYSnxR; zTb2N55x(?;%u^u%j*KoTfx-G}P*MWow}Go=XgDNuaw3ttqg*zc#(koOmlVlRAE;<& zs-p-4cV@u~oXOL3wqF7(-i*v3JQX4{Fs%`R3WW5GtDcLtu#`S%o)Aj&&Sd0TDi34Q zmeomGu5pkeDQ@H;q7Wn$r>CG)sEosZxwH*`UW~fZfg5yrF@w`a&(Wp)8O;J_3IqV8EV~Y&|qetjbCmkw?{S8QG)8uo&7iXHx!n3yfV#70)|TD zP;#VNLNZ%C%Rw|uKe@YD*X%7QJx|$}JJ?Cy94Edq2XX5ujIiecPJ6=Lqi1{yFjz<& zQi>YI5wz*3D8PKBAjxWpOG+7lDT}3_&;w)yv72BML3#`n8}n94!nQQWAdEA`?mCBqF8T4x2QPbW0K}9dF>G z*hy^P6no7kT$EQThNS{v`GHaE&WQ3Rt&E~n+vE^sBEW>}$TbEEfJFzUo1CTMltIoV zc%u{@VI7#QiDJXsi1^6?;~YepQp>=6+aPK7H7|fEk^D>~yfFYzCh-@3=l=r_(h{{^ z0_LJ|JxJw3(C$=n2Ve}^W%Ra=+#1Q@3{kZmc&N=vE%qq1rmr-{a3fcTt$DzW!iioc z4d$9!f)R3;N6x(MD806iLbKtXY5W{U1~BE#YYriMM^ZHF4p_86v=`Yt=>anX2Nr7s z_6*>R-j(Z5H<&OW?i^0V)ld&&V5D0DY%~kvj$twuGm@>>rq{}qaUD#;A?cUGyh8Ou zij8u_t-V>vjaqPGki1`M;YmU!X{clzO5{gFNp9qID_`D5=#foF;*g~^ZleSeN;Dv+ zM@rp#0dW4T=XERcz7@bI^~MOEQg2`&gl7y>Bf$aQ{FZP2{NMeZNEU4AVoiYotkp!; z9b;($G%3s0sFP2th7DMCU<;%oJC-mo8?@ZR{`(L8M!*vAYBpmZJLx^Q0BXlini?GD z&}*3uC8h$)o6=Fqy$`OEwuxs3?po@(=&9De39&J8p%{S<@%Gh9{}+e6ozxXUU4 z7OYS4Kt1+7#qma%#&$kP7&CyyP$Z6%4vP>crPZXUB8ng_-fQJX0Wd)qR)pTL0v9Hw zAr)-GWfm2FX0I`2A9j)pC$+()&@>CWNehj$u{b7;?Gme!OzusR;@=bv8N}XYW)yQS zFs-tBDb;JZbPX*$WYncV{;*d0nL6=qcny&s9|(J!O<`c3ep%}7*m=Ygvs1fhl4@{b z#A4Q>{tAIh*ySUf2!MlB0uvjK6v?LdYX&ec9iRQ|rwaoQkP3hq=vKU)yDZ@xfUOP6 zAQ)y6UehAAUcdD8Ghh0{-+BJHGc;6@S<}U==S0v{L9i?qu|pNmLPesh6kGb5X?TaG zwV^r>$LMtpXV7FbQ;8jcHpQSr>qauf;)s56E+fKA<3+*tfs=)WtDCCYqopEJ;0AJH zw2_uM51w_$01lMMYGG0xr*We8VJ}@tI2IyFid~+j0~c4N%ynX5ibz;XO`#;e1kC~%@NI8<$A9_M zXS7j?6m4u6IFUNs@!G_7HnrUO#@sL)CN!GgnJ7Cp!(ei?Re{ZLLBd8N+s-;p|6v9W zCn>EX8@YS4JeP=7Qh?RaHE4w^lmvJ(5OQ@;j-^ggpNk#*V7Y;o%~Nz>D*}iL;50A^ zZ`N4}2hmw8{h$`PMl%=-USi>1YhqNa&Dw#X0@$?S5p-*x3In$N8NBs;%Dp}b5L)rJ zb+gzREr6*d;Z~zA@_Fl9J(TnVPQCpV8ArY@i zg$)BRvU$m@V`8}?0KfT7-~72Rd>)JL1*~%p_|zw!2?@BQsUlm^ zH&%FyD^+fWv{5$FHEuR8NJHY^xY(4{T7S)KA88~U6ssk`xGa;Ou zLmPH+1u2flp0m7BC(-7Eyay|_%DpdwYb;oeSk@Cor05M}c%3qUsr+qi`Us(>GMSYV zHETDCD@iJHLqT74@J1M=oX$ZPv2Bio!S^z4E`JoRQ6SqyDutOq=*Fv*3XHMDzd0m> z7pFaj#dK_M$RZ`5%yecse<$$y0yxiOF(8YHqO(jfzHT+UipPhnZPGP5aA{=HY(Y{2 z`XJ%M+CzmC=A{y4o>@ds4O@Wd=TBa}O6;jbg--x;Py9wB9g= z$*W6pB^kdYqbRD+DIdQ}oT#Lx_N3iKI`(ywZ7i;hf%E+;Ru@fF7{Z#Z&_iWli(?&7 zgH^;RUAh>M1Yw{m44g&)R$DX~qBqRI+)GOA%iz@a+OpY1@>rx|$F!0P!QYuDXNH8W zymQfy!SyYyCqZ12nVaSd9?w%0`LN39I6!N!Ehxhwj2Kw;+ww2K%K@wl49uYIE#OA} z)Vk0T?kWyp^$I1;f)@PxD-WcxC=Wh*5g3IlV?MQJfgS-*U}T$6Pp0A7=^eZv+zF?mUW z2i1Ysg@Ku)WC5cnq@>js(HK}+QJXX{`~<*R4+R2nDqV}QT22$K4rIp?1{N1Jvc$r7 zf&olHasq9cl2RA|Ymp09sSUs*DVkluTHP*Kz*tc*wR!T4CAoP65O88ucB#E%&>}Q; z=bE|SRFXN`*8I*cvFnD64j2s8%IT{Ky*ySZw7j^80XPMPOUG!k7SzBtmEU zTN49Ip<5WVBr;dVV~UnArVSagrR*Hnc%u!-qTSIIc2qO01u&&Cu~V7=oWV)0Ug*wr zPdxtk$3Ob9#sWjXXs7_z&MJcz#*H{=WTgXe?K&(|*)sR7TbVq&R7_bE3#}Cq8WA)! zlBKW1K8nO>J`B$09A<>)kNV#aKamju)5{{`HN3@B}49x%* z1`fo6+$Ip?NB`o_CEBrSY;45RPQ?K%@rk$KofpIa=JPfRQ*!IfH}&o0HS zI#S(^OM!L`*k`;tFn+&8uCTz&z7EzUwO>^L(@Siy0%lss3j<519Vu}IAcaO{V-PTL z8Bz*l=FWgDHV>B6Mo6|g{zRmSP*DLat4Gi-L<7fq4Jtx2uV)N&w0bZDGYLxoR8j`c zpeNj4^1XW_mCN7PoCm#s$R+G!NiH z!t@}>wjuY^ILN^aeQM7rxz^mIV6buNdC-=|DV`_aE!l~@UhgfAqUsDQBDzmZEhz;{d* zds#>~0yaMEz^+b^;ueu3b-BTc_4EXBd+w%M`6&bN zz=b%t+>dprkiJkP`wD=Q0+>@DqDszKIzLKOmN0NA0Ss!0k-jt{ig151QZ@v@;1x@b zehoE~!1{s?2`x96{C!l3#CEFYCCh9I6QS3K+1EFkf$xCY3d|-#8+r?*jluorVbUcS zn{sV9L)dcwZ74Lf9-}ayU3ejZ(GQe?i6lEQ*kW=yI@UE^gXqK@Qi_g9M@*W;yo_f9 za>gx4$k9dueVJi66Fsmcvr8sIZzOYo8#bVja3m2LM+{6}mX4Eg2U!a?EJ91OA`$1g zh$Xl98v~dPyc|wH5d9_wn~2Z?;1Dd$LAv}H1B;lz4E(Nlz4H?ve=1+*lOO#k*974> zLtwKs!x*e8lXMbP>a1>{$ZgA_cUdadB`u%d&jaf01yd#|$)Tt1~g~GMp3j?#DE>39#SrMcWxpwuC z_M9NOz8$8}1mLg^%(?Dd84m|70G&`mtR&1Br4FrTC0kb~5EUE@Levm+`5OKS?SpGq6^5;n~lv ze+0nN$BUnLUOG116<11fNHD*&M*)sV+Ef4s$-k=r=34RW(!$uT+04LX9uo%6=kA8b zAAkI*kAH#_el}WoK$LkATxD_Mf;cQhY$T?X`;>)}osr)@`SFi)MQP~_X2BK8z@Tkv z)ax6qZ_>E-Hm{o!=wi?)1)=OP(%k|j;g2}Kwbn{#wo49h42x*t_S9kI2Ois)YFzXjd~qiNXW{)ai_qBf`udba&}9G*8!Lu3 zgwlCgLiUY}#n>+00O=ets)vJSGQ|*)4!mA7bmhh5*h!eAWC#rE*&zUHE>MzeMJq<5 zj(RDzMF37}#1aFrmC7Li51ejcrQPhei!?3*E@3$H*vCKmS6mH47&u|DVjv(EIb&c_ zA{4;vs)$m&CtAM=a#AD%FqHasT)0PT;_*=jc9(Hk%_fG)^6xFfJ(SWzu3WyQ-+;6o zl`EVLXQ+kJ)whCZ*_p(^4B*g!r<59>h`|8!1UrM|;EGAts&k|1=ei+{B;T>0Qo ztjUQzMdb}RB@iwrl=n*~H1(37)L;xeB&QkymR^q~4nP6SRp2BaPD@!KWw9CkqGMpL z3oBM=>7~P_$bpkylYvPR-wnW=wZokgHTIB1XbO);ZD4Kfd}A|13InGCV6JTmU=^w= zfHm&I*hA#dB=nmGWi~Z@mwLn8$pIob>#R067qkWy%(-N&HBxW@M)ZMMbrMeitmR3h zaEUzwXX**1#=iN5RFGDcSi)_rV%qXV)%MeFvTRvjV!gYDTnwmlsdIS zYotDl&{Eknwg8S&Mqks0q)vro-HLLmah%zQBx$H@SR$v?Ab``-P-dHnVMGDRYBnl> zwS2S$QLuM6)!L0rX=Jb*(1FmQ|{C=+V!s8Xc` zP4g_#{RP103=dk4!swT+VIVwQ&Z_zDAcZ}+^u4V$Ccf56WN0Le-U94u9u|D+2@_(3 zNpLXw(#sZKS*aMc0?K?D)KUFXSO#{f;9ML2ibKM(X3CAksw4q9;tYuP{-eIxQPGjNx*TaG+ANkm+4L;+?7w%X!a zFD|KND5(f-Mc%Baa>>_`vr2EV$Weplcd3v_Xa(70@F)n9agc;CD}a@OQR7B~QzEO2 zMI=yX$qTi!h1`gr`0@YYw|@IWAVzIB`?QpxnCqp$W+@F8j9)`=YH$&mU2aeTBNQv5 z++m!cH`L6A&~^c|(2hog9+_~9*dCT?bN)l8*@h8@3(o5aq}z$V0)UYPtL!*_jG?)> z^1%W;PEqakGyprxYHv?j2g|94uK~gmkrgxg42sofsT5a7}kF(NN6(V`a|; zFZm<^$IK<+w?XVOj1`htapK8u>3x_;&S6P-Zp?7imNuRJxQx=7qhB1rF1wvN6b4oo z#ZYQBmg2BwWsh7xqs~`u=qcer)?AVumjC_te(xXs!GGeqH?F%!5&)}kF6o4#aKfOL z7nZ0i1GBB0C!(ZNFawL5v6t%JX6qiTa-sRCG;8N<_GyYu_M_k|Z<7@q$6$+OR` zU%0)wyT%hvL*CRzXhjlvS5HC5E>25lJOW(J75}PEXwi=nT9T$sIH-6l;yt zCV=mU-uFYl_q)GejZ7LHqBeMg4wy_RhTGOM3=M!aV$=mdI*=BdR%k+;XWnpWxtTQz zfBeUP?6-dFcY+6e6|U(9z4B)K=kIyVL)TX)>-6HC;kg$!&)ix+{p`uto;~^ct#yX< zv(K+zcxiL@ZrUWP_k{-(znlhK`;H%=j@ccTO&SK#V9}al)eeX3{;Y{xTwSwdZGpu5 zNYMr%-U48(0M>Y5GhhOSVu`iFp{_z1Ncm`~m}sTalWC&Wqp78e3U>9s$%33pA45e_ zvLeTT&;U57#8JiU!ob$8Hq?0AX`pRwj}=_komSuTNp=pvO^i~p_1IzE=|-eIcG|QF z0r;bDdFcQ8nJ2ET`t^VrsLwpN&H#SqdHVO(3!B?_hs}U>Nh}tyaG>Is&0rlk+SKq2 z99jkjsP&3!$5H_zaG^Jj1CWYstgot5S7I!{8FGAVEY`A$*1XRE9NBFv0ThU?u)oVz zRpZ&52yNu8-2?&38B3LNSNYa{P;d@gV_?wu4Ue_b{ zqFYs=MYHdhjm*9V;guG?dCd4KtI*i^O#$^RChuz!M zs0GcjS?sMLXb1(*fg9(kZ$)dIL$ok`JBS`iE1IA+PO8+UfkT4Bpas9xk_?Sc(%Kjc zNtvLkS=clFKdk-l_)nK`rZfYgRYRRUDftvxY`M?OtaApKY9(-+*L3(1=y1ZJ&Y0wu z0+*UQEoFg|rK^5@^G1C8w?1;zb(wy%{G9*IRD6vjCc0}Un{?+SW$But8D)CK){AXRd6Y*}nb4O3QR8u$$4P0*0f$1T2*88dD<5h9G78;CP( z*)9Mx;Iv;d3niQ!2|xJ35B$O}{9=CdrpJzc;(g!vs)vv6o}{mS{q7gPa{J3)yZh1| z%E8EMb$*kD>aRX?_s(uEM{Wn zoqGq%-VnxBD`xL#h16)Tk*YgKa3cl|@B5)2_`To%!##q4=YB#6Z#iE5$eUi985pfC z@y7ZuQKDBD`&I0F@-Ac^&aX9>yH7rFdxq%`_`Xa4KKhn-Q|)T0?c{pMm3g2O%2mh> z24JYwvaJjehSKx`D}bA5-x;KppukaWmr|Kmx`!kL3{xAe@1oQE7k##OQ?sGCSUr!2 zdf>@*&fpbh(d*AL-fa5Y7sl8UJd>F|C%w1NERTQr)|>zL|NecCzVcdrs&`L@+jmm- zBt7@y`quNCXJ5$wuJgay5dHiMo6N>{*Mk%?JP1_1xF|1NZzv7-HZ3T>8$ zrWxTbnANK2zUMvP{gFTWa|N?D7W1tyu!;4-;PlTBTt0y}0>@f=D4nZm2kD5rBF z0V8XS4gQ)9ja2S_-^sZH7ury$trgx*S+gVy}0DR=bAF-lH7Lc4=h5S^b6ieZ=+GO6l zFM=cCdfHGER?&q#dH}$JIR|Hh=AD8H;H|t<43F|w3x1o-w|T>G3*#BU?nK61eA2?V zxO@c3EPCCe*S_^FH{baBhi*Q+%7@8h``nA!rj-^^V7m1UFXvxz-VS7&gZV+=xW-ad-Mwfv?6<$&4$?ug}uImeL>rP zDR#*L|KZEG|NhG_X~?;NI92P9wS(RDW;GuaZy-5Mw3i(mX=3%~lD zYd&1ta7uRxP2^uQyQg5D5lJVWn3|pr%hPyroaR!tBVekB?h!x>r##8@GuUI-{h<3} zKlUR}|J~=`{K&(y()x7aWdCYWk5Chfu~wd4xRL{)FVle48y>gn^e&EKMj~t{aMSpy zH3c`V8mkl>!knNvo-8;{O)a6s?r3wVZ*U5Yt;O{`l5i(TVe1*36?)5g#-M9YgL_8Z z^J+Mh9Lv*1}ilvUc{^ ze{!^Mf8({sUVZIrUq8_#tERnC4JE0)Q%cjaFc+v94%oe%01gfIaPssT@8r~WTZ*uN z%bWAlBTUS~e&5lQ4K9K(l;nXhVMQ0}KR>s&+UAt|?R&`VAAJA& z-mqSyL~(rS>D$jdck<$$QqKU}h%2lfy*9_`0NYDDpnu&vN(0NW0#v8V)CuYnRAJ($ znOOy95L*sEK~_2N{AM9cC4^J4=p`DnmkL{~(76B6-gIsCLvMOa%E)Vehsn(K-_mz& z6bsiF9C5G9K8*W5qIJeW^ynS+Ja^?3gDdRhDy24MQ~gRle$C7STwLcd%!7Qo!qiZZ zi<(lof$SLTixwZ5#9{A|uL$8_iV4TMG%q6~tYI**- z4}RbiPknNHkmhMGn{swII4?yJ{m*^wZy&^IVb{-}r|&Xu#`uPtH=^clnWtAoWmA|^ zaFuCY6h~8UZ;MyyFdpcD{;_YHAZq7hnrq=UtyDHkw#|ta{vIzHaImGEZM^AP|K2ye zM$$bwlR-sj7r&uATw^)B_7ia47JV3(X7pnd)n1Rt`A25L_m{=2ed3P1-V3L=ro)(y zY=vHLQn0!|HB_gT#&jVZ)e1cc$qKU;$-{Gb@T0dt=k}@0n?|S455^kn7F+SQf#vS?C(t)K!!q_%dy}sxRXL<(S9+h<%4|??WXlA^m+aLsUADt1shjD>Jn^2T2 zun0YuD&o8aXNA`06ja?TY3V_WfAi1(kmGR4MiHS;i8|ccI{EOFFURnHy`Z6#34Q8< zlb-{Z+|}v~-1(Slc!#!}=3!j2(Zw6Dq5s}vPnmlywGA^N#;|;f!`N?p%d3vw_r&Y3 z9rsxiKG|qRY-xy?AxbgQ)Zi%u>GA~9u+7EBYPb%Rf}3F>)8jB6)adoU_xL={=W%)r z<9ttz!@N1oxOF?-dg0_14DQxV^b^k_K*9 z6B)!A<%0H;HQAd2J;`D3lEL?+aggmcPNT-@5zU3u~yR@~wV*8_4{tl{oDb!!r# zyAC#5;1Ib?i_{dwQU!P>H6FUR<%j0zMy)PFT(*jT1*`DezTNy=sI zpMb7oAY&jJvHEARlE(pk=GxE%&69!W33u$-&x4^^H0fw#W$|NQCi z`kTLf{*V6ZE18NFz1l(8>JC;g`(y_66;MiQ(m7;E9mcti{*8~`oO>F$-D_VaTmU$O zRJ(;|?jLS50ye|l+b<5AjEBu2com{Ux$Iv$LfTw^=z9O=Z+tjwyr1~Yvrj*J2din?M|8AN9KqKY zZ1T!*emcy4a2WRmz%RXUYo=uBOqZ*s1FTF+77ZgeC!Ct0VRS(IjCOt9E3fGsvk7if z)>rOujS5^%`7o!FPFI91aL&vyMncAF#_eW(vN<`~Y}SHafrq2k3z(2nxpUTH4<3D$ z&D~{dD$(|98ws}5xemgcUjNXmUwNGW{m3Vt{_DTJl}Z_%fWFj@lQ)`_;8FLA0|{TM z0XH6bbll>nas18C7cg33N-5a$^Jmn?*?(9iy+8$Oc_C1Cs`cOfRDl9_+f$KT;Owz6 zR$}$TB;eiTu_pAc*Tb-8Gi$o4Pxm#~ZaneEH&bg^XGTt;W*wo+L#lm75q(0^?s%+2 z1i*tE{rc|hv+wN$wz(&`yTF%w`JrXnSDZiRKHvk=j>y!YDpbmPp59#Rujb2rKlXng#!4V_MYXsefFFE6h@WN z$2Ow+t~L2KNOnf!xhutgQm#zt=9-+tr`V9SDPi!1?B>*9_khnF6n%j7#f{742i~q; zp?i1mUYzEpHg(F133|f7RT;*{tmSWV!^5Hd=rA6{xU_*Bhj9)gt0qUQSQ7eqfRvS8 z4{1_Kr%5La5=XCd)hmuOq)*oA_TAy7{JOKrZ>WjkNq#@vzPmXQV;}Ep)_?6(C8N5Xyy4*h*ZVjQ z0KVd*G++)UEoV&r{a0T4uU~n|#YHwMZi%u?O_}f#bJ7IwR4KZgBls^5<6_4Fz*l^f zTz&h~Ig@;)yEamK+Agwax@nnYca$eQj0+eC0AJ-H#oWO~QPuF~68Rh&^rB1noyKE@ zg`!FORh^$+-C^A8H~{!ck6N(5*8KK0>oEAfgke(Ky{Q!Lg2LOA9I*J{#sR=rd2pzP zb$)FyJVA0(Q1&!|9EWN<4|E&=e3i$li#M+I0f91mQ;9>{gMmwY)nZ7-0}BeoN*ige8oouI6mr*R^1~HuU`M^8<~owdd{7b;noW$Uw!t@ zSDv}^%=34-IM#6IE;)how^U3Aag>TQYTm4)L~4x%>}@#@2mGGbH~{!6kLniUY|7G3 zg=+ajxPGmB%`30vKVQ1DdHUJA&pdx}cP(XSiHfuMO;zqF4l`J5Qmc&RJWs(_5AxlH z4;Z~K;{f2RJbdHWrvIRo(aEU0e%!zMmDe_05jtb|_T7z^gWm8Fv{+AYwFZJFZn7lJ z<={h824Tk5bqMabsBr-BRUR3NC!5swRBMEUXRa431?#e$ocZ>)#6lyk`uOmTRYq~& z!yS>Llj^{M-NnI*`UO{<0bo=@#ap`%Bz!+c*Y!t-yKq$pCRm@W{_aaJ{=-*a`ueS` z=&my|x#%P%`ro0L=gspkt@G=}+nd`b8%a@$UCeks>gnIUr-~`T1$%_H34C&|i|?|2 z7~^qZ;Hx|`P+z(`Y=)C;ufo=-B&kIi%$bKXlJA~mavr#pET&p&j}j7BkeB%`Lwgu1 zE#s11`2gJeI}Qwdl}Co&E3QA>_gz+WZ$7ljhUl9&RyVHq*N&-6L%)iB7rP#qX{pmn zhHEDktj%zhO0BHG%5G>nQqG1&A0T``$AN*b^2qSZ1e>MhjLZz+SHI%;ksGV*Qpy6_*n8aJqX!Y@D^?yYvbDdBU5m`K6`axs(`X1&4Vmo{j^gFK!$d_$rSWx`@|q zy|jM%)}1eZ?e^2R?q*##Git}xM6*;ZGV{Pakn{~&ZTBKbmqh!Itb{3c7+8R2VFeWhQac#pGJdGNtl?vOaw%;Uhv_hB3We8q=EO=iQ@HHwHPJ2NFJ zq+*dGAWG!Mtrt&v_5k-?l$tpM_X=JQYQ$Re_7>gIAl854PJI{`KKc+3t?#ey07x40 z82Sz#y4F8*y+1ypgrkgJDrd(D3}UHfNRt&>yQ~FkDU90wyF)0|q|>BUR@g7}>VWF= z9X%Yc4tL?Ij)#tp-tzi~``8JW-g@cetG6h0a$tjVup~hm*6_j=eCHl$=o((tUUMO@ z0pqBw5JsJ_YHgmwxUkW~(Lsv7vg6^0j^6slM{ZnOb=*NRL-(cIn=C3n^ZZHvH@lQF z_mWhMIB6-V34*0{Lud)sd6g`^f!~tEPX7;WrOLy&sL|(T`EVDm>X4j3(QNZ8!}!&& zIDSLAvEF3g5~cp$zPpif(6=>~W4O(ht^9sdnum}4NtK6dbK@|nYd7kHdcg1njUFDp zcDM^ybv!qOCqMU0$9-V44lFRH@X1&@Ed+_;h%w}^fK=sp{aPx?{aNr%IHKQiiL8wx8ZAFw)p_;44l>WHy_#f@(uo3bA*C$=3G#+oZgdIM;iWveWWqui#E8_7fW z(8cgVM;~8t<8T+Q>WCrY0E?Z*S}vXIjY15Zxp!AkhVQk~p34=>I@Gnhh|%MEINXJ+ zIw<535Ej36+qsWtksP*lPQlb}I-?BFpX)I0b@X`qPWG}V+$=u?jr2(r48W$tLHlUFdTH?t2{8KU{>fYew|t5Zn0b)V0cMJA0Ii0&{uY3 z0~X%h;kaEw^{Jh`=eg-&>^u7O{O!YCxT=Fi=%Yz+)b25pmVfB{dnv~uo$!he414nL z(g%lesYf4g93Sq&RUI+JZXJisq7Z!^a6Lf&L5}|h1DLUm&v>hs00000NkvXXu0mjf DoK&71 literal 0 HcmV?d00001 diff --git a/crates/golden/goldens/transition_wipe.png.attribution b/crates/golden/goldens/transition_wipe.png.attribution new file mode 100644 index 000000000..8ea1f4dff --- /dev/null +++ b/crates/golden/goldens/transition_wipe.png.attribution @@ -0,0 +1,8 @@ +asset: transition_wipe.png +title: Wipe at 50% +author: FilmCraft contributors +source: original work (rendered by FilmCraft's own renderer from a procedurally generated project; no external media) +license: MIT OR Apache-2.0 +license-file: +added: 2026-10-01 by FilmCraft contributors (FILMCRAFT_BLESS=1) +notes: Golden reference image generated by crates/golden/tests/golden.rs (transition_wipe). Regenerate with FILMCRAFT_BLESS=1. Contains no Adobe artwork. diff --git a/crates/golden/src/lib.rs b/crates/golden/src/lib.rs new file mode 100644 index 000000000..71c8cad0e --- /dev/null +++ b/crates/golden/src/lib.rs @@ -0,0 +1,8 @@ +//! Golden-image tests for FilmCraft's renderer (test-only crate; the library is empty). +//! +//! `tests/golden.rs` builds small procedural projects (no media files), renders one frame of each +//! through the CPU reference compositor (`filmcraft-render`) and compares it with a committed PNG +//! in `goldens/` using `filmcraft_testkit::golden`. The same scenes are composited on the GPU +//! (`filmcraft-gpu`) when an adapter is available and compared with the CPU result. +//! +//! Regenerate references with `FILMCRAFT_BLESS=1 cargo test -p filmcraft-golden`. diff --git a/crates/golden/tests/golden.rs b/crates/golden/tests/golden.rs new file mode 100644 index 000000000..ddc3da30b --- /dev/null +++ b/crates/golden/tests/golden.rs @@ -0,0 +1,345 @@ +//! Golden-image tests: procedural projects rendered through the CPU compositor and compared with +//! committed reference PNGs (`goldens/*.png`, made by this test with `FILMCRAFT_BLESS=1`), plus +//! GPU-vs-CPU parity on the same scenes when a GPU adapter is available. +//! +//! Tolerances (8-bit sRGB levels, see `filmcraft_testkit::golden`): +//! - CPU vs golden: `Tolerance::RENDER` — PSNR ≥ 45 dB, max abs ≤ 12, 99th percentile ≤ 2. +//! - GPU vs CPU: 99th percentile of the per-pixel max channel difference ≤ 6 and mean < 1.5 +//! (antialiased edges and half-float textures differ slightly; the CPU is the reference). + +use std::path::PathBuf; +use std::sync::Arc; + +use filmcraft_geom::Vec2; +use filmcraft_media::generators::GeneratorSource; +use filmcraft_media::{DemoScene, Generator, MediaSource, SharedSource}; +use filmcraft_project::{ + ClipId, EffectInstance, ItemId, ItemKind, Label, MediaClip, MediaRef, ParamValue, Project, SequenceSettings, TrackItem, TrackKind, Transition, + TransitionId, find_effect, +}; +use filmcraft_render::{RenderOptions, SourceMap, render_sequence}; +use filmcraft_testkit::golden::{Rgba8, Tolerance, assert_golden, diff}; +use filmcraft_time::{FrameRate, TICKS_PER_SECOND, Tick, TimeRange}; + +const W: u32 = 320; +const H: u32 = 180; +const RATE: FrameRate = FrameRate::FPS_24; + +/// A procedurally generated project and the frame to render. +struct Scene { + project: Project, + seq: ItemId, + sources: SourceMap, + frame: i64, +} + +struct Builder { + p: Project, + map: SourceMap, + seq: ItemId, + next_transition: u64, +} + +impl Builder { + fn new(video_tracks: usize) -> Self { + let mut p = Project::new("golden"); + let seq = p.new_sequence("golden", SequenceSettings { width: W, height: H, frame_rate: RATE, ..Default::default() }, video_tracks, 0, None); + Builder { p, map: SourceMap::default(), seq, next_transition: 1 } + } + + /// A generated media item (640×360, 24 fps, 10 s). + fn media(&mut self, g: Generator) -> ItemId { + let src = GeneratorSource::new(g, 640, 360, RATE, Tick(10 * TICKS_PER_SECOND)); + let info = src.info().clone(); + let id = self.p.add_item( + &info.name.clone(), + Label::Iris, + ItemKind::Media(MediaClip { + media: MediaRef::Generator(src.generator.clone()), + info, + interpret: Default::default(), + mark_in: None, + mark_out: None, + markers: vec![], + offline: false, + proxy: None, + }), + None, + ); + self.map.0.insert(id, Arc::new(src) as SharedSource); + id + } + + fn demo(&mut self, scene: DemoScene) -> ItemId { + self.media(Generator::Demo(scene)) + } + + /// Place `item` on video track `track` (frames), scaled to the frame size. + fn place(&mut self, track: usize, item: ItemId, start: i64, dur: i64) -> ClipId { + let mut ti = self.p.make_track_item(item, TrackKind::Video, RATE.tick_of(start), TimeRange::new(Tick::ZERO, RATE.tick_of(dur)), RATE).unwrap(); + ti.scale_to_frame = true; + let id = ti.id; + let s = self.p.sequence_mut(self.seq).unwrap(); + s.video_tracks[track].items.push(ti); + s.video_tracks[track].sort(); + id + } + + fn clip(&mut self, id: ClipId) -> &mut TrackItem { + self.p.sequence_mut(self.seq).unwrap().find_item_mut(id).unwrap().1 + } + + /// Set intrinsic-effect parameters (`motion`, `opacity`). + fn fixed(&mut self, id: ClipId, effect: &str, params: &[(&str, ParamValue)]) { + let e = self.clip(id).effect_mut(effect).unwrap(); + set(e, params); + } + + /// Append a standard effect with parameters. + fn effect(&mut self, id: ClipId, effect: &str, params: &[(&str, ParamValue)]) { + let mut e = find_effect(effect).unwrap_or_else(|| panic!("no effect {effect}")).instance(); + set(&mut e, params); + self.clip(id).effects.push(e); + } + + /// A transition of `dur` frames centred on the cut at `cut` between `a` and `b` on `track`. + fn transition(&mut self, track: usize, effect: &str, a: ClipId, b: ClipId, cut: i64, dur: i64) { + let id = TransitionId(self.next_transition); + self.next_transition += 1; + let tr = Transition { + id, + effect: find_effect(effect).unwrap_or_else(|| panic!("no transition {effect}")).instance(), + start: RATE.tick_of(cut - dur / 2), + duration: RATE.tick_of(dur), + from: Some(a), + to: Some(b), + align: Default::default(), + reverse: false, + }; + self.p.sequence_mut(self.seq).unwrap().video_tracks[track].transitions.push(tr); + } + + fn at(self, frame: i64) -> Scene { + Scene { project: self.p, seq: self.seq, sources: self.map, frame } + } +} + +fn set(e: &mut EffectInstance, params: &[(&str, ParamValue)]) { + let id = e.effect.clone(); + for (k, v) in params { + e.param_mut(k).unwrap_or_else(|| panic!("{id}: no param {k}")).value = v.clone(); + } +} + +fn fl(v: f64) -> ParamValue { + ParamValue::Float(v) +} + +fn pt(x: f64, y: f64) -> ParamValue { + ParamValue::Vec2(Vec2::new(x, y)) +} + +fn blend(name: &str) -> ParamValue { + ParamValue::Choice(filmcraft_project::effect::BLEND_MODES.iter().position(|b| *b == name).unwrap_or_else(|| panic!("blend {name}")) as u32) +} + +// ---- scenes ---- + +/// Motion (scale, rotation, position) and 70 % opacity over a full-frame background. +fn transform_opacity() -> Scene { + let mut b = Builder::new(2); + let bg = b.demo(DemoScene::OceanSunset); + let fg = b.demo(DemoScene::Aurora); + b.place(0, bg, 0, 48); + let top = b.place(1, fg, 0, 48); + b.fixed(top, "motion", &[("scale", fl(45.0)), ("rotation", fl(20.0)), ("position", pt(215.0, 70.0))]); + b.fixed(top, "opacity", &[("opacity", fl(70.0))]); + b.at(12) +} + +/// Four quadrant layers over a background in Multiply, Screen, Overlay and Difference. +fn blend_modes() -> Scene { + let mut b = Builder::new(5); + let bg = b.demo(DemoScene::OceanSunset); + let fg = b.demo(DemoScene::Dunes); + b.place(0, bg, 0, 48); + for (i, (mode, x, y)) in [("Multiply", 80.0, 45.0), ("Screen", 240.0, 45.0), ("Overlay", 80.0, 135.0), ("Difference", 240.0, 135.0)].into_iter().enumerate() + { + let c = b.place(i + 1, fg, 0, 48); + b.fixed(c, "motion", &[("scale", fl(50.0)), ("position", pt(x, y))]); + b.fixed(c, "opacity", &[("blend", blend(mode))]); + } + b.at(12) +} + +/// Gaussian Blur on colour bars (sharp edges show the kernel). +fn gaussian_blur() -> Scene { + let mut b = Builder::new(1); + let bars = b.media(Generator::BarsAndTone); + let c = b.place(0, bars, 0, 48); + b.effect(c, "gaussian_blur", &[("blurriness", fl(12.0))]); + b.at(12) +} + +/// Lumetri Color basic correction: temperature, exposure, contrast, highlights/shadows, saturation. +fn lumetri_basic() -> Scene { + let mut b = Builder::new(1); + let bg = b.demo(DemoScene::OceanSunset); + let c = b.place(0, bg, 0, 48); + b.effect( + c, + "lumetri", + &[ + ("temperature", fl(25.0)), + ("exposure", fl(0.6)), + ("contrast", fl(30.0)), + ("highlights", fl(-30.0)), + ("shadows", fl(25.0)), + ("saturation", fl(135.0)), + ], + ); + b.at(12) +} + +/// Crop (left/top/right/bottom) of a top layer revealing the background. +fn crop() -> Scene { + let mut b = Builder::new(2); + let bg = b.demo(DemoScene::OceanSunset); + let bars = b.media(Generator::BarsAndTone); + b.place(0, bg, 0, 48); + let c = b.place(1, bars, 0, 48); + b.effect(c, "crop", &[("left", fl(15.0)), ("top", fl(10.0)), ("right", fl(25.0)), ("bottom", fl(20.0))]); + b.at(12) +} + +/// Two clips with a 12-frame transition centred on the cut at frame 24, rendered at `frame`. +fn transition(effect: &str, frame: i64) -> Scene { + let mut b = Builder::new(1); + let a = b.demo(DemoScene::OceanSunset); + let c = b.demo(DemoScene::Aurora); + let ca = b.place(0, a, 0, 24); + let cb = b.place(0, c, 24, 24); + b.transition(0, effect, ca, cb, 24, 12); + b.at(frame) +} + +/// Timecode and Clip Name burn-ins (FilmCraft's built-in bitmap text). +fn text_burnin() -> Scene { + let mut b = Builder::new(1); + let bg = b.demo(DemoScene::CityNight); + let c = b.place(0, bg, 0, 48); + b.effect(c, "timecode", &[("position", pt(160.0, 40.0)), ("size", fl(20.0))]); + b.effect(c, "clip_name", &[("position", pt(160.0, 145.0)), ("size", fl(12.0))]); + b.at(30) +} + +/// (name, title, scene). +fn scenes() -> Vec<(&'static str, &'static str, fn() -> Scene)> { + vec![ + ("transform_opacity", "Motion transform and opacity", transform_opacity), + ("blend_modes", "Blend modes (Multiply, Screen, Overlay, Difference)", blend_modes), + ("gaussian_blur", "Gaussian Blur effect", gaussian_blur), + ("lumetri_basic", "Lumetri Color basic correction", lumetri_basic), + ("crop", "Crop effect", crop), + ("transition_cross_dissolve", "Cross Dissolve at 50%", || transition("cross_dissolve", 24)), + ("transition_dip_to_black", "Dip to Black at 25%", || transition("dip_to_black", 21)), + ("transition_wipe", "Wipe at 50%", || transition("wipe", 24)), + ("text_burnin", "Timecode and Clip Name burn-in text", text_burnin), + ] +} + +fn render_cpu(s: &Scene) -> Rgba8 { + let img = render_sequence(&s.project, s.seq, RATE.tick_of(s.frame), RenderOptions::default(), &s.sources); + Rgba8::new(img.w as u32, img.h as u32, img.over_black_rgba8()) +} + +fn golden_path(name: &str) -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("goldens").join(format!("{name}.png")) +} + +fn check(name: &str) { + let (_, title, make) = scenes().into_iter().find(|(n, _, _)| *n == name).unwrap(); + let img = render_cpu(&make()); + assert_eq!((img.w, img.h), (W, H)); + let d = assert_golden(&golden_path(name), &img, Tolerance::RENDER, title, &format!("crates/golden/tests/golden.rs ({name})")); + eprintln!("{name}: {d}"); +} + +macro_rules! goldens { + ($($name:ident),* $(,)?) => { + mod cpu { + $( + #[test] + fn $name() { + super::check(stringify!($name)); + } + )* + } + + #[test] + fn every_scene_has_a_test() { + let tested = [$(stringify!($name)),*]; + for (n, _, _) in scenes() { + assert!(tested.contains(&n), "scene {n} has no golden test"); + } + } + }; +} + +goldens!(transform_opacity, blend_modes, gaussian_blur, lumetri_basic, crop, transition_cross_dissolve, transition_dip_to_black, transition_wipe, text_burnin); + +/// Sanity: the scenes are not trivially empty or identical to each other. +#[test] +fn scenes_are_distinct() { + let imgs: Vec<(&str, Rgba8)> = scenes().into_iter().map(|(n, _, f)| (n, render_cpu(&f()))).collect(); + for (n, img) in &imgs { + let lit = img.px.chunks_exact(4).filter(|p| p[0] as u32 + p[1] as u32 + p[2] as u32 > 30).count(); + assert!(lit > img.px.len() / 4 / 4, "{n}: mostly black"); + } + for i in 0..imgs.len() { + for j in i + 1..imgs.len() { + let d = diff(&imgs[i].1, &imgs[j].1).unwrap(); + assert!(d.psnr < 30.0, "{} and {} are near-identical ({d})", imgs[i].0, imgs[j].0); + } + } +} + +// ---- GPU parity ---- + +fn device() -> Option<(wgpu::Device, wgpu::Queue)> { + let instance = wgpu::Instance::default(); + let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions::default())).ok()?; + pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor::default())).ok() +} + +#[test] +fn gpu_matches_cpu_on_golden_scenes() { + let Some((dev, q)) = device() else { + eprintln!("SKIPPED (gpu parity): no GPU adapter"); + return; + }; + let mut c = filmcraft_gpu::GpuCompositor::new(&dev, &q); + let mut failures = Vec::new(); + for (name, _, make) in scenes() { + let s = make(); + let t = RATE.tick_of(s.frame); + let cpu = render_cpu(&s); + let plan = filmcraft_render::plan::plan_frame(&s.project, s.seq, t, RenderOptions::default(), &s.sources); + let kind = if matches!(plan, filmcraft_render::plan::FramePlan::Layers { .. }) { "layers" } else { "cpu image" }; + c.composite(&plan); + let (gw, gh, mut px) = c.read_output().expect("GPU readback"); + px.chunks_exact_mut(4).for_each(|p| p[3] = 255); + let gpu = Rgba8::new(gw, gh, px); + let d = diff(&cpu, &gpu).unwrap(); + // mean over RGB only (alpha is equal by construction) + let mean_rgb = d.mean_abs * 4.0 / 3.0; + eprintln!("{name} ({kind}): GPU vs CPU {d}"); + if d.p99 > 6 || mean_rgb >= 1.5 { + let dir = filmcraft_testkit::golden::failures_dir(); + let _ = filmcraft_testkit::golden::write_png(&dir.join(format!("{name}.gpu.png")), &gpu); + let _ = filmcraft_testkit::golden::write_png(&dir.join(format!("{name}.cpu.png")), &cpu); + failures.push(format!("{name} ({kind}): {d}; images in {}", dir.display())); + } + } + assert!(failures.is_empty(), "GPU differs from the CPU reference:\n{}", failures.join("\n")); +} diff --git a/crates/gpu/src/lib.rs b/crates/gpu/src/lib.rs index 83e46f795..790861692 100644 --- a/crates/gpu/src/lib.rs +++ b/crates/gpu/src/lib.rs @@ -27,6 +27,9 @@ struct Uploaded { code_scale: f32, chroma: (u32, u32), last_used: u64, + /// The uploaded pixel buffers, kept alive while cached: the cache key is the buffer address, + /// and a freed buffer's address can be reused by a different frame (stale texture). + _pixels: PixelData, } pub struct GpuCompositor { @@ -245,12 +248,12 @@ impl GpuCompositor { let up = match &f.data { PixelData::Rgba8(d) => { let v = self.plane_texture(w, h, wgpu::TextureFormat::Rgba8UnormSrgb, d, 4); - Uploaded { views: [v, dummy(), dummy()], kind: 0, code_scale: 1.0, chroma: (w, h), last_used: self.clock } + Uploaded { views: [v, dummy(), dummy()], kind: 0, code_scale: 1.0, chroma: (w, h), last_used: self.clock, _pixels: f.data.clone() } } PixelData::RgbaF32(d) => { let half: Vec = d.iter().flat_map(|v| f32_to_f16(*v).to_le_bytes()).collect(); let v = self.plane_texture(w, h, wgpu::TextureFormat::Rgba16Float, &half, 8); - Uploaded { views: [v, dummy(), dummy()], kind: 1, code_scale: 1.0, chroma: (w, h), last_used: self.clock } + Uploaded { views: [v, dummy(), dummy()], kind: 1, code_scale: 1.0, chroma: (w, h), last_used: self.clock, _pixels: f.data.clone() } } PixelData::Yuv8 { planes, chroma, .. } => { let (sx, sy) = chroma.shifts(); @@ -258,7 +261,7 @@ impl GpuCompositor { let y = self.plane_texture(w, h, wgpu::TextureFormat::R8Unorm, &planes[0], 1); let u = self.plane_texture(cw, ch, wgpu::TextureFormat::R8Unorm, &planes[1], 1); let v = self.plane_texture(cw, ch, wgpu::TextureFormat::R8Unorm, &planes[2], 1); - Uploaded { views: [y, u, v], kind: 2, code_scale: 255.0, chroma: (cw, ch), last_used: self.clock } + Uploaded { views: [y, u, v], kind: 2, code_scale: 255.0, chroma: (cw, ch), last_used: self.clock, _pixels: f.data.clone() } } PixelData::Yuv16 { planes, chroma, bits, .. } => { let (sx, sy) = chroma.shifts(); @@ -270,7 +273,7 @@ impl GpuCompositor { let u = self.plane_texture(cw, ch, wgpu::TextureFormat::R16Float, &pu, 2); let v = self.plane_texture(cw, ch, wgpu::TextureFormat::R16Float, &pv, 2); let _ = Chroma::C420; - Uploaded { views: [y, u, v], kind: 2, code_scale: scale, chroma: (cw, ch), last_used: self.clock } + Uploaded { views: [y, u, v], kind: 2, code_scale: scale, chroma: (cw, ch), last_used: self.clock, _pixels: f.data.clone() } } }; self.uploads.insert(key, up); diff --git a/crates/gpu/src/tests.rs b/crates/gpu/src/tests.rs index 9aacbde97..f787d7056 100644 --- a/crates/gpu/src/tests.rs +++ b/crates/gpu/src/tests.rs @@ -77,3 +77,21 @@ fn half_float_conversion() { assert!((d - v).abs() <= v.abs() * 1e-3 + 1e-6, "{v} → {d}"); } } + +/// The upload cache is keyed by pixel-buffer address, so it must keep the buffer alive: otherwise +/// a new frame allocated at a freed frame's address is drawn with the stale texture (seen as +/// whole frames from a previous composite in `crates/golden` GPU parity). +#[test] +fn upload_cache_keeps_buffers_alive() { + let Some((dev, q)) = device() else { + eprintln!("no GPU adapter; skipping"); + return; + }; + let mut c = GpuCompositor::new(&dev, &q); + let px = Arc::new(vec![200u8; 16 * 8 * 4]); + let frame = Arc::new(VideoFrame { width: 16, height: 8, data: PixelData::Rgba8(px.clone()), ..(*yuv_frame(16, 8)).clone() }); + let plan = FramePlan::Layers { width: 16, height: 8, layers: vec![PlanLayer { frame, matrix: Affine::IDENTITY, opacity: 1.0 }] }; + c.composite(&plan); + drop(plan); + assert!(Arc::strong_count(&px) > 1, "cached upload must own its pixel buffer"); +} diff --git a/crates/testkit/src/golden.rs b/crates/testkit/src/golden.rs new file mode 100644 index 000000000..d79fbad02 --- /dev/null +++ b/crates/testkit/src/golden.rs @@ -0,0 +1,344 @@ +//! Golden-image testing: RGBA8 images, PNG I/O, difference metrics and reference checks. +//! +//! A golden test renders an image, then calls [`assert_golden`] with the path of a committed +//! reference PNG and a [`Tolerance`]. On mismatch the actual image and an amplified difference +//! image are written to `/target/golden-failures/` for inspection. +//! +//! `FILMCRAFT_BLESS=1` (re)writes the reference instead of comparing, plus its `.attribution` +//! sidecar when missing (AGENTS.md §1). References must be produced by FilmCraft itself (original +//! work), be small (< [`MAX_GOLDEN_BYTES`]) and be listed in `ATTRIBUTION.md`. + +use std::io::{BufReader, Cursor}; +use std::path::{Path, PathBuf}; + +/// Size limit for a committed golden PNG. +pub const MAX_GOLDEN_BYTES: u64 = 50 * 1024; + +/// An 8-bit RGBA image, row-major, no padding. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Rgba8 { + pub w: u32, + pub h: u32, + pub px: Vec, +} + +impl Rgba8 { + pub fn new(w: u32, h: u32, px: Vec) -> Self { + assert_eq!(px.len(), w as usize * h as usize * 4, "pixel buffer size"); + Self { w, h, px } + } + pub fn get(&self, x: u32, y: u32) -> [u8; 4] { + let i = (y as usize * self.w as usize + x as usize) * 4; + [self.px[i], self.px[i + 1], self.px[i + 2], self.px[i + 3]] + } + fn opaque(&self) -> bool { + self.px.chunks_exact(4).all(|p| p[3] == 255) + } +} + +/// Encode as PNG (RGB when fully opaque, else RGBA), maximum compression. +pub fn encode_png(img: &Rgba8) -> Result, String> { + let mut out = Vec::new(); + { + let mut enc = png::Encoder::new(&mut out, img.w, img.h); + let opaque = img.opaque(); + enc.set_color(if opaque { png::ColorType::Rgb } else { png::ColorType::Rgba }); + enc.set_depth(png::BitDepth::Eight); + enc.set_compression(png::Compression::High); + let mut w = enc.write_header().map_err(|e| e.to_string())?; + if opaque { + let rgb: Vec = img.px.chunks_exact(4).flat_map(|p| [p[0], p[1], p[2]]).collect(); + w.write_image_data(&rgb).map_err(|e| e.to_string())?; + } else { + w.write_image_data(&img.px).map_err(|e| e.to_string())?; + } + w.finish().map_err(|e| e.to_string())?; + } + Ok(out) +} + +/// Decode a PNG (8-bit gray/RGB/RGBA, palette expanded) to RGBA8. +pub fn decode_png(bytes: &[u8]) -> Result { + let mut dec = png::Decoder::new(BufReader::new(Cursor::new(bytes))); + dec.set_transformations(png::Transformations::EXPAND | png::Transformations::STRIP_16); + let mut r = dec.read_info().map_err(|e| e.to_string())?; + let mut buf = vec![0; r.output_buffer_size().ok_or("PNG too large")?]; + let info = r.next_frame(&mut buf).map_err(|e| e.to_string())?; + let (w, h) = (info.width, info.height); + let n = w as usize * h as usize; + let px = match info.color_type { + png::ColorType::Rgba => buf[..n * 4].to_vec(), + png::ColorType::Rgb => buf[..n * 3].chunks_exact(3).flat_map(|p| [p[0], p[1], p[2], 255]).collect(), + png::ColorType::GrayscaleAlpha => buf[..n * 2].chunks_exact(2).flat_map(|p| [p[0], p[0], p[0], p[1]]).collect(), + png::ColorType::Grayscale => buf[..n].iter().flat_map(|&g| [g, g, g, 255]).collect(), + png::ColorType::Indexed => return Err("unexpanded palette PNG".into()), + }; + Ok(Rgba8 { w, h, px }) +} + +pub fn read_png(path: &Path) -> Result { + let bytes = std::fs::read(path).map_err(|e| format!("{}: {e}", path.display()))?; + decode_png(&bytes).map_err(|e| format!("{}: {e}", path.display())) +} + +pub fn write_png(path: &Path, img: &Rgba8) -> Result { + let bytes = encode_png(img)?; + if let Some(d) = path.parent() { + std::fs::create_dir_all(d).map_err(|e| e.to_string())?; + } + std::fs::write(path, &bytes).map_err(|e| format!("{}: {e}", path.display()))?; + Ok(bytes.len() as u64) +} + +/// Per-pixel difference statistics over all four channels (8-bit levels). +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Diff { + /// Largest absolute channel difference. + pub max_abs: u8, + /// Mean absolute channel difference. + pub mean_abs: f64, + /// 99th percentile of the per-pixel maximum channel difference. + pub p99: u8, + /// PSNR in dB over all channels (`f64::INFINITY` when identical). + pub psnr: f64, + /// Pixels with any channel different. + pub differing: usize, +} + +impl std::fmt::Display for Diff { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "PSNR {:.2} dB, max {}, p99 {}, mean {:.3}, {} pixels differ", self.psnr, self.max_abs, self.p99, self.mean_abs, self.differing) + } +} + +/// Compare two images of equal size. +pub fn diff(a: &Rgba8, b: &Rgba8) -> Result { + if (a.w, a.h) != (b.w, b.h) { + return Err(format!("size {}x{} vs {}x{}", a.w, a.h, b.w, b.h)); + } + let mut hist = [0usize; 256]; + let (mut sum, mut sq, mut max, mut differing) = (0u64, 0u64, 0u8, 0usize); + for (p, q) in a.px.chunks_exact(4).zip(b.px.chunks_exact(4)) { + let mut m = 0u8; + for k in 0..4 { + let d = p[k].abs_diff(q[k]); + sum += d as u64; + sq += d as u64 * d as u64; + m = m.max(d); + } + hist[m as usize] += 1; + max = max.max(m); + differing += (m > 0) as usize; + } + let pixels = (a.w as usize * a.h as usize).max(1); + let target = (pixels * 99).div_ceil(100); + let mut acc = 0; + let mut p99 = 0u8; + for (v, n) in hist.iter().enumerate() { + acc += n; + if acc >= target { + p99 = v as u8; + break; + } + } + let n = (pixels * 4) as f64; + let mse = sq as f64 / n; + let psnr = if mse == 0.0 { f64::INFINITY } else { 10.0 * (255.0f64 * 255.0 / mse).log10() }; + Ok(Diff { max_abs: max, mean_abs: sum as f64 / n, p99, psnr, differing }) +} + +/// Acceptance thresholds; every set limit must hold. +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Tolerance { + pub min_psnr: f64, + pub max_abs: u8, + pub p99: u8, +} + +impl Tolerance { + /// Bit-exact. + pub const EXACT: Tolerance = Tolerance { min_psnr: f64::INFINITY, max_abs: 0, p99: 0 }; + /// Default for CPU renders compared with CPU-made references: absorbs float differences + /// between platforms (FMA, SIMD widths, thread scheduling of reductions) but not real changes. + pub const RENDER: Tolerance = Tolerance { min_psnr: 45.0, max_abs: 12, p99: 2 }; + + pub fn accepts(&self, d: &Diff) -> bool { + d.psnr >= self.min_psnr && d.max_abs <= self.max_abs && d.p99 <= self.p99 + } +} + +/// Whether `FILMCRAFT_BLESS` asks to regenerate references. +pub fn blessing() -> bool { + std::env::var("FILMCRAFT_BLESS").is_ok_and(|v| matches!(v.trim().to_ascii_lowercase().as_str(), "1" | "true" | "yes" | "on")) +} + +/// Where failing comparisons write `.actual.png` / `.diff.png`. +pub fn failures_dir() -> PathBuf { + crate::workspace_root().join("target").join("golden-failures") +} + +/// Difference image: |a − b| per channel ×8, opaque. +pub fn diff_image(a: &Rgba8, b: &Rgba8) -> Rgba8 { + let px = + a.px.chunks_exact(4) + .zip(b.px.chunks_exact(4)) + .flat_map(|(p, q)| { + let d = |k: usize| (p[k].abs_diff(q[k]) as u32 * 8).min(255) as u8; + let al = d(3); + [d(0).max(al), d(1).max(al), d(2).max(al), 255] + }) + .collect(); + Rgba8 { w: a.w, h: a.h, px } +} + +/// Today's date (UTC) as YYYY-MM-DD, for attribution sidecars. +fn today() -> String { + let secs = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).map(|d| d.as_secs()).unwrap_or(0); + // civil-from-days (Howard Hinnant) + let z = (secs / 86_400) as i64 + 719_468; + let era = z.div_euclid(146_097); + let doe = z - era * 146_097; + let yoe = (doe - doe / 1460 + doe / 36_524 - doe / 146_096) / 365; + let doy = doe - (365 * yoe + yoe / 4 - yoe / 100); + let mp = (5 * doy + 2) / 153; + let d = doy - (153 * mp + 2) / 5 + 1; + let m = if mp < 10 { mp + 3 } else { mp - 9 }; + let y = yoe + era * 400 + (m <= 2) as i64; + format!("{y:04}-{m:02}-{d:02}") +} + +/// The attribution sidecar text for a generated golden image. +pub fn sidecar_text(file_name: &str, title: &str, generated_by: &str) -> String { + format!( + "asset: {file_name}\n\ + title: {title}\n\ + author: FilmCraft contributors\n\ + source: original work (rendered by FilmCraft's own renderer from a procedurally generated project; no external media)\n\ + license: MIT OR Apache-2.0\n\ + license-file:\n\ + added: {} by FilmCraft contributors (FILMCRAFT_BLESS=1)\n\ + notes: Golden reference image generated by {generated_by}. Regenerate with FILMCRAFT_BLESS=1. Contains no Adobe artwork.\n", + today() + ) +} + +/// The `ATTRIBUTION.md` table row for a golden image at workspace-relative `rel`. +pub fn attribution_row(rel: &str, generated_by: &str) -> String { + format!("| `{rel}` | FilmCraft contributors | Original work: golden reference rendered by FilmCraft ({generated_by}) | MIT OR Apache-2.0 |") +} + +/// Compare `actual` with the golden PNG at `golden` (or bless it). `title` and `generated_by` +/// fill the attribution sidecar written on bless. Returns the difference on success. +pub fn check_golden(golden: &Path, actual: &Rgba8, tol: Tolerance, title: &str, generated_by: &str) -> Result { + let name = golden.file_stem().map(|s| s.to_string_lossy().to_string()).unwrap_or_default(); + if blessing() { + let size = write_png(golden, actual)?; + if size > MAX_GOLDEN_BYTES { + return Err(format!("{}: {size} bytes exceeds the {MAX_GOLDEN_BYTES}-byte golden limit; render smaller", golden.display())); + } + let side = PathBuf::from(format!("{}.attribution", golden.display())); + if !side.exists() { + let file = golden.file_name().map(|s| s.to_string_lossy().to_string()).unwrap_or_default(); + std::fs::write(&side, sidecar_text(&file, title, generated_by)).map_err(|e| e.to_string())?; + } + let root = crate::workspace_root(); + let rel = golden.strip_prefix(&root).unwrap_or(golden).to_string_lossy().replace('\\', "/"); + let index = std::fs::read_to_string(root.join("ATTRIBUTION.md")).unwrap_or_default(); + if !index.contains(&format!("`{rel}`")) { + eprintln!("golden {rel}: add this row to ATTRIBUTION.md:\n{}", attribution_row(&rel, generated_by)); + } + eprintln!("blessed {rel} ({size} bytes)"); + return Ok(Diff { max_abs: 0, mean_abs: 0.0, p99: 0, psnr: f64::INFINITY, differing: 0 }); + } + let expected = read_png(golden).map_err(|e| format!("{e}\n(missing or unreadable golden; generate it with FILMCRAFT_BLESS=1)"))?; + let d = diff(&expected, actual).map_err(|e| format!("{}: {e}", golden.display()))?; + if tol.accepts(&d) { + return Ok(d); + } + let dir = failures_dir(); + let a = dir.join(format!("{name}.actual.png")); + let _ = write_png(&a, actual); + let _ = write_png(&dir.join(format!("{name}.diff.png")), &diff_image(&expected, actual)); + Err(format!( + "{}: {d} (tolerance: PSNR ≥ {} dB, max ≤ {}, p99 ≤ {}); actual and diff written to {}", + golden.display(), + tol.min_psnr, + tol.max_abs, + tol.p99, + dir.display() + )) +} + +/// [`check_golden`] that panics on failure. +pub fn assert_golden(golden: &Path, actual: &Rgba8, tol: Tolerance, title: &str, generated_by: &str) -> Diff { + match check_golden(golden, actual, tol, title, generated_by) { + Ok(d) => d, + Err(e) => panic!("golden mismatch: {e}"), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn ramp(w: u32, h: u32, alpha: u8) -> Rgba8 { + let px = (0..w * h).flat_map(|i| [(i % w * 255 / w) as u8, (i / w * 255 / h) as u8, 77, alpha]).collect(); + Rgba8::new(w, h, px) + } + + #[test] + fn png_round_trip_rgb_and_rgba() { + for a in [255, 128] { + let img = ramp(37, 21, a); + let png = encode_png(&img).unwrap(); + assert_eq!(decode_png(&png).unwrap(), img); + } + } + + #[test] + fn diff_metrics() { + let a = ramp(10, 10, 255); + assert_eq!(diff(&a, &a).unwrap().psnr, f64::INFINITY); + let mut b = a.clone(); + b.px[0] = b.px[0].wrapping_add(10); // one channel of one pixel + let d = diff(&a, &b).unwrap(); + assert_eq!((d.max_abs, d.p99, d.differing), (10, 0, 1)); + assert!((d.mean_abs - 10.0 / 400.0).abs() < 1e-12); + let mse: f64 = 100.0 / 400.0; + assert!((d.psnr - 10.0 * (255.0f64 * 255.0 / mse).log10()).abs() < 1e-9); + assert!(Tolerance::RENDER.accepts(&d)); + assert!(!Tolerance::EXACT.accepts(&d)); + assert!(diff(&a, &ramp(10, 11, 255)).is_err()); + } + + #[test] + fn check_golden_accepts_within_tolerance_and_reports_failures() { + if blessing() { + return; + } + let dir = std::env::temp_dir().join(format!("filmcraft-testkit-golden-{}", std::process::id())); + let path = dir.join("ramp.png"); + let img = ramp(32, 16, 255); + write_png(&path, &img).unwrap(); + assert!(check_golden(&path, &img, Tolerance::EXACT, "t", "unit test").is_ok()); + let mut near = img.clone(); + near.px[5] += 1; + assert!(check_golden(&path, &near, Tolerance::RENDER, "t", "unit test").is_ok()); + let mut far = img.clone(); + far.px.iter_mut().step_by(4).for_each(|v| *v = 255 - *v); + let e = check_golden(&path, &far, Tolerance::RENDER, "t", "unit test").unwrap_err(); + assert!(e.contains("PSNR"), "{e}"); + assert!(check_golden(&dir.join("missing.png"), &img, Tolerance::RENDER, "t", "unit test").unwrap_err().contains("FILMCRAFT_BLESS")); + } + + #[test] + fn date_and_sidecar_fields() { + let t = today(); + assert_eq!(t.len(), 10); + assert!(t.starts_with("20")); + let s = sidecar_text("x.png", "X", "test y"); + for f in ["asset:", "title:", "author:", "source:", "license:", "added:"] { + assert!(s.lines().any(|l| l.starts_with(f) && l.len() > f.len() + 2), "{f}"); + } + } +} diff --git a/crates/testkit/src/lib.rs b/crates/testkit/src/lib.rs index f617e9221..4abcd3a36 100644 --- a/crates/testkit/src/lib.rs +++ b/crates/testkit/src/lib.rs @@ -4,11 +4,14 @@ //! `FILMCRAFT_REQUIRE_ORACLES=1`, fail — when they are missing ([`require_ffmpeg!`] & co.). //! - [`fixtures`]: the shared fixture directory (`/target/fixtures/`) and //! collision-free temporary names for concurrent generators. +//! - [`golden`]: RGBA8 images, PNG I/O, image-difference metrics and golden-file checks +//! (`FILMCRAFT_BLESS=1` regenerates references). //! //! ffmpeg/ffprobe are external test oracles and fixture generators only; they are never linked //! or shipped (AGENTS.md §2). pub mod fixtures; +pub mod golden; pub mod oracle; pub use fixtures::{fixtures_dir, temp_path, workspace_root}; diff --git a/docs/architecture.md b/docs/architecture.md index 5a488be55..c225ff120 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -23,7 +23,7 @@ Design principles: L6 apps/filmcraft · apps/filmcraft-cli L5 ui-egui · automation L4 engine - L3 render · gpu · export + L3 render · gpu · export · golden (test-only) L2 edit · codecs · interchange L1 frame · media · project · audio-dsp L0 foundation: time · geom · color · bitstream · testkit (dev-dependency only) @@ -55,6 +55,7 @@ and `filmcraft-cli`. | `interchange` | L2 | EDL, FCP7 XML, FCPXML and OTIO import/export (no file I/O) | | `render` | L3 | sequence evaluation, CPU compositor, video effects, transitions, audio mix | | `gpu` | L3 | wgpu compositor (WGSL) | +| `golden` | L3 | test-only: golden-image tests of the CPU renderer and GPU-vs-CPU parity; empty library, dev-dependencies only | | `export` | L3 | render → encode → mux pipeline, progress/cancel | | `engine` | L4 | `Session`, command registry, undo history, media pool, jobs, interchange glue | | `ui-egui` | L5 | the egui frontend: docking, panels, timeline, monitors, playback, control-channel handlers | diff --git a/docs/testing.md b/docs/testing.md index 6153af5e5..56fca2664 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -82,9 +82,26 @@ Each codec README has the full fixture matrix and the measured results. difference of ≤ 6 and a mean of < 1.5 (8-bit levels). It skips when no GPU adapter is available. - Effects implemented only on the CPU need no GPU test: the plan pre-renders those layers on the CPU. -- Golden-image files (rendered PNGs compared against committed references) are not used yet. If you - add them, generate the references from FilmCraft itself, give each one an attribution sidecar, - and document the tolerance (PSNR in dB, or max/percentile error). +- **Golden images** (`crates/golden`, a test-only crate): `tests/golden.rs` builds small procedural + projects (demo-generator footage, bars, no media files) at 320×180 and renders one frame of each + through the CPU compositor: Motion transform + opacity, four blend modes (Multiply, Screen, + Overlay, Difference), Gaussian Blur, Lumetri basic correction, Crop, Cross Dissolve at 50 %, Dip + to Black at 25 %, Wipe at 50 %, and Timecode / Clip Name burn-in text. Each frame is compared + with `crates/golden/goldens/.png` by `filmcraft_testkit::golden`: + **PSNR ≥ 45 dB, max abs ≤ 12, 99th-percentile per-pixel max channel difference ≤ 2** (8-bit + sRGB levels; `Tolerance::RENDER`). On failure the actual frame and a ×8 difference image go to + `/target/golden-failures/`. `scenes_are_distinct` guards against blank or duplicate + scenes. +- **Blessing:** `FILMCRAFT_BLESS=1 cargo test -p filmcraft-golden` rewrites the references (and + writes a `.attribution` sidecar for any new one; it prints the `ATTRIBUTION.md` row to add). + References are original work rendered by FilmCraft, must stay under 50 KB (enforced on bless), + and every one needs its sidecar and index row (`cargo xtask assets`). Look at a re-blessed PNG + before committing it. +- The same scenes run through `plan_frame` + `GpuCompositor` when a GPU adapter exists + (`gpu_matches_cpu_on_golden_scenes`, same p99 ≤ 6 / mean < 1.5 criterion; skipped otherwise). + This found a real bug: the GPU upload cache was keyed by pixel-buffer address without keeping + the buffer alive, so a new frame allocated at a freed frame's address was drawn with the stale + texture (fixed; regression test `upload_cache_keeps_buffers_alive`). ## 4. UI: control channel and screenshots diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 03e265913..ee24ea1e5 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -46,6 +46,7 @@ const LAYERS: &[(&str, u8)] = &[ ("interchange", 2), ("render", 3), ("gpu", 3), + ("golden", 3), ("scopes", 3), ("playback", 3), ("export", 3),