New Compositer option: "Free Unused". In the Node Editor header.

This will free all Node output buffers, while compositing, when not needed
anymore. Saves a whole lotta memory, and will enable to use many many more
nodes (or high resolution images).
This commit is contained in:
Ton Roosendaal 2006-05-12 11:27:01 +00:00
parent 6cc46d087e
commit f0a5fe5c76
3 changed files with 50 additions and 2 deletions

View File

@ -1795,6 +1795,7 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
#define NODE_PROCESSING 1
#define NODE_READY 2
#define NODE_FINISHED 4
#define NODE_FREEBUFS 8
/* not changing info, for thread callback */
typedef struct ThreadData {
@ -1890,6 +1891,45 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
return totnode;
}
/* while executing tree, free buffers from nodes that are not needed anymore */
static void freeExecutableNode(bNodeTree *ntree)
{
/* node outputs can be freed when:
- not a render result or image node
- when node outputs go to nodes all being set NODE_FINISHED
*/
bNode *node;
bNodeSocket *sock;
/* set exec flag for finished nodes that might need freed */
for(node= ntree->nodes.first; node; node= node->next) {
if(node->type!=CMP_NODE_R_RESULT)
if(node->exec & NODE_FINISHED)
node->exec |= NODE_FREEBUFS;
}
/* clear this flag for input links that are not done yet */
for(node= ntree->nodes.first; node; node= node->next) {
if((node->exec & NODE_FINISHED)==0) {
for(sock= node->inputs.first; sock; sock= sock->next)
if(sock->link)
sock->link->fromnode->exec &= ~NODE_FREEBUFS;
}
}
/* now we can free buffers */
for(node= ntree->nodes.first; node; node= node->next) {
if(node->exec & NODE_FREEBUFS) {
for(sock= node->outputs.first; sock; sock= sock->next) {
bNodeStack *ns= ntree->stack + sock->stack_index;
if(ns->data) {
free_compbuf(ns->data);
ns->data= NULL;
// printf("freed buf node %s \n", node->name);
}
}
}
}
}
static bNode *getExecutableNode(bNodeTree *ntree)
{
bNode *node;
@ -1950,7 +1990,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
if(BLI_available_threads(&threads)) {
node= getExecutableNode(ntree);
if(node) {
if(ntree->timecursor)
ntree->timecursor(totnode);
if(ntree->stats_draw) {
@ -1983,6 +2023,10 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
if((node->exec & NODE_FINISHED)==0) {
BLI_remove_thread(&threads, node);
node->exec |= NODE_FINISHED;
/* freeing unused buffers */
if(rd->scemode & R_COMP_FREE)
freeExecutableNode(ntree);
}
}
else rendering= 1;

View File

@ -449,6 +449,7 @@ typedef struct Scene {
#define R_FREE_IMAGE 0x0100
#define R_SINGLE_LAYER 0x0200
#define R_EXR_TILE_FILE 0x0400
#define R_COMP_FREE 0x0800
/* alphamode */

View File

@ -170,7 +170,10 @@ void node_buttons(ScrArea *sa)
}
}
else if(snode->treetype==NTREE_COMPOSIT) {
uiDefButS(block, TOG, B_NODE_USESCENE, "Use Nodes", xco+5,0,70,19, &G.scene->use_nodes, 0.0f, 0.0f, 0, 0, "");
uiDefButS(block, TOG, B_NODE_USESCENE, "Use Nodes", xco+5,0,70,19, &G.scene->use_nodes, 0.0f, 0.0f, 0, 0, "Indicate this Scene will use Nodes and execute them while editing");
xco+= 80;
uiDefButBitS(block, TOG, R_COMP_FREE, B_NOP, "Free Unused", xco+5,0,80,19, &G.scene->r.scemode, 0.0f, 0.0f, 0, 0, "Free Nodes that are not used while composite");
xco+= 80;
}
/* always as last */