luv

Workshop wiki

tests.lisp

mcclim/tests.lisp

system luv/mcclim/test · 51 definitions · on GitHub

defpackage#:mcluv.tests
:use#:cl#:rove
:local-nicknames
#:luv#:luv
#:shader#:luv.shader
in-package#:mcluv.tests
defunkey-press
key-name&keycharactermodifiers
make-instance'luv:canvas-key-press-event:timestamp0:key-namekey-name:charactercharacter:unshifted-charactercharacter:modifiersmodifiers
deftestportable-canvas-keys-are-mcclim-gestures

Locks do not stop an application command from being an application command, while an ordinary modifier still denotes another gesture.

ok
mcluv:canvas-key-event-matches-gesture-p
key-press:i:character#\i:modifiers'
:caps-lock
'
#\i
ok
not
mcluv:canvas-key-event-matches-gesture-p
key-press:i:character#\i:modifiers'
:control
'
#\i
ok
string="Ctrl-Q"
ok
string="↑"
defmethodluv:canvas-frame-resource-key
declare
ignorecontextsurface-texture
:same-native-drawable
deftestdirect-compositor-uses-bounded-backend-frame-keys
let*
mirror
make-instance'mcluv::luv-gpu-mirror:sheetnil:targetnil:contextcontext
compositor
make-instance'mcluv:direct-gpu-mirror-compositor:mirrormirror

Fresh borrowed texture wrappers for one native drawable must address the same per-frame uniform state.

ok
eq:same-native-drawable
ok
eq:same-native-drawable
deftestsolid-vertices-carry-premultiplied-color
let*
vertices
mcluv::gpu-medium-verticesmedium
mcluv::gpu-medium-push-vertexmedium0.50.5'
0.80.40.20.25
ok
=0.25
arefvertices2
ok
=0.20
arefvertices3
ok
=0.10
arefvertices4
ok
=0.05
arefvertices5
deftestslug-vertices-carry-premultiplied-color
let
vertices
make-array0:element-type'single-float:adjustablet:fill-pointer0
mcluv::append-gpu-text-vertexvertices10010010200.25001234-1-111'
0.80.40.20.25
ok
=0.25
arefvertices2
ok
=0.20
arefvertices15
ok
=0.10
arefvertices16
ok
=0.05
arefvertices17
defunshader-output-source-value
specificationoutput
third
findoutput
mapcar#'shader:shader-statement-source-form
shader:shader-specification-statementsspecification
:key#'second
deftestsolid-and-slug-shaders-do-not-premultiply-twice
ok
equal'
shader:vec4mcluv::color-inputmcluv::alpha
dolist
ok
equal'
shader:vec4mcluv::color-input
shader:swizzlemcluv::position-alpha:z
shader-output-source-valuespecification'mcluv::render-color

The standalone solid stage names its vec4 binding COLOR. Its rgb operand is a direct input reference, not another multiplication by opacity.

let*
specification
binding
find'clim:color
shader:shader-specification-bindingsspecification
:key#'shader:shader-object-name
deftestprepared-gpu-revisions-copy-and-publish-one-cohort
let*
mirror
make-instance'mcluv::luv-gpu-mirror:sheetnil:targetnil:contextnil
source
vector1.0f02.0f03.0f0
command
mcluv::make-gpu-solid-command:first-vertex1
first
setf
arefsource0
99.0f0
ok
=1.0f0
aref
mcluv::gpu-prepared-frame-verticesfirst
0
ok
equal'
:solid
mcluv::gpu-prepared-frame-pipeline-familiesfirst
let
second
mcluv::make-gpu-mirror-prepared-revisionmirror
list
mcluv::make-gpu-prepared-text-command

A delayed older repaint cannot replace the newer publication.

ok
equal'
:text
mcluv::gpu-prepared-frame-pipeline-familiessecond
defclasscurrent-revision-preparation-probe
revisions:initformnil:accessorcurrent-revision-preparation-probe-revisions
defmethodmcluv::prepare-mirror-compositor-revision
declare
ignoremirror
pushrevision
current-revision-preparation-probe-revisionsprobe
defteststatic-gpu-mirror-prepares-its-current-revision
let*
mirror
make-instance'mcluv:luv-gpu-mirror:sheetnil:targetnil:contextnil
setf
mcluv:mirror-compositormirror
probe

