Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ this file as both a release log and a lightweight development progress record.

### Added

- Phase35 native-vs-modern DisplayEngine visual validation foundation for OVMF
X64: `Scripts/capture-displayengine-ovmf-x64.sh` creates separated native and
modern overlay/build/capture artifact paths under a safe TMPDIR default,
`Tests/Manual/DisplayEngineOvmfX64Visual.md` documents evidence levels and
limitations, and smoke checks enforce the script/doc contract without claiming
visual verification.
- Phase34 DisplayEngine row rendering hardening: statement row GOP surfaces now
classify highlighted/selected, disabled/locked, read-only, changed, invalid,
modal, and action/text affordance state through the private FormModel helpers,
Expand Down
9 changes: 8 additions & 1 deletion Docs/ProductizationValidationMatrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,27 @@ The validation terms below describe current evidence only:
- `Script`: a repository script exists and is checked for syntax/metadata.
- `Manual`: local maintainer validation path is documented, but not CI-gated.
- `Captured`: screenshot/screendump evidence exists for a path.
- `Visual reviewed`: captured native-vs-modern screenshots were inspected by a maintainer; do not use this term for static smoke, build-only, or QEMU boot-only results.
- `Build/script validation`: the script/overlay path is validated without claiming graphical runtime evidence.
- `Planned`: documented target or behavior only; do not describe it as validated.

## XArch Target Validation Matrix

| XArch target | Concrete edk2 ARCH | Platform path | Primary scripts | Current maturity evidence | Productization validation notes |
| --- | --- | --- | --- | --- | --- |
| X64 / OVMF X64 | `X64` | `OvmfPkg/OvmfPkgX64` | `Scripts/build-ovmf-x64.sh`, `Scripts/run-ovmf-x64.sh`, `Scripts/capture-ovmf-x64.sh` | Manual OVMF build/run/capture path; smoke overlay generation; local/manual App validation. | Evidence supports target metadata, native/modern DisplayEngine overlay separation, and local screenshot capture path. |
| X64 / OVMF X64 | `X64` | `OvmfPkg/OvmfPkgX64` | `Scripts/build-ovmf-x64.sh`, `Scripts/run-ovmf-x64.sh`, `Scripts/capture-ovmf-x64.sh`, `Scripts/capture-displayengine-ovmf-x64.sh` | Manual OVMF build/run/capture path; smoke overlay generation; local/manual App validation; Phase35 native-vs-modern DisplayEngine evidence path pending visual review. | Evidence supports target metadata, native/modern DisplayEngine overlay separation, and local screenshot capture path. The DisplayEngine A/B helper defaults to `${TMPDIR:-/tmp}/modernsetup-qemu/displayengine-ovmf-x64` and only becomes screenshot evidence after `--mode capture` produces artifacts. |
| AARCH64 / ArmVirtQemu | `AARCH64` | `ArmVirtPkg/ArmVirtQemu` | `Scripts/build-armvirt.sh`, `Scripts/run-armvirt.sh`, `Scripts/capture-armvirt.sh`, `Scripts/build-modern-app.sh` | Captured ArmVirt before/after evidence; active build/run path; smoke overlay generation. | Primary compatibility capture path for native UiApp/FormBrowser plus ModernDisplayEngine. |
| LOONGARCH64 / LoongArchVirtQemu | `LOONGARCH64` | `OvmfPkg/LoongArchVirt/LoongArchVirtQemu` | `Scripts/build-loongarchvirt.sh`, `Scripts/run-loongarchvirt.sh` | Active build/run script path; smoke overlay generation. | Evidence covers generated overlays and documented manual run path; external cross toolchain remains product-team responsibility. |
| RISCV64 / RiscVVirtQemu | `RISCV64` | `OvmfPkg/RiscVVirt/RiscVVirtQemu` | `Scripts/build-riscvvirt.sh` | Build/script validation; smoke overlay generation. | RISCV64 remains Build/script validation in Phase30; graphical QEMU helper and captured UI evidence are not claimed. |

`Scripts/xarch-validate.sh --all --mode dry-run --format json` is the fast target metadata smoke companion. In Phase30 the smoke gate asserts four target `PASS` results and preserves the RISCV64 `Build/script validation` maturity wording.

## Phase35 DisplayEngine Visual Evidence Path

`Tests/Manual/DisplayEngineOvmfX64Visual.md` documents the OVMF X64 native-vs-modern DisplayEngine visual workflow. `Scripts/capture-displayengine-ovmf-x64.sh` drives the existing OVMF overlay generator with `MODERN_SETUP_DISPLAY_ENGINE=native` and `MODERN_SETUP_DISPLAY_ENGINE=modern`, keeps artifacts separated under `overlays/native`, `overlays/modern`, `firmware/native`, `firmware/modern`, and optional `native`/`modern` capture directories, and preserves upstream edk2 platform files by writing overlays only under `Build/ModernSetupPkgOverlay`. The helper does not inspect pixels and does not mark visual equivalence as verified.

Current Phase35 status in this matrix is `Script`/`Manual` foundation only. Static smoke can check that the helper and manual workflow exist; `--mode generate-only` can check overlay snapshots; `--mode build` can check firmware FD snapshots; only `--mode capture` with successful QEMU `screendump` output creates visual screenshot evidence, and the helper does not inspect pixels or mark visual equivalence as verified.

## Product Class Validation Matrix

| Product class | Evidence-backed App role | Native owner / boundary | Current validation evidence |
Expand Down
9 changes: 8 additions & 1 deletion Docs/ProductizationValidationMatrix.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,27 @@ XArch 是 ModernSetupPkg 的跨架构验证/产品化术语。XArch 不会替代
- `Script`:仓库脚本存在,并被语法/元数据检查覆盖。
- `Manual`:本地维护者验证路径已有文档,但不是 CI gate。
- `Captured`:相关路径有截图或 screendump 证据。
- `Visual reviewed`:维护者已检查 native-vs-modern 截图;不要将此术语用于 static smoke、仅构建或仅 QEMU 启动结果。
- `Build/script validation`:脚本或 overlay 路径已验证,但不声明图形运行证据。
- `Planned`:仅为规划或已记录目标,不应描述成已验证。

## XArch 目标验证矩阵

| XArch 目标 | 具体 edk2 ARCH | 平台路径 | 主要脚本 | 当前成熟度证据 | 产品化验证说明 |
| --- | --- | --- | --- | --- | --- |
| X64 / OVMF X64 | `X64` | `OvmfPkg/OvmfPkgX64` | `Scripts/build-ovmf-x64.sh`, `Scripts/run-ovmf-x64.sh`, `Scripts/capture-ovmf-x64.sh` | Manual OVMF 构建/运行/捕获路径;smoke overlay generation;本地/手动 App 验证。 | 证据覆盖目标元数据、native/modern DisplayEngine overlay 分离和本地截图捕获路径。 |
| X64 / OVMF X64 | `X64` | `OvmfPkg/OvmfPkgX64` | `Scripts/build-ovmf-x64.sh`, `Scripts/run-ovmf-x64.sh`, `Scripts/capture-ovmf-x64.sh`, `Scripts/capture-displayengine-ovmf-x64.sh` | Manual OVMF 构建/运行/捕获路径;smoke overlay generation;本地/手动 App 验证;Phase35 native-vs-modern DisplayEngine 证据路径待 visual review。 | 证据覆盖目标元数据、native/modern DisplayEngine overlay 分离和本地截图捕获路径。DisplayEngine A/B helper 默认输出到 `${TMPDIR:-/tmp}/modernsetup-qemu/displayengine-ovmf-x64`,只有 `--mode capture` 产出 artifact 后才属于截图证据。 |
| AARCH64 / ArmVirtQemu | `AARCH64` | `ArmVirtPkg/ArmVirtQemu` | `Scripts/build-armvirt.sh`, `Scripts/run-armvirt.sh`, `Scripts/capture-armvirt.sh`, `Scripts/build-modern-app.sh` | Captured ArmVirt before/after 证据;active 构建/运行路径;smoke overlay generation。 | native UiApp/FormBrowser 加 ModernDisplayEngine 的主要兼容性捕获路径。 |
| LOONGARCH64 / LoongArchVirtQemu | `LOONGARCH64` | `OvmfPkg/LoongArchVirt/LoongArchVirtQemu` | `Scripts/build-loongarchvirt.sh`, `Scripts/run-loongarchvirt.sh` | Active 构建/运行脚本路径;smoke overlay generation。 | 证据覆盖生成 overlay 和已记录的手动运行路径;外部交叉工具链仍由产品团队负责。 |
| RISCV64 / RiscVVirtQemu | `RISCV64` | `OvmfPkg/RiscVVirt/RiscVVirtQemu` | `Scripts/build-riscvvirt.sh` | Build/script validation;smoke overlay generation。 | Phase30 中 RISCV64 仍保持 Build/script validation;不声明图形 QEMU helper 或捕获 UI 证据。 |

