Fix for #34739 and #35060, avoid ambiguity in compositor viewer nodes.
authorLukas Toenne <lukas.toenne@googlemail.com>
Wed, 24 Apr 2013 16:36:50 +0000 (16:36 +0000)
committerLukas Toenne <lukas.toenne@googlemail.com>
Wed, 24 Apr 2013 16:36:50 +0000 (16:36 +0000)
The design changes coming with pynodes for the node editor allow editing multiple node groups or pinning. This is great for working on different node groups without switching between them all the time, but it causes a problem for viewer nodes: these nodes all write to the same Image data by design, causing access conflicts and in some cases memory corruption. This was not a problem before pynodes because the editor would only allow 1 edited node group at any time. With the new flexibility of node editors this restriction is gone.

In order to avoid concurrent write access to the viewer image buffer and resolve the ambiguity this patch adds an "active viewer key" to the scene->nodetree (added in bNodeTree instead of Scene due to otherwise circular DNA includes). This key identifies a specific node tree/group instance, which enables the compositor to selectively enable only 1 viewer node.

The active viewer key is switched when opening/closing node groups (push/pop on the snode->treepath stack) or when selecting a viewer node. This way only the "last edited" viewer will be active.

Eventually it would be nicer if each viewer had its own buffer per node space so one could actually compare viewers without switching. But that is a major redesign of viewer nodes and images, not a quick fix for bcon4 ...

15 files changed:
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/compositor/intern/COM_CompositorContext.h
source/blender/compositor/intern/COM_ExecutionSystem.cpp
source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp
source/blender/compositor/intern/COM_compositor.cpp
source/blender/editors/include/ED_node.h
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_draw.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_intern.h
source/blender/editors/space_node/node_select.c
source/blender/editors/space_node/space_node.c
source/blender/makesdna/DNA_node_types.h
source/blender/render/intern/source/pipeline.c

index adef4853002081699d3c9640eb7eb257d3888fda..d0b3b47c361d53f248fc72dbd523e44c4602dc33 100644 (file)
@@ -507,6 +507,7 @@ typedef struct bNodeInstanceHash
 typedef void (*bNodeInstanceValueFP)(void *value);
 
 extern const bNodeInstanceKey NODE_INSTANCE_KEY_BASE;
+extern const bNodeInstanceKey NODE_INSTANCE_KEY_NONE;
 
 bNodeInstanceKey       BKE_node_instance_key(bNodeInstanceKey parent_key, struct bNodeTree *ntree, struct bNode *node);
 
index a62bfebed452162e0adcb7b033ab58e75e6652a1..f41d6387e4e3e833124cefb6f6612c8092944ddd 100644 (file)
@@ -2562,6 +2562,7 @@ int BKE_node_clipboard_get_type(void)
 
 /* magic number for initial hash key */
 const bNodeInstanceKey NODE_INSTANCE_KEY_BASE = {5381};
+const bNodeInstanceKey NODE_INSTANCE_KEY_NONE = {0};
 
 /* Generate a hash key from ntree and node names
  * Uses the djb2 algorithm with xor by Bernstein:
index 3c7db703bf92ff0a3f15144a10ef584d2ca677a1..2120c12b04efa65dada168bbc17733408e5c7e03 100644 (file)
@@ -84,6 +84,7 @@ private:
        /* @brief color management settings */
        const ColorManagedViewSettings *m_viewSettings;
        const ColorManagedDisplaySettings *m_displaySettings;
