Recognize preprocessor functions in GLSL code 89/251689/1
authorLukasz Kostyra <l.kostyra@samsung.com>
Mon, 18 Jan 2021 11:34:14 +0000 (12:34 +0100)
committerLukasz Kostyra <l.kostyra@samsung.com>
Mon, 18 Jan 2021 11:37:13 +0000 (12:37 +0100)
On some situations preprocessor code can contain functions.
For now this code is recognized and ignored in order to not produce
syntax errors.

Change-Id: I1e80fc4f07a39dac1c112b7816efb0a813d091f9

GLESv2/yagl_gles2_calls.c
GLESv2/yagl_gles2_context.c
GLESv2/yagl_glsl_lexer.l
GLESv2/yagl_glsl_parser.y

index 38adf7ffa1d4b8fb05b889fec42fa7bdeaf02954..ba0468ccb0e6957a7cf56214ad2125ad5e80df40 100644 (file)
@@ -1406,7 +1406,7 @@ YAGL_API void glShaderSource(GLuint shader, GLsizei count, const GLchar * const
 
     if (have_strings) {
         uint8_t *tmp_buff;
-        char *print_buff; // LKDEBUG
+        char *print_buff;
         int ret;
         int patched_len = 0;
         char *patched_source;
@@ -1426,13 +1426,13 @@ YAGL_API void glShaderSource(GLuint shader, GLsizei count, const GLchar * const
 
         tmp_buff[total_length] = '\0';
 
-        YAGL_LOG_DEBUG("orig source:", tmp_buff);
+        YAGL_LOG_TRACE("orig source:");
         print_buff = (char*)tmp_buff;
         while (print_buff)
         {
             char *next_line = strchr(print_buff, '\n');
             if (next_line) *next_line = 0;
-            YAGL_LOG_DEBUG("%s", print_buff);
+            YAGL_LOG_TRACE("%s", print_buff);
             if (next_line) *next_line = '\n';
             print_buff = next_line ? next_line + 1 : NULL;
         }
@@ -1450,16 +1450,19 @@ YAGL_API void glShaderSource(GLuint shader, GLsizei count, const GLchar * const
             struct yagl_glsl_define *defines = NULL;
             int i = 0, size = 0;
 
+            // to turn off unused variable warning on release build
+            (void)samplers;
+
             patched_source = yagl_glsl_state_get_output(&shader_obj->state,
                                                         &patched_len);
 
-            YAGL_LOG_DEBUG("patched source:");
+            YAGL_LOG_TRACE("patched source:");
             print_buff = patched_source;
             while (print_buff)
             {
                 char *next_line = strchr(print_buff, '\n');
                 if (next_line) *next_line = 0;
-                YAGL_LOG_DEBUG("%s", print_buff);
+                YAGL_LOG_TRACE("%s", print_buff);
                 if (next_line) *next_line = '\n';
                 print_buff = next_line ? next_line + 1 : NULL;
             }
@@ -1499,7 +1502,7 @@ YAGL_API void glShaderSource(GLuint shader, GLsizei count, const GLchar * const
             /*
              * Unable to parse source, pass as-is.
              */
-            YAGL_LOG_DEBUG("unable to patch shader source, passed as-is");
+            YAGL_LOG_TRACE("unable to patch shader source, passed as-is");
             yagl_gles2_shader_source(shader_obj,
                                      (GLchar*)tmp_buff,
                                      (GLchar*)tmp_buff,
index fdca4f83451b09d12b37e4f218266052bdd72771..1ff5f80c58651e668a22edbfa91a49bf1118bfb5 100644 (file)
@@ -676,7 +676,8 @@ void yagl_gles2_context_pre_draw(struct yagl_gles2_context *ctx,
             } else {
                 samplers[i].replaced_tex2d = texture_2d_state->texture_zero->global_name;
             }
-            YAGL_LOG_TRACE("  #%d: slot %d bound texture2D ID %d", i, samplers[i].value, samplers[i].replaced_tex2d);
+            YAGL_LOG_TRACE("  #%d: slot %d texture2D %d => textureExternal %d", i, samplers[i].value, samplers[i].replaced_tex2d,
+                                                                                texture_external_state->texture->global_name);
 
             // samplers[i].value is unit requested by app from shader - replace it
             yagl_host_glActiveTexture(GL_TEXTURE0 + samplers[i].value);
@@ -689,6 +690,8 @@ void yagl_gles2_context_post_draw(struct yagl_gles2_context *ctx,
                                   GLenum mode,
                                   GLint count)
 {
+    YAGL_LOG_FUNC_SET(yagl_gles2_context_post_draw);
+
     if (mode == GL_POINTS) {
         yagl_host_glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
         if (yagl_get_host_gl_version() <= yagl_gl_3_2) {
@@ -723,6 +726,7 @@ void yagl_gles2_context_post_draw(struct yagl_gles2_context *ctx,
         struct yagl_glsl_sampler *samplers;
         int i = 0, samplers_size = 0;
 
+        YAGL_LOG_TRACE("Restoring TEXTURE_2D bindings:");
         samplers = yagl_vector_data(&fragment_shader->state.samplers_ExternalOES);
         samplers_size = yagl_vector_size(&fragment_shader->state.samplers_ExternalOES);
         for (i = 0; i < samplers_size; ++i) {
@@ -731,6 +735,7 @@ void yagl_gles2_context_post_draw(struct yagl_gles2_context *ctx,
                 continue;
             }
 
+            YAGL_LOG_TRACE("  #%d: %d unit => %d texture", i, samplers[i].value, samplers[i].replaced_tex2d);
             yagl_host_glActiveTexture(GL_TEXTURE0 + samplers[i].value);
             yagl_host_glBindTexture(GL_TEXTURE_2D, samplers[i].replaced_tex2d);
             samplers[i].replaced_tex2d = YAGL_GLSL_SAMPLER_VALUE_UNKNOWN;
index 37fc152dc09e4c237e039a2e542f81623c3c60f0..026aba04e018d7adcdd330eeafff8b15596070ef 100644 (file)
@@ -21,9 +21,13 @@ static yy_size_t string_input(char *buf, yy_size_t max_size, yyscan_t yyscanner)
 
 WS [ \r\t\v\f]
 PRECISION_QUAL "lowp"|"mediump"|"highp"
-PRECISION_ALL ${PRECISION_QUAL}|"precision"[^;\n]+;?
 CONTROL [()\[\]{},;?:/%*&|^!+\-=<>\.]
 STRING [^ \r\t\v\f\n()\[\]{},;?:/%*&|^!+\-=<>\.]+
+INTEGER [0-9]+
+DOUBLE {INTEGER}\.{INTEGER}
+FLOAT {DOUBLE}f
+NUMBER {FLOAT}|{DOUBLE}|{INTEGER}
+PP_FUNCTION {STRING}{WS}*\([^\n]+
 
 %%
 
@@ -331,6 +335,24 @@ STRING [^ \r\t\v\f\n()\[\]{},;?:/%*&|^!+\-=<>\.]+
     yagl_glsl_state_new_comment(state, strlen(yytext));
 }
 
+<PP_DEFINE>{FLOAT}|{DOUBLE} {
+    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+    yagl_glsl_state_new_str_token(state, yylval, yytext);
+    return TOK_STRING;
+}
+
+<PP_DEFINE>{INTEGER} {
+    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+    yagl_glsl_state_new_integer_token(state, yylval, strtol(yytext, NULL, 10));
+    return TOK_INTEGER;
+}
+
+<PP_DEFINE>{PP_FUNCTION} {
+    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+    yagl_glsl_state_new_str_token(state, yylval, yytext);
+    return TOK_PP_FUNCTION;
+}
+
 <PP_DEFINE>{STRING} {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     yagl_glsl_state_new_str_token(state, yylval, yytext);
@@ -607,7 +629,7 @@ static yy_size_t string_input(char *buf, yy_size_t max_size, yyscan_t yyscanner)
     return num_read;
 }
 
-extern int yagl_glsl_debug;
+//extern int yagl_glsl_debug;
 
 int yagl_glsl_state_init(struct yagl_glsl_state *state,
                          GLenum shader_type,
@@ -619,7 +641,7 @@ int yagl_glsl_state_init(struct yagl_glsl_state *state,
 
     memset(state, 0, sizeof(*state));
 
-    yagl_glsl_debug = 1;
+    //yagl_glsl_debug = 1;
 
     if (yagl_glsl_lexer_lex_init_extra(state, &scanner)) {
         return 0;
index 08cb11935f6fa86786e525acb744ba19f1ec5fa9..723694dd1dce938ff1c837dcee841f2312ea45ba 100644 (file)
@@ -48,12 +48,17 @@ static int yagl_glsl_lex(union YYSTYPE *val, struct yagl_glsl_state *state)
     } character;
 }
 
+%printer { fprintf(yyo, "%d", $$.value); } <integer>
+%printer { fprintf(yyo, "%s", $$.value); } <str>
+%printer { fprintf(yyo, "%c", $$.c); } <character>
+
 %token <str> TOK_EOL
 %token <character> TOK_EOI
 %token <character> TOK_ARR_PAREN_OPEN
 %token <character> TOK_ARR_PAREN_CLOSE
 %token <str> TOK_VERSION
 %token <str> TOK_DEFINE
+%token <str> TOK_PP_FUNCTION
 %token <str> TOK_UNDEF
 %token <str> TOK_PP_IF
 %token <character> TOK_PP_IF_EOL
@@ -222,6 +227,24 @@ expression
     yagl_glsl_state_flush_pending(state, $1.index);
     yagl_glsl_state_append_output(state, $1.value);
 }
+| TOK_DEFINE TOK_STRING TOK_INTEGER TOK_EOL
+{
+    char s[100];
+
+    yagl_glsl_state_flush_pending(state, $1.index);
+    yagl_glsl_state_append_output(state, $1.value);
+    yagl_glsl_state_flush_pending(state, $2.index);
+    yagl_glsl_state_append_output(state, $2.value);
+    yagl_glsl_state_flush_pending(state, $3.index);
+    snprintf(s, 100, "%d", $3.value);
+    yagl_glsl_state_append_output(state, s);
+    yagl_glsl_state_flush_pending(state, $4.index);
+    yagl_glsl_state_append_output(state, $4.value);
+
+    if (yagl_glsl_state_pp_is_condition_met(state)) {
+        yagl_glsl_state_pp_add_define_int(state, $2.value, $3.value);
+    }
+}
 | TOK_DEFINE TOK_STRING TOK_STRING TOK_EOL
 {
     yagl_glsl_state_flush_pending(state, $1.index);
@@ -234,25 +257,7 @@ expression
     yagl_glsl_state_append_output(state, $4.value);
 
     if (yagl_glsl_state_pp_is_condition_met(state)) {
-        // Determine if $3 is actually a string or an integer.
-        // We do this here because some shaders could use defines to
-        // place in different types of numbers (ex. floats like PI constant).
-        // However, for preprocessor condition resolution we only care about
-        // integers according to GLSL ES specification.
-        int isint = 1;
-        const char *str = $3.value;
-        while (str) {
-            if (!isdigit(*str) && (*str != '-') && (*str != '+')) {
-                isint = 0;
-            }
-            str++;
-        }
-
-        if (isint) {
-            yagl_glsl_state_pp_add_define_int(state, $2.value, atoi($3.value));
-        } else {
-            yagl_glsl_state_pp_add_define_string(state, $2.value, $3.value);
-        }
+        yagl_glsl_state_pp_add_define_string(state, $2.value, $3.value);
     }
 }
 | TOK_DEFINE TOK_STRING TOK_EOL
@@ -267,6 +272,15 @@ expression
     if (yagl_glsl_state_pp_is_condition_met(state))
         yagl_glsl_state_pp_add_define_int(state, $2.value, 1);
 }
+| TOK_DEFINE TOK_PP_FUNCTION TOK_EOL
+{
+    yagl_glsl_state_flush_pending(state, $1.index);
+    yagl_glsl_state_append_output(state, $1.value);
+    yagl_glsl_state_flush_pending(state, $2.index);
+    yagl_glsl_state_append_output(state, $2.value);
+    yagl_glsl_state_flush_pending(state, $3.index);
+    yagl_glsl_state_append_output(state, $3.value);
+}
 | TOK_UNDEF TOK_STRING
 {
     yagl_glsl_state_flush_pending(state, $1.index);
@@ -496,7 +510,7 @@ expression
     char s[100];
 
     yagl_glsl_state_flush_pending(state, $1.index);
-    sprintf(s, "%d", $1.value);
+    snprintf(s, 100, "%d", $1.value);
     yagl_glsl_state_append_output(state, s);
 
     yagl_glsl_state_pp_condition_parse_add_expr(state, NULL, $1.value);
@@ -577,7 +591,7 @@ expression
     char s[100];
 
     yagl_glsl_state_flush_pending(state, $1.index);
-    sprintf(s, "%d", $1.value);
+    snprintf(s, 100, "%d", $1.value);
     yagl_glsl_state_append_output(state, s);
 }
 | TOK_STRING
@@ -676,7 +690,7 @@ expression
     yagl_glsl_state_flush_pending(state, $5.index);
     yagl_glsl_state_append_output_char(state, $5.c);
     yagl_glsl_state_flush_pending(state, $6.index);
-    sprintf(s, "%d", $6.value);
+    snprintf(s, 100, "%d", $6.value);
     yagl_glsl_state_append_output(state, s);
     yagl_glsl_state_flush_pending(state, $7.index);
     yagl_glsl_state_append_output_char(state, $7.c);
@@ -720,7 +734,7 @@ expression
     yagl_glsl_state_flush_pending(state, $4.index);
     yagl_glsl_state_append_output_char(state, $4.c);
     yagl_glsl_state_flush_pending(state, $5.index);
-    sprintf(s, "%d", $5.value);
+    snprintf(s, 100, "%d", $5.value);
     yagl_glsl_state_append_output(state, s);
     yagl_glsl_state_flush_pending(state, $6.index);
     yagl_glsl_state_append_output_char(state, $6.c);