`Scripts/xarch-validate.sh --all --mode dry-run --format json` 是快速目标元数据 smoke 辅助检查。Phase30 smoke gate 会断言四个目标均为 `PASS`,并保持 RISCV64 的 `Build/script validation` 成熟度用语。

## Phase35 DisplayEngine 视觉证据路径

`Tests/Manual/DisplayEngineOvmfX64Visual.md` 记录 OVMF X64 native-vs-modern DisplayEngine 视觉工作流。`Scripts/capture-displayengine-ovmf-x64.sh` 使用 `MODERN_SETUP_DISPLAY_ENGINE=native` 和 `MODERN_SETUP_DISPLAY_ENGINE=modern` 两次驱动既有 OVMF overlay 生成器,将 artifact 分离到 `overlays/native`、`overlays/modern`、`firmware/native`、`firmware/modern` 以及可选的 `native`/`modern` capture 目录,并只在 `Build/ModernSetupPkgOverlay` 下写 overlay,保持 upstream edk2 平台文件不被修改。

本矩阵中的 Phase35 当前状态仅为 `Script`/`Manual` foundation。Static smoke 可检查 helper 和手动工作流存在;`--mode generate-only` 可检查 overlay snapshot;`--mode build` 可检查 firmware FD snapshot;只有 `--mode capture` 成功产出 QEMU `screendump` 后才形成视觉截图证据,并且该 helper 不检查像素,也不会将视觉等价标记为 verified。

## 产品类别验证矩阵

| 产品类别 | 有证据支持的 App 角色 | 原生 owner / 边界 | 当前验证证据 |
Expand Down
212 changes: 212 additions & 0 deletions Scripts/capture-displayengine-ovmf-x64.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
#!/usr/bin/env bash
# Copyright (c) 2026, MarsDoge. All rights reserved.<BR>
# Author: MarsDoge (Dongyan Qian)
# Open source: https://github.com/MarsDoge/ModernSetupPkg
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
set -euo pipefail

PKG_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# shellcheck disable=SC1091
source "${PKG_DIR}/Scripts/edk2-workspace.sh"
WORKSPACE="$(DetectWorkspace)"
TARGET="${TARGET:-DEBUG}"
TOOL_CHAIN_TAG="${TOOL_CHAIN_TAG:-GCC}"
MODE="${MODE:-dry-run}"
BOOT_APP="${BOOT_APP:-0}"
BOOT_WAIT_SECONDS="${BOOT_WAIT_SECONDS:-12}"
SENDKEY_SEQUENCE="${SENDKEY_SEQUENCE:-esc,ret}"
CAPTURE_OUT_DIR="${CAPTURE_OUT_DIR:-${TMPDIR:-/tmp}/modernsetup-qemu/displayengine-ovmf-x64}"
CAPTURE_WORK_DIR="${CAPTURE_WORK_DIR:-${WORKSPACE}/Build/ModernSetupPkgCapture/DisplayEngineOvmfX64}"
BUILD_SCRIPT="${PKG_DIR}/Scripts/build-ovmf-x64.sh"
CAPTURE_SCRIPT="${PKG_DIR}/Scripts/capture-ovmf-x64.sh"

