Skip to content

Commit e1a0684

Browse files
authored
Merge pull request #379 from smuppand/Display
graphics: add adaptive FPS policy to weston-simple-egl
2 parents 6a8cec2 + cd8cfd5 commit e1a0684

2 files changed

Lines changed: 263 additions & 85 deletions

File tree

Runner/suites/Multimedia/Graphics/weston-simple-egl/run.sh

Lines changed: 41 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,21 @@ RUN_LOG="./${TESTNAME}_run.log"
5252
# ---------------------------------------------------------------------------
5353
DURATION="${DURATION:-30s}"
5454
STOP_GRACE="${STOP_GRACE:-3s}"
55-
EXPECT_FPS="${EXPECT_FPS:-60}"
55+
FPS_EXPECT_MODE="${FPS_EXPECT_MODE:-auto}"
56+
EXPECT_FPS="${EXPECT_FPS:-}"
57+
EXPECT_FPS_DEFAULT="${EXPECT_FPS_DEFAULT:-60}"
5658
FPS_TOL_PCT="${FPS_TOL_PCT:-10}"
59+
MIN_FPS_PCT="${MIN_FPS_PCT:-85}"
5760
REQUIRE_FPS="${REQUIRE_FPS:-1}"
5861

5962
# Detect overlay by presence of Adreno GLVND vendor JSON
6063
BUILD_FLAVOUR="base"
6164
EGL_VENDOR_JSON=""
62-
65+
6366
# Check common vendor JSON locations and filename patterns
6467
for d in /usr/share/glvnd/egl_vendor.d /etc/glvnd/egl_vendor.d; do
6568
[ -d "$d" ] || continue
66-
69+
6770
# Try both naming styles: 10_adreno.json and 10_EGL_adreno.json
6871
for f in "$d"/*adreno*.json "$d"/*EGL_adreno*.json; do
6972
[ -e "$f" ] || continue
@@ -74,24 +77,23 @@ for d in /usr/share/glvnd/egl_vendor.d /etc/glvnd/egl_vendor.d; do
7477
fi
7578
done
7679
done
77-
80+
7881
log_info "Weston log directory: $SCRIPT_DIR"
7982
log_info "--------------------------------------------------------------------------"
8083
log_info "------------------- Starting ${TESTNAME} Testcase --------------------------"
81-
84+
8285
# Optional platform details (helper from functestlib)
8386
if command -v detect_platform >/dev/null 2>&1; then
8487
detect_platform
8588
fi
86-
89+
8790
if [ "$BUILD_FLAVOUR" = "overlay" ]; then
8891
log_info "Build flavor: overlay (EGL vendor JSON present: ${EGL_VENDOR_JSON})"
8992
else
9093
log_info "Build flavor: base (no Adreno EGL vendor JSON found)"
9194
fi
9295

93-
log_info "Config: DURATION=${DURATION} STOP_GRACE=${STOP_GRACE} EXPECT_FPS=${EXPECT_FPS}+/-${FPS_TOL_PCT}% REQUIRE_FPS=${REQUIRE_FPS} BUILD_FLAVOUR=${BUILD_FLAVOUR}"
94-
96+
log_info "Input config: DURATION=${DURATION} STOP_GRACE=${STOP_GRACE} FPS_EXPECT_MODE=${FPS_EXPECT_MODE} EXPECT_FPS=${EXPECT_FPS:-<unset>} EXPECT_FPS_DEFAULT=${EXPECT_FPS_DEFAULT} (fallback) FPS_TOL_PCT=${FPS_TOL_PCT}% MIN_FPS_PCT=${MIN_FPS_PCT}% REQUIRE_FPS=${REQUIRE_FPS} BUILD_FLAVOUR=${BUILD_FLAVOUR}"
9597
# ---------------------------------------------------------------------------
9698
# Display snapshot
9799
# ---------------------------------------------------------------------------
@@ -224,29 +226,31 @@ else
224226
log_warn "wayland_connection_ok helper not found continuing without explicit Wayland probe."
225227
fi
226228

229+
if ! display_resolve_fps_policy; then
230+
log_fail "Failed to resolve FPS policy"
231+
echo "${TESTNAME} FAIL" >"$RES_FILE"
232+
exit 0
233+
fi
234+
235+
if [ "${DISPLAY_FPS_MODE:-}" = "detected" ]; then
236+
log_info "Resolved FPS policy: mode=${DISPLAY_FPS_MODE} refresh=${DISPLAY_FPS_DETECTED_HZ}Hz expected=${DISPLAY_FPS_EXPECTED} min_ok=${DISPLAY_FPS_MIN_OK}"
237+
else
238+
log_info "Resolved FPS policy: mode=${DISPLAY_FPS_MODE} expected=${DISPLAY_FPS_EXPECTED} range=[${DISPLAY_FPS_MIN_OK}, ${DISPLAY_FPS_MAX_OK}]"
239+
fi
227240
# ---------------------------------------------------------------------------
228-
# Ensure primary output is ~60Hz (best-effort, no churn if already ~60Hz)
241+
# Apply refresh policy resolved in lib_display.sh
229242
# ---------------------------------------------------------------------------
230243
if command -v display_debug_snapshot >/dev/null 2>&1; then
231-
display_debug_snapshot "${TESTNAME}: before-ensure-60hz"
244+
display_debug_snapshot "${TESTNAME}: before-refresh-policy"
232245
fi
233246
if command -v wayland_debug_snapshot >/dev/null 2>&1; then
234-
wayland_debug_snapshot "${TESTNAME}: before-ensure-60hz"
247+
wayland_debug_snapshot "${TESTNAME}: before-refresh-policy"
235248
fi
236249

237-
if command -v weston_force_primary_1080p60_if_not_60 >/dev/null 2>&1; then
238-
log_info "Ensuring primary output is ~60Hz (best-effort) ..."
239-
if weston_force_primary_1080p60_if_not_60; then
240-
log_info "Primary output is ~60Hz (or was already ~60Hz)."
241-
else
242-
log_warn "Unable to force ~60Hz (continuing; not a hard failure)."
243-
fi
244-
else
245-
log_warn "weston_force_primary_1080p60_if_not_60 helper not found; skipping ~60Hz enforcement."
246-
fi
250+
display_apply_fps_refresh_policy || true
247251

248252
if command -v display_debug_snapshot >/dev/null 2>&1; then
249-
display_debug_snapshot "${TESTNAME}: after-ensure-60hz"
253+
display_debug_snapshot "${TESTNAME}: after-refresh-policy"
250254
fi
251255

252256
# --- Skip if only CPU/software renderer is active (GPU HW accel not enabled) ---
@@ -328,51 +332,19 @@ log_info "Client finished: rc=${rc} elapsed=${elapsed}s"
328332
# FPS parsing: average / min / max from all intervals
329333
# - Discard FIRST sample as warm-up if we have 2+ samples.
330334
# ---------------------------------------------------------------------------
335+
# ---------------------------------------------------------------------------
336+
# FPS parsing
337+
# ---------------------------------------------------------------------------
331338
fps_count=0
332339
fps_avg="-"
333340
fps_min="-"
334341
fps_max="-"
335342

336-
fps_stats=$(
337-
awk '
338-
/[0-9]+[[:space:]]+frames in[[:space:]]+[0-9]+[[:space:]]+seconds/ {
339-
val = $(NF-1) + 0.0
340-
all_n++
341-
all_vals[all_n] = val
342-
}
343-
END {
344-
if (all_n == 0) exit
345-
346-
if (all_n == 1) {
347-
n = 1
348-
sum = all_vals[1]
349-
min = all_vals[1]
350-
max = all_vals[1]
351-
} else {
352-
n = 0
353-
sum = 0.0
354-
for (i = 2; i <= all_n; i++) {
355-
v = all_vals[i]
356-
n++
357-
sum += v
358-
if (n == 1 || v < min) min = v
359-
if (n == 1 || v > max) max = v
360-
}
361-
}
362-
363-
if (n > 0) {
364-
avg = sum / n
365-
printf "n=%d avg=%f min=%f max=%f\n", n, avg, min, max
366-
}
367-
}' "$RUN_LOG" 2>/dev/null || true
368-
)
369-
370-
if [ -n "$fps_stats" ]; then
371-
fps_count=$(printf '%s\n' "$fps_stats" | awk '{print $1}' | sed 's/^n=//')
372-
fps_avg=$(printf '%s\n' "$fps_stats" | awk '{print $2}' | sed 's/^avg=//')
373-
fps_min=$(printf '%s\n' "$fps_stats" | awk '{print $3}' | sed 's/^min=//')
374-
fps_max=$(printf '%s\n' "$fps_stats" | awk '{print $4}' | sed 's/^max=//')
375-
343+
if display_parse_fps_log "$RUN_LOG"; then
344+
fps_count="$DISPLAY_FPS_COUNT"
345+
fps_avg="$DISPLAY_FPS_AVG"
346+
fps_min="$DISPLAY_FPS_MIN"
347+
fps_max="$DISPLAY_FPS_MAX"
376348
log_info "FPS stats from ${RUN_LOG}: samples=${fps_count} avg=${fps_avg} min=${fps_min} max=${fps_max}"
377349
else
378350
log_warn "No FPS lines detected in ${RUN_LOG} weston-simple-egl may not have emitted FPS stats (or output was truncated)."
@@ -383,7 +355,11 @@ if [ "$fps_count" -eq 0 ]; then
383355
fps_for_summary="-"
384356
fi
385357

386-
log_info "Result summary: rc=${rc} elapsed=${elapsed}s fps=${fps_for_summary} (expected ~${EXPECT_FPS}+/-${FPS_TOL_PCT}%)"
358+
if [ "${DISPLAY_FPS_MODE:-}" = "detected" ]; then
359+
log_info "Result summary: rc=${rc} elapsed=${elapsed}s fps=${fps_for_summary} mode=${DISPLAY_FPS_MODE} refresh=${DISPLAY_FPS_DETECTED_HZ}Hz expected=${DISPLAY_FPS_EXPECTED} min_ok=${DISPLAY_FPS_MIN_OK}"
360+
else
361+
log_info "Result summary: rc=${rc} elapsed=${elapsed}s fps=${fps_for_summary} mode=${DISPLAY_FPS_MODE} expected=${DISPLAY_FPS_EXPECTED} range=[${DISPLAY_FPS_MIN_OK}, ${DISPLAY_FPS_MAX_OK}]"
362+
fi
387363

388364
# ---------------------------------------------------------------------------
389365
# PASS / FAIL decision
@@ -401,28 +377,8 @@ if [ "$elapsed" -le 1 ]; then
401377
final="FAIL"
402378
fi
403379

404-
# FPS gating if explicitly required
405-
if [ "$REQUIRE_FPS" -ne 0 ]; then
406-
if [ "$fps_count" -eq 0 ]; then
407-
log_fail "FPS gating enabled (REQUIRE_FPS=${REQUIRE_FPS}) but no FPS samples were found treating as FAIL."
408-
final="FAIL"
409-
else
410-
min_ok=$(awk -v f="$EXPECT_FPS" -v tol="$FPS_TOL_PCT" 'BEGIN { printf "%.0f\n", f * (100.0 - tol) / 100.0 }')
411-
max_ok=$(awk -v f="$EXPECT_FPS" -v tol="$FPS_TOL_PCT" 'BEGIN { printf "%.0f\n", f * (100.0 + tol) / 100.0 }')
412-
413-
fps_int=$(printf '%s\n' "$fps_avg" | awk 'BEGIN {v=0} {v=$1+0.0} END {printf "%.0f\n", v}')
414-
415-
if [ "$fps_int" -lt "$min_ok" ] || [ "$fps_int" -gt "$max_ok" ]; then
416-
log_fail "Average FPS out of range: avg=${fps_avg} (~${fps_int}) not in [${min_ok}, ${max_ok}] (EXPECT_FPS=${EXPECT_FPS}, tol=${FPS_TOL_PCT}%)."
417-
final="FAIL"
418-
fi
419-
fi
420-
else
421-
if [ "$fps_count" -eq 0 ]; then
422-
log_warn "REQUIRE_FPS=0 and no FPS samples found skipping FPS gating."
423-
else
424-
log_info "REQUIRE_FPS=0 FPS stats recorded but not used for gating."
425-
fi
380+
if ! display_fps_gate_avg "$fps_avg" "$fps_count"; then
381+
final="FAIL"
426382
fi
427383

428384
log_info "Final decision for ${TESTNAME}: ${final}"

0 commit comments

Comments
 (0)