RenderEngine: steps towards implementation of this proposal:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 2 Nov 2011 14:33:14 +0000 (14:33 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 2 Nov 2011 14:33:14 +0000 (14:33 +0000)
http://wiki.blender.org/index.php/Dev:2.6/Source/Render/RenderEngineAPI

* RenderEngine is now a persistent python object that exists and retains
  properties as long as a frame is being rendered. This is mostly useful now
  that more than one callback will be added.
* Added update() callback that should ideally be used to export the scene,
  leaving only the rendering to the render() callback. This is not required to
  be used at this point, but separating this will make things more thread safe
  later on.
* Added tag_redraw() and tag_update() functions that will be used for viewport
  rendering.
* Internal change: status text is now retained after update_status calls.

source/blender/makesrna/intern/rna_render.c
source/blender/render/extern/include/RE_engine.h
source/blender/render/intern/source/external_engine.c

index 9b53b47..8f92831 100644 (file)
 #include "BKE_context.h"
 #include "BKE_report.h"
 
-/* RenderEngine */
+/* RenderEngine Callbacks */
+
+void engine_tag_redraw(RenderEngine *engine)
+{
+       engine->flag |= RE_ENGINE_DO_DRAW;
+}
+
+void engine_tag_update(RenderEngine *engine)
+{
+       engine->flag |= RE_ENGINE_DO_UPDATE;
+}
+
+static void engine_update(RenderEngine *engine, Main *bmain, Scene *scene)
+{
+       extern FunctionRNA rna_RenderEngine_update_func;
+       PointerRNA ptr;
+       ParameterList list;
+       FunctionRNA *func;
+
+       RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
+       func= &rna_RenderEngine_update_func;
+
+       RNA_parameter_list_create(&list, &ptr, func);
+       RNA_parameter_set_lookup(&list, "data", &bmain);
+       RNA_parameter_set_lookup(&list, "scene", &scene);
+       engine->type->ext.call(NULL, &ptr, func, &list);
+
+       RNA_parameter_list_free(&list);
+}
 
 static void engine_render(RenderEngine *engine, struct Scene *scene)
 {
        extern FunctionRNA rna_RenderEngine_render_func;
-
        PointerRNA ptr;
        ParameterList list;
        FunctionRNA *func;
@@ -87,7 +114,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
        RenderEngineType *et, dummyet = {NULL};
        RenderEngine dummyengine= {NULL};
        PointerRNA dummyptr;
-       int have_function[1];
+       int have_function[2];
 
        /* setup dummy engine & engine type to store static properties in */
        dummyengine.type= &dummyet;
@@ -122,13 +149,20 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
        et->ext.free= free;
        RNA_struct_blender_type_set(et->ext.srna, et);
 
-       et->render= (have_function[0])? engine_render: NULL;
+       et->update= (have_function[0])? engine_update: NULL;
+       et->render= (have_function[1])? engine_render: NULL;
 
        BLI_addtail(&R_engines, et);
 
        return et->ext.srna;
 }
 
+static void **rna_RenderEngine_instance(PointerRNA *ptr)
+{
+       RenderEngine *engine = ptr->data;
+       return &engine->py_instance;
+}
+
 static StructRNA* rna_RenderEngine_refine(PointerRNA *ptr)
 {
        RenderEngine *engine= (RenderEngine*)ptr->data;
@@ -203,14 +237,28 @@ static void rna_def_render_engine(BlenderRNA *brna)
        RNA_def_struct_sdna(srna, "RenderEngine");
        RNA_def_struct_ui_text(srna, "Render Engine", "Render engine");
        RNA_def_struct_refine_func(srna, "rna_RenderEngine_refine");
-       RNA_def_struct_register_funcs(srna, "rna_RenderEngine_register", "rna_RenderEngine_unregister", NULL);
+       RNA_def_struct_register_funcs(srna, "rna_RenderEngine_register", "rna_RenderEngine_unregister", "rna_RenderEngine_instance");
+
+       /* final render callbacks */
+       func= RNA_def_function(srna, "update", NULL);
+       RNA_def_function_ui_description(func, "Export scene data for render");
+       RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+       RNA_def_pointer(func, "data", "BlendData", "", "");
+       RNA_def_pointer(func, "scene", "Scene", "", "");
 
-       /* render */
        func= RNA_def_function(srna, "render", NULL);
        RNA_def_function_ui_description(func, "Render scene into an image");
-       RNA_def_function_flag(func, FUNC_REGISTER);
+       RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
        RNA_def_pointer(func, "scene", "Scene", "", "");
 
+       /* tag for redraw */
+       RNA_def_function(srna, "tag_redraw", "engine_tag_redraw");
+       RNA_def_function_ui_description(func, "Request redraw for viewport rendering");
+
+       /* tag for update */
+       RNA_def_function(srna, "tag_update", "engine_tag_update");
+       RNA_def_function_ui_description(func, "Request update call for viewport rendering");
+
        func= RNA_def_function(srna, "begin_result", "RE_engine_begin_result");
        prop= RNA_def_int(func, "x", 0, 0, INT_MAX, "X", "", 0, INT_MAX);
        RNA_def_property_flag(prop, PROP_REQUIRED);
index 344ef30..b848dc2 100644 (file)
@@ -55,6 +55,8 @@ struct Scene;
 /* RenderEngine.flag */
 #define RE_ENGINE_ANIMATION            1
 #define RE_ENGINE_PREVIEW              2
+#define RE_ENGINE_DO_DRAW              4
+#define RE_ENGINE_DO_UPDATE            8
 
 extern ListBase R_engines;
 
@@ -66,6 +68,7 @@ typedef struct RenderEngineType {
        char name[64];
        int flag;
 
+       void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene);
        void (*render)(struct RenderEngine *engine, struct Scene *scene);
 
        /* RNA integration */
@@ -74,11 +77,13 @@ typedef struct RenderEngineType {
 
 typedef struct RenderEngine {
        RenderEngineType *type;
+       void *py_instance;
 
        int flag;
 
        struct Render *re;
        ListBase fullresult;
+       char *text;
 } RenderEngine;
 
 RenderEngine *RE_engine_create(RenderEngineType *type);
index a621432..9d48e25 100644 (file)
@@ -61,7 +61,7 @@
 static RenderEngineType internal_render_type = {
        NULL, NULL,
        "BLENDER_RENDER", "Blender Render", RE_INTERNAL,
-       NULL,
+       NULL, NULL,
        {NULL, NULL, NULL}};
 
 #ifdef WITH_GAMEENGINE
@@ -69,7 +69,7 @@ static RenderEngineType internal_render_type = {
 static RenderEngineType internal_game_type = {
        NULL, NULL,
        "BLENDER_GAME", "Blender Game", RE_INTERNAL|RE_GAME,
-       NULL,
+       NULL, NULL,
        {NULL, NULL, NULL}};
 
 #endif
@@ -125,6 +125,15 @@ RenderEngine *RE_engine_create(RenderEngineType *type)
 
 void RE_engine_free(RenderEngine *engine)
 {
+#ifdef WITH_PYTHON
+       if(engine->py_instance) {
+               BPY_DECREF(engine->py_instance);
+       }
+#endif
+
+       if(engine->text)
+               MEM_freeN(engine->text);
+
        MEM_freeN(engine);
 }
 
@@ -216,6 +225,19 @@ void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char
                re->i.infostr= NULL;
                re->i.statstr= NULL;
        }
+
+       /* set engine text */
+       if(engine->text) {
+               MEM_freeN(engine->text);
+               engine->text= NULL;
+       }
+
+       if(stats && stats[0] && info && info[0])
+               engine->text= BLI_sprintfN("%s | %s", stats, info);
+       else if(info && info[0])
+               engine->text= BLI_strdup(info);
+       else if(stats && stats[0])
+               engine->text= BLI_strdup(stats);
 }
 
 void RE_engine_update_progress(RenderEngine *engine, float progress)
@@ -273,8 +295,10 @@ int RE_engine_render(Render *re, int do_all)
        if((re->r.scemode & (R_NO_FRAME_UPDATE|R_PREVIEWBUTS))==0)
                scene_update_for_newframe(re->main, re->scene, re->lay);
 
-       type->render(engine, re->scene);
-
+       if(type->update)
+               type->update(engine, re->main, re->scene);
+       if(type->render)
+               type->render(engine, re->scene);
 
        free_render_result(&engine->fullresult, engine->fullresult.first);