[Bf-blender-cvs] [85ae4b8] master: Fix T44404: freestyle crashes blender.

Tamito Kajiyama noreply at git.blender.org
Tue Apr 28 19:38:01 CEST 2015


Commit: 85ae4b87afa80527a36d3bd3164a9df6544f0c3b
Author: Tamito Kajiyama
Date:   Tue Apr 28 23:18:32 2015 +0900
Branches: master
https://developer.blender.org/rB85ae4b87afa80527a36d3bd3164a9df6544f0c3b

Fix T44404: freestyle crashes blender.

The reported crash case seems to be caused by freeing compiled Python
objects in a thread.  Now this issue is avoided by allocating a buffer to
store a Python script and using BPY_string_exec() to run the script.  This
makes it unnecessary to repeatedly create and destroy Text data blocks.

Many thanks to Campbell Barton for his help on the bug fix.

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

M	source/blender/freestyle/intern/application/Controller.cpp
M	source/blender/freestyle/intern/application/Controller.h
M	source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
M	source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
M	source/blender/freestyle/intern/system/PythonInterpreter.h

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

diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index add7420..5cd2e16 100644
--- a/source/blender/freestyle/intern/application/Controller.cpp
+++ b/source/blender/freestyle/intern/application/Controller.cpp
@@ -927,6 +927,12 @@ void Controller::InsertStyleModule(unsigned index, const char *iFileName)
 	_Canvas->InsertStyleModule(index, sm);
 }
 
+void Controller::InsertStyleModule(unsigned index, const char *iName, const char *iBuffer)
+{
+	StyleModule *sm = new BufferedStyleModule(iBuffer, iName, _inter);
+	_Canvas->InsertStyleModule(index, sm);
+}
+
 void Controller::InsertStyleModule(unsigned index, const char *iName, struct Text *iText)
 {
 	StyleModule *sm = new BlenderStyleModule(iText, iName, _inter);
diff --git a/source/blender/freestyle/intern/application/Controller.h b/source/blender/freestyle/intern/application/Controller.h
index 9fe57d9..a09964a 100644
--- a/source/blender/freestyle/intern/application/Controller.h
+++ b/source/blender/freestyle/intern/application/Controller.h
@@ -90,6 +90,7 @@ public:
 	Render *RenderStrokes(Render *re, bool render);
 	void SwapStyleModules(unsigned i1, unsigned i2);
 	void InsertStyleModule(unsigned index, const char *iFileName);
+	void InsertStyleModule(unsigned index, const char *iName, const char *iBuffer);
 	void InsertStyleModule(unsigned index, const char *iName, struct Text *iText);
 	void AddStyleModule(const char *iFileName);
 	void RemoveStyleModule(unsigned index);
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h b/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
index 2bc4379..1d73125 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
@@ -36,6 +36,34 @@ struct Text;
 
 namespace Freestyle {
 
+class BufferedStyleModule : public StyleModule
+{
+public:
+	BufferedStyleModule(const string& buffer, const string& file_name, Interpreter *inter) : StyleModule(file_name, inter)
+	{
+		_buffer = buffer;
+	}
+
+	virtual ~BufferedStyleModule()
+	{
+	}
+
+protected:
+	virtual int interpret()
+	{
+		PythonInterpreter *py_inter = dynamic_cast<PythonInterpreter*>(_inter);
+		BLI_assert(py_inter != 0);
+		return py_inter->interpretString(_buffer, getFileName());
+	}
+
+private:
+	string _buffer;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+	MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BufferedStyleModule")
+#endif
+};
+
 class BlenderStyleModule : public StyleModule
 {
 public:
@@ -62,7 +90,6 @@ private:
 #ifdef WITH_CXX_GUARDEDALLOC
 	MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderStyleModule")
 #endif
-
 };
 
 } /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 6b10241..8a7753e 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -211,16 +211,12 @@ static char *escape_quotes(char *name)
 	return s;
 }
 