Publication already prepared the semantic revision. Clear that observation to model a later frame whose McCLIM stream stayed static.

setf
current-revision-preparation-probe-revisionsprobe
nil
ok
equal
listrevision
current-revision-preparation-probe-revisionsprobe
defunmount-static-direct-preparation-probe

Give unrealized test frame one immutable direct-GPU revision and a probe.

let*
sheet
make-instance'mcluv:transparent-gpu-top-level-sheet-pane:region
clim:make-bounding-rectangle00640480
mirror
make-instance'mcluv:luv-gpu-mirror:sheetsheet:targetnil:contextnil:embedded-pt
revision
mcluv::make-gpu-mirror-prepared-revisionmirror
list
mcluv::make-gpu-solid-command
setf
slot-valueframe'clim-internals::top-level-sheet
sheet
clim:sheet-direct-mirrorsheet
mirror

Initial semantic publication has no compositor. Every later probe observation therefore belongs to the tested static refresh boundary.

setf
mcluv:mirror-compositormirror
probe
valuesproberevision
deftestconcurrent-prepared-revisions-never-cross-commands-and-bytes
let*
mirror
make-instance'mcluv::luv-gpu-mirror:sheetnil:targetnil:contextnil
threads
loopforworkerbelow4collect
sb-thread:make-thread
lambda
dotimes
let*
value
+
*worker1000
step
revision
mcluv::make-gpu-mirror-prepared-revisionmirror
list
mcluv::make-gpu-solid-command:first-vertexvalue
vector
coercevalue'single-float
mapc#'sb-thread:join-threadthreads
let*
command
first
mcluv::gpu-prepared-frame-commandsrevision
ok
=
mcluv::gpu-mirror-prepared-revision-countermirror
mcluv::gpu-prepared-frame-numberrevision
ok
=
mcluv::gpu-solid-command-first-vertexcommand
aref
mcluv::gpu-prepared-frame-verticesrevision
0
deftestdestination-frame-slots-materialize-revisions-independently
let*
mirror
make-instance'mcluv::luv-gpu-mirror:sheetnil:targetnil:contextnil
compositor
make-instance'mcluv:direct-gpu-mirror-compositor:mirrormirror
slot-a
make-instance'mcluv::direct-widget-frame-state:buffernil:shape-bind-groupnil:source-state
slot-b
make-instance'mcluv::direct-widget-frame-state:buffernil:shape-bind-groupnil:source-state
ok
eqsecond
mcluv::direct-widget-frame-prepared-revisionslot-a
ok
eqfirst
mcluv::direct-widget-frame-prepared-revisionslot-b
ok
not
eq
mcluv::direct-widget-frame-source-stateslot-a
mcluv::direct-widget-frame-source-stateslot-b
deftestlate-direct-pipeline-families-are-guarded-not-compiled
let*
mirror
make-instance'mcluv::luv-gpu-mirror:sheetnil:targetnil:contextnil
compositor
make-instance'mcluv:direct-gpu-mirror-compositor:mirrormirror
ok
zerop
hash-table-count
mcluv::direct-widget-pipelinescompositor
defclassdirect-release-probe
name:initarg:name:readerdirect-release-probe-name
events:initarg:events:readerdirect-release-probe-events
failp:initarg:failp:initformnil:readerdirect-release-probe-failp
defmethodluv:destroy
vector-push-extend
direct-release-probe-nameprobe
direct-release-probe-eventsprobe
when
direct-release-probe-failpprobe
error"scripted release failure"
probe
defunmake-direct-eviction-frame-state
eventsname&keyfail-shape-p
let
source-state
setf
mcluv::gpu-frame-state-vertex-buffersource-state
make-instance'direct-release-probe:name
listname:source
:eventsevents
make-instance'mcluv::direct-widget-frame-state:buffer
make-instance'direct-release-probe:name
listname:buffer
:eventsevents
:shape-bind-group
make-instance'direct-release-probe:name
listname:shape
:eventsevents:failpfail-shape-p
:source-statesource-state
deftestdirect-frame-key-eviction-is-complete-and-bounded
let*
events
make-array0:adjustablet:fill-pointer0
mirror
make-instance'mcluv::luv-gpu-mirror:sheetnil:targetnil:contextnil
compositor
make-instance'mcluv:direct-gpu-mirror-compositor:mirrormirror
drawable-state
setf
gethash:drawable
mcluv::direct-widget-frame-statescompositor
drawable-state

