On Thursday, 2018-12-20 10:02:35 +0000, Silvestrs Timofejevs wrote: > Feature to print out EGL returned configs for debug purposes. > > 'eglChooseConfig' and 'eglGetConfigs' debug information printout is > enabled when the log level equals '_EGL_DEBUG'. The configs are > printed, and if any of them are "chosen" they are marked with their > index in the chosen configs array. > > v2: > a) refactor the code in line with Eric's comments > b) rename function _snprintfStrcat, split it out and put into the > src/util/u_string.h, make it a separate patch. > > Signed-off-by: Silvestrs Timofejevs <silvestrs.timofej...@imgtec.com> > --- > src/egl/Makefile.sources | 4 +- > src/egl/main/eglconfig.c | 20 +++- > src/egl/main/eglconfigdebug.c | 265 > ++++++++++++++++++++++++++++++++++++++++++ > src/egl/main/eglconfigdebug.h | 55 +++++++++ > src/egl/meson.build | 2 + > 5 files changed, 341 insertions(+), 5 deletions(-) > create mode 100644 src/egl/main/eglconfigdebug.c > create mode 100644 src/egl/main/eglconfigdebug.h > > diff --git a/src/egl/Makefile.sources b/src/egl/Makefile.sources > index 0cc5f1b..353a848 100644 > --- a/src/egl/Makefile.sources > +++ b/src/egl/Makefile.sources > @@ -28,7 +28,9 @@ LIBEGL_C_FILES := \ > main/eglsync.c \ > main/eglsync.h \ > main/eglentrypoint.h \ > - main/egltypedefs.h > + main/egltypedefs.h \ > + main/eglconfigdebug.h \ > + main/eglconfigdebug.c > > dri2_backend_core_FILES := \ > drivers/dri2/egl_dri2.c \ > diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c > index a346f93..0095dc2 100644 > --- a/src/egl/main/eglconfig.c > +++ b/src/egl/main/eglconfig.c > @@ -40,6 +40,7 @@ > #include "util/macros.h" > > #include "eglconfig.h" > +#include "eglconfigdebug.h" > #include "egldisplay.h" > #include "eglcurrent.h" > #include "egllog.h" > @@ -797,14 +798,21 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, > const EGLint *attrib_list, > EGLConfig *configs, EGLint config_size, EGLint *num_configs) > { > _EGLConfig criteria; > + EGLBoolean result; > > if (!_eglParseConfigAttribList(&criteria, disp, attrib_list)) > return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); > > - return _eglFilterConfigArray(disp->Configs, > - configs, config_size, num_configs, > - _eglFallbackMatch, _eglFallbackCompare, > - (void *) &criteria); > + result = _eglFilterConfigArray(disp->Configs, > + configs, config_size, num_configs, > + _eglFallbackMatch, _eglFallbackCompare, > + (void *) &criteria); > + > + if (result && (_eglGetLogLevel() == _EGL_DEBUG)) > + eglPrintConfigDebug(drv, disp, configs, *num_configs, > + EGL_CONFIG_DEBUG_CHOOSE); > + > + return result; > } > > > @@ -857,5 +865,9 @@ _eglGetConfigs(_EGLDriver *drv, _EGLDisplay *disp, > EGLConfig *configs, > *num_config = _eglFlattenArray(disp->Configs, (void *) configs, > sizeof(configs[0]), config_size, _eglFlattenConfig); > > + if (_eglGetLogLevel() == _EGL_DEBUG) > + eglPrintConfigDebug(drv, disp, configs, *num_config, > + EGL_CONFIG_DEBUG_GET); > + > return EGL_TRUE; > } > diff --git a/src/egl/main/eglconfigdebug.c b/src/egl/main/eglconfigdebug.c > new file mode 100644 > index 0000000..0617c99 > --- /dev/null > +++ b/src/egl/main/eglconfigdebug.c > @@ -0,0 +1,265 @@ > +/* > + * Copyright 2017 Imagination Technologies. > + * All Rights Reserved. > + * > + * Based on eglinfo, which has copyright: > + * Copyright (C) 2005 Brian Paul All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included > + * in all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN > + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN > + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include <stdlib.h> > +#include <string.h> > +#include <stdio.h> > +#include <stdarg.h> > + > +#include "eglarray.h" > +#include "eglconfig.h" > +#include "eglconfigdebug.h" > +#include "egldisplay.h" > +#include "egllog.h" > +#include "egltypedefs.h" > +#include "util/macros.h" > +#include "util/u_string.h" > + > +/* Max debug message length */ > +#define CONFIG_DEBUG_MSG_MAX 1000 > + > +/* > + * These are X visual types, so if you're running eglinfo under > + * something not X, they probably don't make sense. > + */ > +static const char *const vnames[] = { "SG", "GS", "SC", "PC", "TC", "DC" }; > + > +struct _printAttributes { > + EGLint id, size, level; > + EGLint red, green, blue, alpha; > + EGLint depth, stencil; > + EGLint renderable, surfaces; > + EGLint vid, vtype, caveat, bindRgb, bindRgba; > + EGLint samples, sampleBuffers; > + char surfString[32]; > +}; > + > +static void > +_printHeaderFormat(void) > +{ > + /* > + * EGL configuration output legend: > + * > + * chosen --------------- eglChooseConfig returned config priority, > + * only relevant when eglChooseConfig is called. > + * id ------------------- EGL_CONFIG_ID > + * bfsz ----------------- EGL_BUFFER_SIZE > + * lvl ------------------ EGL_LEVEL > + * > + * colourbuffer > + * r -------------------- EGL_RED_SIZE > + * g -------------------- EGL_GREEN_SIZE > + * b -------------------- EGL_BLUE_SIZE > + * a -------------------- EGL_ALPHA_SIZE > + * dpth ----------------- EGL_DEPTH_SIZE > + * stcl ----------------- EGL_STENCIL_SIZE > + * > + * multisample > + * ns ------------------- EGL_SAMPLES > + * b -------------------- EGL_SAMPLE_BUFFERS > + * visid ---------------- EGL_NATIVE_VISUAL_ID/EGL_NATIVE_VISUAL_TYPE > + * caveat --------------- EGL_CONFIG_CAVEAT > + * bind ----------------- EGL_BIND_TO_TEXTURE_RGB/EGL_BIND_TO_TEXTURE_RGBA > + * > + * renderable > + * gl, es, es2, es3, vg - EGL_RENDERABLE_TYPE > + * > + * supported > + * surfaces ------------- EGL_SURFACE_TYPE > + */ > + _eglLog(_EGL_DEBUG, "---------------"); > + _eglLog(_EGL_DEBUG, "Configurations:"); > + _eglLog(_EGL_DEBUG, "cho bf lv colourbuffer dp st ms vis > cav bi renderable supported"); > + _eglLog(_EGL_DEBUG, "sen id sz l r g b a th cl ns b id > eat nd gl es es2 es3 vg surfaces"); > + _eglLog(_EGL_DEBUG, "---------------"); > +} > + > +static void > +_eglGetConfigAttrs(_EGLDriver *const drv, _EGLDisplay *const dpy, > + _EGLConfig *const conf, struct _printAttributes *const > attr) > +{ > + EGLBoolean success = EGL_TRUE; > + > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_CONFIG_ID, &attr->id); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_BUFFER_SIZE, > &attr->size); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_LEVEL, &attr->level); > + > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_RED_SIZE, &attr->red); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_GREEN_SIZE, > &attr->green); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_BLUE_SIZE, > &attr->blue); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_ALPHA_SIZE, > &attr->alpha); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_DEPTH_SIZE, > &attr->depth); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_STENCIL_SIZE, > &attr->stencil); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_NATIVE_VISUAL_ID, > &attr->vid); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_NATIVE_VISUAL_TYPE, > &attr->vtype); > + > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_CONFIG_CAVEAT, > &attr->caveat); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_BIND_TO_TEXTURE_RGB, > &attr->bindRgb); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_BIND_TO_TEXTURE_RGBA, > &attr->bindRgba); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_RENDERABLE_TYPE, > &attr->renderable); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_SURFACE_TYPE, > &attr->surfaces); > + > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_SAMPLES, > &attr->samples); > + success &= _eglGetConfigAttrib(drv, dpy, conf, EGL_SAMPLE_BUFFERS, > &attr->sampleBuffers); > + > + if (!success) > + _eglLog(_EGL_DEBUG, "%s: config ID = %d, could not obtain all > attributes", > + __func__, conf->ConfigID); > +} > + > +static void > +_eglPrintConfig(_EGLDriver *const drv, _EGLDisplay *const dpy, > + _EGLConfig *const conf, char *const printMsg) > +{ > + struct _printAttributes attr = { 0 }; > + > + _eglGetConfigAttrs(drv, dpy, conf, &attr); > + > + if (attr.surfaces & EGL_WINDOW_BIT) > + strcat(attr.surfString, "win,"); > + if (attr.surfaces & EGL_PBUFFER_BIT) > + strcat(attr.surfString, "pb,"); > + if (attr.surfaces & EGL_PIXMAP_BIT) > + strcat(attr.surfString, "pix,"); > + if (attr.surfaces & EGL_STREAM_BIT_KHR) > + strcat(attr.surfString, "str,"); > + if (attr.surfaces & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) > + strcat(attr.surfString, "prsv"); > + if (strlen(attr.surfString) > 0) > + attr.surfString[strlen(attr.surfString) - 1] = 0; > + > + STATIC_ASSERT(sizeof(attr.surfString) >= sizeof("win,pb,pix,str,prsv")); > + > + util_strnappend(printMsg, CONFIG_DEBUG_MSG_MAX, > + "0x%03x %2d %2d %2d %2d %2d %2d %2d %2d %2d%2d 0x%08x%2s > ", > + attr.id, attr.size, attr.level, > + attr.red, attr.green, attr.blue, attr.alpha, > + attr.depth, attr.stencil, > + attr.samples, attr.sampleBuffers, attr.vid, > + attr.vtype < 6 ? vnames[attr.vtype] : "--"); > + > + util_strnappend(printMsg, CONFIG_DEBUG_MSG_MAX, > + "%c %c %c %c %c %c %c %15s", > + (attr.caveat != EGL_NONE) ? 'y' : ' ', > + (attr.bindRgba) ? 'a' : (attr.bindRgb) ? 'y' : ' ', > + (attr.renderable & EGL_OPENGL_BIT) ? 'y' : ' ', > + (attr.renderable & EGL_OPENGL_ES_BIT) ? 'y' : ' ', > + (attr.renderable & EGL_OPENGL_ES2_BIT) ? 'y' : ' ', > + (attr.renderable & EGL_OPENGL_ES3_BIT) ? 'y' : ' ', > + (attr.renderable & EGL_OPENVG_BIT) ? 'y' : ' ', > + attr.surfString); > + > + _eglLog(_EGL_DEBUG, printMsg); > +} > + > +static void > +_eglWriteChosenConfigOrderNum(_EGLConfig *const config, > + _EGLConfig *const *const chosenConfigs, > + const EGLint numConfigs, char *const printMsg) > +{ > + const char padding[] = " "; > + > + if (chosenConfigs == NULL) { > + util_strnappend(printMsg, CONFIG_DEBUG_MSG_MAX, "%s ", &padding[0]); > + return; > + } > + > + /* Find a match, write its order number and return */ > + for (EGLint i = 0; i < numConfigs; i++) { > + if (config == chosenConfigs[i]) { > + util_strnappend(printMsg, CONFIG_DEBUG_MSG_MAX, "%*d ", > + strlen(padding), i); > + return; > + } > + } > + > + util_strnappend(printMsg, CONFIG_DEBUG_MSG_MAX, "%s ", &padding[0]); > +} > + > +static void > +_eglPrintConfigs(_EGLDriver *const drv, _EGLDisplay *const dpy, > + EGLConfig *const configs, const EGLint numConfigs, > + const enum EGL_CONFIG_DEBUG_OPTION printOption) > +{ > + EGLint numConfigsToPrint; > + _EGLConfig **configsToPrint; > + _EGLConfig **chosenConfigs; > + char *printMsg; > + > + printMsg = malloc(CONFIG_DEBUG_MSG_MAX); > + if (!printMsg) { > + _eglLog(_EGL_DEBUG, "%s: failed to allocate the print message", > __func__); > + return; > + } > + > + /* > + * If the printout request came from the 'eglChooseConfig', all > + * configs are printed, and the "chosen" configs are marked. > + */ > + if (printOption == EGL_CONFIG_DEBUG_CHOOSE) { > + configsToPrint = (_EGLConfig **) dpy->Configs->Elements; > + numConfigsToPrint = dpy->Configs->Size; > + chosenConfigs = (_EGLConfig **) configs; > + } else { > + assert(printOption == EGL_CONFIG_DEBUG_GET); > + configsToPrint = (_EGLConfig **) configs; > + numConfigsToPrint = numConfigs; > + chosenConfigs = NULL; > + } > + > + _printHeaderFormat(); > + for (EGLint i = 0; i < numConfigsToPrint; i++) { > + _EGLConfig *configToPrint = configsToPrint[i]; > + > + /* "clear" message */ > + printMsg[0] = '\0'; > + > + _eglWriteChosenConfigOrderNum(configToPrint, chosenConfigs, numConfigs, > + printMsg); > + > + _eglPrintConfig(drv, dpy, configToPrint, printMsg); > + } > + > + free(printMsg); > +} > + > +void eglPrintConfigDebug(_EGLDriver *const drv, _EGLDisplay *const dpy, > + EGLConfig *const configs, const EGLint numConfigs, > + const enum EGL_CONFIG_DEBUG_OPTION printOption) > +{ > + if (!numConfigs || !configs) { > + _eglLog(_EGL_DEBUG, "%s: nothing to print", __func__); > + return; > + } > + > + switch (printOption) { > + case EGL_CONFIG_DEBUG_CHOOSE: > + case EGL_CONFIG_DEBUG_GET: > + _eglPrintConfigs(drv, dpy, configs, numConfigs, printOption); > + return; > + } > + > + _eglLog(_EGL_DEBUG, "%s: bad debug option", __func__); > +} > diff --git a/src/egl/main/eglconfigdebug.h b/src/egl/main/eglconfigdebug.h > new file mode 100644 > index 0000000..8be6223 > --- /dev/null > +++ b/src/egl/main/eglconfigdebug.h > @@ -0,0 +1,55 @@ > +/************************************************************************** > + * Copyright 2017 Imagination Technologies. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sub license, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial portions > + * of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > + * DEALINGS IN THE SOFTWARE. > + * > + **************************************************************************/ > + > +#ifndef EGLCONFIGDEBUG_INCLUDED > +#define EGLCONFIGDEBUG_INCLUDED > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#include "egltypedefs.h" > + > +/** > + * Config printout options. > + */ > +enum EGL_CONFIG_DEBUG_OPTION { > + EGL_CONFIG_DEBUG_CHOOSE, > + EGL_CONFIG_DEBUG_GET, > +}; > + > +/** > + * Print the list of configs and the associated attributes. > + */ > +void eglPrintConfigDebug(_EGLDriver *const drv, _EGLDisplay *const dpy, > + EGLConfig *const configs, EGLint numConfigs,
Like I said in v1, these 3 `const` don't do anything in a prototype :) Anyway, this all looks good to me; for the series: Reviewed-by: Eric Engestrom <eric.engest...@intel.com> I'd like Emil to at least ack though. Emil? > + enum EGL_CONFIG_DEBUG_OPTION printOption); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* EGLCONFIGDEBUG_INCLUDED */ > diff --git a/src/egl/meson.build b/src/egl/meson.build > index 89bac2c..47ac2c8 100644 > --- a/src/egl/meson.build > +++ b/src/egl/meson.build > @@ -31,6 +31,8 @@ files_egl = files( > 'main/eglapi.h', > 'main/eglarray.c', > 'main/eglarray.h', > + 'main/eglconfigdebug.c', > + 'main/eglconfigdebug.h', > 'main/eglconfig.c', > 'main/eglconfig.h', > 'main/eglcontext.c', > -- > 2.7.4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev