0037-egl-add-config-debug-printout.patch 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. From a5c947e12d7b29419f8996ca3a7beeefe424d8dc Mon Sep 17 00:00:00 2001
  2. From: Silvestrs Timofejevs <silvestrs.timofejevs@imgtec.com>
  3. Date: Mon, 24 Sep 2018 14:14:25 +0100
  4. Subject: [PATCH] egl: add config debug printout
  5. Feature to print out EGL returned configs for debug purposes.
  6. 'eglChooseConfig' and 'eglGetConfigs' debug information printout is
  7. enabled when the log level equals '_EGL_DEBUG'. The configs are
  8. printed, and if any of them are "chosen" they are marked with their
  9. index in the chosen configs array.
  10. ---
  11. src/egl/main/eglconfig.c | 20 ++-
  12. src/egl/main/eglconfigdebug.c | 321 ++++++++++++++++++++++++++++++++++
  13. src/egl/main/eglconfigdebug.h | 55 ++++++
  14. src/egl/main/egllog.c | 9 +
  15. src/egl/main/egllog.h | 4 +
  16. src/egl/meson.build | 2 +
  17. 6 files changed, 407 insertions(+), 4 deletions(-)
  18. create mode 100644 src/egl/main/eglconfigdebug.c
  19. create mode 100644 src/egl/main/eglconfigdebug.h
  20. diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
  21. index 5e56948..ea4b3c1 100644
  22. --- a/src/egl/main/eglconfig.c
  23. +++ b/src/egl/main/eglconfig.c
  24. @@ -40,6 +40,7 @@
  25. #include "util/macros.h"
  26. #include "eglconfig.h"
  27. +#include "eglconfigdebug.h"
  28. #include "egldisplay.h"
  29. #include "eglcurrent.h"
  30. #include "egllog.h"
  31. @@ -1039,14 +1040,21 @@ _eglChooseConfig(_EGLDisplay *disp, const EGLint *attrib_list,
  32. EGLConfig *configs, EGLint config_size, EGLint *num_configs)
  33. {
  34. _EGLConfig criteria;
  35. + EGLBoolean result;
  36. if (!_eglParseConfigAttribList(&criteria, disp, attrib_list))
  37. return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
  38. - return _eglFilterConfigArray(disp->Configs,
  39. - configs, config_size, num_configs,
  40. - _eglFallbackMatch, _eglFallbackCompare,
  41. - (void *) &criteria);
  42. + result = _eglFilterConfigArray(disp->Configs,
  43. + configs, config_size, num_configs,
  44. + _eglFallbackMatch, _eglFallbackCompare,
  45. + (void *) &criteria);
  46. +
  47. + if (result && (_eglGetLogLevel() == _EGL_DEBUG))
  48. + eglPrintConfigDebug(disp, configs, *num_configs,
  49. + EGL_CONFIG_DEBUG_CHOOSE);
  50. +
  51. + return result;
  52. }
  53. @@ -1096,5 +1104,9 @@ _eglGetConfigs(_EGLDisplay *disp, EGLConfig *configs,
  54. *num_config = _eglFlattenArray(disp->Configs, (void *) configs,
  55. sizeof(configs[0]), config_size, _eglFlattenConfig);
  56. + if (_eglGetLogLevel() == _EGL_DEBUG)
  57. + eglPrintConfigDebug(disp, configs, *num_config,
  58. + EGL_CONFIG_DEBUG_GET);
  59. +
  60. return EGL_TRUE;
  61. }
  62. diff --git a/src/egl/main/eglconfigdebug.c b/src/egl/main/eglconfigdebug.c
  63. new file mode 100644
  64. index 0000000..92ac41a
  65. --- /dev/null
  66. +++ b/src/egl/main/eglconfigdebug.c
  67. @@ -0,0 +1,321 @@
  68. +/*
  69. + * Copyright 2017 Imagination Technologies.
  70. + * All Rights Reserved.
  71. + *
  72. + * Based on eglinfo, which has copyright:
  73. + * Copyright (C) 2005 Brian Paul All Rights Reserved.
  74. + *
  75. + * Permission is hereby granted, free of charge, to any person obtaining a
  76. + * copy of this software and associated documentation files (the "Software"),
  77. + * to deal in the Software without restriction, including without limitation
  78. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  79. + * and/or sell copies of the Software, and to permit persons to whom the
  80. + * Software is furnished to do so, subject to the following conditions:
  81. + *
  82. + * The above copyright notice and this permission notice shall be included
  83. + * in all copies or substantial portions of the Software.
  84. + *
  85. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  86. + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  87. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  88. + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  89. + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  90. + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  91. + */
  92. +
  93. +#include <stdlib.h>
  94. +#include <string.h>
  95. +#include <stdio.h>
  96. +#include <stdarg.h>
  97. +
  98. +#include "eglarray.h"
  99. +#include "eglconfig.h"
  100. +#include "eglconfigdebug.h"
  101. +#include "egldisplay.h"
  102. +#include "egllog.h"
  103. +#include "egltypedefs.h"
  104. +
  105. +/* Max debug message length */
  106. +#define CONFIG_DEBUG_MSG_MAX 1000
  107. +
  108. +/*
  109. + * These are X visual types, so if you're running eglinfo under
  110. + * something not X, they probably don't make sense.
  111. + */
  112. +static const char *const vnames[] = { "SG", "GS", "SC", "PC", "TC", "DC" };
  113. +
  114. +struct _printAttributes {
  115. + EGLint id, size, level;
  116. + EGLint red, green, blue, alpha;
  117. + EGLint depth, stencil;
  118. + EGLint renderable, surfaces;
  119. + EGLint vid, vtype, caveat, bindRgb, bindRgba;
  120. + EGLint samples, sampleBuffers;
  121. + char surfString[100];
  122. + EGLint colorBufferType;
  123. + EGLint numPlanes, subsample, order;
  124. +};
  125. +
  126. +static void
  127. +_printHeaderFormat(void)
  128. +{
  129. + /*
  130. + * EGL configuration output legend:
  131. + *
  132. + * chosen --------------- eglChooseConfig returned config priority,
  133. + * only relevant when eglChooseConfig is called.
  134. + * id ------------------- EGL_CONFIG_ID
  135. + * bfsz ----------------- EGL_BUFFER_SIZE
  136. + * lvl ------------------ EGL_LEVEL
  137. + *
  138. + * color size
  139. + * r -------------------- EGL_RED_SIZE
  140. + * g -------------------- EGL_GREEN_SIZE
  141. + * b -------------------- EGL_BLUE_SIZE
  142. + * a -------------------- EGL_ALPHA_SIZE
  143. + * dpth ----------------- EGL_DEPTH_SIZE
  144. + * stcl ----------------- EGL_STENCIL_SIZE
  145. + *
  146. + * multisample
  147. + * ns ------------------- EGL_SAMPLES
  148. + * b -------------------- EGL_SAMPLE_BUFFERS
  149. + * visid ---------------- EGL_NATIVE_VISUAL_ID/EGL_NATIVE_VISUAL_TYPE
  150. + * caveat --------------- EGL_CONFIG_CAVEAT
  151. + * bind ----------------- EGL_BIND_TO_TEXTURE_RGB/EGL_BIND_TO_TEXTURE_RGBA
  152. + *
  153. + * renderable
  154. + * gl, es, es2, es3, vg - EGL_RENDERABLE_TYPE
  155. + *
  156. + * supported
  157. + * surfaces ------------- EGL_SURFACE_TYPE
  158. + * colbuf --------------- EGL_COLOR_BUFFER_TYPE
  159. + *
  160. + * yuv
  161. + * p -------------------- EGL_YUV_NUMBER_OF_PLANES_EXT
  162. + * sub ------------------ EGL_YUV_SUBSAMPLE_EXT
  163. + * ord ------------------ EGL_YUV_ORDER_EXT
  164. + */
  165. + _eglLog(_EGL_DEBUG, "---------------");
  166. + _eglLog(_EGL_DEBUG, "Configurations:");
  167. + _eglLog(_EGL_DEBUG, "cho bf lv color size dp st ms vis cav bi renderable supported"
  168. + " col yuv ");
  169. + _eglLog(_EGL_DEBUG, "sen id sz l r g b a th cl ns b id eat nd gl es es2 es3 vg surfaces"
  170. + " buf p sub ord");
  171. + _eglLog(_EGL_DEBUG, "---------------");
  172. +}
  173. +
  174. +static void
  175. +_snprintfStrcat(char *const msg, const int maxSize, const char *fmt, ...)
  176. +{
  177. + int maxAllowed;
  178. + va_list args;
  179. +
  180. + maxAllowed = maxSize - strlen(msg);
  181. +
  182. + va_start(args, fmt);
  183. + (void) vsnprintf(&msg[strlen(msg)], maxAllowed, fmt, args);
  184. + va_end(args);
  185. +}
  186. +
  187. +static inline const char *_enumToString(EGLint constant)
  188. +{
  189. + switch (constant) {
  190. + case EGL_YUV_SUBSAMPLE_4_2_0_EXT: return "420";
  191. + case EGL_YUV_SUBSAMPLE_4_2_2_EXT: return "422";
  192. + case EGL_YUV_SUBSAMPLE_4_4_4_EXT: return "444";
  193. + case EGL_YUV_ORDER_AYUV_EXT: return "AYUV";
  194. + case EGL_YUV_ORDER_UYVY_EXT: return "UYVY";
  195. + case EGL_YUV_ORDER_VYUY_EXT: return "VYUY";
  196. + case EGL_YUV_ORDER_YUYV_EXT: return "YUYV";
  197. + case EGL_YUV_ORDER_YVYU_EXT: return "YVYU";
  198. + case EGL_YUV_ORDER_YUV_EXT: return "YUV";
  199. + case EGL_YUV_ORDER_YVU_EXT: return "YVU";
  200. + case EGL_LUMINANCE_BUFFER: return "lum";
  201. + case EGL_YUV_BUFFER_EXT: return "yuv";
  202. + case EGL_RGB_BUFFER: return "rgb";
  203. + default: return "?";
  204. + }
  205. +}
  206. +
  207. +static void
  208. +_eglGetConfigAttrs(_EGLDisplay *const dpy, _EGLConfig *const conf,
  209. + struct _printAttributes *const attr)
  210. +{
  211. + EGLBoolean success = EGL_TRUE;
  212. +
  213. + success &= _eglGetConfigAttrib(dpy, conf, EGL_CONFIG_ID, &attr->id);
  214. + success &= _eglGetConfigAttrib(dpy, conf, EGL_BUFFER_SIZE, &attr->size);
  215. + success &= _eglGetConfigAttrib(dpy, conf, EGL_LEVEL, &attr->level);
  216. +
  217. + success &= _eglGetConfigAttrib(dpy, conf, EGL_RED_SIZE, &attr->red);
  218. + success &= _eglGetConfigAttrib(dpy, conf, EGL_GREEN_SIZE, &attr->green);
  219. + success &= _eglGetConfigAttrib(dpy, conf, EGL_BLUE_SIZE, &attr->blue);
  220. + success &= _eglGetConfigAttrib(dpy, conf, EGL_ALPHA_SIZE, &attr->alpha);
  221. + success &= _eglGetConfigAttrib(dpy, conf, EGL_DEPTH_SIZE, &attr->depth);
  222. + success &= _eglGetConfigAttrib(dpy, conf, EGL_STENCIL_SIZE, &attr->stencil);
  223. + success &= _eglGetConfigAttrib(dpy, conf, EGL_NATIVE_VISUAL_ID, &attr->vid);
  224. + success &= _eglGetConfigAttrib(dpy, conf, EGL_NATIVE_VISUAL_TYPE, &attr->vtype);
  225. +
  226. + success &= _eglGetConfigAttrib(dpy, conf, EGL_CONFIG_CAVEAT, &attr->caveat);
  227. + success &= _eglGetConfigAttrib(dpy, conf, EGL_BIND_TO_TEXTURE_RGB, &attr->bindRgb);
  228. + success &= _eglGetConfigAttrib(dpy, conf, EGL_BIND_TO_TEXTURE_RGBA, &attr->bindRgba);
  229. + success &= _eglGetConfigAttrib(dpy, conf, EGL_RENDERABLE_TYPE, &attr->renderable);
  230. + success &= _eglGetConfigAttrib(dpy, conf, EGL_SURFACE_TYPE, &attr->surfaces);
  231. +
  232. + success &= _eglGetConfigAttrib(dpy, conf, EGL_SAMPLES, &attr->samples);
  233. + success &= _eglGetConfigAttrib(dpy, conf, EGL_SAMPLE_BUFFERS, &attr->sampleBuffers);
  234. + success &= _eglGetConfigAttrib(dpy, conf, EGL_COLOR_BUFFER_TYPE, &attr->colorBufferType);
  235. +
  236. + if (conf->Display->Extensions.EXT_yuv_surface) {
  237. + success &= _eglGetConfigAttrib(dpy, conf, EGL_YUV_NUMBER_OF_PLANES_EXT,
  238. + &attr->numPlanes);
  239. + success &= _eglGetConfigAttrib(dpy, conf, EGL_YUV_SUBSAMPLE_EXT, &attr->subsample);
  240. + success &= _eglGetConfigAttrib(dpy, conf, EGL_YUV_ORDER_EXT, &attr->order);
  241. + }
  242. +
  243. + if (!success)
  244. + _eglLog(_EGL_DEBUG, "%s: config tainted, could not obtain all attributes",
  245. + __func__);
  246. +}
  247. +
  248. +static void
  249. +_eglPrintConfig(_EGLDisplay *const dpy, _EGLConfig *const conf,
  250. + char *const printMsg, const int maxMsgSize)
  251. +{
  252. + struct _printAttributes attr = { 0 };
  253. +
  254. + _eglGetConfigAttrs(dpy, conf, &attr);
  255. +
  256. + if (attr.surfaces & EGL_WINDOW_BIT)
  257. + strcat(attr.surfString, "win,");
  258. + if (attr.surfaces & EGL_PBUFFER_BIT)
  259. + strcat(attr.surfString, "pb,");
  260. + if (attr.surfaces & EGL_PIXMAP_BIT)
  261. + strcat(attr.surfString, "pix,");
  262. + if (attr.surfaces & EGL_STREAM_BIT_KHR)
  263. + strcat(attr.surfString, "str,");
  264. + if (attr.surfaces & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
  265. + strcat(attr.surfString, "prsv,");
  266. + if (strlen(attr.surfString) > 0)
  267. + attr.surfString[strlen(attr.surfString) - 1] = 0;
  268. +
  269. + _snprintfStrcat(printMsg, maxMsgSize,
  270. + "0x%03x %2d %2d %2d %2d %2d %2d %2d %2d %2d%2d 0x%08x%2s ",
  271. + attr.id, attr.size, attr.level,
  272. + attr.red, attr.green, attr.blue, attr.alpha,
  273. + attr.depth, attr.stencil,
  274. + attr.samples, attr.sampleBuffers, attr.vid,
  275. + attr.vtype < 6 ? vnames[attr.vtype] : "--");
  276. +
  277. + _snprintfStrcat(printMsg, maxMsgSize,
  278. + "%c %c %c %c %c %c %c %15s",
  279. + (attr.caveat != EGL_NONE) ? 'y' : ' ',
  280. + (attr.bindRgba) ? 'a' : (attr.bindRgb) ? 'y' : ' ',
  281. + (attr.renderable & EGL_OPENGL_BIT) ? 'y' : ' ',
  282. + (attr.renderable & EGL_OPENGL_ES_BIT) ? 'y' : ' ',
  283. + (attr.renderable & EGL_OPENGL_ES2_BIT) ? 'y' : ' ',
  284. + (attr.renderable & EGL_OPENGL_ES3_BIT) ? 'y' : ' ',
  285. + (attr.renderable & EGL_OPENVG_BIT) ? 'y' : ' ',
  286. + attr.surfString);
  287. +
  288. + _snprintfStrcat(printMsg, maxMsgSize, " %3.3s",
  289. + _enumToString(attr.colorBufferType));
  290. +
  291. + if (attr.colorBufferType == EGL_YUV_BUFFER_EXT)
  292. + _snprintfStrcat(printMsg, maxMsgSize, " %1.1d %3.3s %4.4s", attr.numPlanes,
  293. + _enumToString(attr.subsample), _enumToString(attr.order));
  294. +
  295. + _eglLog(_EGL_DEBUG, printMsg);
  296. +}
  297. +
  298. +static void
  299. +_eglMarkChosenConfig(_EGLConfig *const config,
  300. + _EGLConfig *const *const chosenConfigs,
  301. + const EGLint numConfigs, char *const printMsg,
  302. + const int maxMsgSize)
  303. +{
  304. + const char padding[] = " ";
  305. +
  306. + if (chosenConfigs == NULL) {
  307. + _snprintfStrcat(printMsg, maxMsgSize, "%s ", &padding[0]);
  308. + return;
  309. + }
  310. +
  311. + /* Find a match, "mark" and return */
  312. + for (EGLint i = 0; i < numConfigs; i++) {
  313. + if (config == chosenConfigs[i]) {
  314. + _snprintfStrcat(printMsg, maxMsgSize, "%*d ", strlen(padding), i);
  315. + return;
  316. + }
  317. + }
  318. +
  319. + _snprintfStrcat(printMsg, maxMsgSize, "%s ", &padding[0]);
  320. +}
  321. +
  322. +static void
  323. +_eglPrintConfigs(_EGLDisplay *const dpy,
  324. + EGLConfig *const configs, const EGLint numConfigs,
  325. + const enum EGL_CONFIG_DEBUG_OPTION printOption)
  326. +{
  327. + const int maxMsgSize = CONFIG_DEBUG_MSG_MAX;
  328. + EGLint numConfigsToPrint;
  329. + _EGLConfig **configsToPrint;
  330. + _EGLConfig **chosenConfigs;
  331. + char *printMsg;
  332. +
  333. + printMsg = malloc(maxMsgSize);
  334. + if (!printMsg) {
  335. + _eglLog(_EGL_DEBUG, "%s: failed to allocate the print message", __func__);
  336. + return;
  337. + }
  338. +
  339. + /*
  340. + * If the printout request came from the 'eglChooseConfig', all
  341. + * configs are printed, and the "chosen" configs are marked.
  342. + */
  343. + if (printOption == EGL_CONFIG_DEBUG_CHOOSE) {
  344. + configsToPrint = (_EGLConfig **) dpy->Configs->Elements;
  345. + numConfigsToPrint = dpy->Configs->Size;
  346. + chosenConfigs = (_EGLConfig **) configs;
  347. + } else {
  348. + assert(printOption == EGL_CONFIG_DEBUG_GET);
  349. + configsToPrint = (_EGLConfig **) configs;
  350. + numConfigsToPrint = numConfigs;
  351. + chosenConfigs = NULL;
  352. + }
  353. +
  354. + _printHeaderFormat();
  355. + for (EGLint i = 0; i < numConfigsToPrint; i++) {
  356. + _EGLConfig *configToPrint = configsToPrint[i];
  357. +
  358. + /* "clear" message */
  359. + printMsg[0] = '\0';
  360. +
  361. + _eglMarkChosenConfig(configToPrint, chosenConfigs, numConfigs,
  362. + printMsg, maxMsgSize);
  363. +
  364. + _eglPrintConfig(dpy, configToPrint, printMsg, maxMsgSize);
  365. + }
  366. +
  367. + free(printMsg);
  368. +}
  369. +
  370. +void eglPrintConfigDebug(_EGLDisplay *const dpy,
  371. + EGLConfig *const configs, const EGLint numConfigs,
  372. + const enum EGL_CONFIG_DEBUG_OPTION printOption)
  373. +{
  374. + if (!numConfigs || !configs) {
  375. + _eglLog(_EGL_DEBUG, "%s: nothing to print", __func__);
  376. + return;
  377. + }
  378. +
  379. + switch (printOption) {
  380. + case EGL_CONFIG_DEBUG_CHOOSE:
  381. + case EGL_CONFIG_DEBUG_GET:
  382. + _eglPrintConfigs(dpy, configs, numConfigs, printOption);
  383. + break;
  384. + default:
  385. + _eglLog(_EGL_DEBUG, "%s: bad debug option", __func__);
  386. + break;
  387. + }
  388. +}
  389. diff --git a/src/egl/main/eglconfigdebug.h b/src/egl/main/eglconfigdebug.h
  390. new file mode 100644
  391. index 0000000..562aeff
  392. --- /dev/null
  393. +++ b/src/egl/main/eglconfigdebug.h
  394. @@ -0,0 +1,55 @@
  395. +/**************************************************************************
  396. + * Copyright 2017 Imagination Technologies.
  397. + * All Rights Reserved.
  398. + *
  399. + * Permission is hereby granted, free of charge, to any person obtaining a
  400. + * copy of this software and associated documentation files (the
  401. + * "Software"), to deal in the Software without restriction, including
  402. + * without limitation the rights to use, copy, modify, merge, publish,
  403. + * distribute, sub license, and/or sell copies of the Software, and to
  404. + * permit persons to whom the Software is furnished to do so, subject to
  405. + * the following conditions:
  406. + *
  407. + * The above copyright notice and this permission notice (including the
  408. + * next paragraph) shall be included in all copies or substantial portions
  409. + * of the Software.
  410. + *
  411. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  412. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  413. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  414. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  415. + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  416. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  417. + * DEALINGS IN THE SOFTWARE.
  418. + *
  419. + **************************************************************************/
  420. +
  421. +#ifndef EGLCONFIGDEBUG_INCLUDED
  422. +#define EGLCONFIGDEBUG_INCLUDED
  423. +
  424. +#ifdef __cplusplus
  425. +extern "C" {
  426. +#endif
  427. +
  428. +#include "egltypedefs.h"
  429. +
  430. +/**
  431. + * Config printout options.
  432. + */
  433. +enum EGL_CONFIG_DEBUG_OPTION {
  434. + EGL_CONFIG_DEBUG_CHOOSE,
  435. + EGL_CONFIG_DEBUG_GET,
  436. +};
  437. +
  438. +/**
  439. + * Print the list of configs and the associated attributes.
  440. + */
  441. +void eglPrintConfigDebug(_EGLDisplay *const dpy,
  442. + EGLConfig *const configs, const EGLint numConfigs,
  443. + const enum EGL_CONFIG_DEBUG_OPTION printOption);
  444. +
  445. +#ifdef __cplusplus
  446. +}
  447. +#endif
  448. +
  449. +#endif /* EGLCONFIGDEBUG_INCLUDED */
  450. diff --git a/src/egl/main/egllog.c b/src/egl/main/egllog.c
  451. index 973b760..7a9032f 100644
  452. --- a/src/egl/main/egllog.c
  453. +++ b/src/egl/main/egllog.c
  454. @@ -153,6 +153,15 @@ _eglInitLogger(void)
  455. }
  456. }
  457. +/**
  458. + * Return the log level.
  459. + */
  460. +EGLint
  461. +_eglGetLogLevel(void)
  462. +{
  463. + return logging.level;
  464. +}
  465. +
  466. /**
  467. * Log a message with message logger.
  468. diff --git a/src/egl/main/egllog.h b/src/egl/main/egllog.h
  469. index 2a06a34..a1cf977 100644
  470. --- a/src/egl/main/egllog.h
  471. +++ b/src/egl/main/egllog.h
  472. @@ -44,6 +44,10 @@ extern "C" {
  473. #define _EGL_DEBUG 3 /* useful info for debugging */
  474. +extern EGLint
  475. +_eglGetLogLevel(void);
  476. +
  477. +
  478. extern void
  479. _eglLog(EGLint level, const char *fmtStr, ...);
  480. diff --git a/src/egl/meson.build b/src/egl/meson.build
  481. index daa6a3a..384bb98 100644
  482. --- a/src/egl/meson.build
  483. +++ b/src/egl/meson.build
  484. @@ -31,6 +31,8 @@ files_egl = files(
  485. 'main/eglapi.c',
  486. 'main/eglarray.c',
  487. 'main/eglarray.h',
  488. + 'main/eglconfigdebug.c',
  489. + 'main/eglconfigdebug.h',
  490. 'main/eglconfig.c',
  491. 'main/eglconfig.h',
  492. 'main/eglcontext.c',