Each capture target has a fresh identity. Repeating screenshots must return every per-frame cache to the one persistent drawable slot.

dotimes
capture-index2
let*
frame-key
list:capturecapture-index
frame-state
setf
gethashframe-key
mcluv::direct-widget-frame-statescompositor
frame-state
loopfortablein
list
mcluv::direct-widget-text-bind-groupscompositor
mcluv::direct-widget-image-bind-groupscompositor
mcluv::direct-widget-lattice-bind-groupscompositor
forkindin'
:text:image:lattice
do
setf
gethash
listkindframe-state
table
make-instance'direct-release-probe:name
listframe-keykind
:eventsevents
ok
eqcompositor
ok
=1
hash-table-count
mcluv::direct-widget-frame-statescompositor
dolist
table
list
mcluv::direct-widget-text-bind-groupscompositor
mcluv::direct-widget-image-bind-groupscompositor
mcluv::direct-widget-lattice-bind-groupscompositor
ok
zerop
hash-table-counttable

Retrying cleanup cannot release wrappers a second time.

let
release-count
lengthevents
ok
=release-count
lengthevents

A failing native wrapper must not strand the state or prevent sibling resources from being released, and a retry remains a no-op.

let*
frame-key'
:capture:failing
frame-state
make-direct-eviction-frame-stateeventsframe-key:fail-shape-pt
image-group
make-instance'direct-release-probe:name
listframe-key:image
:eventsevents
setf
gethashframe-key
mcluv::direct-widget-frame-statescompositor
frame-state
gethash
list:imageframe-state
mcluv::direct-widget-image-bind-groupscompositor
image-group
ok
=1
hash-table-count
mcluv::direct-widget-frame-statescompositor
ok
zerop
hash-table-count
mcluv::direct-widget-image-bind-groupscompositor
let
release-count
lengthevents
ok
=release-count
lengthevents
ok
eqdrawable-state
gethash:drawable
mcluv::direct-widget-frame-statescompositor

The two complete capture cohorts contribute six releases each; the deliberately failing cohort still attempts all four of its resources.

ok
=16
lengthevents
deftestdirect-compositor-release-is-exhaustive-and-idempotent
let*
events
make-array0:adjustablet:fill-pointer0
mirror
make-instance'mcluv::luv-gpu-mirror:sheetnil:targetnil:contextnil
compositor
make-instance'mcluv:direct-gpu-mirror-compositor:mirrormirror
setf
mcluv::direct-widget-resourcescompositor
list
make-instance'direct-release-probe:name:first:eventsevents
make-instance'direct-release-probe:name:failing:eventsevents:failpt
make-instance'direct-release-probe:name:last:eventsevents
ok
=3
lengthevents
ok
find:firstevents
ok
find:failingevents
ok
find:lastevents
ok
null
mcluv::direct-widget-resourcescompositor

Logical ownership was detached before the error; retry is a no-op.

