Merging r57729 through r57815 from trunk into soc-2013-depsgraph_mt
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 27 Jun 2013 09:07:19 +0000 (09:07 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 27 Jun 2013 09:07:19 +0000 (09:07 +0000)
14 files changed:
release/datafiles/startup.blend
release/scripts/startup/bl_ui/properties_render.py
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/BKE_mball.h
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/mball.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/render/render_internal.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/makesrna/intern/rna_scene.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c

index c604d16829ce6a5106e895002102e33bd2a83707..805308cf6629f2517aa45ab14d2676d204bc4a0d 100644 (file)
Binary files a/release/datafiles/startup.blend and b/release/datafiles/startup.blend differ
index 799c109ae0cd0606ce2260c4dc6b786277538132..bf4975f2e43ab4f3b2f54e6cc41cc3a507a76e21 100644 (file)
@@ -70,6 +70,7 @@ class RENDER_PT_render(RenderButtonsPanel, Panel):
         row.operator("render.play_rendered_anim", text="Play", icon='PLAY')
 
         layout.prop(rd, "display_mode", text="Display")
+        layout.prop(rd, "use_lock_interface")
 
 
 class RENDER_PT_dimensions(RenderButtonsPanel, Panel):
index 3be77086336b44c34a97a315229763076f4e3373..6c5bbbd487ea67557d412b68cb73962059e10ab2 100644 (file)
@@ -86,7 +86,7 @@ struct ListBase *BKE_curve_editNurbs_get(struct Curve *cu);
 float *BKE_curve_make_orco(struct Scene *scene, struct Object *ob, int *r_numVerts);
 float *BKE_curve_surf_make_orco(struct Object *ob);
 
-void BKE_curve_bevelList_make(struct Object *ob);
+void BKE_curve_bevelList_make(struct Object *ob, bool for_render);
 void BKE_curve_bevel_make(struct Scene *scene, struct Object *ob,  struct ListBase *disp, int forRender, int renderResolution);
 
 void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride);
index 9bbff51598368566d0123b6d77859059fb43db78..9a9b8a4da4db523ad6c42a190fda51eb32bad107 100644 (file)
@@ -47,7 +47,7 @@ void BKE_mball_make_local(struct MetaBall *mb);
 
 void BKE_mball_cubeTable_free(void);
 
-void BKE_mball_polygonize(struct Scene *scene, struct Object *ob, struct ListBase *dispbase);
+void BKE_mball_polygonize(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, bool for_render);
 bool BKE_mball_is_basis_for(struct Object *ob1, struct Object *ob2);
 bool BKE_mball_is_basis(struct Object *ob);
 struct Object *BKE_mball_basis_find(struct Scene *scene, struct Object *ob);
index 3b9fbbb1c4d98948dfbb57ee9ff707250fbc7089..3b902a2b6768b6552d6eac77ec21696f60b99123 100644 (file)
@@ -2269,7 +2269,7 @@ static void make_bevel_list_2D(BevList *bl)
        }
 }
 