+
 public:
        /**
         * @brief constructor initializes the context with default values.
index 450d1b03917527024731a584bf7c4370afba2c37..ad29405d2e9578e8ac1c3199e7f6a2584ac99432 100644 (file)
@@ -53,16 +53,6 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re
        this->m_context.setbNodeTree(editingtree);
        this->m_context.setPreviewHash(editingtree->previews);
        this->m_context.setFastCalculation(fastcalculation);
-#if 0  /* XXX TODO find a better way to define visible output nodes from all editors */
-       bNode *gnode;
-       for (gnode = (bNode *)editingtree->nodes.first; gnode; gnode = gnode->next) {
-               if (gnode->type == NODE_GROUP && gnode->typeinfo->group_edit_get(gnode)) {
-                       this->m_context.setActivegNode(gnode);
-                       break;
-               }
-       }
-#endif
-
        /* initialize the CompositorContext */
        if (rendering) {
                this->m_context.setQuality((CompositorQuality)editingtree->render_quality);
index eb0c9cbdf11d162d45816f2206bf5d19bbbfbc9a..9f0a943c8a2f19c50509821059e6781c3fdd27c9 100644 (file)
@@ -47,12 +47,12 @@ void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_star
        vector<Node *>& nodes = system.getNodes();
        vector<SocketConnection *>& links = system.getConnections();
        
+       bool is_active_group = (parent_key.value == system.getContext().getbNodeTree()->active_viewer_key.value);
+       
        /* add all nodes of the tree to the node list */
        bNode *node = (bNode *)tree->nodes.first;
        while (node != NULL) {
-               /* XXX TODO replace isActiveGroup by a more accurate check, all visible editors should do this! */
-               bool isActiveGroup = true;
-               Node *nnode = addNode(nodes, node, isActiveGroup, system.getContext().isFastCalculation());
+               Node *nnode = addNode(nodes, node, is_active_group, system.getContext().isFastCalculation());
                if (nnode) {
                        nnode->setbNodeTree(tree);
                        nnode->setInstanceKey(BKE_node_instance_key(parent_key, tree, node));
index a0f660058f9963fb29bd6ffe17254049f32fd40e..a0eb52068053fc5799ad6671c18efb9f58252f4c 100644 (file)
@@ -92,7 +92,8 @@ void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering,
                }
        }
 
-       ExecutionSystem *system = new ExecutionSystem(rd, editingtree, rendering, false, viewSettings, displaySettings);
+       ExecutionSystem *system = new ExecutionSystem(rd, editingtree, rendering, false,
+                                                     viewSettings, displaySettings);
        system->execute();
        delete system;
 
index 448a15334c71befb7cb36d41f8765446481846c7..2f16d84aed017bcde8f1920609591841ff1cd22f 100644 (file)
@@ -65,6 +65,8 @@ void ED_node_tree_pop(struct SpaceNode *snode);
 int ED_node_tree_depth(struct SpaceNode *snode);
 struct bNodeTree *ED_node_tree_get(struct SpaceNode *snode, int level);
 
+void ED_node_set_active_viewer_key(struct SpaceNode *snode);
+
 /* drawnode.c */
 void ED_node_init_butfuncs(void);
 void ED_init_custom_node_type(struct bNodeType *ntype);
index d326bd6eca57db8e894a65e0aa9a8e3c92342036..5ab8a248d63a3097a7cae51dec3c57e5ef079ba3 100644 (file)
@@ -2835,135 +2835,143 @@ void ED_init_node_socket_type_virtual(bNodeSocketType *stype)
 
 /* ************** Generic drawing ************** */
 
-void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
-{
-       if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) {
-               Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
-               void *lock;
-               ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
-               if (ibuf) {
-                       float x, y; 
-                       
-                       glMatrixMode(GL_PROJECTION);
-                       glPushMatrix();
-                       glMatrixMode(GL_MODELVIEW);
-                       glPushMatrix();
-
-                       /* keep this, saves us from a version patch */
-                       if (snode->zoom == 0.0f) snode->zoom = 1.0f;
-                       
-                       /* somehow the offset has to be calculated inverse */
-                       
-                       glaDefine2DArea(&ar->winrct);
-                       /* ortho at pixel level curarea */
-                       wmOrtho2(-GLA_PIXEL_OFS, ar->winx - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, ar->winy - GLA_PIXEL_OFS);
+void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeInstanceKey parent_key)
+{
+       bNodeInstanceKey active_viewer_key = (snode->nodetree ? snode->nodetree->active_viewer_key : NODE_INSTANCE_KEY_NONE);
+       Image *ima;
+       void *lock;
+       ImBuf *ibuf;
+       
+       if (!(snode->flag & SNODE_BACKDRAW) || !ED_node_is_compositor(snode))
+               return;
+       
+       if (parent_key.value != active_viewer_key.value)
+               return;
+       
+       ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+       ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+       if (ibuf) {
+               float x, y; 
+               
+               glMatrixMode(GL_PROJECTION);
+               glPushMatrix();
+               glMatrixMode(GL_MODELVIEW);
+               glPushMatrix();
+               
+               /* keep this, saves us from a version patch */
+               if (snode->zoom == 0.0f) snode->zoom = 1.0f;
+               
+               /* somehow the offset has to be calculated inverse */
+               
+               glaDefine2DArea(&ar->winrct);
+               /* ortho at pixel level curarea */
+               wmOrtho2(-GLA_PIXEL_OFS, ar->winx - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, ar->winy - GLA_PIXEL_OFS);
+               
+               x = (ar->winx - snode->zoom * ibuf->x) / 2 + snode->xof;
+               y = (ar->winy - snode->zoom * ibuf->y) / 2 + snode->yof;
+               
+               if (ibuf->rect || ibuf->rect_float) {
+                       unsigned char *display_buffer = NULL;
+                       void *cache_handle = NULL;
                        
-                       x = (ar->winx - snode->zoom * ibuf->x) / 2 + snode->xof;
-                       y = (ar->winy - snode->zoom * ibuf->y) / 2 + snode->yof;
-
-                       if (ibuf->rect || ibuf->rect_float) {
-                               unsigned char *display_buffer = NULL;
-                               void *cache_handle = NULL;
-
-                               if (snode->flag & (SNODE_SHOW_R | SNODE_SHOW_G | SNODE_SHOW_B)) {
-                                       int ofs;
-
-                                       display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
-
+                       if (snode->flag & (SNODE_SHOW_R | SNODE_SHOW_G | SNODE_SHOW_B)) {
+                               int ofs;
+                               
+                               display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
+                               
 #ifdef __BIG_ENDIAN__
-                                       if      (snode->flag & SNODE_SHOW_R) ofs = 2;
-                                       else if (snode->flag & SNODE_SHOW_G) ofs = 1;
-                                       else                                 ofs = 0;
+                               if      (snode->flag & SNODE_SHOW_R) ofs = 2;
+                               else if (snode->flag & SNODE_SHOW_G) ofs = 1;
+                               else                                 ofs = 0;
 #else
-                                       if      (snode->flag & SNODE_SHOW_R) ofs = 1;
-                                       else if (snode->flag & SNODE_SHOW_G) ofs = 2;
-                                       else                                 ofs = 3;
+                               if      (snode->flag & SNODE_SHOW_R) ofs = 1;
+                               else if (snode->flag & SNODE_SHOW_G) ofs = 2;
+                               else                                 ofs = 3;
 #endif
-
-                                       glPixelZoom(snode->zoom, snode->zoom);
-                                       /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
-
-                                       glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT,
-                                                         display_buffer + ofs);
-
-                                       glPixelZoom(1.0f, 1.0f);
-                               }
-                               else if (snode->flag & SNODE_SHOW_ALPHA) {
-                                       display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
-
-                                       glPixelZoom(snode->zoom, snode->zoom);
-                                       /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
+                               
+                               glPixelZoom(snode->zoom, snode->zoom);
+                               /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
+                               
+                               glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT,
+                                                 display_buffer + ofs);
+                               
+                               glPixelZoom(1.0f, 1.0f);
+                       }
+                       else if (snode->flag & SNODE_SHOW_ALPHA) {
+                               display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
+                               
+                               glPixelZoom(snode->zoom, snode->zoom);
+                               /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
 #ifdef __BIG_ENDIAN__
-                                       glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
+                               glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
 #endif
-                                       glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT, display_buffer);
-
+                               glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT, display_buffer);
+                               
 #ifdef __BIG_ENDIAN__
-                                       glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
+                               glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
 #endif
-                                       glPixelZoom(1.0f, 1.0f);
-                               }
-                               else if (snode->flag & SNODE_USE_ALPHA) {
-                                       glEnable(GL_BLEND);
-                                       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-                                       glPixelZoom(snode->zoom, snode->zoom);
-                                       
-                                       glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
-                                       
-                                       glPixelZoom(1.0f, 1.0f);
-                                       glDisable(GL_BLEND);
-                               }
-                               else {
-                                       glPixelZoom(snode->zoom, snode->zoom);
-
-                                       glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
-                                       
-                                       glPixelZoom(1.0f, 1.0f);
-                               }
-
-                               if (cache_handle)
-                                       IMB_display_buffer_release(cache_handle);
+                               glPixelZoom(1.0f, 1.0f);
                        }
-
-                       /** @note draw selected info on backdrop */
-                       if (snode->edittree) {
-                               bNode *node = snode->edittree->nodes.first;
-                               rctf *viewer_border = &snode->nodetree->viewer_border;
-                               while (node) {
-                                       if (node->flag & NODE_SELECT) {
-                                               if (node->typeinfo->uibackdropfunc) {
-                                                       node->typeinfo->uibackdropfunc(snode, ibuf, node, x, y);
-                                               }
+                       else if (snode->flag & SNODE_USE_ALPHA) {
+                               glEnable(GL_BLEND);
+                               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                               glPixelZoom(snode->zoom, snode->zoom);
+                               
+                               glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
+                               
+                               glPixelZoom(1.0f, 1.0f);
+                               glDisable(GL_BLEND);
+                       }
+                       else {
+                               glPixelZoom(snode->zoom, snode->zoom);
+                               
+                               glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
+                               
+                               glPixelZoom(1.0f, 1.0f);
+                       }
+                       
+                       if (cache_handle)
+                               IMB_display_buffer_release(cache_handle);
+               }
+               
+               /** @note draw selected info on backdrop */
+               if (snode->edittree) {
+                       bNode *node = snode->edittree->nodes.first;
+                       rctf *viewer_border = &snode->nodetree->viewer_border;
+                       while (node) {
+                               if (node->flag & NODE_SELECT) {
+                                       if (node->typeinfo->uibackdropfunc) {
+                                               node->typeinfo->uibackdropfunc(snode, ibuf, node, x, y);
                                        }
-                                       node = node->next;
-                               }
-
-                               if ((snode->nodetree->flag & NTREE_VIEWER_BORDER) &&
-                                   viewer_border->xmin < viewer_border->xmax &&
-                                   viewer_border->ymin < viewer_border->ymax)
-                               {
-                                       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-                                       setlinestyle(3);
-                                       cpack(0x4040FF);
-
-                                       glRectf(x + snode->zoom * viewer_border->xmin * ibuf->x,
-                                               y + snode->zoom * viewer_border->ymin * ibuf->y,
-                                               x + snode->zoom * viewer_border->xmax * ibuf->x,
-                                               y + snode->zoom * viewer_border->ymax * ibuf->y);
-
-                                       setlinestyle(0);
-                                       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
                                }
+                               node = node->next;
                        }
                        
-                       glMatrixMode(GL_PROJECTION);
-                       glPopMatrix();
-                       glMatrixMode(GL_MODELVIEW);
-                       glPopMatrix();
+                       if ((snode->nodetree->flag & NTREE_VIEWER_BORDER) &&
+                               viewer_border->xmin < viewer_border->xmax &&
+                               viewer_border->ymin < viewer_border->ymax)
+                       {
+                               glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+                               setlinestyle(3);
+                               cpack(0x4040FF);
+                               
+                               glRectf(x + snode->zoom * viewer_border->xmin * ibuf->x,
+                                       y + snode->zoom * viewer_border->ymin * ibuf->y,
+                                       x + snode->zoom * viewer_border->xmax * ibuf->x,
+                                       y + snode->zoom * viewer_border->ymax * ibuf->y);
+                               
+                               setlinestyle(0);
+                               glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+                       }
                }
-
-               BKE_image_release_ibuf(ima, ibuf, lock);
+               
+               glMatrixMode(GL_PROJECTION);
+               glPopMatrix();
+               glMatrixMode(GL_MODELVIEW);
+               glPopMatrix();
        }
+       
+       BKE_image_release_ibuf(ima, ibuf, lock);
 }
 
 
index 871d3751a4daee0d539755f774a1b838b65ba3fa..992caf5285f83fe4b333f560bc43bc6708d1b212 100644 (file)
@@ -1314,7 +1314,7 @@ void drawnodespace(const bContext *C, ARegion *ar)
                        UI_view2d_multi_grid_draw(v2d, (depth > 0 ? TH_NODE_GROUP : TH_BACK), U.widget_unit, 5, 2);
                        
                        /* backdrop */
-                       draw_nodespace_back_pix(C, ar, snode);
+                       draw_nodespace_back_pix(C, ar, snode, path->parent_key);
                        
                        draw_nodetree(C, ar, ntree, path->parent_key);
                }
@@ -1339,7 +1339,7 @@ void drawnodespace(const bContext *C, ARegion *ar)
                UI_view2d_multi_grid_draw(v2d, TH_BACK, U.widget_unit, 5, 2);
                
                /* backdrop */
-               draw_nodespace_back_pix(C, ar, snode);
+               draw_nodespace_back_pix(C, ar, snode, NODE_INSTANCE_KEY_NONE);
        }
        
        ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
