1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright 2019 Imagination Technologies.
3bf215546Sopenharmony_ci * All Rights Reserved.
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Based on eglinfo, which has copyright:
6bf215546Sopenharmony_ci * Copyright (C) 2005  Brian Paul   All Rights Reserved.
7bf215546Sopenharmony_ci *
8bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
9bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
10bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
11bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
13bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included
16bf215546Sopenharmony_ci * in all copies or substantial portions of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21bf215546Sopenharmony_ci * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22bf215546Sopenharmony_ci * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24bf215546Sopenharmony_ci */
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include <stdlib.h>
27bf215546Sopenharmony_ci#include <string.h>
28bf215546Sopenharmony_ci#include <stdio.h>
29bf215546Sopenharmony_ci#include <stdarg.h>
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci#include "eglarray.h"
32bf215546Sopenharmony_ci#include "eglconfig.h"
33bf215546Sopenharmony_ci#include "eglconfigdebug.h"
34bf215546Sopenharmony_ci#include "egldisplay.h"
35bf215546Sopenharmony_ci#include "egllog.h"
36bf215546Sopenharmony_ci#include "egltypedefs.h"
37bf215546Sopenharmony_ci#include "util/macros.h"
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ci/* Max debug message length */
40bf215546Sopenharmony_ci#define CONFIG_DEBUG_MSG_MAX 1000
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci/*
43bf215546Sopenharmony_ci * These are X visual types, so if you're running eglinfo under
44bf215546Sopenharmony_ci * something not X, they probably don't make sense.
45bf215546Sopenharmony_ci */
46bf215546Sopenharmony_cistatic const char *const vnames[] = { "SG", "GS", "SC", "PC", "TC", "DC" };
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_cistatic void
49bf215546Sopenharmony_ci_printHeaderFormat(void)
50bf215546Sopenharmony_ci{
51bf215546Sopenharmony_ci   /*
52bf215546Sopenharmony_ci    * EGL configuration output legend:
53bf215546Sopenharmony_ci    *
54bf215546Sopenharmony_ci    * chosen --------------- eglChooseConfig returned config priority,
55bf215546Sopenharmony_ci    *                        only relevant when eglChooseConfig is called.
56bf215546Sopenharmony_ci    * id ------------------- EGL_CONFIG_ID
57bf215546Sopenharmony_ci    * bfsz ----------------- EGL_BUFFER_SIZE
58bf215546Sopenharmony_ci    * lvl ------------------ EGL_LEVEL
59bf215546Sopenharmony_ci    *
60bf215546Sopenharmony_ci    * colourbuffer
61bf215546Sopenharmony_ci    * r -------------------- EGL_RED_SIZE
62bf215546Sopenharmony_ci    * g -------------------- EGL_GREEN_SIZE
63bf215546Sopenharmony_ci    * b -------------------- EGL_BLUE_SIZE
64bf215546Sopenharmony_ci    * a -------------------- EGL_ALPHA_SIZE
65bf215546Sopenharmony_ci    * dpth ----------------- EGL_DEPTH_SIZE
66bf215546Sopenharmony_ci    * stcl ----------------- EGL_STENCIL_SIZE
67bf215546Sopenharmony_ci    *
68bf215546Sopenharmony_ci    * multisample
69bf215546Sopenharmony_ci    * ns ------------------- EGL_SAMPLES
70bf215546Sopenharmony_ci    * b -------------------- EGL_SAMPLE_BUFFERS
71bf215546Sopenharmony_ci    * visid ---------------- EGL_NATIVE_VISUAL_ID/EGL_NATIVE_VISUAL_TYPE
72bf215546Sopenharmony_ci    * caveat --------------- EGL_CONFIG_CAVEAT
73bf215546Sopenharmony_ci    * bind ----------------- EGL_BIND_TO_TEXTURE_RGB/EGL_BIND_TO_TEXTURE_RGBA
74bf215546Sopenharmony_ci    *
75bf215546Sopenharmony_ci    * renderable
76bf215546Sopenharmony_ci    * gl, es, es2, es3, vg - EGL_RENDERABLE_TYPE
77bf215546Sopenharmony_ci    *
78bf215546Sopenharmony_ci    * supported
79bf215546Sopenharmony_ci    * surfaces ------------- EGL_SURFACE_TYPE
80bf215546Sopenharmony_ci    */
81bf215546Sopenharmony_ci   _eglLog(_EGL_DEBUG, "---------------");
82bf215546Sopenharmony_ci   _eglLog(_EGL_DEBUG, "Configurations:");
83bf215546Sopenharmony_ci   _eglLog(_EGL_DEBUG, "cho       bf lv colourbuffer dp st  ms           vis  cav  bi     renderable           supported");
84bf215546Sopenharmony_ci   _eglLog(_EGL_DEBUG, "sen    id sz  l  r  g  b  a  th cl ns b           id  eat  nd  gl es es2 es3 vg         surfaces");
85bf215546Sopenharmony_ci   _eglLog(_EGL_DEBUG, "---------------");
86bf215546Sopenharmony_ci}
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci/* Append a formatted string to the buffer, up to the buffer size */
89bf215546Sopenharmony_cistatic inline void
90bf215546Sopenharmony_ci_strnAppend(char *const buf, const int bufSize, const char *fmt, ...)
91bf215546Sopenharmony_ci{
92bf215546Sopenharmony_ci   int maxAllowed;
93bf215546Sopenharmony_ci   va_list args;
94bf215546Sopenharmony_ci   size_t bufLen = strlen(buf);
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci   maxAllowed = bufSize - bufLen;
97bf215546Sopenharmony_ci   assert(maxAllowed >= 0);
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci   va_start(args, fmt);
100bf215546Sopenharmony_ci   (void) vsnprintf(&buf[bufLen], maxAllowed, fmt, args);
101bf215546Sopenharmony_ci   va_end(args);
102bf215546Sopenharmony_ci}
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_cistatic void
105bf215546Sopenharmony_ci_eglPrintConfig(_EGLConfig *const conf, const int chosenIndex)
106bf215546Sopenharmony_ci{
107bf215546Sopenharmony_ci   const char padding[] = "   ";
108bf215546Sopenharmony_ci   char printMsg[CONFIG_DEBUG_MSG_MAX] = "";
109bf215546Sopenharmony_ci   char surfString[32] = "";
110bf215546Sopenharmony_ci   EGLint renderable, surfaces, vtype, bindRgb, bindRgba;
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci   vtype = conf->NativeVisualType;
113bf215546Sopenharmony_ci   surfaces = conf->SurfaceType;
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci   STATIC_ASSERT(sizeof(surfString) >= sizeof("win,pb,pix,str,prsv"));
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci   if (surfaces & EGL_WINDOW_BIT)
118bf215546Sopenharmony_ci      strcat(surfString, "win,");
119bf215546Sopenharmony_ci   if (surfaces & EGL_PBUFFER_BIT)
120bf215546Sopenharmony_ci      strcat(surfString, "pb,");
121bf215546Sopenharmony_ci   if (surfaces & EGL_PIXMAP_BIT)
122bf215546Sopenharmony_ci      strcat(surfString, "pix,");
123bf215546Sopenharmony_ci   if (surfaces & EGL_STREAM_BIT_KHR)
124bf215546Sopenharmony_ci      strcat(surfString, "str,");
125bf215546Sopenharmony_ci   if (surfaces & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
126bf215546Sopenharmony_ci      strcat(surfString, "prsv");
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci   /* If one of chosen configs, print its index in the returned config array */
129bf215546Sopenharmony_ci   if (chosenIndex >= 0)
130bf215546Sopenharmony_ci      _strnAppend(printMsg, sizeof(printMsg), "%*d ", strlen(padding),
131bf215546Sopenharmony_ci                  chosenIndex);
132bf215546Sopenharmony_ci   else
133bf215546Sopenharmony_ci      _strnAppend(printMsg, sizeof(printMsg), "%s ", &padding[0]);
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci   _strnAppend(printMsg, sizeof(printMsg),
136bf215546Sopenharmony_ci               "0x%03x %2d %2d %2d %2d %2d %2d  %2d %2d %2d%2d 0x%08x%2s     ",
137bf215546Sopenharmony_ci               conf->ConfigID, conf->BufferSize, conf->Level,
138bf215546Sopenharmony_ci               conf->RedSize, conf->GreenSize, conf->BlueSize, conf->AlphaSize,
139bf215546Sopenharmony_ci               conf->DepthSize, conf->StencilSize,
140bf215546Sopenharmony_ci               conf->Samples, conf->SampleBuffers, conf->NativeVisualID,
141bf215546Sopenharmony_ci               vtype < 6 ? vnames[vtype] : "--");
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci   bindRgb = conf->BindToTextureRGB;
144bf215546Sopenharmony_ci   bindRgba = conf->BindToTextureRGBA;
145bf215546Sopenharmony_ci   renderable = conf->RenderableType;
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci   _strnAppend(printMsg, sizeof(printMsg),
148bf215546Sopenharmony_ci               "%c  %c   %c  %c   %c   %c   %c %15s",
149bf215546Sopenharmony_ci               (conf->ConfigCaveat != EGL_NONE) ? 'y' : ' ',
150bf215546Sopenharmony_ci               (bindRgba) ? 'a' : (bindRgb) ? 'y' : ' ',
151bf215546Sopenharmony_ci               (renderable & EGL_OPENGL_BIT) ? 'y' : ' ',
152bf215546Sopenharmony_ci               (renderable & EGL_OPENGL_ES_BIT) ? 'y' : ' ',
153bf215546Sopenharmony_ci               (renderable & EGL_OPENGL_ES2_BIT) ? 'y' : ' ',
154bf215546Sopenharmony_ci               (renderable & EGL_OPENGL_ES3_BIT) ? 'y' : ' ',
155bf215546Sopenharmony_ci               (renderable & EGL_OPENVG_BIT) ? 'y' : ' ',
156bf215546Sopenharmony_ci               surfString);
157bf215546Sopenharmony_ci
158bf215546Sopenharmony_ci   _eglLog(_EGL_DEBUG, printMsg);
159bf215546Sopenharmony_ci}
160bf215546Sopenharmony_ci
161bf215546Sopenharmony_civoid eglPrintConfigDebug(const _EGLDisplay *const disp,
162bf215546Sopenharmony_ci                         const EGLConfig *const configs,
163bf215546Sopenharmony_ci                         const EGLint numConfigs, const EGLBoolean printChosen)
164bf215546Sopenharmony_ci{
165bf215546Sopenharmony_ci   EGLint numConfigsToPrint;
166bf215546Sopenharmony_ci   _EGLConfig **configsToPrint;
167bf215546Sopenharmony_ci   _EGLConfig **chosenConfigs;
168bf215546Sopenharmony_ci
169bf215546Sopenharmony_ci   if (!numConfigs || !configs) {
170bf215546Sopenharmony_ci      _eglLog(_EGL_DEBUG, "%s: nothing to print", __func__);
171bf215546Sopenharmony_ci      return;
172bf215546Sopenharmony_ci   }
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_ci   /*
175bf215546Sopenharmony_ci    * If the printout request came from the 'eglChooseConfig', all
176bf215546Sopenharmony_ci    * configs are printed, and the "chosen" configs are marked.
177bf215546Sopenharmony_ci    */
178bf215546Sopenharmony_ci   if (printChosen) {
179bf215546Sopenharmony_ci      configsToPrint = (_EGLConfig **) disp->Configs->Elements;
180bf215546Sopenharmony_ci      numConfigsToPrint = disp->Configs->Size;
181bf215546Sopenharmony_ci      chosenConfigs = (_EGLConfig **) configs;
182bf215546Sopenharmony_ci   } else {
183bf215546Sopenharmony_ci      configsToPrint = (_EGLConfig **) configs;
184bf215546Sopenharmony_ci      numConfigsToPrint = numConfigs;
185bf215546Sopenharmony_ci      chosenConfigs = NULL;
186bf215546Sopenharmony_ci   }
187bf215546Sopenharmony_ci
188bf215546Sopenharmony_ci   _printHeaderFormat();
189bf215546Sopenharmony_ci   for (EGLint i = 0; i < numConfigsToPrint; i++) {
190bf215546Sopenharmony_ci      _EGLConfig *configToPrint = configsToPrint[i];
191bf215546Sopenharmony_ci      EGLint chosenIndex = -1;
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci      /* See if the current config to print is one of the chosen configs */
194bf215546Sopenharmony_ci      if (chosenConfigs)
195bf215546Sopenharmony_ci         for (EGLint j = 0; j < numConfigs; j++)
196bf215546Sopenharmony_ci            if (configToPrint == chosenConfigs[j])
197bf215546Sopenharmony_ci               chosenIndex = j;
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci      _eglPrintConfig(configToPrint, chosenIndex);
200bf215546Sopenharmony_ci   }
201bf215546Sopenharmony_ci}
202