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:
vrld
2013-11-03 18:27:36 +01:00
parent 3c2e8ddd87
commit 3b04eeeec8
2 changed files with 32 additions and 5 deletions
+26 -3
View File
@@ -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)
+6 -2
View File
@@ -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;