-void BKE_curve_bevelList_make(Object *ob)
+void BKE_curve_bevelList_make(Object *ob, bool for_render)
 {
        /*
         * - convert all curves to polys, with indication of resol and flags for double-vertices
@@ -2325,7 +2325,7 @@ void BKE_curve_bevelList_make(Object *ob)
                        bl->nr = 0;
                }
                else {
-                       if (G.is_rendering && cu->resolu_ren != 0)
+                       if (for_render && cu->resolu_ren != 0)
                                resolu = cu->resolu_ren;
                        else
                                resolu = nu->resolu;
index 38a0b8483397a4e9c588b7e0a60e1f08146a307e..edfcefe14c7f90f26a2a6adf241cccef62932626 100644 (file)
@@ -712,17 +712,11 @@ void BKE_displist_make_mball(Scene *scene, Object *ob)
        if (!ob || ob->type != OB_MBALL)
                return;
 
-       /* XXX: mball stuff uses plenty of global variables
-        *      while this is unchanged updating during render is unsafe
-        */
-       if (G.is_rendering)
-               return;
-
        BKE_displist_free(&(ob->disp));
 
        if (ob->type == OB_MBALL) {
                if (ob == BKE_mball_basis_find(scene, ob)) {
-                       BKE_mball_polygonize(scene, ob, &ob->disp);
+                       BKE_mball_polygonize(scene, ob, &ob->disp, false);
                        BKE_mball_texspace_calc(ob);
 
                        object_deform_mball(ob, &ob->disp);
@@ -734,7 +728,7 @@ void BKE_displist_make_mball(Scene *scene, Object *ob)
 
 void BKE_displist_make_mball_forRender(Scene *scene, Object *ob, ListBase *dispbase)
 {
-       BKE_mball_polygonize(scene, ob, dispbase);
+       BKE_mball_polygonize(scene, ob, dispbase, true);
        BKE_mball_texspace_calc(ob);
 
        object_deform_mball(ob, dispbase);
@@ -1407,7 +1401,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
                if (!forOrco)
                        curve_calc_modifiers_pre(scene, ob, forRender, renderResolution, &originalVerts, &deformedVerts, &numVerts);
 
-               BKE_curve_bevelList_make(ob);
+               BKE_curve_bevelList_make(ob, forRender != FALSE);
 
                /* If curve has no bevel will return nothing */
                BKE_curve_bevel_make(scene, ob, &dlbev, forRender, renderResolution);
index 8361f0c4f6c77ed5b622668ede583706fd48576d..afe1c0f24df952828e5d9fcff41a61dc44fc6842 100644 (file)
@@ -2269,7 +2269,7 @@ static void mball_count(PROCESS *process, Scene *scene, Object *basis)
        }
 }
 
-void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
+void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase, bool for_render)
 {
        MetaBall *mb;
        DispList *dl;
@@ -2282,7 +2282,7 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
        mball_count(&process, scene, ob);
 
        if (process.totelem == 0) return;
-       if ((G.is_rendering == FALSE) && (mb->flag == MB_UPDATE_NEVER)) return;
+       if ((for_render == FALSE) && (mb->flag == MB_UPDATE_NEVER)) return;
        if ((G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) && mb->flag == MB_UPDATE_FAST) return;
 
        process.thresh = mb->thresh;
@@ -2320,7 +2320,7 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
        }
 
        /* width is size per polygonize cube */
-       if (G.is_rendering) {
+       if (for_render) {
                width = mb->rendersize;
        }
        else {
index 673cd3f7b2630d661b73dc99a9a473698a568576..917b1e5d054eff0749418c863421ad1f99978f5f 100644 (file)
@@ -5514,6 +5514,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
        wm->winactive = NULL;
        wm->initialized = 0;
        wm->op_undo_depth = 0;
+       wm->is_interface_locked = 0;
 }
 
 static void lib_link_windowmanager(FileData *fd, Main *main)
index 09138a5523aeeaf0a767d02bbfb2f88dca80b231..563f416ead0bc84799d2e4988caa7cc5dda529c5 100644 (file)
@@ -273,6 +273,7 @@ typedef struct RenderJob {
        short *do_update;
        float *progress;
        ReportList *reports;
+       bool interface_locked;
 } RenderJob;
 
 static void render_freejob(void *rjv)
@@ -498,6 +499,15 @@ static void render_endjob(void *rjv)
 
                BKE_image_release_ibuf(ima, ibuf, lock);
        }
+
+       /* Finally unlock the user interface (if it was locked). */
+       if (rj->interface_locked) {
+               /* Interface was locked, so window manager couldn't have been changed
+                * and using one from Global will unlock exactly the same manager as
+                * was locked before running the job.
+                */
+               WM_set_locked_interface(G.main->wm.first, false);
+       }
 }
 
 /* called by render, check job 'stop' value or the global */
@@ -523,10 +533,14 @@ static int render_break(void *UNUSED(rjv))
 
 /* runs in thread, no cursor setting here works. careful with notifiers too (malloc conflicts) */
 /* maybe need a way to get job send notifer? */
-static void render_drawlock(void *UNUSED(rjv), int lock)
+static void render_drawlock(void *rjv, int lock)
 {
-       BKE_spacedata_draw_locks(lock);
-       
+       RenderJob *rj = rjv;
+
+       /* If interface is locked, renderer callback shall do nothing. */
+       if (!rj->interface_locked) {
+               BKE_spacedata_draw_locks(lock);
+       }
 }
 
 /* catch esc */
@@ -649,6 +663,23 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
                        rj->lay |= v3d->localvd->lay;
        }
 
