Merging r58701 through r58746 from trunk into soc-2013-depsgraph_mt
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 30 Jul 2013 19:05:29 +0000 (19:05 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 30 Jul 2013 19:05:29 +0000 (19:05 +0000)
1  2 
source/blender/editors/sculpt_paint/sculpt.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_scene.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c

index 6181861a6e30fb9b646da99cc2964948d9449b4b,4b7c2995ea708e34773492844f5226a7359daadb..9720256df056954ea723179f51d18de4865c0569
@@@ -150,7 -150,6 +150,7 @@@ MultiresModifierData *sculpt_multires_a
  {
        Mesh *me = (Mesh *)ob->data;
        ModifierData *md;
 +      VirtualModifierData virtualModifierData;
  
        if (ob->sculpt && ob->sculpt->bm) {
                /* can't combine multires and dynamic topology */
                return NULL;
        }
  
 -      for (md = modifiers_getVirtualModifierList(ob); md; md = md->next) {
 +      for (md = modifiers_getVirtualModifierList(ob, &virtualModifierData); md; md = md->next) {
                if (md->type == eModifierType_Multires) {
                        MultiresModifierData *mmd = (MultiresModifierData *)md;
  
  static int sculpt_has_active_modifiers(Scene *scene, Object *ob)
  {
        ModifierData *md;
 +      VirtualModifierData virtualModifierData;
  
 -      md = modifiers_getVirtualModifierList(ob);
 +      md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
  
        /* exception for shape keys because we can edit those */
        for (; md; md = md->next) {
@@@ -200,7 -198,6 +200,7 @@@ static int sculpt_modifiers_active(Scen
        ModifierData *md;
        Mesh *me = (Mesh *)ob->data;
        MultiresModifierData *mmd = sculpt_multires_active(scene, ob);
 +      VirtualModifierData virtualModifierData;
  
        if (mmd || ob->sculpt->bm)
                return 0;
        if ((ob->shapeflag & OB_SHAPE_LOCK) == 0 && me->key && ob->shapenr)
                return 1;
  
 -      md = modifiers_getVirtualModifierList(ob);
 +      md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
  
        /* exception for shape keys because we can edit those */
        for (; md; md = md->next) {
@@@ -4591,14 -4588,21 +4591,21 @@@ void sculpt_dynamic_topology_enable(bCo
        Object *ob = CTX_data_active_object(C);
        SculptSession *ss = ob->sculpt;
        Mesh *me = ob->data;
+       const BMAllocTemplate allocsize = {me->totvert,
+                                          me->totedge,
+                                          me->totloop,
+                                          me->totpoly};
  
        sculpt_pbvh_clear(ob);
  
        ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags &
                                 SCULPT_DYNTOPO_SMOOTH_SHADING);
  
+       /* Dynamic topology doesn't ensure selection state is valid, so remove [#36280] */
+       BKE_mesh_mselect_clear(me);
        /* Create triangles-only BMesh */
-       ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
+       ss->bm = BM_mesh_create(&allocsize);
  
        BM_mesh_bm_from_me(ss->bm, me, true, true, ob->shapenr);
        sculpt_dynamic_topology_triangulate(ss->bm);
index ac38578b981b8e1b9907d9c661860352405385e2,dd194ed389fa6b14f34a67ae262b7ae24cf0858a..035238299f85a0315703bbd5d69290e2f7ab9571
@@@ -428,8 -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.
@@@ -653,7 -652,8 +653,8 @@@ typedef struct GameData 
        short mode, matmode;
        short occlusionRes;             /* resolution of occlusion Z buffer in pixel */
        short physicsEngine;
-       short exitkey, pad;
+       short exitkey;
+       short vsync; /* Controls vsync: off, on, or adaptive (if supported) */
        short ticrate, maxlogicstep, physubstep, maxphystep;
        short obstacleSimulation;
        short raster_storage;
  #define RAS_STORE_VA          2
  #define RAS_STORE_VBO         3
  
+ /* vsync */
+ #define VSYNC_OFF     0
+ #define VSYNC_ON      1
+ #define VSYNC_ADAPTIVE        2
  /* GameData.flag */
  #define GAME_RESTRICT_ANIM_UPDATES                    (1 << 0)
  #define GAME_ENABLE_ALL_FRAMES                                (1 << 1)
index 79085538a3c31aea7e9bcf07a5652275ddf404c3,a0e1e29ab55b32aefa3f56dccf339b3f1d93760e..34c4fbfc6093a7afbe74403a248a6a23c1d4f820
@@@ -3126,6 -3126,13 +3126,13 @@@ static void rna_def_scene_game_data(Ble
                {0, NULL, 0, NULL, NULL}
        };
  
+       static EnumPropertyItem vsync_items[] = {
+               {VSYNC_OFF, "OFF", 0, "Off", "Disables vsync"},
+               {VSYNC_ON, "ON", 0, "On", "Enables vsync"},
+               {VSYNC_ADAPTIVE, "ADAPTIVE", 0, "Adaptive", "Enables adaptive vsync (if supported)"},
+               {0, NULL, 0, NULL, NULL}
+       };
        static EnumPropertyItem storage_items[] = {
                {RAS_STORE_AUTO, "AUTO", 0, "Auto Select", "Chooses the best supported mode"},
                {RAS_STORE_IMMEDIATE, "IMMEDIATE", 0, "Immediate Mode", "Slowest performance, requires OpenGL (any version)"},
        RNA_def_property_range(prop, 4, 10000);
        RNA_def_property_ui_text(prop, "Resolution Y", "Number of vertical pixels in the screen");
        RNA_def_property_update(prop, NC_SCENE, NULL);
+       prop = RNA_def_property(srna, "vsync", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "vsync");
+       RNA_def_property_enum_items(prop, vsync_items);
+       RNA_def_property_ui_text(prop, "Vsync", "Change vsync settings");
        
        prop = RNA_def_property(srna, "samples", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "aasamples");
@@@ -4528,12 -4540,7 +4540,12 @@@ static void rna_def_scene_render_data(B
        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 d293ca07c5a9f34186412362dcdb5c88f5dea643,76fb88c8d25398e547f00b2380bece246516b584..918acb78193a99da295cf650b025224f356edff9
@@@ -187,6 -187,8 +187,8 @@@ __attribute__ ((format(printf, 3, 4))
  ;
  
  void          wm_event_add(struct wmWindow *win, const struct wmEvent *event_to_add);
+ void          wm_event_init_from_window(struct wmWindow *win, struct wmEvent *event);
  
                        /* at maximum, every timestep seconds it triggers event_type events */
  struct wmTimer *WM_event_add_timer(struct wmWindowManager *wm, struct wmWindow *win, int event_type, double timestep);
@@@ -423,9 -425,6 +425,9 @@@ void        WM_main_playanim(int argc, 
  /* 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 a83ce2efabfae0499ee2cceb3e4f69f0124f845c,862e4a41cf04efa6ef9f0648fdf0ab0f5e3ea8c2..2377a2cbc84bed5e5f6062310adec42f93c9d988
@@@ -132,6 -132,14 +132,14 @@@ void wm_event_free_all(wmWindow *win
        }
  }
  
+ void wm_event_init_from_window(wmWindow *win, wmEvent *event)
+ {
+       /* make sure we don't copy any owned pointers */
+       BLI_assert(win->eventstate->tablet_data == NULL);
+       *event = *(win->eventstate);
+ }
  /* ********************* notifiers, listeners *************** */
  
  static int wm_test_duplicate_notifier(wmWindowManager *wm, unsigned int type, void *reference)
@@@ -445,7 -453,9 +453,9 @@@ static void wm_handler_ui_cancel(bConte
                nexthandler = handler->next;
  
                if (handler->ui_handle) {
-                       wmEvent event = *(win->eventstate);
+                       wmEvent event;
+                       wm_event_init_from_window(win, &event);
                        event.type = EVT_BUT_CANCEL;
                        handler->ui_handle(C, &event, handler->ui_userdata);
                }
@@@ -1453,22 -1463,6 +1463,22 @@@ static void wm_event_modalkeymap(const 
        }
  }
  
 +/* Check whether operator is allowed to run in case interface is locked,
 + * If interface is unlocked, will always return truth.
 + */
 +static bool wm_operator_check_locked_interface(bContext *C, wmOperatorType *ot)
 +{
 +      wmWindowManager *wm = CTX_wm_manager(C);
 +
 +      if (wm->is_interface_locked) {
 +              if ((ot->flag & OPTYPE_ALLOW_LOCKED) == 0) {
 +                      return false;
 +              }
 +      }
 +
 +      return true;
 +}
 +
  /* bad hacking event system... better restore event type for checking of KM_CLICK for example */
  /* XXX modal maps could use different method (ton) */
  static void wm_event_modalmap_end(wmEvent *event)
@@@ -1495,12 -1489,7 +1505,12 @@@ static int wm_handler_operator_call(bCo
                wmOperator *op = handler->op;
                wmOperatorType *ot = op->type;
  
 -              if (ot->modal) {
 +              if (!wm_operator_check_locked_interface(C, ot)) {
 +                      /* Interface is locked and pperator is not allowed to run,
 +                       * nothing to do in this case.
 +                       */
 +              }
 +              else if (ot->modal) {
                        /* we set context to where modal handler came from */
                        wmWindowManager *wm = CTX_wm_manager(C);
                        ScrArea *area = CTX_wm_area(C);
                wmOperatorType *ot = WM_operatortype_find(event->keymap_idname, 0);
  
                if (ot) {
 -                      retval = wm_operator_invoke(C, ot, event, properties, NULL, FALSE);
 +                      if (wm_operator_check_locked_interface(C, ot)) {
 +                              retval = wm_operator_invoke(C, ot, event, properties, NULL, FALSE);
 +                      }
                }
        }
        /* Finished and pass through flag as handled */
@@@ -1780,11 -1767,7 +1790,11 @@@ static int wm_handlers_do_intern(bConte
                /* comment this out to flood the console! (if you really want to test) */
                !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)
                ;
 +#    define PRINT if (do_debug_handler) printf
 +#else
 +#  define PRINT(format, ...)
  #endif
 +
        wmWindowManager *wm = CTX_wm_manager(C);
        wmEventHandler *handler, *nexthandler;
        int action = WM_HANDLER_CONTINUE;
                                wmKeyMap *keymap = WM_keymap_active(wm, handler->keymap);
                                wmKeyMapItem *kmi;
  
 -#ifndef NDEBUG
 -                              if (do_debug_handler) {
 -                                      printf("%s:   checking '%s' ...", __func__, keymap->idname);
 -                              }
 -#endif
 +                              PRINT("%s:   checking '%s' ...", __func__, keymap->idname);
  
                                if (!keymap->poll || keymap->poll(C)) {
  
 -#ifndef NDEBUG
 -                                      if (do_debug_handler) {
 -                                              printf("pass\n");
 -                                      }
 -#endif
 +                                      PRINT("pass\n");
  
                                        for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
                                                if (wm_eventmatch(event, kmi)) {
  
 -#ifndef NDEBUG
 -                                                      if (do_debug_handler) {
 -                                                              printf("%s:     item matched '%s'\n", __func__, kmi->idname);
 -                                                      }
 -#endif
 +                                                      PRINT("%s:     item matched '%s'\n", __func__, kmi->idname);
  
                                                        /* weak, but allows interactive callback to not use rawkey */
                                                        event->keymap_idname = kmi->idname;
                                                                        if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS))
                                                                                printf("%s:       handled - and pass on! '%s'\n", __func__, kmi->idname);
                                                                
 -#ifndef NDEBUG
 -                                                              if (do_debug_handler) {
 -                                                                      printf("%s:       un-handled '%s'...", __func__, kmi->idname);
 -                                                              }
 -#endif
 +                                                                      PRINT("%s:       un-handled '%s'...", __func__, kmi->idname);
                                                        }
                                                }
                                        }
                                }
                                else {
 -#ifndef NDEBUG
 -                                      if (do_debug_handler) {
 -                                              printf("fail\n");
 -                                      }
 -#endif
 +                                      PRINT("fail\n");
                                }
                        }
                        else if (handler->ui_handle) {
 -                              action |= wm_handler_ui_call(C, handler, event, always_pass);
 +                              if (!wm->is_interface_locked) {
 +                                      action |= wm_handler_ui_call(C, handler, event, always_pass);
 +                              }
                        }
                        else if (handler->type == WM_HANDLER_FILESELECT) {
 -                              /* screen context changes here */
 -                              action |= wm_handler_fileselect_call(C, handlers, handler, event);
 +                              if (!wm->is_interface_locked) {
 +                                      /* screen context changes here */
 +                                      action |= wm_handler_fileselect_call(C, handlers, handler, event);
 +                              }
                        }
                        else if (handler->dropboxes) {
 -                              if (event->type == EVT_DROP) {
 +                              if (!wm->is_interface_locked && event->type == EVT_DROP) {
                                        wmDropBox *drop = handler->dropboxes->first;
                                        for (; drop; drop = drop->next) {
                                                /* other drop custom types allowed */
        if (action == (WM_HANDLER_BREAK | WM_HANDLER_MODAL))
                wm_cursor_arrow_move(CTX_wm_window(C), event);
  
 +#undef PRINT
 +
        return action;
  }
  
@@@ -3246,24 -3243,3 +3256,24 @@@ void wm_event_add_ghostevent(wmWindowMa
        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);
 +}