change curve evaluation functions never to modify curve data (ensures thread safety...
authorCampbell Barton <ideasman42@gmail.com>
Tue, 21 Aug 2012 14:43:51 +0000 (14:43 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 21 Aug 2012 14:43:51 +0000 (14:43 +0000)
16 files changed:
source/blender/blenkernel/BKE_colortools.h
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/colortools.c
source/blender/blenkernel/intern/world.c
source/blender/compositor/nodes/COM_TimeNode.cpp
source/blender/gpu/intern/gpu_material.c
source/blender/makesrna/intern/rna_color.c
source/blender/modifiers/intern/MOD_warp.c
source/blender/modifiers/intern/MOD_weightvg_util.c
source/blender/nodes/composite/nodes/node_composite_curves.c
source/blender/nodes/composite/nodes/node_composite_huecorrect.c
source/blender/nodes/shader/nodes/node_shader_curves.c
source/blender/nodes/texture/nodes/node_texture_curves.c
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/pointdensity.c
source/blender/render/intern/source/shadeoutput.c

index 249cb32a0826cad8d282ad8574aff3b319fb7600..9ce2de79dbf99472943acfe82af324d71764795f 100644 (file)
@@ -67,25 +67,31 @@ void                    curvemap_sethandle(struct CurveMap *cuma, int type);
 void                curvemapping_changed(struct CurveMapping *cumap, int rem_doubles);
 void                curvemapping_changed_all(struct CurveMapping *cumap);
 
+/* call before _all_ evaluation functions */
+void                curvemapping_initialize(struct CurveMapping *cumap);
+
+/* keep these (const CurveMap) - to help with thread safety */
 /* single curve, no table check */
-float               curvemap_evaluateF(struct CurveMap *cuma, float value);
+float               curvemap_evaluateF(const struct CurveMap *cuma, float value);
 /* single curve, with table check */
-float               curvemapping_evaluateF(struct CurveMapping *cumap, int cur, float value);
-void                curvemapping_evaluate3F(struct CurveMapping *cumap, float vecout[3], const float vecin[3]);
-void                curvemapping_evaluateRGBF(struct CurveMapping *cumap, float vecout[3], const float vecin[3]);
-void                curvemapping_evaluate_premulRGB(struct CurveMapping *cumap, unsigned char vecout_byte[3], const unsigned char vecin_byte[3]);
-void                curvemapping_evaluate_premulRGBF_ex(struct CurveMapping *cumap, float vecout[3], const float vecin[3],
+float               curvemapping_evaluateF(const struct CurveMapping *cumap, int cur, float value);
+void                curvemapping_evaluate3F(const struct CurveMapping *cumap, float vecout[3], const float vecin[3]);
+void                curvemapping_evaluateRGBF(const struct CurveMapping *cumap, float vecout[3], const float vecin[3]);
+void                curvemapping_evaluate_premulRGB(const struct CurveMapping *cumap, unsigned char vecout_byte[3], const unsigned char vecin_byte[3]);
+void                curvemapping_evaluate_premulRGBF_ex(const struct CurveMapping *cumap, float vecout[3], const float vecin[3],
                                                         const float black[3], const float bwmul[3]);
-void                curvemapping_evaluate_premulRGBF(struct CurveMapping *cumap, float vecout[3], const float vecin[3]);
+void                curvemapping_evaluate_premulRGBF(const struct CurveMapping *cumap, float vecout[3], const float vecin[3]);
+int                 curvemapping_RGBA_does_something(const struct CurveMapping *cumap);
+void                curvemapping_table_RGBA(const struct CurveMapping *cumap, float **array, int *size);
+
+/* non-const, these modify the curve */
 void                curvemapping_do_ibuf(struct CurveMapping *cumap, struct ImBuf *ibuf);
 void                curvemapping_premultiply(struct CurveMapping *cumap, int restore);
-int                 curvemapping_RGBA_does_something(struct CurveMapping *cumap);
-void                curvemapping_initialize(struct CurveMapping *cumap);
-void                curvemapping_table_RGBA(struct CurveMapping *cumap, float **array, int *size);
+
+
 void                BKE_histogram_update_sample_line(struct Histogram *hist, struct ImBuf *ibuf, const short use_color_management);
 void                scopes_update(struct Scopes *scopes, struct ImBuf *ibuf, int use_color_management);
 void                scopes_free(struct Scopes *scopes);
 void                scopes_new(struct Scopes *scopes);
 
 #endif
-
index fc4df9594f30b583f074af3d8ca3542accd5cb63..fde95e0767eb30bd3ef60b582e9068958c1ee401 100644 (file)
@@ -1253,7 +1253,9 @@ float BKE_brush_curve_strength_clamp(Brush *br, float p, const float len)
        if (p >= len) return 0;
        else p = p / len;
 
+       curvemapping_initialize(br->curve);
        p = curvemapping_evaluateF(br->curve, 0, p);
+
        if (p < 0.0f) p = 0.0f;
        else if (p > 1.0f) p = 1.0f;
        return p;
@@ -1267,6 +1269,7 @@ float BKE_brush_curve_strength(Brush *br, float p, const float len)
        else
                p = p / len;
 
+       curvemapping_initialize(br->curve);
        return curvemapping_evaluateF(br->curve, 0, p);
 }
 
index 24a84d7993591bcc80204df4371b62e6adac1a80..79cd97ed25c18608c5ab2ce3362977d2fded498a 100644 (file)
@@ -440,7 +440,7 @@ static void calchandle_curvemap(BezTriple *bezt, BezTriple *prev, BezTriple *nex
 
 /* in X, out Y. 
  * X is presumed to be outside first or last */
-static float curvemap_calc_extend(CurveMap *cuma, float x, const float first[2], const float last[2])
+static float curvemap_calc_extend(const CurveMap *cuma, float x, const float first[2], const float last[2])
 {
        if (x <= first[0]) {
                if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
@@ -739,7 +739,7 @@ void curvemapping_changed_all(CurveMapping *cumap)
 }
 
 /* table should be verified */
-float curvemap_evaluateF(CurveMap *cuma, float value)
+float curvemap_evaluateF(const CurveMap *cuma, float value)
 {
        float fi;
        int i;
@@ -761,33 +761,26 @@ float curvemap_evaluateF(CurveMap *cuma, float value)
 }
 
 /* works with curve 'cur' */
-float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value)
+float curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value)
 {
-       CurveMap *cuma = cumap->cm + cur;
-       
-       /* allocate or bail out */
-       if (cuma->table == NULL) {
-               curvemap_make_table(cuma, &cumap->clipr);
-               if (cuma->table == NULL)
-                       return 1.0f - value;
-       }
+       const CurveMap *cuma = cumap->cm + cur;
        return curvemap_evaluateF(cuma, value);
 }
 
 /* vector case */
-void curvemapping_evaluate3F(CurveMapping *cumap, float vecout[3], const float vecin[3])
+void curvemapping_evaluate3F(const CurveMapping *cumap, float vecout[3], const float vecin[3])
 {
-       vecout[0] = curvemapping_evaluateF(cumap, 0, vecin[0]);
-       vecout[1] = curvemapping_evaluateF(cumap, 1, vecin[1]);
-       vecout[2] = curvemapping_evaluateF(cumap, 2, vecin[2]);
+       vecout[0] = curvemap_evaluateF(&cumap->cm[0], vecin[0]);
+       vecout[1] = curvemap_evaluateF(&cumap->cm[1], vecin[1]);
+       vecout[2] = curvemap_evaluateF(&cumap->cm[2], vecin[2]);
 }
 
 /* RGB case, no black/white points, no premult */
-void curvemapping_evaluateRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3])
+void curvemapping_evaluateRGBF(const CurveMapping *cumap, float vecout[3], const float vecin[3])
 {
-       vecout[0] = curvemapping_evaluateF(cumap, 0, curvemapping_evaluateF(cumap, 3, vecin[0]));
-       vecout[1] = curvemapping_evaluateF(cumap, 1, curvemapping_evaluateF(cumap, 3, vecin[1]));
-       vecout[2] = curvemapping_evaluateF(cumap, 2, curvemapping_evaluateF(cumap, 3, vecin[2]));
+       vecout[0] = curvemap_evaluateF(&cumap->cm[0], curvemap_evaluateF(&cumap->cm[3], vecin[0]));
+       vecout[1] = curvemap_evaluateF(&cumap->cm[1], curvemap_evaluateF(&cumap->cm[3], vecin[1]));
+       vecout[2] = curvemap_evaluateF(&cumap->cm[2], curvemap_evaluateF(&cumap->cm[3], vecin[2]));
 }
 
 /** same as #curvemapping_evaluate_premulRGBF
@@ -799,7 +792,7 @@ void curvemapping_evaluateRGBF(CurveMapping *cumap, float vecout[3], const float
  * \param black Use instead of cumap->black
  * \param bwmul Use instead of cumap->bwmul
  */
