Implement renderer screenshot automation#351
Conversation
bfe47f3 to
bc10c7c
Compare
528c423 to
f28fd8f
Compare
ed8bb82 to
b29fcef
Compare
|
This has been rebased to include the changes (and notably the fidelity test) that landed in #338 |
scripts/filament-screenshot.sh
Outdated
| fi | ||
|
|
||
| if [ -z "$TMPDIR" ]; then | ||
| TMPDIR="/tmp/"; |
There was a problem hiding this comment.
mktemp -d (with a template, so it might be mktemp -d filament) will be more portable.
There was a problem hiding this comment.
Also trap "{ rm -f $TMPDIR; }" EXIT might do cleanup when the script exits (although it's not clear this is the right script, I'm still reading).
There was a problem hiding this comment.
I think (after further reading) the tension is between my suggestion of mktemp against the desire to cache a build of filament so every run (especially repeated runs while developing) don't require filament rebuilds.
One way might be to cache the temp directory locally (echo $TMPDIR > .filament-dir, and then in the check use [ -d \cat .filament-dir` ]`.
There was a problem hiding this comment.
Mmm, yeah. We could also just do as much diligence as possible and keep filament local to the project directory. That's actually how I wrote this the first time around. I'm not married to putting it in a temp directory. And yah, rebuilding it is a huge pain in the butt.
There was a problem hiding this comment.
(and by diligence, I mean maintain a persistent clone of the Filament repo and use scripts to keep it up to date over time)
There was a problem hiding this comment.
I've switched us from using a temp dir to maintaining an untracked "renderers" folder in the project repository. There is an install script that can be run to install and/or update Filament (and other renderers in the future).
scripts/filament-screenshot.sh
Outdated
| fi | ||
|
|
||
| if [ -f $SCREENSHOT_OUTPUT_PATH ]; then | ||
| rm $SCREENSHOT_OUTPUT_PATH |
There was a problem hiding this comment.
... although, given that it's a parameter that feels dangerous. This seems like an error condition, not something to fix?
There was a problem hiding this comment.
The screenshot is just a file, this might be a misleading variable name
There was a problem hiding this comment.
Is SCREENSHOT_OUTPUT_FILE okay?
scripts/render-vm-startup-script.sh
Outdated
|
|
||
| # If Filament is still around, delete it so that we are sure to build it | ||
| # cleanly from scratch | ||
| if [ -d /tmp/filament ]; then |
There was a problem hiding this comment.
I think switch to mktemp in filament-screenshot.sh means we don't need to remove filament here (although there's a chance it might exist, the trap will probably remove it and the randomness of mktemp will mean we won't use it even if it exists)
There was a problem hiding this comment.
.. assuming we go down the mktemp path of course.
There was a problem hiding this comment.
After a bit more thought.. the reason I recommended this is that it seemed like a break in the encapsulation. It'd be great if one script knew about setting up the OS (see below), one script knows about compiling filament (and how to delete it), and one script knows how to start filament and capture a screenshot.
There was a problem hiding this comment.
Sounds good. I'll refactor.
There was a problem hiding this comment.
I have split the startup script into three subscripts that cover:
- Provisioning the VM
- Installing renderers such as Filament
- Taking screenshots and producing a PR if needed
This ended up being a much better approach because - in addition to making the scripts easier to understand - the subscripts can be updated without changing the startup script configured for the VM.
| https://api.github.com/repos/googlewebcomponents/model-viewer/pulls | ||
| fi | ||
|
|
||
| sudo poweroff |
There was a problem hiding this comment.
I didn't know about poweroff! My incantation was shutdown now -h.
There was a problem hiding this comment.
I was taught that poweroff was the clean way, but after reading the manpage for shutdown I wonder if that makes me a bad person:
The shutdown utility provides an automated shutdown procedure for super-users to nicely notify users when the system is shutting down, saving them from system administrators, hackers, and gurus, who would otherwise not bother with such niceties.
There was a problem hiding this comment.
Haha. Well, not with now - it sends a notification, but there's no time to respond to it.
scripts/update-screenshots.js
Outdated
| * limitations under the License. | ||
| */ | ||
|
|
||
| // const {promisify} = require('util'); |
| const filePath = path.resolve(scenarioDirectory, file); | ||
|
|
||
| switch (name) { | ||
| case 'Filament': |
There was a problem hiding this comment.
Maybe a default case with an error message in case something other than Filament gets passed in?
scripts/render-vm-startup-script.sh
Outdated
| # Install NPM dependencies and update the screenshots | ||
| npm install | ||
| # NOTE: This will cause Filament to be compiled | ||
| npm run update-screenshots |
There was a problem hiding this comment.
Capturing the screenshots and running comparisons (which appears to be here down?) seems to have a different purpose than setting up the VM (above).
I might split them into two separate scripts and have an orchestration script to do them both? It won't be functionally different but I think it might be clearer.
There was a problem hiding this comment.
👍 Good call, will fix
Co-Authored-By: cdata <chris@scriptolo.gy>
|
I discovered that the Filament renderer does not produce consistently sized PNGs. On so-called high-DPI displays, the PNGs can be a multiple of the dimensions requested by the invoker (screenshots produced on the headless VM are the expected size). I'm working on extending the Filament patch to address this. |
|
In 576c64a I expanded Initially, I thought I could address this by deriving a scaling factor from the display density. However, I learned that (on Mac at least) display density does not directly correlate with scaling factor. I took a cue from the remarks section in this part of the SDL docs to land on the strategy I ultimately used for adjusting for high-DPI displays. |
|
Good find on the scaling! I've added comments, but looking back through them they're not blockers. |
| const backgroundImageRe = /background-image\="([^"]+)"/; | ||
| const modelSourceRe = /src\="([^"]+)"/ | ||
|
|
||
| const updateScreenshots = async (config) => { |
There was a problem hiding this comment.
config is a shadowed variable here
517007e to
ebf3343
Compare
ebf3343 to
9bb6afc
Compare
| https://api.github.com/repos/googlewebcomponents/model-viewer/pulls | ||
| fi | ||
| # Invoke relevant startup sub-scripts | ||
| source $MODEL_VIEWER_CHECKOUT_DIRECTORY/scripts/provision-ubuntu-xenial-vm.sh |
There was a problem hiding this comment.
Why source instead of just invoking the scripts?
There was a problem hiding this comment.
To spare having to set exported environment variables multiple times in different places
This change proposes a strategy to automatically collect updated screenshots for third party renderers over time to satisfy the requirements of #358 . This tooling will provide critical support as we approach #309 and #360. Some high level details of the change:
gltf_renderer) has been introducedgltf_rendereris a mash-up of thegltf_viewerandframe_recordersamples in the Filament repocmgen-produced IBL, a width and a heightgltf_rendereris built by applying a patch on top of the Filament project repository and running Filament's build scriptgltf-renderercan be installed / updated by invokingnpm run install-renderersnpm run update-screenshotscmgenandgltf_rendererfrom scratch if they are not availablecmgenif they are not availableAutomation strategy
In order to minimize the effort required to keep screenshots up to date, and also to reduce the likelihood of frustration arising from inconsistencies in local dev environments, cloud infrastructure has been introduced to automate screenshot collection updates.
Virtual infrastructure limitations
Initially, I expected that we could accomplish this as a specialized CI build on Travis. However, Filament requires a minimum OpenGL version of 4.1 to run. Initial investigation of Travis options here proved discouraging. It seems that a lot of standard virtual infrastructure does not support a recent enough version of OpenGL due to limitations of VMWare support in the Mesa GL driver.
In the end I was able to build Filament in Travis, but we are unable to use Travis to render because Filament cannot find a suitable rendering backend.
Enter GCP
Thankfully, the requirements for our automation are pretty basic: provision an environment to build Filament (and other renderers in the future), take some screenshots and then make a PR.
I turned to GCP in the hopes that a VM with attached GPU would offer a suitable version of OpenGL for rendering Filament. And I'm happy to report: it does.
The infrastructure that has been put in place is modeled after this one diagramed in a Google Cloud Scheduler tutorial:
The arrangement specific to our own infrastructure can be described as follows:
rendermaticis presumed to have been created with an attached GPU, and with the startup script introduced by this change.rendermaticrendermaticVMrendermaticboots up, the startup script runs, producing screenshots and crafting a PR if necessaryrendermaticis powered offrendermaticnot being powered off, a subsequently scheduled PubSub message at 2 AM invokes a final Cloud Function that shuts down the VMGenerated update PRs
The automation infrastructure produces PRs if (and only if) there are changes among the fidelity test goldens checked into the repository. Here is an example of what the automatically crafted PRs look like:
It is expected that a human reviewer will look over the automatically generated PR before it is merged so that we an stay on top of any significant changes that occur in third party renderers over time.
Fixes #358