index bf4a41e35c3e8e4aa2e1532ced9d4f84306b1770..80504dda80b891a4887540c3afdea09919b085ab 100644 (file)
@@ -253,7 +253,8 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog
 
        // XXX BIF_store_spare();
        
-       ntreeCompositExecTree(ntree, &cj->scene->r, 0, 1, &scene->view_settings, &scene->display_settings);  /* 1 is do_previews */
+       /* 1 is do_previews */
+       ntreeCompositExecTree(ntree, &cj->scene->r, FALSE, TRUE, &scene->view_settings, &scene->display_settings);
 
        ntree->test_break = NULL;
        ntree->stats_draw = NULL;
index 4b31f22b172b207c0bb7c0dca3f4e746c1e1f389..c31bb5ba832271a168f43fb90eb695eda5c54dc5 100644 (file)
@@ -136,7 +136,7 @@ void node_draw_link(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLin
 void node_draw_link_bezier(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3);
 int  node_link_bezier_points(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link, float coord_array[][2], int resol);
 // void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 );
-void draw_nodespace_back_pix(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode);
+void draw_nodespace_back_pix(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode, bNodeInstanceKey parent_key);
 
 
 /* node_add.c */
index 366fcce3dd5290e876a1a7b1b8035355f1a6d928..ea745c4769000f30b7f67b474db8d37fb1ba080f 100644 (file)
@@ -293,6 +293,7 @@ void node_select_single(bContext *C, bNode *node)
        nodeSetSelected(node, TRUE);
        
        ED_node_set_active(bmain, snode->edittree, node);
+       ED_node_set_active_viewer_key(snode);
        
        ED_node_sort(snode->edittree);
        
@@ -374,8 +375,10 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i
        }
        
        /* update node order */
