From 25eac8db2bdc5b45e3407b589fc252d079d7c6f4 Mon Sep 17 00:00:00 2001 From: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com> Date: Mon, 17 Mar 2025 09:46:31 +0200 Subject: [PATCH 1/9] Update Shader.hx --- src/openfl/display/Shader.hx | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/openfl/display/Shader.hx b/src/openfl/display/Shader.hx index ad8cea5575..09d0e58aba 100644 --- a/src/openfl/display/Shader.hx +++ b/src/openfl/display/Shader.hx @@ -12,6 +12,7 @@ import openfl.display3D._internal.GLShader; import openfl.utils.ByteArray; import openfl.utils._internal.Float32Array; import openfl.utils._internal.Log; +import openfl.Lib; /** // TODO: Document GLSL Shaders @@ -119,6 +120,8 @@ import openfl.utils._internal.Log; @:access(openfl.display3D.Program3D) @:access(openfl.display.ShaderInput) @:access(openfl.display.ShaderParameter) +@:access(openfl.display.Stage) +@:access(openfl.events.UncaughtErrorEvents) // #if (!display && !macro) #if !macro @:autoBuild(openfl.utils._internal.ShaderMacro.build()) @@ -622,7 +625,22 @@ class Shader // TODO // program.uploadSources (vertex, fragment); - program.__glProgram = __createGLProgram(vertex, fragment); + + if (Lib.current.stage.__uncaughtErrorEvents.__enabled) + { + try + { + program.__glProgram = __createGLProgram(vertex, fragment); + } + catch (e:Dynamic) + { + Lib.current.stage.__handleError(e); + + program.__glProgram = null; + } + } + else + program.__glProgram = __createGLProgram(vertex, fragment); __context.__programs.set(id, program); } From a04aef6d64011e458611578064171e0ca9bbb0f0 Mon Sep 17 00:00:00 2001 From: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com> Date: Mon, 17 Mar 2025 10:05:08 +0200 Subject: [PATCH 2/9] Don't make the program null. From 83f1d8544340b0e44c800cda98a4c1c09cdbb290 Mon Sep 17 00:00:00 2001 From: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com> Date: Mon, 17 Mar 2025 10:13:36 +0200 Subject: [PATCH 3/9] Don't crash if it can't set the `field`. --- src/openfl/display/Shader.hx | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/openfl/display/Shader.hx b/src/openfl/display/Shader.hx index 09d0e58aba..bd926fd6c9 100644 --- a/src/openfl/display/Shader.hx +++ b/src/openfl/display/Shader.hx @@ -748,7 +748,13 @@ class Shader } Reflect.setField(__data, name, input); - if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, input); + + try + { + if (__isGenerated) Reflect.setField(this, name, input); + if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, input); + } + catch (e:Dynamic) {} } else if (!Reflect.hasField(__data, name) || Reflect.field(__data, name) == null) { @@ -814,7 +820,13 @@ class Shader } Reflect.setField(__data, name, parameter); - if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter); + + try + { + if (__isGenerated) Reflect.setField(this, name, parameter); + if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter); + } + catch (e:Dynamic) {} case INT, INT2, INT3, INT4: var parameter = new ShaderParameter(); @@ -825,9 +837,16 @@ class Shader parameter.__isUniform = isUniform; parameter.__length = length; __paramInt.push(parameter); + Reflect.setField(__data, name, parameter); + if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter); + try + { + if (__isGenerated) Reflect.setField(this, name, parameter); + } + catch (e:Dynamic) {} default: var parameter = new ShaderParameter(); parameter.name = name; @@ -857,7 +876,13 @@ class Shader } Reflect.setField(__data, name, parameter); - if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter); + + try + { + if (__isGenerated) Reflect.setField(this, name, parameter); + if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter); + } + catch (e:Dynamic) {} } } From 9dcad636624a34ef6c1f4e0c4a8c6ed97ab11f2b Mon Sep 17 00:00:00 2001 From: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com> Date: Mon, 17 Mar 2025 13:47:14 +0200 Subject: [PATCH 4/9] Add a `debug` log instead of failing silently. --- src/openfl/display/Shader.hx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/openfl/display/Shader.hx b/src/openfl/display/Shader.hx index bd926fd6c9..034cfafd53 100644 --- a/src/openfl/display/Shader.hx +++ b/src/openfl/display/Shader.hx @@ -754,7 +754,8 @@ class Shader if (__isGenerated) Reflect.setField(this, name, input); if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, input); } - catch (e:Dynamic) {} + catch (e:Dynamic) + Log.debug('Failed to set field $name: $e'); } else if (!Reflect.hasField(__data, name) || Reflect.field(__data, name) == null) { @@ -826,7 +827,8 @@ class Shader if (__isGenerated) Reflect.setField(this, name, parameter); if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter); } - catch (e:Dynamic) {} + catch (e:Dynamic) + Log.debug('Failed to set field $name: $e'); case INT, INT2, INT3, INT4: var parameter = new ShaderParameter(); @@ -846,7 +848,8 @@ class Shader { if (__isGenerated) Reflect.setField(this, name, parameter); } - catch (e:Dynamic) {} + catch (e:Dynamic) + Log.debug('Failed to set field $name: $e'); default: var parameter = new ShaderParameter(); parameter.name = name; @@ -882,7 +885,8 @@ class Shader if (__isGenerated) Reflect.setField(this, name, parameter); if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter); } - catch (e:Dynamic) {} + catch (e:Dynamic) + Log.debug('Failed to set field $name: $e'); } } From c933529582e21326805c74bb54db7c3f3b2d8583 Mon Sep 17 00:00:00 2001 From: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com> Date: Mon, 17 Mar 2025 13:51:25 +0200 Subject: [PATCH 5/9] Fix style --- src/openfl/display/Shader.hx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/openfl/display/Shader.hx b/src/openfl/display/Shader.hx index 034cfafd53..5060906d7b 100644 --- a/src/openfl/display/Shader.hx +++ b/src/openfl/display/Shader.hx @@ -755,7 +755,9 @@ class Shader if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, input); } catch (e:Dynamic) + { Log.debug('Failed to set field $name: $e'); + } } else if (!Reflect.hasField(__data, name) || Reflect.field(__data, name) == null) { @@ -828,7 +830,9 @@ class Shader if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter); } catch (e:Dynamic) + { Log.debug('Failed to set field $name: $e'); + } case INT, INT2, INT3, INT4: var parameter = new ShaderParameter(); @@ -849,7 +853,9 @@ class Shader if (__isGenerated) Reflect.setField(this, name, parameter); } catch (e:Dynamic) + { Log.debug('Failed to set field $name: $e'); + } default: var parameter = new ShaderParameter(); parameter.name = name; @@ -886,7 +892,9 @@ class Shader if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter); } catch (e:Dynamic) + { Log.debug('Failed to set field $name: $e'); + } } } From 417258c2688c053b15972c8ea9fe288a6cbd00fc Mon Sep 17 00:00:00 2001 From: George FunBook Date: Tue, 7 Jan 2025 23:48:50 -0600 Subject: [PATCH 6/9] add pretty printing to shader errors and info --- src/openfl/display/Shader.hx | 58 +++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/src/openfl/display/Shader.hx b/src/openfl/display/Shader.hx index 5060906d7b..9a562bb13f 100644 --- a/src/openfl/display/Shader.hx +++ b/src/openfl/display/Shader.hx @@ -420,21 +420,63 @@ class Shader gl.compileShader(shader); var shaderInfoLog = gl.getShaderInfoLog(shader); var hasInfoLog = shaderInfoLog != null && StringTools.trim(shaderInfoLog) != ""; - var compileStatus = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + var isError = gl.getShaderParameter(shader, gl.COMPILE_STATUS) == 0; - if (hasInfoLog || compileStatus == 0) + if (hasInfoLog || isError) { - var message = (compileStatus == 0) ? "Error" : "Info"; - message += (type == gl.VERTEX_SHADER) ? " compiling vertex shader" : " compiling fragment shader"; - message += "\n" + shaderInfoLog; - message += "\n" + source; - if (compileStatus == 0) Log.error(message); - else if (hasInfoLog) Log.debug(message); + __logGLShaderInfo(isError, type, shaderInfoLog, source); } return shader; } + private var __lineExtractor = ~/^\w+?: \d+:(\d+):(.+$)/; + @:noCompletion private function __logGLShaderInfo(isError:Bool, type:Int, infoLog:String, source:String):Void + { + var message = isError ? "Error" : "Info"; + var typeName = (type == __context.gl.VERTEX_SHADER) ? "vertex" : "fragment"; + message += ' compiling $typeName shader'; + + var lines = source.split("\n"); + var success = true; + var prettyLog = ""; + for (log in infoLog.split("\n")) + { + if (StringTools.trim(log) == "") + continue; + + // look for a line number + if (!__lineExtractor.match(log)) + { + // Could not find line numbers + success = false; + break; + } + + var lineNumber = Std.parseInt(__lineExtractor.matched(1)); + // Note lines is zero-based while lineNumber is 1-based + if (lines.length <= lineNumber - 1) + { + // Invalid line number + success = false; + break; + } + + // Add the relevant line to each log + var info = StringTools.trim(__lineExtractor.matched(2)); + var line = StringTools.trim(lines[lineNumber - 1]); + prettyLog += '\n\nLine $lineNumber: $info\n\t$line'; + } + + if (success) + message += prettyLog; + else + message += "\nFailed to simplify log info, showing full source\n" + infoLog + "\n" + source; + + if (isError) Log.error(message); + else Log.debug(message); + } + @:noCompletion private function __createGLProgram(vertexSource:String, fragmentSource:String):GLProgram { var gl = __context.gl; From e17ad7c2918c5ed5663d65608bc79d2b0f55c5f5 Mon Sep 17 00:00:00 2001 From: George FunBook Date: Wed, 8 Jan 2025 00:16:46 -0600 Subject: [PATCH 7/9] omit lines on EOF errors --- src/openfl/display/Shader.hx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/openfl/display/Shader.hx b/src/openfl/display/Shader.hx index 9a562bb13f..57a5ae3a1d 100644 --- a/src/openfl/display/Shader.hx +++ b/src/openfl/display/Shader.hx @@ -454,16 +454,15 @@ class Shader } var lineNumber = Std.parseInt(__lineExtractor.matched(1)); - // Note lines is zero-based while lineNumber is 1-based - if (lines.length <= lineNumber - 1) + var info = StringTools.trim(__lineExtractor.matched(2)); + // EOF errors will not have a valid line + if (lineNumber > lines.length) { - // Invalid line number - success = false; - break; + prettyLog += '\n\nLine $lineNumber: $info'; + continue; } // Add the relevant line to each log - var info = StringTools.trim(__lineExtractor.matched(2)); var line = StringTools.trim(lines[lineNumber - 1]); prettyLog += '\n\nLine $lineNumber: $info\n\t$line'; } From b5011b391dabed35100b2868abad5deecada7524 Mon Sep 17 00:00:00 2001 From: George FunBook Date: Mon, 3 Feb 2025 13:41:10 -0600 Subject: [PATCH 8/9] Improve error format --- src/openfl/display/Shader.hx | 50 +++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/openfl/display/Shader.hx b/src/openfl/display/Shader.hx index 57a5ae3a1d..8c84c9a08f 100644 --- a/src/openfl/display/Shader.hx +++ b/src/openfl/display/Shader.hx @@ -430,7 +430,17 @@ class Shader return shader; } - private var __lineExtractor = ~/^\w+?: \d+:(\d+):(.+$)/; + /** + * Retrieves the line number from a shader log line. + */ + @:noCompletion private var __lineExtractor = ~/^\w+?: \d+:(\d+):(.+$)/; + /** + * Searches for strings that have only whitespace. + * + * **Note:** Searching for all whitespace via `~/^\s*$/` caused false-negatives, + * notably: `String.fromCharCode(0)` is `false` but `\W` is `true`. + */ + @:noCompletion private var __isEmptyLine = ~/^\W*$/; @:noCompletion private function __logGLShaderInfo(isError:Bool, type:Int, infoLog:String, source:String):Void { var message = isError ? "Error" : "Info"; @@ -438,39 +448,43 @@ class Shader message += ' compiling $typeName shader'; var lines = source.split("\n"); - var success = true; var prettyLog = ""; + var failingLine:String = null; for (log in infoLog.split("\n")) { - if (StringTools.trim(log) == "") + // ignore empty lines + if (__isEmptyLine.match(log)) continue; // look for a line number if (!__lineExtractor.match(log)) { - // Could not find line numbers - success = false; + // Could not find expected info, abort pretty formatting + failingLine = log; break; } - var lineNumber = Std.parseInt(__lineExtractor.matched(1)); - var info = StringTools.trim(__lineExtractor.matched(2)); - // EOF errors will not have a valid line - if (lineNumber > lines.length) + var lineNumberStr = __lineExtractor.matched(1); + var lineNumber = Std.parseInt(lineNumberStr); + var info = __lineExtractor.matched(2); + if (lineNumber >= lines.length) { - prettyLog += '\n\nLine $lineNumber: $info'; - continue; + // EOF errors will not have a valid line + prettyLog += '\n\n $lineNumber | $info'; + } + else + { + // Add the relevant line to each log + var line = lines[lineNumber - 1]; + var indent = StringTools.lpad("|", " ", lineNumberStr.length + 3); + prettyLog += '\n\n $lineNumber | $line\n$indent ${info}'; } - - // Add the relevant line to each log - var line = StringTools.trim(lines[lineNumber - 1]); - prettyLog += '\n\nLine $lineNumber: $info\n\t$line'; } - if (success) - message += prettyLog; + if (failingLine != null) + message += '\nFailed to simplify log:"$failingLine"\n$infoLog\n$source'; else - message += "\nFailed to simplify log info, showing full source\n" + infoLog + "\n" + source; + message += prettyLog; if (isError) Log.error(message); else Log.debug(message); From 316d19de1b3c3a8041d20a604454d1f2c3161d28 Mon Sep 17 00:00:00 2001 From: George FunBook Date: Mon, 3 Feb 2025 15:26:03 -0600 Subject: [PATCH 9/9] cleanup + finalize --- src/openfl/display/Shader.hx | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/openfl/display/Shader.hx b/src/openfl/display/Shader.hx index 8c84c9a08f..a96bf2a109 100644 --- a/src/openfl/display/Shader.hx +++ b/src/openfl/display/Shader.hx @@ -443,12 +443,8 @@ class Shader @:noCompletion private var __isEmptyLine = ~/^\W*$/; @:noCompletion private function __logGLShaderInfo(isError:Bool, type:Int, infoLog:String, source:String):Void { - var message = isError ? "Error" : "Info"; - var typeName = (type == __context.gl.VERTEX_SHADER) ? "vertex" : "fragment"; - message += ' compiling $typeName shader'; - + var message = ""; var lines = source.split("\n"); - var prettyLog = ""; var failingLine:String = null; for (log in infoLog.split("\n")) { @@ -470,24 +466,24 @@ class Shader if (lineNumber >= lines.length) { // EOF errors will not have a valid line - prettyLog += '\n\n $lineNumber | $info'; + message += '\n\n $lineNumber | $info'; } else { // Add the relevant line to each log var line = lines[lineNumber - 1]; var indent = StringTools.lpad("|", " ", lineNumberStr.length + 3); - prettyLog += '\n\n $lineNumber | $line\n$indent ${info}'; + message += '\n\n $lineNumber | $line\n$indent ${info}'; } } + // If we couldn't parse the logs, output the old, verbose format if (failingLine != null) - message += '\nFailed to simplify log:"$failingLine"\n$infoLog\n$source'; - else - message += prettyLog; - - if (isError) Log.error(message); - else Log.debug(message); + message = '\nFailed to simplify log:"$failingLine"\n$infoLog\n$source'; + + var typeName = (type == __context.gl.VERTEX_SHADER) ? "vertex" : "fragment"; + if (isError) Log.error('Error compiling $typeName shader $message'); + else Log.debug('Info compiling $typeName shader $message'); } @:noCompletion private function __createGLProgram(vertexSource:String, fragmentSource:String):GLProgram