ok
=3
lengthevents
deftestthe-unqualified-luv-port-is-direct-gpu
multiple-value-bind
classtransform
ok
eq'identitytransform
multiple-value-bind
classtransform
ok
eq'identitytransform
defmethodmcluv::rebase-gpu-command
declare
ignoreoffsets
command
defmethodmcluv::prepare-gpu-command
mirrorframe-build
declare
ignoremirrorframe-build
command
defmethodmcluv::gpu-command-clip
protocol-test-gpu-command-clipcommand
defmethodmcluv::encode-gpu-command
passframe-state
listcommandpassframe-state
defclassgpu-command-spy-encoder
commands:initformnil:accessorgpu-command-spy-commands
defmethodluv:encode
pushcommand
gpu-command-spy-commandsencoder
encoder
deftestgpu-command-phases-are-an-open-command-grain-protocol
let
command
make-protocol-test-gpu-command:clip'
1234
ok
eqcommand
ok
eqcommand
ok
equal'
1234
ok
equal
listcommand:pass:frame-state
mcluv::encode-gpu-commandcommand:pass:frame-state
deftestbuilt-in-gpu-commands-rebase-their-own-dense-stream
let*
offsets
mcluv::make-gpu-command-offsets:vertex10:analytic20:relief30:gradient40:image50
solid
mcluv::rebase-gpu-command
mcluv::make-gpu-solid-command:first-vertex1:vertex-count6:clip'
1234
offsets
analytic
mcluv::rebase-gpu-command
mcluv::make-gpu-analytic-command:first-vertex2
offsets
lattice
mcluv::rebase-gpu-command
mcluv::make-gpu-lattice-command:modules:modules:first-vertex3
offsets
relief
mcluv::rebase-gpu-command
mcluv::make-gpu-relief-analytic-command:first-vertex4
offsets
gradient
mcluv::rebase-gpu-command
mcluv::make-gpu-gradient-analytic-command:first-vertex5
offsets
design
list:design
image
mcluv::rebase-gpu-command
mcluv::make-gpu-image-command:designdesign:first-vertex6
offsets
text
mcluv::make-gpu-text-command
ok
=11
mcluv::gpu-solid-command-first-vertexsolid
ok
=6
mcluv::gpu-solid-command-vertex-countsolid
ok
ok
=22
mcluv::gpu-analytic-command-first-vertexanalytic
ok
=23
mcluv::gpu-lattice-command-first-vertexlattice
ok
eq:modules
mcluv::gpu-lattice-command-moduleslattice
ok
=34
mcluv::gpu-relief-analytic-command-first-vertexrelief
ok
=45
mcluv::gpu-gradient-analytic-command-first-vertexgradient
ok
=56
mcluv::gpu-image-command-first-verteximage
ok
eqdesign
mcluv::gpu-image-command-designimage
ok
eqtext
deftestevery-built-in-command-has-its-required-phase-methods
let
prepare
dolist
command
list
mcluv::make-gpu-solid-command
mcluv::make-gpu-analytic-command
mcluv::make-gpu-relief-analytic-command
mcluv::make-gpu-gradient-analytic-command
mcluv::make-gpu-lattice-command
mcluv::make-gpu-image-command
mcluv::make-gpu-text-command
ok
compute-applicable-methodsprepare
listcommandnilnil
let
clip
state
make-instance'mcluv::gpu-mirror-frame-state:mirrornil
dolist
command
list
mcluv::make-gpu-solid-command
mcluv::make-gpu-analytic-command
mcluv::make-gpu-relief-analytic-command
mcluv::make-gpu-gradient-analytic-command
mcluv::make-gpu-prepared-lattice-command
mcluv::make-gpu-prepared-image-command
mcluv::make-gpu-prepared-text-command
ok
compute-applicable-methodsclip
listcommand
ok
compute-applicable-methodsencode
listcommandnilstate
deftestnative-command-encoders-map-to-their-dense-gpu-resources
let*
mirror
make-instance'mcluv:luv-gpu-mirror:sheetnil:targetnil
state
make-instance'mcluv::gpu-mirror-frame-state:mirrormirror:vertex-buffer:solid-buffer:analytic-buffer:analytic-buffer:relief-buffer:relief-buffer:gradient-buffer:gradient-buffer:image-buffer:image-buffer:text-buffer:text-buffer
lattice-paint
mcluv::make-gpu-lattice-paint:texture:lattice-texture:view:lattice-view:bind-group:lattice-bind-group
image-paint
make-instance'mcluv::gpu-cached-image-paint:texture:image-texture:view:image-view:bind-group:image-bind-group:width16:height8
atlas:text-atlas
setf
mcluv::gpu-mirror-pipelinemirror
:solid-pipeline
mcluv::gpu-mirror-analytic-pipelinemirror
:analytic-pipeline
mcluv::gpu-mirror-relief-pipelinemirror
:relief-pipeline
mcluv::gpu-mirror-gradient-analytic-pipelinemirror
:gradient-pipeline
mcluv::gpu-mirror-lattice-pipelinemirror
:lattice-pipeline
mcluv::gpu-mirror-image-pipelinemirror
:image-pipeline
mcluv::gpu-mirror-text-pipelinemirror
:text-pipeline
mcluv::gpu-mirror-bind-groupmirror
:shape-bind-group
gethashatlas
mcluv::gpu-mirror-text-bind-groupsmirror
:text-bind-group
dolist
specification
list
list
mcluv::make-gpu-solid-command:first-vertex11:vertex-count3
:solid-pipeline:shape-bind-group:solid-buffer113
list
mcluv::make-gpu-analytic-command:first-vertex22:vertex-count6
:analytic-pipeline:shape-bind-group:analytic-buffer226
list
mcluv::make-gpu-relief-analytic-command:first-vertex33:vertex-count9
:relief-pipeline:shape-bind-group:relief-buffer339
list
mcluv::make-gpu-gradient-analytic-command:first-vertex44:vertex-count12
:gradient-pipeline:shape-bind-group:gradient-buffer4412
list
mcluv::make-gpu-prepared-lattice-command:paintlattice-paint:first-vertex55:vertex-count15
:lattice-pipeline:lattice-bind-group:analytic-buffer5515
list
mcluv::make-gpu-prepared-image-command:paintimage-paint:first-vertex66:vertex-count18
:image-pipeline:image-bind-group:image-buffer6618
list
mcluv::make-gpu-prepared-text-command:atlasatlas:first-vertex77:vertex-count21
:text-pipeline:text-bind-group:text-buffer7721
destructuring-bind
commandexpected-pipelineexpected-bind-groupexpected-bufferexpected-first-vertexexpected-vertex-count
specification
let
encoder
mcluv::encode-gpu-commandcommandencoderstate
let
commands
reverse
gpu-command-spy-commandsencoder
ok
=4
lengthcommands
destructuring-bind
pipeline-commandbind-group-commandvertex-buffer-commanddraw-command
commands
ok
typeppipeline-command'luv:gpu-set-pipeline-command
ok
eqexpected-pipeline
luv::gpu-set-pipeline-command-pipelinepipeline-command
ok
typepbind-group-command'luv:gpu-set-bind-group-command
ok
zerop
luv::gpu-set-bind-group-command-indexbind-group-command
ok
eqexpected-bind-group
luv::gpu-set-bind-group-command-bind-groupbind-group-command
ok
typepvertex-buffer-command'luv:gpu-set-vertex-buffer-command
ok
zerop
luv::gpu-set-vertex-buffer-command-slotvertex-buffer-command
ok
eqexpected-buffer
luv::gpu-set-vertex-buffer-command-buffervertex-buffer-command
ok
zerop
luv::gpu-set-vertex-buffer-command-offsetvertex-buffer-command
ok
typepdraw-command'luv:gpu-draw-command
ok
=expected-vertex-count
luv::gpu-draw-command-vertex-countdraw-command
ok
=1
luv::gpu-draw-command-instance-countdraw-command
ok
=expected-first-vertex
luv::gpu-draw-command-first-vertexdraw-command
ok
zerop
luv::gpu-draw-command-first-instancedraw-command
deftestfilled-rectangles-become-one-analytic-command
let
ok
=1
length
mcluv::gpu-medium-commandsmedium
ok
typep
aref
mcluv::gpu-medium-commandsmedium
0
'mcluv::gpu-analytic-command
ok
=72
length
mcluv::gpu-medium-analytic-verticesmedium
deftestfull-ellipses-are-analytic-while-arcs-retain-the-fallback
let
clim:medium-draw-ellipse*medium8060358-5200
*2pi
t
ok
typep
aref
mcluv::gpu-medium-commandsmedium
0
'mcluv::gpu-analytic-command
clim:medium-draw-ellipse*medium8060358-5200pit
ok
find:ellipse:key
lambda
entry
getfentry:primitive
deftestroundrect-command-carries-the-semantic-radius
let
let
vertices
mcluv::gpu-medium-analytic-verticesmedium

