1
0
Fork 0

hswaw/signage: reuse compiled shader, better error handling

Shader will now only be recompiled whenever its code changes. This helps
with hangs on node transitions on underpowered devices.

If shader reload failed an error message will now be rendered over an
existing shader.

File load errors are properly handled.

Change-Id: I97a75b85620614252040b76e4f3aaa0ea1f0a7e3
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1337
Reviewed-by: q3k <q3k@hackerspace.pl>
master
informatic 2022-07-08 00:21:37 +02:00 committed by informatic
parent 8f986c181b
commit a7dbf25588
1 changed files with 30 additions and 12 deletions

View File

@ -5,6 +5,7 @@ local smallFont = love.graphics.newFont('fonts/Lato-Light.ttf', 20)
function node:init(config) function node:init(config)
node.super.init(self, config) node.super.init(self, config)
self.prevShaderData = nil
self.path = self.path or "test.glsl" self.path = self.path or "test.glsl"
self.resolution = self.resolution or {1280, 720} self.resolution = self.resolution or {1280, 720}
@ -13,6 +14,10 @@ end
function node:beforeEnter() function node:beforeEnter()
self:loadShader() self:loadShader()
if self.iSystem and self.iSystem.iGlobalTime then
print("Resetting time")
self.iSystem.iGlobalTime = 0
end
end end
function node:loadShader() function node:loadShader()
@ -26,8 +31,20 @@ function node:loadShader()
} }
]] ]]
local file = io.open(self.path, "r") local file = io.open(self.path, "r")
if file == nil then
self.shaderLoadError = self.path .. " does not exist"
return
end
local shaderData = file:read("*all") local shaderData = file:read("*all")
if self.prevShaderData == shaderData then
print("Shader didn't change, not reloading")
return
end
self.prevShaderData = shaderData
shaderData = string.gsub(shaderData,"texture2D","Texel") shaderData = string.gsub(shaderData,"texture2D","Texel")
shaderData = string.gsub(shaderData,"iTime","iGlobalTime") shaderData = string.gsub(shaderData,"iTime","iGlobalTime")
shaderData = string.gsub(shaderData,"precision highp float;","") shaderData = string.gsub(shaderData,"precision highp float;","")
@ -62,16 +79,16 @@ function node:loadShader()
shaderData = shaderData.."\n"..ender shaderData = shaderData.."\n"..ender
end end
print('Shader loaded') print("Shader loaded, compiling...")
self.shaderLoadError = nil self.shaderLoadError = nil
shaderLoaded, self.shader = pcall(love.graphics.newShader, shaderData) shaderLoaded, shader = pcall(love.graphics.newShader, shaderData)
if not shaderLoaded then if not shaderLoaded then
print('Shader load failed:', self.shader) print("Shader compile failed:", shader)
self.shaderLoadError = self.shader self.shaderLoadError = shader
self.shader = nil
else else
print(shaderLoaded, self.shader) self.shader = shader
if iSystem.iResolution then if iSystem.iResolution then
self.shader:send("iResolution",iSystem.iResolution) self.shader:send("iResolution",iSystem.iResolution)
end end
@ -95,12 +112,7 @@ function node:render()
love.graphics.setColor( 0, 0, 0 ) love.graphics.setColor( 0, 0, 0 )
love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
if self.shaderLoadError ~= nil then if self.shader ~= nil then
print('render!')
love.graphics.setColor(1.0, 0.0, 0.0, 1.0)
love.graphics.setFont(smallFont)
love.graphics.printf(self.shaderLoadError, 0, 0.1*love.graphics.getHeight(), love.graphics.getWidth(), 'left');
elseif self.shader ~= nil then
oldCanvas = love.graphics.getCanvas( ) oldCanvas = love.graphics.getCanvas( )
love.graphics.setColor( 1.0, 1.0, 1.0 ) love.graphics.setColor( 1.0, 1.0, 1.0 )
self.canvas:renderTo(function () self.canvas:renderTo(function ()
@ -112,6 +124,12 @@ function node:render()
love.graphics.draw(self.canvas,0,0,math.pi,love.graphics.getWidth() / self.resolution[1], love.graphics.getHeight() / self.resolution[2], self.resolution[1], self.resolution[2]) love.graphics.draw(self.canvas,0,0,math.pi,love.graphics.getWidth() / self.resolution[1], love.graphics.getHeight() / self.resolution[2], self.resolution[1], self.resolution[2])
end end
if self.shaderLoadError ~= nil then
love.graphics.setColor(1.0, 0.0, 0.0, 1.0)
love.graphics.setFont(smallFont)
love.graphics.printf(self.shaderLoadError, 0, 0.1*love.graphics.getHeight(), love.graphics.getWidth(), 'left');
end
end end
return node return node