From 78425b245e9e0747eaa7905e1bc5fb73ea9126bc Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 19 Feb 2019 21:48:05 +0100 Subject: [PATCH] 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). --- panda/src/pgraph/paramNodePath.I | 18 ------------ panda/src/pgraph/paramNodePath.cxx | 47 ++++++++++++++++++++++++++++++ panda/src/pgraph/paramNodePath.h | 4 +-- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/panda/src/pgraph/paramNodePath.I b/panda/src/pgraph/paramNodePath.I index 354a2af7ec..67a9d24ea6 100644 --- a/panda/src/pgraph/paramNodePath.I +++ b/panda/src/pgraph/paramNodePath.I @@ -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(). */ diff --git a/panda/src/pgraph/paramNodePath.cxx b/panda/src/pgraph/paramNodePath.cxx index 72a3563b22..45bfe0c12f 100644 --- a/panda/src/pgraph/paramNodePath.cxx +++ b/panda/src/pgraph/paramNodePath.cxx @@ -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 { diff --git a/panda/src/pgraph/paramNodePath.h b/panda/src/pgraph/paramNodePath.h index daab53e41e..63798cc4a8 100644 --- a/panda/src/pgraph/paramNodePath.h +++ b/panda/src/pgraph/paramNodePath.h @@ -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;