mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
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.
This commit is contained in:
@@ -91,6 +91,12 @@ Shader::~Shader()
|
||||
if (current == this)
|
||||
detach();
|
||||
|
||||
for (auto it = boundRetainables.begin(); it != boundRetainables.end(); ++it)
|
||||
{
|
||||
it->second->release();
|
||||
boundRetainables.erase(it);
|
||||
}
|
||||
|
||||
unloadVolatile();
|
||||
}
|
||||
|
||||
@@ -331,8 +337,13 @@ void Shader::attach(bool temporary)
|
||||
{
|
||||
if (current != this)
|
||||
{
|
||||
if (current != NULL)
|
||||
current->release();
|
||||
|
||||
glUseProgram(program);
|
||||
current = this;
|
||||
|
||||
current->retain();
|
||||
}
|
||||
|
||||
if (!temporary)
|
||||
@@ -558,14 +569,26 @@ void Shader::sendTexture(const std::string &name, GLuint texture)
|
||||
activeTextureUnits[textureunit-1] = texture;
|
||||
}
|
||||
|
||||
void Shader::sendImage(const std::string &name, const Image &image)
|
||||
void Shader::retainTexture(const std::string &name, Object *texture)
|
||||
{
|
||||
sendTexture(name, image.getTextureName());
|
||||
auto it = boundRetainables.find(name);
|
||||
if (it != boundRetainables.end())
|
||||
it->second->release();
|
||||
|
||||
texture->retain();
|
||||
boundRetainables[name] = texture;
|
||||
}
|
||||
|
||||
void Shader::sendCanvas(const std::string &name, const Canvas &canvas)
|
||||
void Shader::sendImage(const std::string &name, Image &image)
|
||||
{
|
||||
sendTexture(name, image.getTextureName());
|
||||
retainTexture(name, &image);
|
||||
}
|
||||
|
||||
void Shader::sendCanvas(const std::string &name, Canvas &canvas)
|
||||
{
|
||||
sendTexture(name, canvas.getTextureName());
|
||||
retainTexture(name, &canvas);
|
||||
}
|
||||
|
||||
int Shader::getTextureUnit(const std::string &name)
|
||||
|
||||
@@ -124,14 +124,14 @@ public:
|
||||
*
|
||||
* @param name The name of the uniform variable in the source code.
|
||||
**/
|
||||
void sendImage(const std::string &name, const Image &image);
|
||||
void sendImage(const std::string &name, Image &image);
|
||||
|
||||
/**
|
||||
* Send a canvas to this Shader as a uniform.
|
||||
*
|
||||
* @param name The name of the uniform variable in the source code.
|
||||
**/
|
||||
void sendCanvas(const std::string &name, const Canvas &canvas);
|
||||
void sendCanvas(const std::string &name, Canvas &canvas);
|
||||
|
||||
static std::string getGLSLVersion();
|
||||
static bool isSupported();
|
||||
@@ -173,6 +173,7 @@ private:
|
||||
int getTextureUnit(const std::string &name);
|
||||
|
||||
void sendTexture(const std::string &name, GLuint texture);
|
||||
void retainTexture(const std::string &name, Object *texture);
|
||||
|
||||
// Get any warnings or errors generated only by the shader program object.
|
||||
std::string getProgramWarnings() const;
|
||||
@@ -193,6 +194,9 @@ private:
|
||||
std::map<std::string, GLint> textureUnitPool; // textureUnitPool[name] = textureunit
|
||||
std::vector<GLuint> activeTextureUnits; // activeTextureUnits[textureunit-1] = textureid
|
||||
|
||||
// Uniform name to retainable objects
|
||||
std::map<std::string, Object*> boundRetainables;
|
||||
|
||||
// Max GPU texture units available for sent images
|
||||
static GLint maxTextureUnits;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user