-       if (selected)
+       if (selected) {
+               ED_node_set_active_viewer_key(snode);
                ED_node_sort(snode->edittree);
+       }
        
        return selected;
 }
index e234b4255ed169e62df7b69ca665a7df94c7cde3..ec5c4657b9c9e62b17a7774227b0fe63701ce3ca 100644 (file)
@@ -90,6 +90,8 @@ void ED_node_tree_start(SpaceNode *snode, bNodeTree *ntree, ID *id, ID *from)
        snode->id = id;
        snode->from = from;
        
+       ED_node_set_active_viewer_key(snode);
+       
        WM_main_add_notifier(NC_SCENE | ND_NODES, NULL);
 }
 
@@ -117,6 +119,8 @@ void ED_node_tree_push(SpaceNode *snode, bNodeTree *ntree, bNode *gnode)
        /* update current tree */
        snode->edittree = ntree;
        
+       ED_node_set_active_viewer_key(snode);
+       
        WM_main_add_notifier(NC_SCENE | ND_NODES, NULL);
 }
 
@@ -135,6 +139,8 @@ void ED_node_tree_pop(SpaceNode *snode)
        path = snode->treepath.last;
        snode->edittree = path->nodetree;
        
+       ED_node_set_active_viewer_key(snode);
+       
        /* listener updates the View2D center from edittree */
        WM_main_add_notifier(NC_SCENE | ND_NODES, NULL);
 }
