[Bf-blender-cvs] [4c0f0eb] master: Fix T44691 Freestyle render crashes when Views is on (Blender Internal).

Tamito Kajiyama noreply at git.blender.org
Sat May 16 17:19:02 CEST 2015


Commit: 4c0f0eb33897464144735000837a99e86530e3cc
Author: Tamito Kajiyama
Date:   Sat May 16 23:55:45 2015 +0900
Branches: master
https://developer.blender.org/rB4c0f0eb33897464144735000837a99e86530e3cc

Fix T44691 Freestyle render crashes when Views is on (Blender Internal).

In pipeline.c the function add_freestyle() was supposed to be called once
per frame, but after the Multi-view merge the function are called as many
as the number of views.  There were however a few Freestyle parameters
that have to be initialized per frame, and initializing one of the
parameters for each view was causing double freeing of allocated memory
which was enough to result in a crash.

===================================================================

M	source/blender/freestyle/FRS_freestyle.h
M	source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
M	source/blender/render/intern/source/pipeline.c

===================================================================

diff --git a/source/blender/freestyle/FRS_freestyle.h b/source/blender/freestyle/FRS_freestyle.h
index 9766372..975b121 100644
--- a/source/blender/freestyle/FRS_freestyle.h
+++ b/source/blender/freestyle/FRS_freestyle.h
@@ -45,9 +45,10 @@ void FRS_initialize(void);
 void FRS_set_context(struct bContext *C);
 void FRS_read_file(struct bContext *C);
 int FRS_is_freestyle_enabled(struct SceneRenderLayer *srl);
-void FRS_init_stroke_rendering(struct Render *re);
+void FRS_init_stroke_renderer(struct Render *re);
+void FRS_begin_stroke_rendering(struct Render *re);
 struct Render *FRS_do_stroke_rendering(struct Render *re, struct SceneRenderLayer *srl, int render);
-void FRS_finish_stroke_rendering(struct Render *re);
+void FRS_end_stroke_rendering(struct Render *re);
 void FRS_free_view_map_cache(void);
 void FRS_composite_result(struct Render *re, struct SceneRenderLayer *srl, struct Render *freestyle_render);
 void FRS_exit(void);
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 64c6bd3..46724ff 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -576,7 +576,7 @@ int FRS_is_freestyle_enabled(SceneRenderLayer *srl)
 	return (!(srl->layflag & SCE_LAY_DISABLE) && srl->layflag & SCE_LAY_FRS && displayed_layer_count(srl) > 0);
 }
 
-void FRS_init_stroke_rendering(Render *re)
+void FRS_init_stroke_renderer(Render *re)
 {
 	if (G.debug & G_DEBUG_FREESTYLE) {
 		cout << endl;
@@ -586,11 +586,15 @@ void FRS_init_stroke_rendering(Render *re)
 	}
 
 	init_view(re);
-	init_camera(re);
 
 	controller->ResetRenderCount();
 }
 
+void FRS_begin_stroke_rendering(Render *re)
+{
+	init_camera(re);
+}
+
 Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl, int render)
 {
 	Render *freestyle_render = NULL;
@@ -645,7 +649,7 @@ Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl, int render)
 	return freestyle_render;
 }
 
-void FRS_finish_stroke_rendering(Render * /*re*/)
+void FRS_end_stroke_rendering(Render * /*re*/)
 {
 	// clear canvas
 	controller->Clear();
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 3d61cd4..9407412 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1377,6 +1377,7 @@ static void threaded_tile_processor(Render *re)
 }
 
 #ifdef WITH_FREESTYLE
+static void init_freestyle(Render *re);
 static void add_freestyle(Render *re, int render);
 static void free_all_freestyle_renders(void);
 #endif