-void curvemapping_evaluate_premulRGBF_ex(CurveMapping *cumap, float vecout[3], const float vecin[3],
+void curvemapping_evaluate_premulRGBF_ex(const CurveMapping *cumap, float vecout[3], const float vecin[3],
                                          const float black[3], const float bwmul[3])
 {
        vecout[0] = curvemap_evaluateF(&cumap->cm[0], (vecin[0] - black[0]) * bwmul[0]);
@@ -808,7 +801,7 @@ void curvemapping_evaluate_premulRGBF_ex(CurveMapping *cumap, float vecout[3], c
 }
 
 /* RGB with black/white points and premult. tables are checked */
-void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3])
+void curvemapping_evaluate_premulRGBF(const CurveMapping *cumap, float vecout[3], const float vecin[3])
 {
        vecout[0] = curvemap_evaluateF(&cumap->cm[0], (vecin[0] - cumap->black[0]) * cumap->bwmul[0]);
        vecout[1] = curvemap_evaluateF(&cumap->cm[1], (vecin[1] - cumap->black[1]) * cumap->bwmul[1]);
@@ -816,7 +809,7 @@ void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float vecout[3], cons
 }
 
 /* same as above, byte version */
-void curvemapping_evaluate_premulRGB(CurveMapping *cumap, unsigned char vecout_byte[3], const unsigned char vecin_byte[3])
+void curvemapping_evaluate_premulRGB(const CurveMapping *cumap, unsigned char vecout_byte[3], const unsigned char vecin_byte[3])
 {
        float vecin[3], vecout[3];
 
@@ -889,7 +882,7 @@ void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf)
        curvemapping_premultiply(cumap, 1);
 }
 