-static Text *create_lineset_handler(Main *bmain, char *layer_name, char *lineset_name)
+static char * create_lineset_handler(char *layer_name, char *lineset_name)
 {
+	char *fmt = "__import__('parameter_editor').process('%s', '%s')\n";
 	char *s1 = escape_quotes(layer_name);
 	char *s2 = escape_quotes(lineset_name);
-	Text *text = BKE_text_add(bmain, lineset_name);
-	BKE_text_write(text, "import parameter_editor; parameter_editor.process('");
-	BKE_text_write(text, s1);
-	BKE_text_write(text, "', '");
-	BKE_text_write(text, s2);
-	BKE_text_write(text, "')\n");
+	char *text = BLI_sprintfN(fmt, s1, s2);
 	MEM_freeN(s1);
 	MEM_freeN(s2);
 	return text;
@@ -293,7 +289,7 @@ static bool test_edge_type_conditions(struct edge_type_condition *conditions,
 	return true;
 }
 
-static void prepare(Main *bmain, Render *re, SceneRenderLayer *srl)
+static void prepare(Render *re, SceneRenderLayer *srl)
 {
 	// load mesh
 	re->i.infostr = "Freestyle: Mesh loading";
@@ -369,9 +365,10 @@ static void prepare(Main *bmain, Render *re, SceneRenderLayer *srl)
 					cout << "  " << layer_count+1 << ": " << lineset->name << " - " <<
 					        (lineset->linestyle ? (lineset->linestyle->id.name + 2) : "<NULL>") << endl;
 				}
-				Text *text = create_lineset_handler(bmain, srl->name, lineset->name);
-				controller->InsertStyleModule(layer_count, lineset->name, text);
+				char *buffer = create_lineset_handler(srl->name, lineset->name);
+				controller->InsertStyleModule(layer_count, lineset->name, buffer);
 				controller->toggleLayer(layer_count, true);
+				MEM_freeN(buffer);
 				if (!(lineset->selection & FREESTYLE_SEL_EDGE_TYPES) || !lineset->edge_types) {
 					++use_ridges_and_valleys;
 					++use_suggestive_contours;
@@ -584,9 +581,7 @@ void FRS_init_stroke_rendering(Render *re)
 
 Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl, int render)
 {
-	Main *freestyle_bmain = re->freestyle_bmain;
 	Render *freestyle_render = NULL;
-	Text *text, *next_text;
 
 	if (!render)
 		return controller->RenderStrokes(re, false);
@@ -607,7 +602,7 @@ Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl, int render)
 	//   - add style modules
 	//   - set parameters
 	//   - compute view map
-	prepare(freestyle_bmain, re, srl);
+	prepare(re, srl);
 
 	if (re->test_break(re->tbh)) {
 		controller->CloseFile();
@@ -635,14 +630,6 @@ Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl, int render)
 		}
 	}
 
-	// Free temp main (currently only text blocks are stored there)
-	for (text = (Text *)freestyle_bmain->text.first; text; text = next_text) {
-		next_text = (Text *) text->id.next;
-
-		BKE_text_unlink(freestyle_bmain, text);
-		BKE_libblock_free(freestyle_bmain, text);
-	}
-
 	return freestyle_render;
 }
 
diff --git a/source/blender/freestyle/intern/system/PythonInterpreter.h b/source/blender/freestyle/intern/system/PythonInterpreter.h
index 6019359..ddb79b2 100644
--- a/source/blender/freestyle/intern/system/PythonInterpreter.h
+++ b/source/blender/freestyle/intern/system/PythonInterpreter.h
@@ -51,6 +51,8 @@ extern "C" {
 #include "BKE_text.h"
 
 #include "BPY_extern.h"
+
+#include "bpy_util.h"
 }
 
 namespace Freestyle {
@@ -105,6 +107,26 @@ public:
 		return 0;
 	}
 
+	int interpretString(const string& str, const string& name)
+	{
+		ReportList *reports = CTX_wm_reports(_context);
+
+		BKE_reports_clear(reports);
+
+		if (BPY_string_exec(_context, str.c_str()) != 0) {
+			BPy_errors_to_report(reports);
+			cerr << "\nError executing Python script from PythonInterpreter::interpretString" << endl;
+			cerr << "Name: " << name << endl;
+			cerr << "Errors: " << endl;
+			BKE_reports_print(reports, RPT_ERROR);
+			return 1;
+		}
+
+		BKE_reports_clear(reports);
+
+		return 0;
+	}
+
 	int interpretText(struct Text *text, const string& name)
 	{
 		ReportList *reports = CTX_wm_reports(_context);




More information about the Bf-blender-cvs mailing list