@@ -208,6 +214,14 @@ void ED_node_tree_path_get_fixedbuf(SpaceNode *snode, char *value, int max_lengt
        }
 }
 
+void ED_node_set_active_viewer_key(SpaceNode *snode)
+{
+       bNodeTreePath *path = snode->treepath.last;
+       if (snode->nodetree && path) {
+               snode->nodetree->active_viewer_key = path->parent_key;
+       }
+}
+
 void snode_group_offset(SpaceNode *snode, float *x, float *y)
 {
        bNodeTreePath *path = snode->treepath.last;
index b6a5c758dc00e1a998820069f3498224d527b056..3ed97c2480ffd05b9755a374c2bb496f3a2f2b57 100644 (file)
@@ -370,6 +370,13 @@ typedef struct bNodeTree {
         * Only available in base node trees (e.g. scene->node_tree)
         */
        struct bNodeInstanceHash *previews;
+       /* XXX workaround for ambiguous viewer output:
+        * Viewer nodes all write to the same image buffer.
+        * This determines the tree instance containing the "active" output.
+        * Only used in local scene->nodetree.
+        */
+       bNodeInstanceKey active_viewer_key;
+       int pad;
        
        /* execution data */
        /* XXX It would be preferable to completely move this data out of the underlying node tree,
@@ -403,7 +410,7 @@ typedef struct bNodeTree {
 #define NTREE_COM_OPENCL                       2       /* use opencl */
 #define NTREE_TWO_PASS                         4       /* two pass */
 #define NTREE_COM_GROUPNODE_BUFFER     8       /* use groupnode buffers */
-#define NTREE_VIEWER_BORDER            16      /* use a border for viewer nodes */
+#define NTREE_VIEWER_BORDER                    16      /* use a border for viewer nodes */
 
 /* XXX not nice, but needed as a temporary flags
  * for group updates after library linking.
index 5510c07e19c9eca2b299cf9594b533a45572b589..0a92e09e6643d418ba54b5631b6a195df5010f6c 100644 (file)
@@ -1732,7 +1732,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
                        ntreeCompositTagRender(re->scene);
                        ntreeCompositTagAnimated(ntree);
                        
-                       ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0, &re->scene->view_settings, &re->scene->display_settings);
+                       ntreeCompositExecTree(ntree, &re->r, TRUE, G.background == 0, &re->scene->view_settings, &re->scene->display_settings);
                }
                
                /* ensure we get either composited result or the active layer */
@@ -1909,7 +1909,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
                                if (re->r.scemode & R_FULL_SAMPLE)
                                        do_merge_fullsample(re, ntree);
                                else {
-                                       ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0, &re->scene->view_settings, &re->scene->display_settings);
+                                       ntreeCompositExecTree(ntree, &re->r, TRUE, G.background == 0, &re->scene->view_settings, &re->scene->display_settings);
                                }
                                
                                ntree->stats_draw = NULL;