usage() {
cat <<'USAGE'
Usage: Scripts/capture-displayengine-ovmf-x64.sh [--mode dry-run|generate-only|build|capture]

Create an OVMF X64 native-vs-modern DisplayEngine evidence directory without
modifying upstream edk2 platform files. The helper drives the existing OVMF
overlay generator twice, once with MODERN_SETUP_DISPLAY_ENGINE=native and once
with MODERN_SETUP_DISPLAY_ENGINE=modern.

Modes:
dry-run Print the planned artifact paths and commands only. Default.
generate-only Generate and copy native/modern overlay DSC/FDF files only.
build Build each variant and copy OVMF_CODE.fd/OVMF_VARS.fd into the
evidence directory for stable later capture.
capture Build each variant, then invoke Scripts/capture-ovmf-x64.sh for
QEMU screendumps in native/ and modern/ subdirectories.

Important environment overrides:
WORKSPACE edk2 workspace. Auto-detected like other scripts.
TARGET, TOOL_CHAIN_TAG, JOBS, MODERN_SETUP_THEME
CAPTURE_OUT_DIR default: ${TMPDIR:-/tmp}/modernsetup-qemu/displayengine-ovmf-x64
CAPTURE_WORK_DIR default: ${WORKSPACE}/Build/ModernSetupPkgCapture/DisplayEngineOvmfX64
BOOT_APP default: 0, firmware/FormBrowser capture path
BOOT_WAIT_SECONDS default: 12
SENDKEY_SEQUENCE default: esc,ret; comma-separated QEMU monitor sendkey list

Limitations: capture mode collects QEMU screendumps and serial logs, but it does not inspect pixels and cannot guarantee host-independent navigation into a given
FormBrowser page. Treat generated files/builds/captures as separate evidence
levels in docs and reports.
USAGE
}

while [[ $# -gt 0 ]]; do
case "$1" in
--help|-h)
usage
exit 0
;;
--mode)
if [[ $# -lt 2 ]]; then
echo "Missing value for --mode" >&2
exit 2
fi
MODE="$2"
shift 2
;;
--mode=*)
MODE="${1#--mode=}"
shift
;;
*)
echo "Unknown option '$1'" >&2
usage >&2
exit 2
;;
esac
done

case "${MODE}" in
dry-run|generate-only|build|capture) ;;
*)
echo "Unsupported MODE/--mode '${MODE}'; use dry-run, generate-only, build, or capture" >&2
exit 2
;;
esac

if [[ -z "${CAPTURE_OUT_DIR}" ]]; then
echo "CAPTURE_OUT_DIR must not be empty" >&2
exit 2
fi

variants=(native modern)

locate_build_fd() {
local name="$1"
local found=""
shopt -s nullglob
for candidate in "${WORKSPACE}"/Build/OvmfX64*/"${TARGET}_${TOOL_CHAIN_TAG}"/FV/"${name}"; do
if [[ -z "${found}" || "${candidate}" -nt "${found}" ]]; then
found="${candidate}"
fi
done
shopt -u nullglob
if [[ -n "${found}" ]]; then
printf '%s\n' "${found}"
fi
}

copy_overlay_artifacts() {
local variant="$1"
local variant_overlay_dir="${CAPTURE_OUT_DIR}/overlays/${variant}"
mkdir -p "${variant_overlay_dir}"
cp "${WORKSPACE}/Build/ModernSetupPkgOverlay/OvmfX64ModernSetup.dsc" "${variant_overlay_dir}/OvmfX64ModernSetup.dsc"
cp "${WORKSPACE}/Build/ModernSetupPkgOverlay/OvmfX64ModernSetup.fdf" "${variant_overlay_dir}/OvmfX64ModernSetup.fdf"
}

copy_firmware_artifacts() {
local variant="$1"
local code_fd vars_fd variant_firmware_dir
code_fd="$(locate_build_fd OVMF_CODE.fd)"
vars_fd="$(locate_build_fd OVMF_VARS.fd)"
if [[ -z "${code_fd}" || -z "${vars_fd}" || ! -f "${code_fd}" || ! -f "${vars_fd}" ]]; then
echo "Unable to locate built OVMF_CODE.fd/OVMF_VARS.fd for ${variant} after build" >&2
exit 1
fi
variant_firmware_dir="${CAPTURE_OUT_DIR}/firmware/${variant}"
mkdir -p "${variant_firmware_dir}"
cp "${code_fd}" "${variant_firmware_dir}/OVMF_CODE.fd"
cp "${vars_fd}" "${variant_firmware_dir}/OVMF_VARS.fd"
}

