1/* 2 * Copyright © 2019 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include <stdio.h> 25#include <string.h> 26#include <stdlib.h> 27 28#include "overlay_params.h" 29 30static enum overlay_param_position 31parse_position(const char *str) 32{ 33 if (!str || !strcmp(str, "top-left")) 34 return LAYER_POSITION_TOP_LEFT; 35 if (!strcmp(str, "top-right")) 36 return LAYER_POSITION_TOP_RIGHT; 37 if (!strcmp(str, "bottom-left")) 38 return LAYER_POSITION_BOTTOM_LEFT; 39 if (!strcmp(str, "bottom-right")) 40 return LAYER_POSITION_BOTTOM_RIGHT; 41 return LAYER_POSITION_TOP_LEFT; 42} 43 44static FILE * 45parse_output_file(const char *str) 46{ 47 return fopen(str, "w+"); 48} 49 50static uint32_t 51parse_fps_sampling_period(const char *str) 52{ 53 return strtol(str, NULL, 0) * 1000; 54} 55 56static bool 57parse_no_display(const char *str) 58{ 59 return strtol(str, NULL, 0) != 0; 60} 61 62static unsigned 63parse_unsigned(const char *str) 64{ 65 return strtol(str, NULL, 0); 66} 67 68#define parse_width(s) parse_unsigned(s) 69#define parse_height(s) parse_unsigned(s) 70 71static bool 72parse_help(const char *str) 73{ 74 fprintf(stderr, "Layer params using VK_LAYER_MESA_OVERLAY_CONFIG=\n"); 75#define OVERLAY_PARAM_BOOL(name) \ 76 fprintf(stderr, "\t%s=0|1\n", #name); 77#define OVERLAY_PARAM_CUSTOM(name) 78 OVERLAY_PARAMS 79#undef OVERLAY_PARAM_BOOL 80#undef OVERLAY_PARAM_CUSTOM 81 fprintf(stderr, "\tposition=top-left|top-right|bottom-left|bottom-right\n"); 82 fprintf(stderr, "\tfps_sampling_period=number-of-milliseconds\n"); 83 fprintf(stderr, "\tno_display=0|1\n"); 84 fprintf(stderr, "\toutput_file=/path/to/output.txt\n"); 85 fprintf(stderr, "\twidth=width-in-pixels\n"); 86 fprintf(stderr, "\theight=height-in-pixels\n"); 87 88 return true; 89} 90 91static bool is_delimiter(char c) 92{ 93 return c == 0 || c == ',' || c == ':' || c == ';' || c == '='; 94} 95 96static int 97parse_string(const char *s, char *out_param, char *out_value) 98{ 99 int i = 0; 100 101 for (; !is_delimiter(*s); s++, out_param++, i++) 102 *out_param = *s; 103 104 *out_param = 0; 105 106 if (*s == '=') { 107 s++; 108 i++; 109 for (; !is_delimiter(*s); s++, out_value++, i++) 110 *out_value = *s; 111 } else 112 *(out_value++) = '1'; 113 *out_value = 0; 114 115 if (*s && is_delimiter(*s)) { 116 s++; 117 i++; 118 } 119 120 if (*s && !i) { 121 fprintf(stderr, "mesa-overlay: syntax error: unexpected '%c' (%i) while " 122 "parsing a string\n", *s, *s); 123 fflush(stderr); 124 } 125 126 return i; 127} 128 129const char *overlay_param_names[] = { 130#define OVERLAY_PARAM_BOOL(name) #name, 131#define OVERLAY_PARAM_CUSTOM(name) 132 OVERLAY_PARAMS 133#undef OVERLAY_PARAM_BOOL 134#undef OVERLAY_PARAM_CUSTOM 135}; 136 137void 138parse_overlay_env(struct overlay_params *params, 139 const char *env) 140{ 141 uint32_t num; 142 char key[256], value[256]; 143 144 memset(params, 0, sizeof(*params)); 145 146 /* Visible by default */ 147 params->enabled[OVERLAY_PARAM_ENABLED_fps] = true; 148 params->enabled[OVERLAY_PARAM_ENABLED_frame_timing] = true; 149 params->fps_sampling_period = 500000; /* 500ms */ 150 params->width = params->height = 300; 151 152 if (!env) 153 return; 154 155 while ((num = parse_string(env, key, value)) != 0) { 156 env += num; 157 158#define OVERLAY_PARAM_BOOL(name) \ 159 if (!strcmp(#name, key)) { \ 160 params->enabled[OVERLAY_PARAM_ENABLED_##name] = \ 161 strtol(value, NULL, 0); \ 162 continue; \ 163 } 164#define OVERLAY_PARAM_CUSTOM(name) \ 165 if (!strcmp(#name, key)) { \ 166 params->name = parse_##name(value); \ 167 continue; \ 168 } 169 OVERLAY_PARAMS 170#undef OVERLAY_PARAM_BOOL 171#undef OVERLAY_PARAM_CUSTOM 172 fprintf(stderr, "Unknown option '%s'\n", key); 173 } 174} 175