Commit Graph

6 Commits

Author SHA1 Message Date
ykcheungab 433b76e43c 修复 Studio 失败测试并新增合并门禁
把丢失的 box 录像放回 apps/studio/tests/data/,修掉第 3 节 3–10 号与两处过时测试桩,
注册 timing 标记并让根目录收集零错误;新增 tools/gate.ps1 与可选的 pre-push 钩子。
验证:studio 524 通过 19 跳过、shared 467 通过 18 跳过、ui_check 632 项 0 失败、gate.ps1 退出码 0。
细节见 docs/test-repair-plan.zh.md。
2026-10-18 19:24:31 +08:00
ykcheungab ccedb9ddd9 migrate pyqt5 to pyside6 2026-09-21 09:34:56 +08:00
ykcheungab 5cd92254e1 feat(studio-3d): 阶段 5 —— 发布保护(签名/可选加密/平台锁定)与性能长时报告
- What: 新增 `scene3d/protect.py`(封套 v2:Ed25519 签名 + 可选 AES-256-GCM,nonce/salt 每包唯一、
  元数据作 AAD、明文摘要进签名、KeyProvider 只问 get_content_key)与 `record/visualization3d.py`
  (session.json 的 visualization3d 块:写入版本化、读取时缺块=不支持);`package.py` 支持 v2
  (payload=plain 仅签名 / aes-gcm 签名+加密)并继续读 v1,新增解压比上限与"写入后自读回"校验;
  `contracts.py` 新增 PlatformLock/PlatformInfo/check_platform_lock、Sealing、platform_mismatch 诊断码;
  `Scene3DView` 在装配前查 OS/架构、拿到 capabilities 后查图形半区,违反即撤下场景并在面板显示原因;
  工具 `compile_scene.py` 新增 --sign-key/--write-verify-key/--encrypt-key-id/--key-file/--lock-from-probe,
  `validate_scene.py` 新增 --key-file/--key-id/--verify-key/--require-signature(发布门禁),
  新增 `bench_scene.py`(p50/p95 分阶段 + --cpu-only + --vertices N + --package)与
  `soak_scene.py`(RSS 四分位速率 + 队列上界 + 抽稀采样);两份报告落到 docs/architecture/。
- Why: 规格 §5.2 的保护目标是"提高复制成本"而不是"防提取",所以要的是签名(来源)+ 可选认证加密(机密性)
  + 密钥隔离,而不是自制加密或把 ZIP 当加密;§12 的"包保护/性能/长时"三行需要可复现的数字与判定标准,
  而不是一次性的观感。平台锁定还必须只降级三维:锁定不通过时二维照常。
- Verification: shared 全量通过(新增 test_scene3d_protect.py 35 项:封套往返/篡改/密钥/锁定/记录块/
  compile→validate 端到端发布流程;test_scene3d_package.py 20 项含 v1↔v2 兼容);apps/studio 全量通过
  (test_scene3d_view.py 30 项含锁定拒绝与 session.json 块);ui_check 566 项 0 失败;locale_check 0 缺失;
  真实资产端到端:1032 顶点编译出 signed+sealed+locked 包(56 927 B 密文),validate --require-signature 退出 0,
  改一个字节退出 2;性能报告(perf-report-windows-dev.json):1032 顶点 compose p50 0.50 ms(30 fps 上限内),
  20022 顶点/39480 三角形 compose p50 6.15 ms(约 33 ms 帧的 18%),采集线程 submit p95 < 0.4 ms(合成器被人为放慢到 50 ms);
  长时报告(soak-report-windows-dev.json):无窗口 10 min/60 fps 尾段 0.354 MB/min,GUI 4 min/30 fps 尾段 0.809 MB/min,
  队列上界(mailbox=1、单飞行合成)两者均成立。过程中修掉:GUI 进程里的合成器计时被 GIL/vsync 污染(98.8 ms vs 真值 6.1 ms)、
  跨线程读 last_stats 撕裂、key id 无 provider 时会静默写明文包、soak 工具自身记时间列表会无界增长、RSS 读取失败伪装成零增长、
  平台锁定不是终态诊断。
- Not in this change: ARM 板卡的能力报告与 2 小时门禁运行(按用户要求暂缓;命令与判定标准已写入阶段 5 文档);
  GPU 显存随时间的测量(无可移植 API,报告说明渲染器缓冲估计恒定且更新路径不新建 GPU 对象);
  `cryptography` 在此环境无法联网安装,本机验收用的是本机已有的 cp310 构建(pyproject 里已声明为可选 extra
  `protected-assets`)。
2026-09-14 16:44:33 +08:00
ykcheungab 5767b4bf11 阶段 1:平台 PoC —— 真实 GL 上跑通静态场景,并修掉它抓出的相机/上下文错误 - What: 按 docs/architecture/studio-3d-stages.md 阶段 1 落地图形栈。OrbitCamera 全部实现(target/distance/yaw/pitch 表示;fit 按包围球与较窄的那个视场轴定距离;orbit/pan/zoom 有界;set_preset 从 eye/target 反解角度使拖动可延续;matrices 输出只读 float32 view/projection;另加 depth_range_m() 便于断言)。gl_backend:GLDispatch.bind_current_context 真正绑定 PyOpenGL 并读 vendor/renderer/GL/GLSL/max texture、判软件渲染、profile 不达标时抛 ThreeDUnsupported 并带回能力;GLRenderer 实现 initialize(两个 program,desktop33/gles30 共用同一份着色器主体、只换头部)、upload_scene(每 part 一套 VAO/VBO/EBO,交错 layout position/normal/scalar/valid = 8 float)、update_surface(只对感知面 glBufferSubData,绝不重建索引)、draw(绑 Qt 的 defaultFramebufferObject、深度测试、按 role 选 program、housing 隐藏即跳过、scalar 经 LUT 纹理与 range uniform 上色,Python 不生成 RGB 数组)、release(幂等);纯函数 pack_part/pack_scene_part/estimate_gpu_bytes/rest_surface/shader_source/shader_header/lut_rgba/is_software_renderer/profile_from_renderable_type 都可在无 GPU 环境测试。Sensor3DWidget 实现 initializeGL/paintGL/resizeGL/release_resources/aboutToBeDestroyed/showEvent/hideEvent 与鼠标事件;加载场景时先采用资产自带的默认视角再 fit;一帧几何不匹配只"拒绝该帧"(计数 + 诊断 + 用 rest_surface 清掉上次测量)而不是把整个视图打成不可用。shared/scene3d/synthetic.py 提供 PoC 与测试共用的已知场景(20mm 感知板 + 外壳盒,米、sensor 坐标系、带默认三视角预设)。tools/scene_assets/probe_gl.py 真实现:真实窗口取 context 并输出 JSON 报告(平台/Qt/PyOpenGL/vendor/renderer/GL/GLSL/DPR/framebuffer/是否软件渲染),退出码即门禁(0 通过、3 软件渲染、4 无上下文);apps/studio/pyproject.toml 增加 [three-d] 可选依赖(仅 PyOpenGL;Open3D 不进运行时)。测试:apps/studio/tests/test_scene3d_stage1.py 24 项(相机数学、PoC 场景合规、打包布局、着色器两方言共用主体、LUT、软件渲染识别、renderableType 映射、GPU 预算、参考帧语义,全部无需 GPU)+ test_scene3d_gl_smoke.py 8 项(真实 context:能力、两个 part 都画出来、外壳可隐藏、参考帧中性 vs 色图有差异、动态更新不动 housing 缓冲、坏几何帧被拒且视图存活、resize 跟随、release 幂等且新 context 能重传场景、探针如实报告);offscreen 下后者自动 skip。docs/architecture/gl-report-windows-dev.json 为本机平台报告。 - Why: 用户要求"从骨架搭起→计划阶段→逐阶段实现与验收",并明确 ARM 暂缓。阶段 1 的产出本身就是一份能回答"这块板的图形栈能不能用"的报告,所以先把它做实、把 profile 冻结点定在真实 context 上,而不是先堆屏幕上的东西。 - Verification: 真实 context(QT_QPA_PLATFORM=windows)下 8 项 GL 验收全过;offscreen 下 24 项 CPU 项全过、GL 项按设计 skip;shared 全量 187 passed;studio 全量 116 passed(含新 32 项);ui_check 554 项 0 失败;probe_gl 输出 verdict=ok(NVIDIA RTX 4080 SUPER、GL 3.3 Core、GLSL 3.30、非软件渲染)。过程中这套验收抓出并修掉了 7 个真实缺陷:Qt renderableType 映射反了(NVIDIA 兼容 ES 着色器所以本机看不出,Intel/ARM 会直接失败)、观察相机是左手基导致整模型镜像(det=-1)、近平面过近使 NDC z 全挤在 0.99(深度精度归零、外壳与感知面会 z-fighting)、手动 makeCurrent 早于 Qt 首次绘制会把 GPU 对象建在被丢弃的 context 里(glBindVertexArray 报 INVALID_OPERATION)、context 重建后不重传场景、一帧几何不匹配把整个视图打死、以及 grabFramebuffer 是 BGRA+stride 导致颜色断言全部读错通道。 - Not in this change: 未接入 app_window/main.py(三维对现有应用仍完全惰性,故"开/关三维 CSV 行序一致"这条验收随阶段 4 做);阶段 2 的资产导入/坐标/包格式;ARM 平台实测(probe 已可在板上直接运行)。 2026-09-14 14:55:45 +08:00
ykcheungab 904c27125f changed customer to studio 2026-09-12 14:03:00 +08:00
ykcheungab a2db648560 dsh ui improve: add brand bar 2026-09-12 13:51:05 +08:00