55# DRM display + Weston + Wayland helpers
66# (assumes log_info/log_warn/log_error and run_with_timeout from functestlib.sh)
77# ##############################################################################
8-
98# ##############################################################################
109# Internal helpers
1110# ##############################################################################
11+ # These are intentional cache outputs used by callers after display_print_eglinfo_pipeline().
12+ # ShellCheck cannot always see cross-file/global usage.
13+ # shellcheck disable=SC2034
14+ EGLI_LAST_PLATFORM=" "
15+ EGLI_LAST_DRIVER=" "
16+ EGLI_LAST_GL_VENDOR=" "
17+ EGLI_LAST_GL_RENDERER=" "
18+ EGLI_LAST_PIPE_KIND=" "
19+ EGLI_LAST_OUT=" "
20+
1221debugfs_is_mounted () {
1322 awk ' $3=="debugfs" && $2=="/sys/kernel/debug" {found=1} END{exit(found?0:1)}' /proc/mounts 2> /dev/null
1423}
@@ -1062,6 +1071,66 @@ egli_pick_platform_flag() {
10621071 return 0
10631072}
10641073
1074+ egli_glvnd_icd_from_json () {
1075+ # Extract ICD library_path from a GLVND EGL vendor JSON (no jq).
1076+ # Prints the value (e.g., libEGL_adreno.so.1) or empty on failure.
1077+ f=" $1 "
1078+ [ -r " $f " ] || { printf ' %s\n' " " ; return 0; }
1079+
1080+ # Match a line containing "library_path" : "...."
1081+ # Keep it resilient to whitespace.
1082+ sed -n ' s/.*"library_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' " $f " | head -n 1
1083+ }
1084+
1085+ egli_glvnd_icd_from_json () {
1086+ # Extract ICD library_path from a GLVND EGL vendor JSON (no jq).
1087+ # Prints the value (e.g., libEGL_adreno.so.1) or empty on failure.
1088+ f=" $1 "
1089+ [ -r " $f " ] || { printf ' %s\n' " " ; return 0; }
1090+
1091+ # Match a line containing "library_path" : "...."
1092+ # Keep it resilient to whitespace.
1093+ sed -n ' s/.*"library_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' " $f " | head -n 1
1094+ }
1095+
1096+ egli_derive_driver_name () {
1097+ # Best-effort for log readability only.
1098+ # Inputs: gl_vendor gl_renderer
1099+ v=" $1 "
1100+ r=" $2 "
1101+
1102+ # Qualcomm/Adreno path
1103+ if printf ' %s %s\n' " $v " " $r " | grep -Eqi ' (qualcomm|adreno)' ; then
1104+ icd=" "
1105+ if [ -f /usr/share/glvnd/egl_vendor.d/10_EGL_adreno.json ]; then
1106+ icd=" $( egli_glvnd_icd_from_json /usr/share/glvnd/egl_vendor.d/10_EGL_adreno.json) "
1107+ fi
1108+ if [ -n " $icd " ]; then
1109+ printf ' %s\n' " adreno ($icd )"
1110+ return 0
1111+ fi
1112+ printf ' %s\n' " adreno"
1113+ return 0
1114+ fi
1115+
1116+ # Mesa path
1117+ if printf ' %s %s\n' " $v " " $r " | grep -Eqi ' (mesa|llvmpipe|softpipe|swrast|lavapipe)' ; then
1118+ icd=" "
1119+ if [ -f /usr/share/glvnd/egl_vendor.d/50_mesa.json ]; then
1120+ icd=" $( egli_glvnd_icd_from_json /usr/share/glvnd/egl_vendor.d/50_mesa.json) "
1121+ fi
1122+ if [ -n " $icd " ]; then
1123+ printf ' %s\n' " mesa ($icd )"
1124+ return 0
1125+ fi
1126+ printf ' %s\n' " mesa"
1127+ return 0
1128+ fi
1129+
1130+ printf ' %s\n' " unknown"
1131+ return 0
1132+ }
1133+
10651134egli_get_field () {
10661135 key=" $1 "
10671136 awk -v k=" $key " '
@@ -1142,6 +1211,32 @@ egli_classify_pipeline() {
11421211 return 0
11431212}
11441213
1214+ egli_wayland_socket_ok () {
1215+ wd=" ${WAYLAND_DISPLAY:- } "
1216+ [ -n " $wd " ] || return 1
1217+
1218+ case " $wd " in
1219+ /* )
1220+ [ -S " $wd " ] && return 0
1221+ return 1
1222+ ;;
1223+ * )
1224+ xrd=" ${XDG_RUNTIME_DIR:- } "
1225+ if [ -n " $xrd " ]; then
1226+ [ -S " $xrd /$wd " ] && return 0
1227+ return 1
1228+ fi
1229+
1230+ # Fallbacks when XDG_RUNTIME_DIR is unset (common in minimal shells)
1231+ [ -S " /run/user/0/$wd " ] && return 0
1232+ [ -S " /run/user/1000/$wd " ] && return 0
1233+ [ -S " /run/$wd " ] && return 0
1234+
1235+ return 1
1236+ ;;
1237+ esac
1238+ }
1239+
11451240egli_print_legacy () {
11461241 plat=" $1 "
11471242 driver=" $2 "
@@ -1182,9 +1277,9 @@ egli_try_one_platform() {
11821277 egl_api_ver=" $( printf ' %s\n' " $out " | egli_get_field " EGL API version" ) "
11831278
11841279 ok=0
1185- if [ -n " $egl_vendor " ]; then ok=1; fi
1186- if [ -n " $egl_version " ]; then ok=1; fi
1187- if [ -n " $egl_api_ver " ]; then ok=1; fi
1280+ [ -n " $egl_vendor " ] && ok=1
1281+ [ -n " $egl_version " ] && ok=1
1282+ [ -n " $egl_api_ver " ] && ok=1
11881283
11891284 if [ " $rc " -ne 0 ] || [ " $ok " -eq 0 ]; then
11901285 log_warn " eglinfo platform '$plat ' did not initialize cleanly (rc=$rc )."
@@ -1203,35 +1298,47 @@ egli_try_one_platform() {
12031298 " Driver name" \
12041299 " Driver" ) "
12051300
1206- # GL vendor (prefer explicit GL_VENDOR if present)
1301+ # GL vendor
12071302 gl_vendor=" $( egli_get_first " $out " \
12081303 " GL_VENDOR" \
12091304 " OpenGL ES profile vendor string" \
12101305 " OpenGL vendor string" \
12111306 " OpenGL ES vendor string" ) "
12121307
1213- # GL renderer (prefer explicit GL_RENDERER if present)
1308+ # GL renderer
12141309 gl_renderer=" $( egli_get_first " $out " \
12151310 " GL_RENDERER" \
12161311 " OpenGL ES profile renderer string" \
12171312 " OpenGL renderer string" \
12181313 " OpenGL ES renderer string" ) "
12191314
1220- # NEW: avoid classification on empty strings
1315+ # Avoid classification on empty strings
12211316 [ -n " $driver " ] || driver=" unknown"
12221317 [ -n " $gl_vendor " ] || gl_vendor=" unknown"
12231318 [ -n " $gl_renderer " ] || gl_renderer=" unknown"
12241319
1225- # If we got nothing useful, treat as failure (prevents misleading GPU/CPU label)
1226- if [ " $driver " = " unknown" ] && [ " $gl_vendor " = " unknown" ] && [ " $gl_renderer " = " unknown" ]; then
1227- log_warn " eglinfo platform '$plat ' returned no driver/vendor/renderer strings; skipping classification."
1228- return 1
1320+ # If eglinfo didn't expose a driver name, derive one from GLVND JSON + strings
1321+ if [ " $driver " = " unknown" ]; then
1322+ driver=" $( egli_derive_driver_name " $gl_vendor " " $gl_renderer " ) "
12291323 fi
12301324
1231- # Print GPU/CPU pipeline type (align to your sample: no extra indentation)
1325+ # Print GPU/CPU pipeline type
12321326 pipe_kind=" $( egli_classify_pipeline " $driver " " $gl_vendor " " $gl_renderer " ) "
12331327 log_info " EGLINFO: Pipeline type: $pipe_kind "
12341328
1329+ # ---- Cache what we used, so decision uses the same data ----
1330+ EGLI_LAST_PLATFORM=" $plat "
1331+ EGLI_LAST_DRIVER=" $driver "
1332+ EGLI_LAST_GL_VENDOR=" $gl_vendor "
1333+ EGLI_LAST_GL_RENDERER=" $gl_renderer "
1334+ EGLI_LAST_PIPE_KIND=" $pipe_kind "
1335+ if [ " ${EGLINFO_CACHE_OUTPUT:- 0} " = " 1" ]; then
1336+ EGLI_LAST_OUT=" $out "
1337+ else
1338+ EGLI_LAST_OUT=" "
1339+ fi
1340+ # -----------------------------------------------------------
1341+
12351342 egli_print_legacy " $plat " " $driver " " $gl_vendor " " $gl_renderer "
12361343 return 0
12371344}
@@ -1240,20 +1347,28 @@ display_print_eglinfo_pipeline() {
12401347 # Usage: display_print_eglinfo_pipeline auto|wayland|gbm|device|surfaceless
12411348 mode=" ${1:- auto} "
12421349
1350+ # Clear cached result on every call (prevents stale decisions)
1351+ EGLI_LAST_PLATFORM=" "
1352+ EGLI_LAST_DRIVER=" "
1353+ EGLI_LAST_GL_VENDOR=" "
1354+ EGLI_LAST_GL_RENDERER=" "
1355+ EGLI_LAST_PIPE_KIND=" "
1356+ EGLI_LAST_OUT=" "
1357+
12431358 EGLINFO=" ${EGLINFO:- eglinfo} "
12441359 if ! command -v " $EGLINFO " > /dev/null 2>&1 ; then
12451360 log_error " eglinfo not found (EGLINFO='$EGLINFO ')"
12461361 return 1
12471362 fi
12481363
1249- # NOTE: unchanged usage; now egli_pick_platform_flag can return 1
1250- # but when it does, plat_flag will be empty and caller already checked eglinfo.
1364+ # egli_pick_platform_flag may return non-zero; treat empty as "use EGL_PLATFORM="
12511365 plat_flag=" $( egli_pick_platform_flag 2> /dev/null) " || plat_flag=" "
12521366
12531367 log_info " ---------------- EGLINFO pipeline detection (select one) ----------------"
12541368
12551369 if [ " $mode " = " auto" ]; then
1256- if [ -n " ${WAYLAND_DISPLAY:- } " ]; then
1370+ # Prefer wayland only if the socket really exists (base/prop handled)
1371+ if egli_wayland_socket_ok; then
12571372 if egli_try_one_platform " wayland" " $plat_flag " ; then
12581373 log_info " ---------------- End EGLINFO pipeline detection --------------------------"
12591374 return 0
@@ -1282,18 +1397,24 @@ display_print_eglinfo_pipeline() {
12821397
12831398 case " $mode " in
12841399 wayland|gbm|device|surfaceless)
1285- if ! egli_try_one_platform " $mode " " $plat_flag " ; then
1400+ # If user explicitly requested wayland but socket is not present, warn and fallback
1401+ if [ " $mode " = " wayland" ] && ! egli_wayland_socket_ok; then
1402+ log_warn " Requested 'wayland' but WAYLAND_DISPLAY socket is not present; trying fallbacks..."
1403+ else
1404+ if egli_try_one_platform " $mode " " $plat_flag " ; then
1405+ log_info " ---------------- End EGLINFO pipeline detection --------------------------"
1406+ return 0
1407+ fi
12861408 log_warn " Requested '$mode ' did not work. Trying fallbacks..."
1409+ fi
12871410
1288- if ! egli_try_one_platform " gbm" " $plat_flag " ; then
1289- if ! egli_try_one_platform " device" " $plat_flag " ; then
1290- if ! egli_try_one_platform " surfaceless" " $plat_flag " ; then
1291- if ! egli_try_one_platform " wayland" " $plat_flag " ; then
1292- log_warn " No fallback platforms worked either."
1293- fi
1294- fi
1295- fi
1296- fi
1411+ # Fallback order: gbm -> device -> surfaceless -> wayland (last)
1412+ if egli_try_one_platform " gbm" " $plat_flag " ; then : ;
1413+ elif egli_try_one_platform " device" " $plat_flag " ; then : ;
1414+ elif egli_try_one_platform " surfaceless" " $plat_flag " ; then : ;
1415+ elif egli_wayland_socket_ok && egli_try_one_platform " wayland" " $plat_flag " ; then : ;
1416+ else
1417+ log_warn " No fallback platforms worked either."
12971418 fi
12981419
12991420 log_info " ---------------- End EGLINFO pipeline detection --------------------------"
@@ -1312,102 +1433,21 @@ display_print_eglinfo_pipeline() {
13121433# ##############################################################################
13131434display_is_cpu_renderer () {
13141435 # Usage: display_is_cpu_renderer <mode>
1315- # Prints EGLINFO block when called (your requirement ).
1436+ # Prints EGLINFO block via display_print_eglinfo_pipeline( ).
13161437 # Returns: 0 if CPU/software renderer detected, 1 otherwise (GPU or unknown)
13171438 mode=" ${1:- auto} "
13181439
1319- # Always print EGLINFO pipeline detection (do NOT redirect )
1440+ # Print + cache a single selected platform (no re-run of eglinfo for decision )
13201441 display_print_eglinfo_pipeline " $mode " || true
13211442
1322- EGLINFO= " ${EGLINFO :- eglinfo} "
1323- if ! command -v " $EGLINFO " > /dev/null 2>&1 ; then
1443+ # If we couldn't cache anything usable, do NOT claim CPU.
1444+ if [ -z " ${EGLI_LAST_PIPE_KIND :- } " ] ; then
13241445 return 1
13251446 fi
13261447
1327- # NOTE: unchanged usage; now egli_pick_platform_flag can return 1
1328- plat_flag=" $( egli_pick_platform_flag 2> /dev/null) " || plat_flag=" "
1329-
1330- # Run eglinfo and decide CPU/software for one platform.
1331- # Return 0 if CPU/software, 1 otherwise.
1332- egli_is_cpu_for_platform () {
1333- p=" $1 "
1334-
1335- if [ -n " $plat_flag " ]; then
1336- out=" $( " $EGLINFO " " $plat_flag " " $p " 2>&1 ) "
1337- rc=$?
1338- else
1339- out=" $( EGL_PLATFORM=" $p " " $EGLINFO " 2>&1 ) "
1340- rc=$?
1341- fi
1342-
1343- # Must initialize
1344- egl_vendor=" $( printf ' %s\n' " $out " | egli_get_field " EGL vendor string" ) "
1345- egl_version=" $( printf ' %s\n' " $out " | egli_get_field " EGL version string" ) "
1346- egl_api_ver=" $( printf ' %s\n' " $out " | egli_get_field " EGL API version" ) "
1347-
1348- ok=0
1349- if [ -n " $egl_vendor " ]; then ok=1; fi
1350- if [ -n " $egl_version " ]; then ok=1; fi
1351- if [ -n " $egl_api_ver " ]; then ok=1; fi
1352- if [ " $rc " -ne 0 ] || [ " $ok " -eq 0 ]; then
1353- return 1
1354- fi
1355-
1356- driver=" $( egli_get_first " $out " \
1357- " EGL driver name" \
1358- " EGL driver" \
1359- " Driver name" \
1360- " Driver" ) "
1361-
1362- gl_vendor=" $( egli_get_first " $out " \
1363- " GL_VENDOR" \
1364- " OpenGL ES profile vendor string" \
1365- " OpenGL vendor string" \
1366- " OpenGL ES vendor string" ) "
1367-
1368- gl_renderer=" $( egli_get_first " $out " \
1369- " GL_RENDERER" \
1370- " OpenGL ES profile renderer string" \
1371- " OpenGL renderer string" \
1372- " OpenGL ES renderer string" ) "
1373-
1374- # NEW: avoid classification on empty strings
1375- [ -n " $driver " ] || driver=" unknown"
1376- [ -n " $gl_vendor " ] || gl_vendor=" unknown"
1377- [ -n " $gl_renderer " ] || gl_renderer=" unknown"
1378-
1379- # If we got nothing useful, treat as not-CPU (unknown) rather than mislabel
1380- if [ " $driver " = " unknown" ] && [ " $gl_vendor " = " unknown" ] && [ " $gl_renderer " = " unknown" ]; then
1381- return 1
1382- fi
1383-
1384- pipe_kind=" $( egli_classify_pipeline " $driver " " $gl_vendor " " $gl_renderer " ) "
1385- if printf ' %s\n' " $pipe_kind " | grep -qi ' ^CPU' ; then
1386- return 0
1387- fi
1388- return 1
1389- }
1390-
1391- if [ " $mode " = " auto" ]; then
1392- # Match display_print_eglinfo_pipeline(auto) preference order.
1393- if [ -n " ${WAYLAND_DISPLAY:- } " ]; then
1394- if egli_is_cpu_for_platform " wayland" ; then return 0; fi
1395- fi
1396- if egli_is_cpu_for_platform " gbm" ; then return 0; fi
1397- if egli_is_cpu_for_platform " device" ; then return 0; fi
1398- if egli_is_cpu_for_platform " surfaceless" ; then return 0; fi
1399- return 1
1448+ if printf ' %s\n' " $EGLI_LAST_PIPE_KIND " | grep -qi ' ^CPU' ; then
1449+ return 0
14001450 fi
14011451
1402- case " $mode " in
1403- wayland|gbm|device|surfaceless)
1404- if egli_is_cpu_for_platform " $mode " ; then
1405- return 0
1406- fi
1407- return 1
1408- ;;
1409- * )
1410- return 1
1411- ;;
1412- esac
1452+ return 1
14131453}
0 commit comments