Each vertex is position, local coordinate, half-size/radius, color.

ok
=50.0
arefvertices6
ok
=20.0
arefvertices7
ok
=12.0
arefvertices8
ok
=1
length
mcluv::gpu-medium-commandsmedium
deftestroundrect-has-a-native-mcclim-output-record
ok
find-class'mcluv::draw-analytic-rounded-rectangle-output-recordnil
ok
typep'generic-function
deftestlinear-gradient-coordinates-and-colors
let
gradient
mcluv:make-linear-gradient102011020clim:+black+clim:+white+
ok
multiple-value-bind
redgreenbluealpha
mcluv::color-rgba
mcluv::design-inkgradient6020
ok
=0.5red
ok
=0.5green
ok
=0.5blue
ok
=1.0alpha
deftestradial-gradient-coordinates
let
gradient
mcluv:make-radial-gradient506025clim:+white+clim:+black+
ok
deftestrelief-design-is-a-semantic-height-bearing-ink
let*
albedo
clim:make-rgb-color0.20.40.7
transformed
clim:transform-region
clim:make-translation-transformation1020
relief
ok
eqalbedo
ok
=6.5
ok
eqalbedo
mcluv:relief-albedotransformed
deftestrelief-roundrect-is-one-dense-analytic-command
let
setf
clim:medium-inkmedium
mcluv:make-relief-design
clim:make-rgb-color0.20.40.7
7.0
ok
=1
length
mcluv::gpu-medium-commandsmedium
ok
typep
aref
mcluv::gpu-medium-commandsmedium
0
'mcluv::gpu-relief-analytic-command