run_variant() {
local variant="$1"
local generate_only=1
local variant_capture_dir

case "${MODE}" in
dry-run)
echo "Would run: MODERN_SETUP_DISPLAY_ENGINE=${variant} GENERATE_ONLY=1 ${BUILD_SCRIPT}"
echo "Would write overlay artifacts: ${CAPTURE_OUT_DIR}/overlays/${variant}/"
if [[ "${variant}" == "modern" ]]; then
echo "Modern variant keeps product path: EDKII_FORM_DISPLAY_ENGINE_PROTOCOL -> ModernDisplayEngineDxe -> ModernUiCustomizedDisplayLib -> private FormModel -> renderer"
else
echo "Native variant keeps upstream MdeModulePkg DisplayEngineDxe/CustomizedDisplayLib"
fi
return 0
;;
generate-only)
generate_only=1
;;
build|capture)
generate_only=0
;;
esac

MODERN_SETUP_DISPLAY_ENGINE="${variant}" GENERATE_ONLY="${generate_only}" "${BUILD_SCRIPT}"
copy_overlay_artifacts "${variant}"

if [[ "${MODE}" == "build" || "${MODE}" == "capture" ]]; then
copy_firmware_artifacts "${variant}"
fi

if [[ "${MODE}" == "capture" ]]; then
variant_capture_dir="${CAPTURE_OUT_DIR}/${variant}"
mkdir -p "${variant_capture_dir}"
OVMF_CODE="${CAPTURE_OUT_DIR}/firmware/${variant}/OVMF_CODE.fd" \
OVMF_VARS="${CAPTURE_OUT_DIR}/firmware/${variant}/OVMF_VARS.fd" \
BOOT_APP="${BOOT_APP}" \
BOOT_WAIT_SECONDS="${BOOT_WAIT_SECONDS}" \
SENDKEY_SEQUENCE="${SENDKEY_SEQUENCE}" \
CAPTURE_OUT_DIR="${variant_capture_dir}" \
CAPTURE_WORK_DIR="${CAPTURE_WORK_DIR}/${variant}" \
CAPTURE_PREFIX="displayengine-ovmf-x64-${variant}" \
"${CAPTURE_SCRIPT}"
fi
}

mkdir -p "${CAPTURE_OUT_DIR}" "${CAPTURE_WORK_DIR}"

cat > "${CAPTURE_OUT_DIR}/README.txt" <<EOF_README
DisplayEngine OVMF X64 native-vs-modern evidence directory
Mode: ${MODE}
Workspace: ${WORKSPACE}
Target/toolchain: ${TARGET}_${TOOL_CHAIN_TAG}
Native selector: MODERN_SETUP_DISPLAY_ENGINE=native
Modern selector: MODERN_SETUP_DISPLAY_ENGINE=modern
Default output root: \${TMPDIR:-/tmp}/modernsetup-qemu/displayengine-ovmf-x64

Evidence levels:
- dry-run: no overlay, build, QEMU, or visual evidence.
- generate-only: overlay DSC/FDF snapshots only.
- build: overlay plus OVMF_CODE.fd/OVMF_VARS.fd snapshots.
- capture: build artifacts plus QEMU screendump files. This script does not
inspect pixels and does not mark visual equivalence as verified.
EOF_README

for variant in "${variants[@]}"; do
run_variant "${variant}"
done

echo "DisplayEngine OVMF X64 evidence root: ${CAPTURE_OUT_DIR}"
echo "Native artifacts: ${CAPTURE_OUT_DIR}/overlays/native"
echo "Modern artifacts: ${CAPTURE_OUT_DIR}/overlays/modern"
if [[ "${MODE}" == "capture" ]]; then
echo "Native capture dir: ${CAPTURE_OUT_DIR}/native"
echo "Modern capture dir: ${CAPTURE_OUT_DIR}/modern"
echo "Note: captures are screendump artifacts only; no pixel inspection was performed."
fi
Loading
Loading