@@ -1394,8 +1395,8 @@ void RE_TileProcessor(Render *re)
 	/* Freestyle */
 	if (re->r.mode & R_EDGE_FRS) {
 		if (!re->test_break(re->tbh)) {
+			init_freestyle(re);
 			add_freestyle(re, 1);
-	
 			free_all_freestyle_renders();
 			
 			re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime;
@@ -1430,6 +1431,12 @@ static void do_render_3d(Render *re)
 	/* init main render result */
 	main_render_result_new(re);
 
+#ifdef WITH_FREESTYLE
+	if (re->r.mode & R_EDGE_FRS) {
+		init_freestyle(re);
+	}
+#endif
+
 	/* we need a new database for each view */
 	for (rv = re->result->views.first; rv; rv = rv->next) {
 		RE_SetActiveRenderView(re, rv->name);
@@ -2065,6 +2072,23 @@ static void render_composit_stats(void *UNUSED(arg), const char *str)
 }
 
 #ifdef WITH_FREESTYLE
+/* init Freestyle renderer */
+static void init_freestyle(Render *re)
+{
+	re->freestyle_bmain = BKE_main_new();
+
+	/* We use the same window manager for freestyle bmain as
+	* real bmain uses. This is needed because freestyle's
+	* bmain could be used to tag scenes for update, which
+	* implies call of ED_render_scene_update in some cases
+	* and that function requires proper window manager
+	* to present (sergey)
+	*/
+	re->freestyle_bmain->wm = re->main->wm;
+
+	FRS_init_stroke_renderer(re);
+}
+
 /* invokes Freestyle stroke rendering */
 static void add_freestyle(Render *re, int render)
 {
@@ -2075,18 +2099,7 @@ static void add_freestyle(Render *re, int render)
 
 	actsrl = BLI_findlink(&re->r.layers, re->r.actlay);
 
-	re->freestyle_bmain = BKE_main_new();
-
-	/* We use the same window manager for freestyle bmain as
-	 * real bmain uses. This is needed because freestyle's
-	 * bmain could be used to tag scenes for update, which
-	 * implies call of ED_render_scene_update in some cases
-	 * and that function requires proper window manager
-	 * to present (sergey)
-	 */
-	re->freestyle_bmain->wm = re->main->wm;
-
-	FRS_init_stroke_rendering(re);
+	FRS_begin_stroke_rendering(re);
 
 	for (srl = (SceneRenderLayer *)re->r.layers.first; srl; srl = srl->next) {
 		if (do_link) {
@@ -2102,7 +2115,7 @@ static void add_freestyle(Render *re, int render)
 		}
 	}
 
-	FRS_finish_stroke_rendering(re);
+	FRS_end_stroke_rendering(re);
 
 	/* restore the global R value (invalidated by nested execution of the internal renderer) */
 	R = *re;
@@ -2112,28 +2125,32 @@ static void add_freestyle(Render *re, int render)
 static void composite_freestyle_renders(Render *re, int sample)
 {
 	Render *freestyle_render;
+	RenderView *rv;
 	SceneRenderLayer *srl, *actsrl;
 	LinkData *link;
 
 	actsrl = BLI_findlink(&re->r.layers, re->r.actlay);
 
 	link = (LinkData *)re->freestyle_renders.first;
-	for (srl= (SceneRenderLayer *)re->r.layers.first; srl; srl= srl->next) {
-		if ((re->r.scemode & R_SINGLE_LAYER) && srl != actsrl)
-			continue;
 
-		if (FRS_is_freestyle_enabled(srl)) {
-			freestyle_render = (Render *)link->data;
+	for (rv = re->result->views.first; rv; rv = rv->next) {
+		for (srl = (SceneRenderLayer *)re->r.layers.first; srl; srl = srl->next) {
+			if ((re->r.scemode & R_SINGLE_LAYER) && srl != actsrl)
+				continue;
 
-			/* may be NULL in case of empty render layer */
-			if (freestyle_render) {
-				render_result_exr_file_read_sample(freestyle_render, sample);
-				FRS_composite_result(re, srl, freestyle_render);
-				RE_FreeRenderResult(freestyle_render->result);
-				freestyle_render->result = NULL;
+			if (FRS_is_freestyle_enabled(srl)) {
+				freestyle_render = (Render *)link->data;
+
+				/* may be NULL in case of empty render layer */
+				if (freestyle_render) {
+					render_result_exr_file_read_sample(freestyle_render, sample);
+					FRS_composite_result(re, srl, freestyle_render);
+					RE_FreeRenderResult(freestyle_render->result);
+					freestyle_render->result = NULL;
+				}
 			}
+			link = link->next;
 		}
-		link = link->next;
 	}
 }
 
@@ -2375,8 +2392,10 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree)
 	re->display_clear(re->dch, re->result);
 	
 #ifdef WITH_FREESTYLE
-	if (re->r.mode & R_EDGE_FRS)
+	if (re->r.mode & R_EDGE_FRS) {
+		init_freestyle(re);
 		add_freestyle(re, 0);
+	}
 #endif
 
 	do_merge_fullsample(re, ntree);
@@ -3095,6 +3114,7 @@ void RE_RenderFreestyleExternal(Render *re)
 	if (!re->test_break(re->tbh)) {
 		RE_Database_FromScene(re, re->main, re->scene, re->lay, 1);
 		RE_Database_Preprocess(re);
+		init_freestyle(re);
 		add_freestyle(re, 1);
 		RE_Database_Free(re);
 	}




More information about the Bf-blender-cvs mailing list