Sending an Image to a shader does not retain it

Issue #756 resolved
Boolsheet
created an issue

When sending an Image to a Shader with Shader:send, it does not get retained. If Lua then drops its reference, the Image will be deleted and the Shader just lost the texture.

function love.load()
    local imgd = love.image.newImageData(256, 256)
    imgd:mapPixel(function(x, y, r, g, b, a)
        return math.random(0, 255), math.random(0, 255), math.random(0, 255), math.random(0, 255)
    end)
    local img = love.graphics.newImage(imgd)

    local shdr = love.graphics.newShader([[
        extern Image blub;
        vec4 effect(vec4 c, Image i, vec2 tc, vec2 fc)
        {
            return Texel(blub, fc / 600.0);
        }
    ]])

    shdr:send("blub", img)
    love.graphics.setShader(shdr)
    -- At this point, Lua loses all references to the Image and the collector will eat it.
end

function love.draw()
    love.graphics.rectangle("fill", 0, 0, 600, 600)
    collectgarbage() -- Making the testcase faster.
end

Comments (5)

  1. Matthias Richter

    Fix #756: Sending an Image to a shader does not retain it

    Each shader contains a map of uniform name -> bound retainable Object. After setting the uniform, sendImage() and sendCanvas() release() the Object with the requested name (if present) and record the new Image/Canvas.

    Related bugfix: Shader::attach() calls retain()/release() on the shader.

    → <<cset 0a0b2c39fbf1>>

  2. Log in to comment