pgraph: fix shadow buffer leak when light passed via shader input

This is an extension of the fix in 9a40febdb9ce40a0936d164a2ed3d72ddf7dcc8a, but that only applied when the light was passed to the shader via LightAttrib, and not via shader inputs.

ParamNodePath is not the ideal place to put this, but it's convenient (and probably more efficient than putting it into ShaderAttrib).
This commit is contained in:
rdb 2019-02-19 21:48:05 +01:00
parent 2574d85049
commit 78425b245e
3 changed files with 49 additions and 20 deletions

View File

@ -11,24 +11,6 @@
* @date 2015-02-25
*/
/**
* Creates a new ParamNodePath storing the given node path object.
*/
INLINE ParamNodePath::
ParamNodePath(const NodePath &node_path) :
_node_path(node_path)
{
}
/**
* Creates a new ParamNodePath storing the given node path object.
*/
INLINE ParamNodePath::
ParamNodePath(NodePath &&node_path) noexcept :
_node_path(std::move(node_path))
{
}
/**
* Returns NodePath::get_class_type().
*/

View File

@ -14,9 +14,41 @@
#include "paramNodePath.h"
#include "dcast.h"
#include "pandaNode.h"
#include "light.h"
TypeHandle ParamNodePath::_type_handle;
/**
* Creates a new ParamNodePath storing the given node path object.
*/
ParamNodePath::
ParamNodePath(NodePath node_path) :
_node_path(std::move(node_path))
{
// The reason to construct a ParamNodePath is often to apply a light to a
// shader input, so we want to keep track of the fact that the light is in
// use.
if (!_node_path.is_empty()) {
Light *light = _node_path.node()->as_light();
if (light != nullptr) {
light->attrib_ref();
}
}
}
/**
*
*/
ParamNodePath::
~ParamNodePath() {
if (!_node_path.is_empty()) {
Light *light = _node_path.node()->as_light();
if (light != nullptr) {
light->attrib_unref();
}
}
}
/**
*
*/
@ -68,6 +100,13 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
_node_path = NodePath(DCAST(PandaNode, p_list[pi++]));
}
if (!_node_path.is_empty()) {
Light *light = _node_path.node()->as_light();
if (light != nullptr) {
light->attrib_ref();
}
}
return pi;
}
@ -96,6 +135,14 @@ void ParamNodePath::
fillin(DatagramIterator &scan, BamReader *manager) {
ParamValueBase::fillin(scan, manager);
if (!_node_path.is_empty()) {
Light *light = _node_path.node()->as_light();
if (light != nullptr) {
light->attrib_unref();
}
_node_path.clear();
}
if (manager->get_file_minor_ver() >= 40) {
_node_path.fillin(scan, manager);
} else {

View File

@ -26,8 +26,8 @@ protected:
INLINE ParamNodePath() {};
PUBLISHED:
INLINE ParamNodePath(const NodePath &node_path);
INLINE ParamNodePath(NodePath &&node_path) noexcept;
ParamNodePath(NodePath node_path);
virtual ~ParamNodePath();
INLINE virtual TypeHandle get_value_type() const;
INLINE NodePath get_value() const;