Six vertices, each containing five packed float32x3 attributes.

ok
=90
length
mcluv::gpu-medium-relief-verticesmedium
ok
=7.0
aref
mcluv::gpu-medium-relief-verticesmedium
12
ok
zerop
length
mcluv::gpu-medium-verticesmedium
ok
zerop
length
mcluv::gpu-medium-analytic-verticesmedium
deftestgradient-roundrect-is-one-dense-analytic-command
let*
gradient
mcluv:make-linear-gradient102011020clim:+black+clim:+white+
setf
clim:medium-inkmedium
gradient
ok
=1
length
mcluv::gpu-medium-commandsmedium
ok
typep
aref
mcluv::gpu-medium-commandsmedium
0
'mcluv::gpu-gradient-analytic-command

Six vertices, each containing seven packed float32x3 attributes.

ok
=126
length
mcluv::gpu-medium-gradient-verticesmedium
ok
zerop
length
mcluv::gpu-medium-verticesmedium
ok
zerop
length
mcluv::gpu-medium-analytic-verticesmedium
defuntiny-image-pattern
clim:make-pattern
make-array'
44
:element-type'
unsigned-byte32
:initial-element#xff3366cc
nil
deftestdraw-pattern-is-one-cached-image-command
let
ok
=1
length
mcluv::gpu-medium-commandsmedium
let
command
aref
mcluv::gpu-medium-commandsmedium
0
ok
eqpattern
mcluv::gpu-image-paint-source
mcluv::gpu-image-command-designcommand
ok
=72
length
mcluv::gpu-medium-image-verticesmedium
deftesttransformed-image-paint-keeps-source-and-affine-coordinates
let*
transformation
clim:make-transformation20.5-0.2534060
paint
clim:transform-regiontransformationpattern
multiple-value-bind
xy
clim:transform-positiontransformation23
multiple-value-bind
uv
ok
<
abs
-u0.5
1.0e-6
ok
<
abs
-v0.75
1.0e-6
deftestpolygons-use-native-gradient-and-image-paints
dolist
paint
list
mcluv:make-linear-gradient001000clim:+black+clim:+white+
let
setf
clim:medium-inkmedium
paint
clim:medium-draw-polygon*medium
1010902070802070
tt
ok
=1
length
mcluv::gpu-medium-commandsmedium
ok
typep
aref
mcluv::gpu-medium-commandsmedium
0
deftestcommands-retain-mcclim-clipping-for-native-scissors
let
setf
clim:medium-clipping-regionmedium
clim:make-rectangle*0.10.20.80.9
let
clip
mcluv::gpu-analytic-command-clip
aref
mcluv::gpu-medium-commandsmedium
0
okclip
ok
equal'
0.10.20.80.9
clip