-int curvemapping_RGBA_does_something(CurveMapping *cumap)
+int curvemapping_RGBA_does_something(const CurveMapping *cumap)
 {
        int a;
        
@@ -925,13 +918,12 @@ void curvemapping_initialize(CurveMapping *cumap)
        }
 }
 
-void curvemapping_table_RGBA(CurveMapping *cumap, float **array, int *size)
+void curvemapping_table_RGBA(const CurveMapping *cumap, float **array, int *size)
 {
        int a;
        
        *size = CM_TABLE + 1;
        *array = MEM_callocN(sizeof(float) * (*size) * 4, "CurveMapping");
-       curvemapping_initialize(cumap);
 
        for (a = 0; a < *size; a++) {
                if (cumap->cm[0].table)
index 303098ea0bd64e64b8d9e7c12320b3402fe7602b..dd71e43182e9e2a0646f0237d66682bc042ae996 100644 (file)
@@ -128,8 +128,9 @@ World *BKE_world_copy(World *wrld)
                }
        }
 
-       if (wrld->nodetree)
+       if (wrld->nodetree) {
                wrldn->nodetree = ntreeCopyTree(wrld->nodetree);
+       }
        
        if (wrld->preview)
                wrldn->preview = BKE_previewimg_copy(wrld->preview);
index 84ee4e77b0600c7d5d9c67bffa05e8e0a6515e11..82c8deafd9de03adf535a2ae037962f1b5539638 100644 (file)
@@ -33,6 +33,8 @@ TimeNode::TimeNode(bNode *editorNode) : Node(editorNode)
        /* pass */
 }
 
+////curvemapping_initialize(&hcmd->curve_mapping);
+
 void TimeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
 {
        SetValueOperation *operation = new SetValueOperation();
@@ -53,6 +55,7 @@ void TimeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
                fac = (context->getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1);
        }
 
+       curvemapping_initialize((CurveMapping *)node->storage);
        fac = curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac);
        operation->setValue(CLAMPIS(fac, 0.0f, 1.0f));
        graph->addOperation(operation);
index bd25a042ee41d4a0c7d910b166a2dffadbda28a2..efb243757297eb2a55db77ce4a2e8e829327ea88 100644 (file)
@@ -427,6 +427,7 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode
                                        float *array;
                                        int size;
 
+                                       curvemapping_initialize(lamp->curfalloff);
                                        curvemapping_table_RGBA(lamp->curfalloff, &array, &size);
                                        GPU_link(mat, "lamp_falloff_curve", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), GPU_texture(size, array), *dist, &visifac);
                                }
index 5dafe77f9c16dcdd904fdf9417796e45f9ea51e1..0bd42c2f5a0a3a696b2ba16245a664426ee9fb4b 100644 (file)
@@ -337,6 +337,12 @@ static void rna_Scopes_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointer
        s->ok = 0;
 }
 
