bobframes 0.2.0__tar.gz → 0.2.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bobframes-0.2.7/CHANGELOG.md +167 -0
- bobframes-0.2.7/PKG-INFO +237 -0
- bobframes-0.2.7/README.md +206 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/_default_config.toml +6 -2
- bobframes-0.2.7/bobframes/_version.py +1 -0
- bobframes-0.2.7/bobframes/aggregates.py +231 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/catalog.py +7 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/cli.py +95 -8
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/config.py +77 -1
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/global_entities.py +7 -0
- bobframes-0.2.7/bobframes/health.py +233 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/html/template.py +173 -215
- bobframes-0.2.7/bobframes/package.py +607 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/paths.py +13 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/__init__.py +2 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/_tokens.py +2 -2
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/ab.py +18 -0
- bobframes-0.2.7/bobframes/reports/assets/chrome.css +353 -0
- bobframes-0.2.7/bobframes/reports/assets/components.css +153 -0
- bobframes-0.2.7/bobframes/reports/assets/components.js +186 -0
- bobframes-0.2.7/bobframes/reports/assets/container.css +34 -0
- bobframes-0.2.7/bobframes/reports/assets/design_tokens.css +79 -0
- bobframes-0.2.7/bobframes/reports/assets/icon_sprite.html +27 -0
- bobframes-0.2.7/bobframes/reports/assets/link_kind.css +75 -0
- bobframes-0.2.7/bobframes/reports/assets/per_drop.css +102 -0
- bobframes-0.2.7/bobframes/reports/assets/print.css +73 -0
- bobframes-0.2.7/bobframes/reports/assets/rdc_table.css +154 -0
- bobframes-0.2.7/bobframes/reports/assets/rdc_table.js +665 -0
- bobframes-0.2.7/bobframes/reports/assets/sticky.css +48 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/base.py +37 -5
- bobframes-0.2.7/bobframes/reports/chrome.py +1068 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/dashboard.py +173 -124
- bobframes-0.2.7/bobframes/reports/delta.py +223 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/design_tokens.toml +51 -29
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/discovery.py +9 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/draws_by_class.py +50 -52
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/formatters.py +22 -4
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/instancing_opportunities.py +80 -72
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/orchestrator.py +36 -6
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/overdraw.py +65 -79
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/pass_gpu.py +22 -10
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/preview.py +76 -4
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/shader_hotlist.py +108 -128
- bobframes-0.2.7/bobframes/reports/summary.py +307 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/trend_table.py +146 -114
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/run.py +16 -4
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/_render_util.py +18 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/draws_by_class.html +806 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/index.html +181 -403
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/index.html +794 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/instancing_opportunities.html +796 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/overdraw.html +805 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/pass_gpu.html +806 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/draws_by_class.html +804 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/index.html +795 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/instancing_opportunities.html +793 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/overdraw.html +803 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/pass_gpu.html +802 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/shader_hotlist.html +793 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/summary.html +793 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/shader_hotlist.html +796 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/summary.html +796 -0
- bobframes-0.2.7/bobframes/tests/data/golden/_reports/trend_table.html +807 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/index.html +157 -76
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/README.txt +7 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_pagedata/catalog.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/draws_by_class.html +806 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/index.html +1842 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/index.html +794 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/instancing_opportunities.html +796 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/overdraw.html +805 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/pass_gpu.html +806 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/draws_by_class.html +804 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/index.html +795 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/instancing_opportunities.html +793 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/overdraw.html +803 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/pass_gpu.html +802 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/shader_hotlist.html +793 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/summary.html +793 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/shader_hotlist.html +796 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/summary.html +796 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/trend_table.html +807 -0
- {bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565 → bobframes-0.2.7/bobframes/tests/data/golden_package/redacted}/index.html +1172 -198
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/README.txt +7 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_assets/catalog.css +1073 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_assets/catalog.js +665 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_assets/report.css +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_assets/report.js +751 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_pagedata/catalog.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/draws_by_class.html +56 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/index.html +104 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/index.html +44 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/instancing_opportunities.html +46 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/overdraw.html +55 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/pass_gpu.html +56 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/draws_by_class.html +54 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/index.html +45 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/instancing_opportunities.html +43 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/overdraw.html +53 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/pass_gpu.html +52 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/shader_hotlist.html +43 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/summary.html +43 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/shader_hotlist.html +46 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/summary.html +46 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/trend_table.html +57 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared/index.html +24 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/README.txt +7 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_assets/catalog.css +1073 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_assets/catalog.js +665 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_assets/report.css +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_assets/report.js +751 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_pagedata/catalog.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/draws_by_class.html +56 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +1 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/index.html +104 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/index.html +44 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/instancing_opportunities.html +46 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/overdraw.html +55 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/pass_gpu.html +56 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/draws_by_class.html +54 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/index.html +45 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/instancing_opportunities.html +43 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/overdraw.html +53 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/pass_gpu.html +52 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/shader_hotlist.html +43 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/summary.html +43 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/shader_hotlist.html +46 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/summary.html +46 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/trend_table.html +57 -0
- bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/index.html +24 -0
- bobframes-0.2.7/bobframes/tests/data/golden_preview/_chrome_preview.html +817 -0
- bobframes-0.2.7/bobframes/tests/make_package_golden.py +78 -0
- bobframes-0.2.7/bobframes/tests/test_aggregates.py +175 -0
- bobframes-0.2.7/bobframes/tests/test_assets.py +63 -0
- bobframes-0.2.7/bobframes/tests/test_browser_shots.py +90 -0
- bobframes-0.2.7/bobframes/tests/test_catalog_backup_dedup.py +70 -0
- bobframes-0.2.7/bobframes/tests/test_components.py +55 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_config.py +60 -1
- bobframes-0.2.7/bobframes/tests/test_contrast.py +102 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_design_tokens.py +56 -17
- bobframes-0.2.7/bobframes/tests/test_draws_by_class_kpis.py +34 -0
- bobframes-0.2.7/bobframes/tests/test_element_builder.py +88 -0
- bobframes-0.2.7/bobframes/tests/test_head_assets.py +126 -0
- bobframes-0.2.7/bobframes/tests/test_health.py +163 -0
- bobframes-0.2.7/bobframes/tests/test_js_coupled_classes.py +54 -0
- bobframes-0.2.7/bobframes/tests/test_multicapture_normalize.py +95 -0
- bobframes-0.2.7/bobframes/tests/test_package.py +559 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_parity.py +3 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_report_polish.py +3 -2
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_report_structure.py +41 -10
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_run_model.py +32 -1
- bobframes-0.2.7/bobframes/tests/test_summary.py +136 -0
- bobframes-0.2.7/bobframes/tests/test_table_component.py +224 -0
- bobframes-0.2.7/bobframes/tests/test_theme.py +97 -0
- bobframes-0.2.7/bobframes/tests/test_token_guard.py +48 -0
- bobframes-0.2.7/bobframes/tests/test_trend_regression_basis.py +103 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/pyproject.toml +13 -0
- bobframes-0.2.0/CHANGELOG.md +0 -77
- bobframes-0.2.0/PKG-INFO +0 -168
- bobframes-0.2.0/README.md +0 -137
- bobframes-0.2.0/bobframes/_version.py +0 -1
- bobframes-0.2.0/bobframes/reports/chrome.py +0 -2395
- bobframes-0.2.0/bobframes/reports/delta.py +0 -179
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/draws_by_class.html +0 -844
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/index.html +0 -787
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/instancing_opportunities.html +0 -789
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/overdraw.html +0 -798
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/pass_gpu.html +0 -799
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/draws_by_class.html +0 -843
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/instancing_opportunities.html +0 -787
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/overdraw.html +0 -797
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/pass_gpu.html +0 -796
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/shader_hotlist.html +0 -787
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/shader_hotlist.html +0 -789
- bobframes-0.2.0/bobframes/tests/data/golden/_reports/trend_table.html +0 -920
- bobframes-0.2.0/bobframes/tests/data/golden_preview/_chrome_preview.html +0 -804
- {bobframes-0.2.0 → bobframes-0.2.7}/.gitignore +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/LICENSE +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/__init__.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derive_post_merge.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/__init__.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/classifier.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/draw_classifier.toml +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/pass_class_breakdown.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/presets/custom-template.toml +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/presets/godot.toml +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/presets/unity.toml +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/texture_usage.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/discovery.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/errors.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/html/__init__.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/lint.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/lint_banlist.toml +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/manifest.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/parquetize.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/parsers/__init__.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/parsers/derive_program_transitions.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/parsers/parse_init_state.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/probes/__init__.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/probes/whatif.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/qrd_harness.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/query_examples.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/rdcmd.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/replay/__init__.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/replay/replay_main.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/assets/Inter-OFL.txt +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/assets/README.md +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/assets/inter-subset.woff2 +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/cache.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/charts.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/cli.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/resource_labels.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/schemas.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/stable_keys.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/__init__.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_pagedata/catalog.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden_parquet/digests.json +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/_manifest.json +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/buffers.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/clears.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/counters_per_event.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/descriptor_access.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/dispatches.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/draw_bindings.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/draws.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/events.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/fbos.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/frame_totals.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/ibo_samples.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/indirect_args.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/passes.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/pixel_history.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/post_vs_samples.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/program_transitions.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/programs.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/render_targets.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/resource_creation.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/rt_event_timeline.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/samplers.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/shaders.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/state_change_events.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/texture_samples.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/textures.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/vbo_samples.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/vertex_inputs.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/_manifest.json +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/buffers.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/clears.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/counters_per_event.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/descriptor_access.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/dispatches.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/draw_bindings.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/draws.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/events.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/fbos.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/frame_totals.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/ibo_samples.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/indirect_args.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/passes.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/pixel_history.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/post_vs_samples.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/program_transitions.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/programs.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/render_targets.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/resource_creation.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/rt_event_timeline.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/samplers.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/shaders.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/state_change_events.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/texture_samples.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/textures.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/vbo_samples.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/vertex_inputs.parquet +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/make_golden.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/make_parquet_golden.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/make_preview_golden.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/make_synthetic.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/smoke.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_cache.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_charts.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_classifier.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_delta.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_determinism.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_discovery.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_fonts.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_hardening.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_manifest_guard.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_parquet_parity.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_parquetize.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_perf.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_replay_drift.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_schemas.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_schemas_unit.py +0 -0
- {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_stable_keys.py +0 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Changes to this project are documented here, newest first.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.2.7] - 2026-06-24
|
|
11
|
+
|
|
12
|
+
An aggregation-consistency pass plus four report/sharing correctness fixes. Every KPI now names its
|
|
13
|
+
estimator and rate KPIs read on one per-frame basis, so the same metric agrees across the summary,
|
|
14
|
+
dashboard, and trend. No schema change (still schema 3); parquet digests stay byte-identical on the
|
|
15
|
+
same captures. `_version` 0.2.6 -> 0.2.7.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- One canonical aggregation policy (ADR-46): every rendered KPI label names its estimator precisely --
|
|
19
|
+
`Pooled mean`, `Mean (per area)`, `Median`, `Total` -- and never a bare "avg". Rate KPIs (GPU, draws)
|
|
20
|
+
read per-frame on a single basis, so the same area's GPU now reads identically across the summary,
|
|
21
|
+
dashboard, and trend (previously e.g. `0.0356`/frame on the summary vs a raw `0.178` total on the
|
|
22
|
+
dashboard with no bridge). A naming gate (`test_no_vague_estimator_labels`) fails the build on any
|
|
23
|
+
vague estimator word. (D-13..D-16, Q-10..Q-13)
|
|
24
|
+
- Regression detection unified on the per-frame basis with config-driven thresholds: `trend_table`
|
|
25
|
+
reads every KPI per frame, so a regression flag is capture-count-independent and agrees with the
|
|
26
|
+
build-health verdict (a 7-vs-5-capture run no longer reports a false +40%); the per-KPI thresholds
|
|
27
|
+
(`draws`/`vbo`/`ibo`/`program_switches`) move from code literals to the `[report]` config, with
|
|
28
|
+
defaults that reproduce the prior values. (H-41)
|
|
29
|
+
- `draws_by_class` ratios use `statistics.median` (was the upper-middle `sorted[n//2]`, an off-by-one
|
|
30
|
+
on even N).
|
|
31
|
+
- `aggregates.frame_counts` is the single owner of every per-(drop, area) frame count; when the
|
|
32
|
+
GPU/draws denominator and the entity-rate denominator legitimately differ (a capture that replayed
|
|
33
|
+
but exported partial entity rows), the divergence is logged as a WARNING rather than silently
|
|
34
|
+
normalized away.
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
- Run-selector dropdown did nothing on every report: the component JS runs in `<head>`, so the custom
|
|
38
|
+
element upgraded before its child `<select>` had parsed; initialization now defers to
|
|
39
|
+
`DOMContentLoaded`. (R-20)
|
|
40
|
+
- Exported standalone one-pager carried dead tree-relative navigation -- a run dropdown pointing at
|
|
41
|
+
siblings not in the bundle, a breadcrumb, the dashboard link, and a "viewing an older run" banner.
|
|
42
|
+
The detached summary now strips them; the in-tree summary keeps its working navigation. (R-21)
|
|
43
|
+
- Older-run report pages showed cross-drop graphs and tables spanning all runs, including ones newer
|
|
44
|
+
than the page's own run. Cross-drop renderers now scope to run history (up to and including the
|
|
45
|
+
current run) while the run picker keeps the full list. (R-22)
|
|
46
|
+
|
|
47
|
+
## [0.2.6] - 2026-06-06
|
|
48
|
+
|
|
49
|
+
A build-health one-pager, a shareable `package` bundle, a server-side component system, and a full visual
|
|
50
|
+
redesign. No schema change (still schema 3); parquet digests stay byte-identical to 0.1.0/0.2.0 on the same
|
|
51
|
+
captures. Per ADR-43 there is no standalone 0.2.5 -- this release carries the c16q-c16x foundation AND the
|
|
52
|
+
redesign, so `_version` jumps `0.2.0 -> 0.2.6`.
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
- Build-health one-pager (`bobframes report summary`): a presentation-independent verdict/trend module
|
|
56
|
+
(`health.py` -- ordered OK<UNKNOWN<AT_RISK<ALARM so a real alarm is never masked yet missing data is
|
|
57
|
+
never a false green) feeding a print-first exec summary (verdict bar, averaged KPIs with vs-prior pills +
|
|
58
|
+
sparklines, a baseline-gated movement card, a worst-first by-area table). (ADR-39)
|
|
59
|
+
- `bobframes package`: a non-mutating transform of a rendered tree into a shareable `<project>-<date>-report.zip`
|
|
60
|
+
(reproducible bytes) + a standalone self-contained `summary.html`. `--shared-assets` (the default) dedupes
|
|
61
|
+
chrome into `_assets/` linked per page (built at the render seam, not by scraping HTML); `--inline` opts out;
|
|
62
|
+
`--redact` scrubs device/host provenance at the data seam (whole-tree drop-sidecars excluded). (ADR-40/41)
|
|
63
|
+
- Server-side component system (`reports/chrome.py`): an escape-by-construction element builder (`el`/`raw`/
|
|
64
|
+
`el_void`/`classes`), a normalized table-component family (`Column`/`data_table`/`static_table` + a virtual
|
|
65
|
+
`table_controls`/`virtual_host`/`virtual_table_section` host), a delta-column factory, and a token-validity
|
|
66
|
+
guard (`undefined_tokens()` -- a typo'd `var(--x)` is a CI failure + a `preview` warning). CSS/JS now live as
|
|
67
|
+
real `reports/assets/*.{css,js}` files. A `bobframes preview` gallery documents every component. (ADR-42)
|
|
68
|
+
- User theme override for pip installs: a `.bobframes.toml [theme]` section + `render/preview --accent`/
|
|
69
|
+
`--accent-data` flags re-hue the accent/status/chart colors WITHOUT editing the packaged `design_tokens.toml`
|
|
70
|
+
(deep-merged through the existing config cascade; color-key allowlist; ASCII/injection-guarded). `export-tokens
|
|
71
|
+
--theme-template` emits a paste-ready starter; `--watch` polls `.bobframes.toml`. (ADR-45)
|
|
72
|
+
- Dev-only screenshot harness `tools/shoot.py` (headless-Chrome over CDP, light/dark/print; not shipped) + a
|
|
73
|
+
`-m browser` opt-in matrix + a dependency-free oklch->WCAG contrast test, for the redesign's visual gate.
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
- Visual redesign anchored on shadcn/ui + Grafana density (ADR-43/44): a neutral grayscale palette (chroma 0),
|
|
77
|
+
WCAG-AA tertiary text, FLAT border-led surfaces (reverses the ADR-34 depth -- a 1px border + a `--radius`
|
|
78
|
+
6/8/10 token scale replaces the elevation shadows + the hardcoded 2/3/4px radii), `:focus-visible` rings,
|
|
79
|
+
reduced-motion-safe `:active`, container-query responsive, and a print pass. Restrained type tune with hero
|
|
80
|
+
numerals scoped to the summary one-pager; Grafana-dense rows/cards everywhere else; the catalog/drill data
|
|
81
|
+
browser widened (max data-per-screen).
|
|
82
|
+
- "Everything is a component": the summary, dashboard minis, the 6 detail reports, and the catalog/drill virtual
|
|
83
|
+
hosts all render through the component family; the remaining hand-written chrome leaves were migrated onto `el`
|
|
84
|
+
(the bespoke-markup long-tail is closed -- only the fixed page scaffold remains, by necessity). `data_table`
|
|
85
|
+
normalizes the previously hand-written report tables (the visual-parity gate is intentionally replaced by a
|
|
86
|
+
structural + data-preservation gate per ADR-43).
|
|
87
|
+
- Per-frame normalization for multi-capture runs (instancing repeat + shader cost read per distinct capture,
|
|
88
|
+
no-op for 1-capture data so it stays byte-identical) and a single `aggregates.py` data layer feeding the
|
|
89
|
+
dashboard/reports/verdict so they cannot disagree.
|
|
90
|
+
- Run model + sharing surfaced in the root catalog (build-health + dashboard chips, A/B pair lists).
|
|
91
|
+
|
|
92
|
+
### Fixed
|
|
93
|
+
- Single-drop trend-table crash (`'str' object has no attribute 'get'`); `--force` rotation-backup
|
|
94
|
+
double-counting in the catalog + global-entities walkers (canonical-basename reconstruction).
|
|
95
|
+
- WCAG-AA contrast on tertiary text; print no longer hugs the paper edge.
|
|
96
|
+
|
|
97
|
+
## [0.2.0] - 2026-06-03
|
|
98
|
+
|
|
99
|
+
De-hardcoding + a full report overhaul. No schema change (still schema 3); extraction output is stable
|
|
100
|
+
where the pipeline is unchanged, so parquet digests are byte-identical to 0.1.0 on the same captures.
|
|
101
|
+
|
|
102
|
+
### Added
|
|
103
|
+
- Inline-SVG chart toolkit (`reports/charts.py`): a flagship chart per report (pass-GPU treemap,
|
|
104
|
+
draws-by-class donut, shader complexity-vs-cost scatter, overdraw reject-rate bars, instancing
|
|
105
|
+
wasted-index bars, per-KPI trend lines), deterministic and dependency-free (no `random`/`Date`).
|
|
106
|
+
- Report design language: hero KPI strip, callouts with config-driven severity, provenance/device
|
|
107
|
+
strip, section cards, sticky section headers, copy buttons on long IDs, vendored Inter subset font
|
|
108
|
+
(offline, base64-inlined), and an auto-tint heatmap on ranked numeric columns.
|
|
109
|
+
- Run model: per-run truth (each report names "run N of M"), a run picker, A/B compare, and a trend
|
|
110
|
+
table across runs; older runs are pre-rendered up to a configurable limit.
|
|
111
|
+
- One unified `rdc-table` engine (progressive enhancement, two modes): server-baked `static` for reports
|
|
112
|
+
(JS-off / print / Ctrl-F / golden all hold) and windowed `virtual` for the catalog + per-drop drill.
|
|
113
|
+
Shared natural-numeric sort, type-split, heatmap, column groups, search/filter, controllable cell
|
|
114
|
+
truncation with hover-reveal, and full sort/filter a11y (aria-sort + keyboard-operable headers + a
|
|
115
|
+
labelled filter input) across both modes.
|
|
116
|
+
- TOML config (`.bobframes.toml`, `[report]`/`[pipeline]` sections), `design_tokens.toml` token system,
|
|
117
|
+
and a state-capable draw classifier driven by table columns.
|
|
118
|
+
- Reports cache with a SHA256 sidecar (corrupt/missing/mismatch falls back to a live scan, never
|
|
119
|
+
silent-empty); manifest schema-version guard (`ingest --force` hint on mismatch).
|
|
120
|
+
|
|
121
|
+
### Changed
|
|
122
|
+
- Catalog + drill readability: roomier rows, type-split mono/sans, and the heavy per-table row data moved
|
|
123
|
+
out of the HTML into `_pagedata/*.js` companions (the ~21 MB time-to-interactive fix) loaded via a
|
|
124
|
+
file://-safe `<script defer src>`.
|
|
125
|
+
- External tool resolution + clearer pipeline error messages and exit codes; environment variables
|
|
126
|
+
renamed `RDC_*` -> `BOBFRAMES_*` (one-release legacy fallback with a deprecation warning).
|
|
127
|
+
- Project paths, the report registry, and the drill-size budget are configurable rather than hardcoded.
|
|
128
|
+
|
|
129
|
+
## [0.1.0] - 2026-05-31
|
|
130
|
+
|
|
131
|
+
First standalone release. v1 is Windows-only (the replay stage drives `qrenderdoc`).
|
|
132
|
+
|
|
133
|
+
### Added
|
|
134
|
+
- Single `bobframes` binary with subcommands `ingest`, `render`, `ab`, `report`, `catalog`, `lint`,
|
|
135
|
+
`check`, `serve`, `smoke`, and `version`. Positional `root` (default `.`) across verbs; long-flag
|
|
136
|
+
only; exit codes `0`/`1`/`2`/`3`/`4`. stdlib `logging` at INFO by default, `--verbose` for DEBUG,
|
|
137
|
+
`[HH:MM:SS]` line format (G-8).
|
|
138
|
+
- Replay script located via `importlib.resources` (`bobframes.replay.replay_script_path`) so replay
|
|
139
|
+
works from an installed wheel, not just an in-tree checkout.
|
|
140
|
+
- Reliability hardening: atomic writes for `_manifest.json`, Parquet+CSV pairs, and `done.marker`
|
|
141
|
+
(`.tmp` + `os.replace`, rollback on failure); process-tree kill (`taskkill /T /F`) when a
|
|
142
|
+
`qrenderdoc` replay times out; per-capture replay-failure isolation
|
|
143
|
+
(`capture_status='replay_failed'` instead of aborting the whole drop); subprocess stderr logged on
|
|
144
|
+
convert-timeout and on every parse; manifest provenance fields `tool_versions` and `host_info`.
|
|
145
|
+
- Test gates: golden-snapshot parity, schema regression, determinism, performance, and a replay
|
|
146
|
+
column-drift guard against `schemas.py` (H-6); mocked-subprocess tests for the hardening branches
|
|
147
|
+
the GPU-less runner cannot exercise; a data-driven `smoke` (render-only against a bundled synthetic
|
|
148
|
+
fixture by default); unit tests for stable keys, schemas, and drop discovery.
|
|
149
|
+
- GitHub Actions CI across a Windows / Python / pyarrow matrix, with a tag-gated PyPI publish job.
|
|
150
|
+
|
|
151
|
+
### Changed
|
|
152
|
+
- **Stable-key format upgrade:** stable keys now carry a `KEY_VERSION = 1` version byte in the hash
|
|
153
|
+
input. Keys produced before this release are not comparable with `0.1.0` keys; rebuild affected
|
|
154
|
+
data with `bobframes ingest --force`. `KEY_VERSION` bumps on any future key-derivation rule change.
|
|
155
|
+
- Timestamps unified to a single UTC `now_iso()` helper (`bobframes.manifest.now_iso`); the
|
|
156
|
+
local-time variant in `reports/cli` was dropped.
|
|
157
|
+
|
|
158
|
+
### Removed
|
|
159
|
+
- The project-embedded `_analysis` package. `python -m _analysis.run` and the other
|
|
160
|
+
`python -m _analysis.*` entry points no longer work; switch to the `bobframes` commands (see the
|
|
161
|
+
migration table in the README). This is a hard rename with no compatibility shim.
|
|
162
|
+
|
|
163
|
+
[Unreleased]: https://github.com/altpsyche/bobframes/compare/v0.2.7...HEAD
|
|
164
|
+
[0.2.7]: https://github.com/altpsyche/bobframes/compare/v0.2.6...v0.2.7
|
|
165
|
+
[0.2.6]: https://github.com/altpsyche/bobframes/compare/v0.2.0...v0.2.6
|
|
166
|
+
[0.2.0]: https://github.com/altpsyche/bobframes/compare/v0.1.0...v0.2.0
|
|
167
|
+
[0.1.0]: https://github.com/altpsyche/bobframes/releases/tag/v0.1.0
|
bobframes-0.2.7/PKG-INFO
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bobframes
|
|
3
|
+
Version: 0.2.7
|
|
4
|
+
Summary: RenderDoc capture pipeline: ingest, analyze, render.
|
|
5
|
+
Project-URL: Homepage, https://github.com/altpsyche/bobframes
|
|
6
|
+
Project-URL: Issues, https://github.com/altpsyche/bobframes/issues
|
|
7
|
+
Project-URL: Changelog, https://github.com/altpsyche/bobframes/blob/main/CHANGELOG.md
|
|
8
|
+
Author-email: Siva Subramanyam <sivasubramanyam@mayhem-studios.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: gpu,parquet,profiling,renderdoc
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
21
|
+
Classifier: Topic :: Software Development :: Debuggers
|
|
22
|
+
Requires-Python: <3.15,>=3.10
|
|
23
|
+
Requires-Dist: pyarrow<22,>=17
|
|
24
|
+
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: build; extra == 'dev'
|
|
27
|
+
Requires-Dist: hatchling; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
29
|
+
Requires-Dist: twine; extra == 'dev'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# BobFrames
|
|
33
|
+
|
|
34
|
+
RenderDoc capture pipeline: ingest, analyze, render. Point it at a folder of `.rdc` captures and it
|
|
35
|
+
produces `_data/` (Parquet tables) plus `_reports/` -- static, offline, `file://`-safe HTML you can
|
|
36
|
+
browse: a one-page **build-health summary**, a reports dashboard, per-aspect reports (overdraw, shader
|
|
37
|
+
hotlist, instancing, draws-by-class, pass-GPU, cross-run trend), and a per-drop drill-down data browser.
|
|
38
|
+
Reports are self-contained, printable, Ctrl-F-able, and work with JavaScript off. Windows-only in v1.
|
|
39
|
+
|
|
40
|
+
> Built for **Mayhem Studios** -- see [Built for Mayhem Studios](#built-for-mayhem-studios) below.
|
|
41
|
+
|
|
42
|
+
## Requirements
|
|
43
|
+
|
|
44
|
+
- Windows 10 or later (the replay stage drives `qrenderdoc`, which is Windows-only in v1).
|
|
45
|
+
- Python 3.10 - 3.13.
|
|
46
|
+
- RenderDoc 1.x, or Arm Performance Studio, providing `renderdoccmd` and `qrenderdoc` on disk.
|
|
47
|
+
|
|
48
|
+
## Install
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
pipx install bobframes
|
|
52
|
+
bobframes check
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`bobframes check` prints the resolved paths for `renderdoccmd` and `qrenderdoc` and exits non-zero if
|
|
56
|
+
either is missing, so you can confirm the toolchain before a long ingest.
|
|
57
|
+
|
|
58
|
+
## Quickstart
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
cd path\to\captures # a folder of <Area>\<YYYY-MM-DD[_label]>\*.rdc
|
|
62
|
+
bobframes ingest . # export, parse, replay, parquetize, derive, render
|
|
63
|
+
bobframes serve . # open a local static preview of the reports
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`ingest` writes Parquet under `_data/` and HTML under `_reports/`. Re-run `bobframes render .` any
|
|
67
|
+
time to rebuild the HTML from existing Parquet without re-replaying captures.
|
|
68
|
+
|
|
69
|
+
## Commands
|
|
70
|
+
|
|
71
|
+
| Command | Purpose |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `ingest [root] [--area X] [--label Y] [--capture N] [--force] [--pixel-grid 4] [--render-only]` | Full pipeline: export, parse, replay, parquetize, derive, manifest, commit, catalog, render. |
|
|
74
|
+
| `render [root] [--area X] [--label Y] [--accent OKLCH] [--accent-data OKLCH] [--watch]` | Rebuild HTML and catalog from existing Parquet. `--accent`/`--accent-data` re-hue the theme for this render (ADR-45). `--watch` re-renders on `design_tokens.toml`, chrome, or `.bobframes.toml` edits (alpha). |
|
|
75
|
+
| `ab [root] --baseline-label X --compare-label Y` | All reports for one drop pair under `_reports/ab/<pair>/`. |
|
|
76
|
+
| `report [root] <name>` | Build one named report (summary, draws-by-class, trend, instancing, pass-gpu, shader, overdraw, dashboard). `summary` is the exec build-health one-pager. |
|
|
77
|
+
| `catalog [root]` | Rebuild `_data/_catalog.parquet` only. |
|
|
78
|
+
| `lint <file>...` | Check HTML or markdown against the banlist. |
|
|
79
|
+
| `check` | Print resolved tool paths; non-zero when a tool is missing. |
|
|
80
|
+
| `serve [root] [--port 8000] [--bind 127.0.0.1]` | Static preview via the stdlib HTTP server. |
|
|
81
|
+
| `package [root] [--inline] [--light] [--redact] [--redact-paths {strip,fail}] [--out PATH] [--run KEY] [--no-summary-file] [--stage]` | Bundle a rendered tree into a shareable `<project>-<rundate>-report.zip` + a standalone `<project>-<rundate>-summary.html`, both written OUTSIDE `<root>` (non-mutating). `--redact` scrubs device/host provenance + absolute paths for external sharing. |
|
|
82
|
+
| `preview [root] [--accent OKLCH] [--accent-data OKLCH]` | Render the chrome gallery to `_reports/_chrome_preview.html`; no capture data needed. `--accent` previews a theme override before you commit it. |
|
|
83
|
+
| `export-tokens [--format toml\|json\|css] [--theme-template]` | Print the design tokens to stdout in the chosen format. `--theme-template` emits a paste-ready `[theme]` block for `.bobframes.toml`. |
|
|
84
|
+
| `smoke [--data DIR]` | End-to-end check; render-only against the bundled fixture when `--data` is omitted. |
|
|
85
|
+
| `version` | Print `bobframes`, schema, and pyarrow versions. |
|
|
86
|
+
|
|
87
|
+
`<root>` is positional and defaults to `.`. Flags are long-form only. Exit codes: `0` success,
|
|
88
|
+
`1` pipeline or build failure, `2` usage error, `3` external tool missing, `4` interrupted.
|
|
89
|
+
|
|
90
|
+
## Sharing a report
|
|
91
|
+
|
|
92
|
+
`bobframes package <root>` turns a rendered tree into two friendly artifacts beside it (it only READS
|
|
93
|
+
`<root>`):
|
|
94
|
+
|
|
95
|
+
- `<project>-<rundate>-report.zip` -- the full explorable tree. **Extract the whole folder before
|
|
96
|
+
opening** (`index.html`, then the Build Health Summary): the pages link each other and a shared
|
|
97
|
+
`_assets/` folder by relative path, so opening one file straight out of the zip breaks those links.
|
|
98
|
+
- `<project>-<rundate>-summary.html` -- a standalone, self-contained one-pager. Email it, double-click
|
|
99
|
+
it, or `Ctrl-P -> Save as PDF`; no unzip needed. (Its deep links into the reports only resolve when
|
|
100
|
+
the zip is shipped alongside.)
|
|
101
|
+
|
|
102
|
+
The zip DEFAULTS to **shared assets**: the ~95 KB of chrome (font + CSS + JS) lives once in `_assets/`
|
|
103
|
+
and every page links it, so a multi-run bundle is markedly smaller. Because the pages share that
|
|
104
|
+
folder, **no single page is portable on its own** -- keep the extracted folder together, or send the
|
|
105
|
+
standalone `summary.html` when you need just one file. `--inline` opts out and makes each page
|
|
106
|
+
self-contained (larger, but any single report file is portable). `--light` bundles only `index.html`
|
|
107
|
+
+ the top-level reports (no drill pages or data) for a quick "read, don't drill" share.
|
|
108
|
+
|
|
109
|
+
### Sharing externally -- `--redact`
|
|
110
|
+
|
|
111
|
+
`bobframes package <root> --redact` produces a bundle safe to hand to someone outside your team. It
|
|
112
|
+
scrubs the GPU / driver / CPU / OS + capture-tool versions from every page's device strip (replaced with
|
|
113
|
+
`redacted`), drops the raw provenance sidecars (`_manifest.json`, `frame_metadata.jsonl`) from the
|
|
114
|
+
bundle, and replaces absolute Windows paths (`C:\...`) with `<path redacted>` across the pages and the
|
|
115
|
+
downloadable CSVs. Redaction re-renders the tree, so `--inline --redact` is no longer a fast copy.
|
|
116
|
+
|
|
117
|
+
- `--redact-paths=strip` (default) -- replace the path tokens; the bundle stays usable on a real capture.
|
|
118
|
+
- `--redact-paths=fail` -- a CI completeness check: exit nonzero (don't write the zip) if any absolute
|
|
119
|
+
path remains in a rendered page, so a leak fails the build.
|
|
120
|
+
|
|
121
|
+
**Caveat:** the pages and the downloadable CSVs are sanitized, but the **binary `.parquet`** tables still
|
|
122
|
+
contain resource paths (they can't be string-edited safely) -- strip `_data/` if the parquet itself must
|
|
123
|
+
leave your team. UNC (`\\host\share`) and forward-slash (`C:/...`) paths are not auto-stripped.
|
|
124
|
+
|
|
125
|
+
## Customizing reports
|
|
126
|
+
|
|
127
|
+
The look is shadcn-clean, neutral, and flat by default. Two ways to re-color it:
|
|
128
|
+
|
|
129
|
+
### Pip installs -- re-hue without editing source (recommended)
|
|
130
|
+
|
|
131
|
+
`pip install bobframes` puts the design tokens in site-packages, where edits are lost on upgrade -- so
|
|
132
|
+
re-hue the accent / status / chart colors through the config cascade instead:
|
|
133
|
+
|
|
134
|
+
- **Persistent:** add a `[theme]` section to `.bobframes.toml` in your capture root (or
|
|
135
|
+
`%APPDATA%/bobframes/config.toml`). `bobframes export-tokens --theme-template` prints a ready-to-paste
|
|
136
|
+
starter with just the overridable color knobs.
|
|
137
|
+
- **One-shot:** `bobframes render . --accent '<oklch>'` (and `--accent-data '<oklch>'`) -- the top
|
|
138
|
+
precedence tier (CLI > env > config > bundled default). `bobframes preview --accent '<oklch>'` previews
|
|
139
|
+
it with no capture data.
|
|
140
|
+
|
|
141
|
+
Only color hues (accent, the four status colors, the draw-class + chart palette) are overridable; layout,
|
|
142
|
+
spacing, type, and the table engine stay bundled, so an override can never desync the rendering. A bad or
|
|
143
|
+
non-color value warns and is ignored. `--watch` live-reloads on `.bobframes.toml` edits too.
|
|
144
|
+
|
|
145
|
+
### Source checkouts -- edit the bundled tokens
|
|
146
|
+
|
|
147
|
+
The full palette lives in `bobframes/reports/design_tokens.toml` (colors, spacing, type, motion, radius,
|
|
148
|
+
and base layout sizes). The CSS variable name is fixed by its key: `surface_0` becomes `--surface-0`,
|
|
149
|
+
`accent_primary` becomes `--accent-primary`.
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
bobframes preview # writes _reports/_chrome_preview.html (every component, no data)
|
|
153
|
+
# edit a value in design_tokens.toml
|
|
154
|
+
bobframes preview # under a second; reload the page in a browser
|
|
155
|
+
bobframes render C:\captures # apply the change to real reports from existing Parquet
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`bobframes render --watch` re-runs render-only whenever `design_tokens.toml`, a chrome module, or
|
|
159
|
+
`.bobframes.toml` changes (alpha; a 500ms poll, no extra dependency). `bobframes export-tokens --format
|
|
160
|
+
css` prints the live `:root` block; `--format json` the nested table; `--format toml` the file itself.
|
|
161
|
+
|
|
162
|
+
## External tools
|
|
163
|
+
|
|
164
|
+
The export stage runs `renderdoccmd convert`; the replay stage runs `qrenderdoc --python`. bobframes
|
|
165
|
+
resolves both from (in order) a config file (`.bobframes.toml`), version-globbed Arm Performance Studio
|
|
166
|
+
install paths, and `PATH`. Install RenderDoc / Arm Performance Studio anywhere on those, or point a
|
|
167
|
+
config entry at it. Run `bobframes check` to see what was resolved.
|
|
168
|
+
|
|
169
|
+
## Output layout
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
<root>/
|
|
173
|
+
index.html root catalog view
|
|
174
|
+
<area>/<drop>/ raw RDC inputs (left untouched)
|
|
175
|
+
_data/ pipeline outputs
|
|
176
|
+
_catalog.parquet (+ .csv, .json)
|
|
177
|
+
_global_entities.parquet (+ .csv)
|
|
178
|
+
_query_examples.md
|
|
179
|
+
<area>/<drop>/ per-drop data (29 Parquet tables)
|
|
180
|
+
*.parquet (+ matching .csv)
|
|
181
|
+
_manifest.json, _resource_labels.json
|
|
182
|
+
shader_src/*.glsl, jsonl sidecars
|
|
183
|
+
done.marker
|
|
184
|
+
_reports/ rendered HTML
|
|
185
|
+
*.html (dashboard + reports)
|
|
186
|
+
ab/<pair>/*.html
|
|
187
|
+
drill/<area>/<drop>/index.html per-drop browser
|
|
188
|
+
_cache/
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
The catalog stores each drop's path relative to `<root>` for portability.
|
|
192
|
+
|
|
193
|
+
## Migrating from `_analysis`
|
|
194
|
+
|
|
195
|
+
v1 is a hard rename of the older project-embedded `_analysis` package, with no compatibility shim:
|
|
196
|
+
`python -m _analysis.*` stops working once `bobframes` is installed. Map old invocations to new ones:
|
|
197
|
+
|
|
198
|
+
| Old (`_analysis`) | New (`bobframes`) |
|
|
199
|
+
|---|---|
|
|
200
|
+
| `python -m _analysis.run --root . --area X --label Y` | `bobframes ingest . --area X --label Y` |
|
|
201
|
+
| `python -m _analysis.reports.ab --root . --baseline-label X --compare-label Y` | `bobframes ab . --baseline-label X --compare-label Y` |
|
|
202
|
+
| `python -m _analysis.lint <file>` | `bobframes lint <file>` |
|
|
203
|
+
| `python -m _analysis.tests.smoke` | `bobframes smoke` |
|
|
204
|
+
|
|
205
|
+
## Troubleshooting
|
|
206
|
+
|
|
207
|
+
| Symptom | Resolution |
|
|
208
|
+
|---|---|
|
|
209
|
+
| `renderdoccmd not found` (exit 3) | Install RenderDoc or Arm Performance Studio, or put the executable on `PATH`; confirm with `bobframes check`. |
|
|
210
|
+
| `qrenderdoc` replay hangs | v1 kills the replay process tree on timeout and records `capture_status='replay_failed'` for that capture; the rest of the drop still completes. Re-run with `--force` to retry. |
|
|
211
|
+
| Lint failure during render | The emitted HTML contains a banned token. Run `bobframes lint <file>` to see the line and label. |
|
|
212
|
+
| `schema mismatch` (exit 1) | A drop's `_manifest.json` schema version differs from the installed schema. Rebuild it with `bobframes ingest --force` (the v1 schema-migration path; see G-3). |
|
|
213
|
+
| Permission denied on `_data` | Close any viewer holding a Parquet open, then re-run; writes are staged and renamed atomically. |
|
|
214
|
+
|
|
215
|
+
## Advanced
|
|
216
|
+
|
|
217
|
+
- A/B reports: `bobframes ab . --baseline-label OLD --compare-label NEW` builds a side-by-side set.
|
|
218
|
+
- Programmatic use: import `bobframes.schemas`, `bobframes.discovery`, and `bobframes.paths` to drive
|
|
219
|
+
table lookups, drop discovery, and path resolution from your own scripts.
|
|
220
|
+
- `bobframes/probes/whatif.py` is a manual qrenderdoc-side probe and is not wired as a CLI command.
|
|
221
|
+
- TOML config (`.bobframes.toml`), an externalized draw classifier, and design-token theming
|
|
222
|
+
(`[theme]` / `--accent`) shipped in v0.2.6. `bobframes package` produces shareable, optionally
|
|
223
|
+
redacted bundles (see [Sharing a report](#sharing-a-report)).
|
|
224
|
+
|
|
225
|
+
## Built for Mayhem Studios
|
|
226
|
+
|
|
227
|
+
BobFrames is built and maintained for **Mayhem Studios** -- it powers the studio's GPU
|
|
228
|
+
capture-analysis and frame-performance work, and is open-sourced here for the wider RenderDoc and
|
|
229
|
+
graphics community.
|
|
230
|
+
|
|
231
|
+
If BobFrames helps your work, please **support Mayhem Studios** -- the studio that makes this tool
|
|
232
|
+
possible. Follow the studio, play and wishlist our games, and tell a friend who fights frame times.
|
|
233
|
+
A on the [GitHub repo](https://github.com/altpsyche/bobframes) helps too. Thank you.
|
|
234
|
+
|
|
235
|
+
## License
|
|
236
|
+
|
|
237
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# BobFrames
|
|
2
|
+
|
|
3
|
+
RenderDoc capture pipeline: ingest, analyze, render. Point it at a folder of `.rdc` captures and it
|
|
4
|
+
produces `_data/` (Parquet tables) plus `_reports/` -- static, offline, `file://`-safe HTML you can
|
|
5
|
+
browse: a one-page **build-health summary**, a reports dashboard, per-aspect reports (overdraw, shader
|
|
6
|
+
hotlist, instancing, draws-by-class, pass-GPU, cross-run trend), and a per-drop drill-down data browser.
|
|
7
|
+
Reports are self-contained, printable, Ctrl-F-able, and work with JavaScript off. Windows-only in v1.
|
|
8
|
+
|
|
9
|
+
> Built for **Mayhem Studios** -- see [Built for Mayhem Studios](#built-for-mayhem-studios) below.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
- Windows 10 or later (the replay stage drives `qrenderdoc`, which is Windows-only in v1).
|
|
14
|
+
- Python 3.10 - 3.13.
|
|
15
|
+
- RenderDoc 1.x, or Arm Performance Studio, providing `renderdoccmd` and `qrenderdoc` on disk.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
pipx install bobframes
|
|
21
|
+
bobframes check
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`bobframes check` prints the resolved paths for `renderdoccmd` and `qrenderdoc` and exits non-zero if
|
|
25
|
+
either is missing, so you can confirm the toolchain before a long ingest.
|
|
26
|
+
|
|
27
|
+
## Quickstart
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
cd path\to\captures # a folder of <Area>\<YYYY-MM-DD[_label]>\*.rdc
|
|
31
|
+
bobframes ingest . # export, parse, replay, parquetize, derive, render
|
|
32
|
+
bobframes serve . # open a local static preview of the reports
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`ingest` writes Parquet under `_data/` and HTML under `_reports/`. Re-run `bobframes render .` any
|
|
36
|
+
time to rebuild the HTML from existing Parquet without re-replaying captures.
|
|
37
|
+
|
|
38
|
+
## Commands
|
|
39
|
+
|
|
40
|
+
| Command | Purpose |
|
|
41
|
+
|---|---|
|
|
42
|
+
| `ingest [root] [--area X] [--label Y] [--capture N] [--force] [--pixel-grid 4] [--render-only]` | Full pipeline: export, parse, replay, parquetize, derive, manifest, commit, catalog, render. |
|
|
43
|
+
| `render [root] [--area X] [--label Y] [--accent OKLCH] [--accent-data OKLCH] [--watch]` | Rebuild HTML and catalog from existing Parquet. `--accent`/`--accent-data` re-hue the theme for this render (ADR-45). `--watch` re-renders on `design_tokens.toml`, chrome, or `.bobframes.toml` edits (alpha). |
|
|
44
|
+
| `ab [root] --baseline-label X --compare-label Y` | All reports for one drop pair under `_reports/ab/<pair>/`. |
|
|
45
|
+
| `report [root] <name>` | Build one named report (summary, draws-by-class, trend, instancing, pass-gpu, shader, overdraw, dashboard). `summary` is the exec build-health one-pager. |
|
|
46
|
+
| `catalog [root]` | Rebuild `_data/_catalog.parquet` only. |
|
|
47
|
+
| `lint <file>...` | Check HTML or markdown against the banlist. |
|
|
48
|
+
| `check` | Print resolved tool paths; non-zero when a tool is missing. |
|
|
49
|
+
| `serve [root] [--port 8000] [--bind 127.0.0.1]` | Static preview via the stdlib HTTP server. |
|
|
50
|
+
| `package [root] [--inline] [--light] [--redact] [--redact-paths {strip,fail}] [--out PATH] [--run KEY] [--no-summary-file] [--stage]` | Bundle a rendered tree into a shareable `<project>-<rundate>-report.zip` + a standalone `<project>-<rundate>-summary.html`, both written OUTSIDE `<root>` (non-mutating). `--redact` scrubs device/host provenance + absolute paths for external sharing. |
|
|
51
|
+
| `preview [root] [--accent OKLCH] [--accent-data OKLCH]` | Render the chrome gallery to `_reports/_chrome_preview.html`; no capture data needed. `--accent` previews a theme override before you commit it. |
|
|
52
|
+
| `export-tokens [--format toml\|json\|css] [--theme-template]` | Print the design tokens to stdout in the chosen format. `--theme-template` emits a paste-ready `[theme]` block for `.bobframes.toml`. |
|
|
53
|
+
| `smoke [--data DIR]` | End-to-end check; render-only against the bundled fixture when `--data` is omitted. |
|
|
54
|
+
| `version` | Print `bobframes`, schema, and pyarrow versions. |
|
|
55
|
+
|
|
56
|
+
`<root>` is positional and defaults to `.`. Flags are long-form only. Exit codes: `0` success,
|
|
57
|
+
`1` pipeline or build failure, `2` usage error, `3` external tool missing, `4` interrupted.
|
|
58
|
+
|
|
59
|
+
## Sharing a report
|
|
60
|
+
|
|
61
|
+
`bobframes package <root>` turns a rendered tree into two friendly artifacts beside it (it only READS
|
|
62
|
+
`<root>`):
|
|
63
|
+
|
|
64
|
+
- `<project>-<rundate>-report.zip` -- the full explorable tree. **Extract the whole folder before
|
|
65
|
+
opening** (`index.html`, then the Build Health Summary): the pages link each other and a shared
|
|
66
|
+
`_assets/` folder by relative path, so opening one file straight out of the zip breaks those links.
|
|
67
|
+
- `<project>-<rundate>-summary.html` -- a standalone, self-contained one-pager. Email it, double-click
|
|
68
|
+
it, or `Ctrl-P -> Save as PDF`; no unzip needed. (Its deep links into the reports only resolve when
|
|
69
|
+
the zip is shipped alongside.)
|
|
70
|
+
|
|
71
|
+
The zip DEFAULTS to **shared assets**: the ~95 KB of chrome (font + CSS + JS) lives once in `_assets/`
|
|
72
|
+
and every page links it, so a multi-run bundle is markedly smaller. Because the pages share that
|
|
73
|
+
folder, **no single page is portable on its own** -- keep the extracted folder together, or send the
|
|
74
|
+
standalone `summary.html` when you need just one file. `--inline` opts out and makes each page
|
|
75
|
+
self-contained (larger, but any single report file is portable). `--light` bundles only `index.html`
|
|
76
|
+
+ the top-level reports (no drill pages or data) for a quick "read, don't drill" share.
|
|
77
|
+
|
|
78
|
+
### Sharing externally -- `--redact`
|
|
79
|
+
|
|
80
|
+
`bobframes package <root> --redact` produces a bundle safe to hand to someone outside your team. It
|
|
81
|
+
scrubs the GPU / driver / CPU / OS + capture-tool versions from every page's device strip (replaced with
|
|
82
|
+
`redacted`), drops the raw provenance sidecars (`_manifest.json`, `frame_metadata.jsonl`) from the
|
|
83
|
+
bundle, and replaces absolute Windows paths (`C:\...`) with `<path redacted>` across the pages and the
|
|
84
|
+
downloadable CSVs. Redaction re-renders the tree, so `--inline --redact` is no longer a fast copy.
|
|
85
|
+
|
|
86
|
+
- `--redact-paths=strip` (default) -- replace the path tokens; the bundle stays usable on a real capture.
|
|
87
|
+
- `--redact-paths=fail` -- a CI completeness check: exit nonzero (don't write the zip) if any absolute
|
|
88
|
+
path remains in a rendered page, so a leak fails the build.
|
|
89
|
+
|
|
90
|
+
**Caveat:** the pages and the downloadable CSVs are sanitized, but the **binary `.parquet`** tables still
|
|
91
|
+
contain resource paths (they can't be string-edited safely) -- strip `_data/` if the parquet itself must
|
|
92
|
+
leave your team. UNC (`\\host\share`) and forward-slash (`C:/...`) paths are not auto-stripped.
|
|
93
|
+
|
|
94
|
+
## Customizing reports
|
|
95
|
+
|
|
96
|
+
The look is shadcn-clean, neutral, and flat by default. Two ways to re-color it:
|
|
97
|
+
|
|
98
|
+
### Pip installs -- re-hue without editing source (recommended)
|
|
99
|
+
|
|
100
|
+
`pip install bobframes` puts the design tokens in site-packages, where edits are lost on upgrade -- so
|
|
101
|
+
re-hue the accent / status / chart colors through the config cascade instead:
|
|
102
|
+
|
|
103
|
+
- **Persistent:** add a `[theme]` section to `.bobframes.toml` in your capture root (or
|
|
104
|
+
`%APPDATA%/bobframes/config.toml`). `bobframes export-tokens --theme-template` prints a ready-to-paste
|
|
105
|
+
starter with just the overridable color knobs.
|
|
106
|
+
- **One-shot:** `bobframes render . --accent '<oklch>'` (and `--accent-data '<oklch>'`) -- the top
|
|
107
|
+
precedence tier (CLI > env > config > bundled default). `bobframes preview --accent '<oklch>'` previews
|
|
108
|
+
it with no capture data.
|
|
109
|
+
|
|
110
|
+
Only color hues (accent, the four status colors, the draw-class + chart palette) are overridable; layout,
|
|
111
|
+
spacing, type, and the table engine stay bundled, so an override can never desync the rendering. A bad or
|
|
112
|
+
non-color value warns and is ignored. `--watch` live-reloads on `.bobframes.toml` edits too.
|
|
113
|
+
|
|
114
|
+
### Source checkouts -- edit the bundled tokens
|
|
115
|
+
|
|
116
|
+
The full palette lives in `bobframes/reports/design_tokens.toml` (colors, spacing, type, motion, radius,
|
|
117
|
+
and base layout sizes). The CSS variable name is fixed by its key: `surface_0` becomes `--surface-0`,
|
|
118
|
+
`accent_primary` becomes `--accent-primary`.
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
bobframes preview # writes _reports/_chrome_preview.html (every component, no data)
|
|
122
|
+
# edit a value in design_tokens.toml
|
|
123
|
+
bobframes preview # under a second; reload the page in a browser
|
|
124
|
+
bobframes render C:\captures # apply the change to real reports from existing Parquet
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`bobframes render --watch` re-runs render-only whenever `design_tokens.toml`, a chrome module, or
|
|
128
|
+
`.bobframes.toml` changes (alpha; a 500ms poll, no extra dependency). `bobframes export-tokens --format
|
|
129
|
+
css` prints the live `:root` block; `--format json` the nested table; `--format toml` the file itself.
|
|
130
|
+
|
|
131
|
+
## External tools
|
|
132
|
+
|
|
133
|
+
The export stage runs `renderdoccmd convert`; the replay stage runs `qrenderdoc --python`. bobframes
|
|
134
|
+
resolves both from (in order) a config file (`.bobframes.toml`), version-globbed Arm Performance Studio
|
|
135
|
+
install paths, and `PATH`. Install RenderDoc / Arm Performance Studio anywhere on those, or point a
|
|
136
|
+
config entry at it. Run `bobframes check` to see what was resolved.
|
|
137
|
+
|
|
138
|
+
## Output layout
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
<root>/
|
|
142
|
+
index.html root catalog view
|
|
143
|
+
<area>/<drop>/ raw RDC inputs (left untouched)
|
|
144
|
+
_data/ pipeline outputs
|
|
145
|
+
_catalog.parquet (+ .csv, .json)
|
|
146
|
+
_global_entities.parquet (+ .csv)
|
|
147
|
+
_query_examples.md
|
|
148
|
+
<area>/<drop>/ per-drop data (29 Parquet tables)
|
|
149
|
+
*.parquet (+ matching .csv)
|
|
150
|
+
_manifest.json, _resource_labels.json
|
|
151
|
+
shader_src/*.glsl, jsonl sidecars
|
|
152
|
+
done.marker
|
|
153
|
+
_reports/ rendered HTML
|
|
154
|
+
*.html (dashboard + reports)
|
|
155
|
+
ab/<pair>/*.html
|
|
156
|
+
drill/<area>/<drop>/index.html per-drop browser
|
|
157
|
+
_cache/
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The catalog stores each drop's path relative to `<root>` for portability.
|
|
161
|
+
|
|
162
|
+
## Migrating from `_analysis`
|
|
163
|
+
|
|
164
|
+
v1 is a hard rename of the older project-embedded `_analysis` package, with no compatibility shim:
|
|
165
|
+
`python -m _analysis.*` stops working once `bobframes` is installed. Map old invocations to new ones:
|
|
166
|
+
|
|
167
|
+
| Old (`_analysis`) | New (`bobframes`) |
|
|
168
|
+
|---|---|
|
|
169
|
+
| `python -m _analysis.run --root . --area X --label Y` | `bobframes ingest . --area X --label Y` |
|
|
170
|
+
| `python -m _analysis.reports.ab --root . --baseline-label X --compare-label Y` | `bobframes ab . --baseline-label X --compare-label Y` |
|
|
171
|
+
| `python -m _analysis.lint <file>` | `bobframes lint <file>` |
|
|
172
|
+
| `python -m _analysis.tests.smoke` | `bobframes smoke` |
|
|
173
|
+
|
|
174
|
+
## Troubleshooting
|
|
175
|
+
|
|
176
|
+
| Symptom | Resolution |
|
|
177
|
+
|---|---|
|
|
178
|
+
| `renderdoccmd not found` (exit 3) | Install RenderDoc or Arm Performance Studio, or put the executable on `PATH`; confirm with `bobframes check`. |
|
|
179
|
+
| `qrenderdoc` replay hangs | v1 kills the replay process tree on timeout and records `capture_status='replay_failed'` for that capture; the rest of the drop still completes. Re-run with `--force` to retry. |
|
|
180
|
+
| Lint failure during render | The emitted HTML contains a banned token. Run `bobframes lint <file>` to see the line and label. |
|
|
181
|
+
| `schema mismatch` (exit 1) | A drop's `_manifest.json` schema version differs from the installed schema. Rebuild it with `bobframes ingest --force` (the v1 schema-migration path; see G-3). |
|
|
182
|
+
| Permission denied on `_data` | Close any viewer holding a Parquet open, then re-run; writes are staged and renamed atomically. |
|
|
183
|
+
|
|
184
|
+
## Advanced
|
|
185
|
+
|
|
186
|
+
- A/B reports: `bobframes ab . --baseline-label OLD --compare-label NEW` builds a side-by-side set.
|
|
187
|
+
- Programmatic use: import `bobframes.schemas`, `bobframes.discovery`, and `bobframes.paths` to drive
|
|
188
|
+
table lookups, drop discovery, and path resolution from your own scripts.
|
|
189
|
+
- `bobframes/probes/whatif.py` is a manual qrenderdoc-side probe and is not wired as a CLI command.
|
|
190
|
+
- TOML config (`.bobframes.toml`), an externalized draw classifier, and design-token theming
|
|
191
|
+
(`[theme]` / `--accent`) shipped in v0.2.6. `bobframes package` produces shareable, optionally
|
|
192
|
+
redacted bundles (see [Sharing a report](#sharing-a-report)).
|
|
193
|
+
|
|
194
|
+
## Built for Mayhem Studios
|
|
195
|
+
|
|
196
|
+
BobFrames is built and maintained for **Mayhem Studios** -- it powers the studio's GPU
|
|
197
|
+
capture-analysis and frame-performance work, and is open-sourced here for the wider RenderDoc and
|
|
198
|
+
graphics community.
|
|
199
|
+
|
|
200
|
+
If BobFrames helps your work, please **support Mayhem Studios** -- the studio that makes this tool
|
|
201
|
+
possible. Follow the studio, play and wishlist our games, and tell a friend who fights frame times.
|
|
202
|
+
A on the [GitHub repo](https://github.com/altpsyche/bobframes) helps too. Thank you.
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -56,6 +56,10 @@ preset = "ue" # draw_classifier.toml (UE default); "unity"/"godot"
|
|
|
56
56
|
shader_complexity_high = 60.0 # fragment shaders at/above this complexity are flagged
|
|
57
57
|
overdraw_reject_warn_pct = 40.0 # RT sample-rejection % -> warn callout
|
|
58
58
|
overdraw_reject_alarm_pct = 70.0 # RT sample-rejection % -> alarm callout
|
|
59
|
-
instancing_repeat_min = 4 # min mesh repeat to
|
|
60
|
-
gpu_regression_pct = 10.0 # latest-vs-previous GPU increase % -> regression
|
|
59
|
+
instancing_repeat_min = 4 # min mesh repeat PER FRAME to flag an instancing candidate (c16v: repeat + shader cost are per-frame rates, normalized by the drop's captured-frame count)
|
|
60
|
+
gpu_regression_pct = 10.0 # latest-vs-previous GPU/frame increase % -> regression (per frame, capture-count-independent)
|
|
61
|
+
draws_regression_pct = 10.0 # H-41 — per-KPI trend regression thresholds (were baked in trend_table.KPIS literals)
|
|
62
|
+
vbo_regression_pct = 15.0 # " vertex-buffer bytes / frame
|
|
63
|
+
ibo_regression_pct = 15.0 # " index-buffer bytes / frame
|
|
64
|
+
program_switches_regression_pct = 20.0 # " program switches / frame
|
|
61
65
|
max_prerendered_runs = 10 # c16f — cap on pre-rendered older-run pages (run selector)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.7"
|