+       /* Lock the user interface depending on render settings. */
+       if (scene->r.use_lock_interface) {
+               WM_set_locked_interface(CTX_wm_manager(C), true);
+
+               /* Set flag interface need to be unlocked.
+                *
+                * This is so because we don't have copy of render settings
+                * accessible from render job and copy is needed in case
+                * of non-locked rendering, so we wouldn't try to unlock
+                * anything if option was initially unset but then was
+                * enabled during rendering.
+                */
+               rj->interface_locked = true;
+
+               /* TODO(sergey): clean memory used by viewport? */
+       }
+
        /* setup job */
        if (RE_seq_render_active(scene, &scene->r)) name = "Sequence Render";
        else name = "Render";
index 5e877ed697b35a43cb0dee974d7c1847a61b867c..ac38578b981b8e1b9907d9c661860352405385e2 100644 (file)
@@ -428,7 +428,8 @@ typedef struct RenderData {
         * Render to image editor, fullscreen or to new window.
         */
        short displaymode;
-       short pad7;
+       char use_lock_interface;
+       char pad7;
 
        /**
         * Flags for render settings. Use bit-masking to access the settings.
index 27aef3b8ec63715969d37b88dfa05bdc4dd999d8..29fac36ddd078030b854496a8c44a605704b2474 100644 (file)
@@ -151,6 +151,9 @@ typedef struct wmWindowManager {
 
        ListBase timers;                                        /* active timers */
        struct wmTimer *autosavetimer;          /* timer for auto save */
+
+       char is_interface_locked;               /* indicates whether interface is locked for user interaction */
+       char par[7];
 } wmWindowManager;
 
 /* wmWindowManager.initialized */
index d46b1a2843945ae1769a0881904d98f0c705796e..cb6ba0f85d0400d24b3ed7a10f06256ed221ea89 100644 (file)
@@ -4520,7 +4520,12 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
        RNA_def_property_enum_items(prop, display_mode_items);
        RNA_def_property_ui_text(prop, "Display", "Select where rendered images will be displayed");
        RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-       
+
+       prop = RNA_def_property(srna, "use_lock_interface", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "use_lock_interface", 1);
+       RNA_def_property_ui_text(prop, "Lock Interface", "Lock interface during rendering in favor of giving more memory to the renderer");
+       RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
        prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
        RNA_def_property_string_sdna(prop, NULL, "pic");
        RNA_def_property_ui_text(prop, "Output Path",
index 72b54e2f1f7359fea668a6806b75f583e8de34e4..fb9b8b8f10b37bca5477137bc8ffa38d3fd15310 100644 (file)
@@ -412,6 +412,9 @@ void        WM_main_playanim(int argc, const char **argv);
 /* debugging only, convenience function to write on crash */
 int write_crash_blend(void);
 
+                       /* Lock the interface for any communication */
+void        WM_set_locked_interface(struct wmWindowManager *wm, bool lock);
+
 #ifdef __cplusplus
 }
 #endif
index d94cfaa5aee144ccaaf890682a2a7ffe1779a724..d91f954fca27dda48ae6c4178565aa24490f3181 100644 (file)
@@ -2093,6 +2093,21 @@ void wm_event_do_handlers(bContext *C)
        wmWindowManager *wm = CTX_wm_manager(C);
        wmWindow *win;
 
+       if (wm->is_interface_locked) {
+               /* If we're in locked interaction mode, skip all the events
+                * from the queue and prevent them from being accumulated.
+                * This is so no events are applied after interface is unlocked.
+                */
+               for (win = wm->windows.first; win; win = win->next) {
+                       wmEvent *event;
+                       while ( (event = win->queue.first) ) {
+                               BLI_remlink(&win->queue, event);
+                               wm_event_free(event);
+                       }
+               }
+               return;
+       }
+
        /* update key configuration before handling events */
        WM_keyconfig_update(wm);
 
@@ -3219,3 +3234,24 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
        WM_event_print(&event);
 #endif
 }
+
+void WM_set_locked_interface(wmWindowManager *wm, bool lock)
+{
+       /* This will prevent events from being handled while interface is locked
+        *
+        * Use a "local" flag for now, because currently no other areas could
+        * benefit of locked interface anyway (aka using G.is_interface_locked
+        * wouldn't be useful anywhere outside of window manager, so let's not
+        * pollute global context with such an information for now).
+        */
+       wm->is_interface_locked = lock ? 1 : 0;
+
+       /* This will prevent drawing regions which uses non-threadsafe data.
+        * Currently it'll be just a 3D viewport.
+        *
+        * TODO(sergey): Make it different locked states, so different jobs
+        *               could lock different areas of blender and allow
+        *               interation with others?
+        */
+       BKE_spacedata_draw_locks(lock);
+}