+/* this function only exists because #curvemap_evaluateF uses a 'const' qualifier */
+float rna_CurveMap_evaluateF(struct CurveMap *cuma, float value)
+{
+       return curvemap_evaluateF(cuma, value);
+}
+
 #else
 
 static void rna_def_curvemappoint(BlenderRNA *brna)
@@ -419,7 +425,7 @@ static void rna_def_curvemap(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Points", "");
        rna_def_curvemap_points_api(brna, prop);
 
-       func = RNA_def_function(srna, "evaluate", "curvemap_evaluateF");
+       func = RNA_def_function(srna, "evaluate", "rna_CurveMap_evaluateF");
        RNA_def_function_ui_description(func, "Evaluate curve at given location");
        parm = RNA_def_float(func, "position", 0.0f, -FLT_MAX, FLT_MAX, "Position", "Position to evaluate curve at", -FLT_MAX, FLT_MAX);
        RNA_def_property_flag(parm, PROP_REQUIRED);
index 9eb360f68193c98974bdefa9bfbbae8a6b47ca53..95f6ef60665d8e08dcc954eb06ff89f5b8c66dc9 100644 (file)
@@ -195,6 +195,10 @@ static void warpModifier_do(WarpModifierData *wmd, Object *ob,
        if (wmd->curfalloff == NULL) /* should never happen, but bad lib linking could cause it */
                wmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
 
+       if (wmd->curfalloff) {
+               curvemapping_initialize(wmd->curfalloff);
+       }
+
        invert_m4_m4(obinv, ob->obmat);
 
        mult_m4_m4m4(mat_from, obinv, wmd->object_from->obmat);
index 81cdad0d5e5e8b71ff992943a8393d59a2073d9b..7181b5bbb447a8587f90aefe7c958fa4274a491d 100644 (file)
@@ -73,6 +73,10 @@ void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cm
                return;
        }
 
+       if (cmap && falloff_type == MOD_WVG_MAPPING_CURVE) {
+               curvemapping_initialize(cmap);
+       }
+
        /* Map each weight (vertex) to its new value, accordingly to the chosen mode. */
        for (i = 0; i < num; ++i) {
                float fac = new_w[i];
index 85830e8ca142a7ee7245e45fb475b92b0e4bcdaa..ddc93e940617ec6af27b9d60f71529f7b3f10d79 100644 (file)
@@ -52,7 +52,9 @@ static void node_composit_exec_curves_time(void *data, bNode *node, bNodeStack *
        if (node->custom1 < node->custom2)
                fac= (rd->cfra - node->custom1)/(float)(node->custom2-node->custom1);
        
-       fac= curvemapping_evaluateF(node->storage, 0, fac);
+       curvemapping_initialize(node->storage);
+       fac = curvemapping_evaluateF(node->storage, 0, fac);
+
        out[0]->vec[0]= CLAMPIS(fac, 0.0f, 1.0f);
 }
 
@@ -100,7 +102,8 @@ static void node_composit_exec_curve_vec(void *UNUSED(data), bNode *node, bNodeS
 {
        /* stack order input:  vec */
        /* stack order output: vec */
-       
+
+       curvemapping_initialize(node->storage);
        curvemapping_evaluate_premulRGBF(node->storage, out[0]->vec, in[0]->vec);
 }
 
@@ -146,13 +149,15 @@ static bNodeSocketTemplate cmp_node_curve_rgb_out[]= {
 
 static void do_curves(bNode *node, float *out, float *in)
 {
+       curvemapping_initialize(node->storage);
        curvemapping_evaluate_premulRGBF(node->storage, out, in);
        out[3]= in[3];
 }
 
 static void do_curves_fac(bNode *node, float *out, float *in, float *fac)
 {
-       
+       curvemapping_initialize(node->storage);
+
        if (*fac >= 1.0f)
                curvemapping_evaluate_premulRGBF(node->storage, out, in);
        else if (*fac <= 0.0f) {
@@ -176,6 +181,8 @@ static void node_composit_exec_curve_rgb(void *UNUSED(data), bNode *node, bNodeS
        if (out[0]->hasoutput==0)
                return;
 
+       curvemapping_initialize(node->storage);
+
        /* input no image? then only color operation */
        if (in[1]->data==NULL) {
                curvemapping_evaluateRGBF(node->storage, out[0]->vec, in[1]->vec);
index 1f343c648c37ab3531cd94681b4e3f5f10a7ba5a..7e3f6a5fb3aecdf12be7d0f63644b08704f387f3 100644 (file)
@@ -51,6 +51,8 @@ static void do_huecorrect(bNode *node, float *out, float *in)
        
        rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
        
+       curvemapping_initialize(node->storage);
+
        /* adjust hue, scaling returned default 0.5 up to 1 */
        f = curvemapping_evaluateF(node->storage, 0, hsv[0]);
        hsv[0] += f-0.5f;
@@ -79,6 +81,8 @@ static void do_huecorrect_fac(bNode *node, float *out, float *in, float *fac)
        
        rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
        
+       curvemapping_initialize(node->storage);
+
        /* adjust hue, scaling returned default 0.5 up to 1 */
        f = curvemapping_evaluateF(node->storage, 0, hsv[0]);
        hsv[0] += f-0.5f;
@@ -118,7 +122,7 @@ static void node_composit_exec_huecorrect(void *UNUSED(data), bNode *node, bNode
                out[0]->data = pass_on_compbuf(cbuf);
                return;
        }
-       
+
        /* input no image? then only color operation */
        if (in[1]->data==NULL) {
                do_huecorrect_fac(node, out[0]->vec, in[1]->vec, in[0]->vec);
index be7f3c1c614626f75baa8af6baab51d3740fe965..512182ebe12c55e2df3b034c0d52f8130dd2ec97 100644 (file)
@@ -65,6 +65,7 @@ static int gpu_shader_curve_vec(GPUMaterial *mat, bNode *node, GPUNodeStack *in,
        float *array;
        int size;
 
+       curvemapping_initialize(node->storage);
        curvemapping_table_RGBA(node->storage, &array, &size);
        return GPU_stack_link(mat, "curves_vec", in, out, GPU_texture(size, array));
 }
@@ -120,6 +121,8 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat, bNode *node, GPUNodeStack *in,
 {
        float *array;
        int size;
+
+       curvemapping_initialize(node->storage);
        curvemapping_table_RGBA(node->storage, &array, &size);
        return GPU_stack_link(mat, "curves_rgb", in, out, GPU_texture(size, array));
 }
index a56d69a6657ea220e262d5fce90f55e79799fbf2..35e14c592a7b85b4e65d543e1176f46e32bf063b 100644 (file)
@@ -49,6 +49,7 @@ static void time_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNU
        if (node->custom1 < node->custom2)
                fac = (p->cfra - node->custom1)/(float)(node->custom2-node->custom1);
        
+       curvemapping_initialize(node->storage);
        fac = curvemapping_evaluateF(node->storage, 0, fac);
        out[0] = CLAMPIS(fac, 0.0f, 1.0f);
 }
index f34bd352e624dcef7d44e01a98a53cefb554a399..6bd95e824eb02e04511b0fd6b1a752309e2318ef 100644 (file)
@@ -3824,6 +3824,11 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
        lar->ld2= la->att2;
        lar->curfalloff = curvemapping_copy(la->curfalloff);
 
+       if (lar->curfalloff) {
+               /* so threads don't conflict on init */
+               curvemapping_initialize(lar->curfalloff);
+       }
+
        if (lar->type==LA_SPOT) {
 
                normalize_v3(lar->imat[0]);
index 3c1a18316ca26a1aad9054e7096e79f89d17fe8c..49c2bf1d053ba913d569f0f7f0efe7186087f5ad 100644 (file)
@@ -379,6 +379,7 @@ static void accum_density(void *userdata, int index, float squared_dist)
        }
        
        if (pdr->density_curve && dist != 0.0f) {
+               curvemapping_initialize(pdr->density_curve);
                density = curvemapping_evaluateF(pdr->density_curve, 0, density/dist)*dist;
        }
        
index e209baa49a8037b4bba12c335249c2f164471f32..6883710d1beb6dcc56a648aaaa3797cc51e6cc4e 100644 (file)
@@ -1192,6 +1192,7 @@ float lamp_get_visibility(LampRen *lar, const float co[3], float lv[3], float *d
                                                visifac*= lar->distkw/(lar->distkw+lar->ld2*dist[0]*dist[0]);
                                        break;
                                case LA_FALLOFF_CURVE:
+                                       /* curvemapping_initialize is called from #add_render_lamp */
                                        visifac = curvemapping_evaluateF(lar->curfalloff, 0, dist[0]/lar->dist);
                                        break;
                        }