Ghost Context Refactor
[blender-staging.git] / source / creator / creator.c
index 418c05e22ce69ce679b39e6425255226faf4bbed..12ae5c502e4f2344df3d0e696f7f2ad6f164ca9b 100644 (file)
 #  include <xmmintrin.h>
 #endif
 
-/* crash handler */
-#ifdef WIN32
-#  include <process.h> /* getpid */
-#else
-#  include <unistd.h> /* getpid */
-#endif
-
 #ifdef WIN32
+#  if defined(_MSC_VER) && _MSC_VER >= 1800 && defined(_M_X64)
+#    include <math.h> /* needed for _set_FMA3_enable */
+#  endif
 #  include <windows.h>
 #  include "utfconv.h"
 #endif
@@ -63,6 +59,7 @@
 #include <stddef.h>
 #include <string.h>
 #include <errno.h>
+#include <time.h>
 
 /* This little block needed for linking to Blender... */
 
 #include "BLI_threads.h"
 #include "BLI_utildefines.h"
 #include "BLI_callbacks.h"
+#include "BLI_blenlib.h"
+#include "BLI_mempool.h"
+#include "BLI_system.h"
+#include BLI_SYSTEM_PID_H
 
 #include "DNA_ID.h"
 #include "DNA_scene_types.h"
 #include "DNA_userdef_types.h"
 
-#include "BLI_blenlib.h"
-
 #include "BKE_blender.h"
 #include "BKE_brush.h"
 #include "BKE_context.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_material.h"
-#include "BKE_packedFile.h"
+#include "BKE_modifier.h"
 #include "BKE_scene.h"
 #include "BKE_node.h"
 #include "BKE_report.h"
 #include "BKE_sound.h"
 #include "BKE_image.h"
+#include "BKE_particle.h"
 
 #include "IMB_imbuf.h"  /* for IMB_init */
 
 #include "RE_pipeline.h"
 
 #include "ED_datafiles.h"
+#include "ED_util.h"
 
 #include "WM_api.h"
 
 #include "GPU_draw.h"
 #include "GPU_extensions.h"
 
-#include "BLI_scanfill.h" /* for BLI_setErrorCallBack, TODO, move elsewhere */
-
 #ifdef WITH_FREESTYLE
 #  include "FRS_freestyle.h"
 #endif
 #  include "libmv-capi.h"
 #endif
 
+#ifdef WITH_CYCLES_LOGGING
+#  include "CCL_api.h"
+#endif
+
 /* from buildinfo.c */
 #ifdef BUILD_DATE
 extern char build_date[];
 extern char build_time[];
-extern char build_rev[];
+extern char build_hash[];
+extern unsigned long build_commit_timestamp;
+
+/* TODO(sergey): ideally size need to be in sync with buildinfo.c */
+extern char build_commit_date[16];
+extern char build_commit_time[16];
+
+extern char build_branch[];
 extern char build_platform[];
 extern char build_type[];
 extern char build_cflags[];
@@ -173,11 +183,12 @@ static int print_version(int argc, const char **argv, void *data);
 #endif
 
 /* for the callbacks: */
-
+#ifndef WITH_PYTHON_MODULE
 #define BLEND_VERSION_FMT         "Blender %d.%02d (sub %d)"
 #define BLEND_VERSION_ARG         BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION
 /* pass directly to printf */
 #define BLEND_VERSION_STRING_FMT  BLEND_VERSION_FMT "\n", BLEND_VERSION_ARG
+#endif
 
 /* Initialize callbacks for the modules that need them */
 static void setCallbacks(void); 
@@ -200,7 +211,7 @@ static void blender_esc(int sig)
 {
        static int count = 0;
        
-       G.is_break = TRUE;  /* forces render loop to read queue, not sure if its needed */
+       G.is_break = true;  /* forces render loop to read queue, not sure if its needed */
        
        if (sig == 2) {
                if (count) {
@@ -219,7 +230,9 @@ static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUS
 #ifdef BUILD_DATE
        printf("\tbuild date: %s\n", build_date);
        printf("\tbuild time: %s\n", build_time);
-       printf("\tbuild revision: %s\n", build_rev);
+       printf("\tbuild commit date: %s\n", build_commit_date);
+       printf("\tbuild commit time: %s\n", build_commit_time);
+       printf("\tbuild hash: %s\n", build_hash);
        printf("\tbuild platform: %s\n", build_platform);
        printf("\tbuild type: %s\n", build_type);
        printf("\tbuild c flags: %s\n", build_cflags);
@@ -249,12 +262,12 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
        BLI_argsPrintArgDoc(ba, "--frame-jump");
        BLI_argsPrintArgDoc(ba, "--render-output");
        BLI_argsPrintArgDoc(ba, "--engine");
+       BLI_argsPrintArgDoc(ba, "--threads");
        
        printf("\n");
        printf("Format Options:\n");
        BLI_argsPrintArgDoc(ba, "--render-format");
        BLI_argsPrintArgDoc(ba, "--use-extension");
-       BLI_argsPrintArgDoc(ba, "--threads");
 
        printf("\n");
        printf("Animation Playback Options:\n");
@@ -266,26 +279,57 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
        BLI_argsPrintArgDoc(ba, "--window-borderless");
        BLI_argsPrintArgDoc(ba, "--window-geometry");
        BLI_argsPrintArgDoc(ba, "--start-console");
+       BLI_argsPrintArgDoc(ba, "--no-native-pixels");
+
 
        printf("\n");
        printf("Game Engine Specific Options:\n");
        BLI_argsPrintArgDoc(ba, "-g");
 
        printf("\n");
-       printf("Misc Options:\n");
+       printf("Python Options:\n");
+       BLI_argsPrintArgDoc(ba, "--enable-autoexec");
+       BLI_argsPrintArgDoc(ba, "--disable-autoexec");
+
+       printf("\n");
+
+       BLI_argsPrintArgDoc(ba, "--python");
+       BLI_argsPrintArgDoc(ba, "--python-text");
+       BLI_argsPrintArgDoc(ba, "--python-console");
+       BLI_argsPrintArgDoc(ba, "--addons");
+
+
+       printf("\n");
+       printf("Debug Options:\n");
        BLI_argsPrintArgDoc(ba, "--debug");
-       BLI_argsPrintArgDoc(ba, "--debug-fpe");
-       BLI_argsPrintArgDoc(ba, "--disable-crash-handler");
+       BLI_argsPrintArgDoc(ba, "--debug-value");
 
+       printf("\n");
+       BLI_argsPrintArgDoc(ba, "--debug-events");
 #ifdef WITH_FFMPEG
        BLI_argsPrintArgDoc(ba, "--debug-ffmpeg");
 #endif
-
+       BLI_argsPrintArgDoc(ba, "--debug-handlers");
 #ifdef WITH_LIBMV
        BLI_argsPrintArgDoc(ba, "--debug-libmv");
 #endif
+#ifdef WITH_CYCLES_LOGGING
+       BLI_argsPrintArgDoc(ba, "--debug-cycles");
+#endif
+       BLI_argsPrintArgDoc(ba, "--debug-memory");
+       BLI_argsPrintArgDoc(ba, "--debug-jobs");
+       BLI_argsPrintArgDoc(ba, "--debug-python");
+       BLI_argsPrintArgDoc(ba, "--debug-depsgraph");
+
+       BLI_argsPrintArgDoc(ba, "--debug-wm");
+       BLI_argsPrintArgDoc(ba, "--debug-all");
+
+       printf("\n");
+       BLI_argsPrintArgDoc(ba, "--debug-fpe");
+       BLI_argsPrintArgDoc(ba, "--disable-crash-handler");
 
        printf("\n");
+       printf("Misc Options:\n");
        BLI_argsPrintArgDoc(ba, "--factory-startup");
        printf("\n");
        BLI_argsPrintArgDoc(ba, "--env-system-config");
@@ -302,18 +346,6 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
 
        BLI_argsPrintArgDoc(ba, "--help");
 
-       printf("\n");
-
-       BLI_argsPrintArgDoc(ba, "--enable-autoexec");
-       BLI_argsPrintArgDoc(ba, "--disable-autoexec");
-
-       printf("\n");
-
-       BLI_argsPrintArgDoc(ba, "--python");
-       BLI_argsPrintArgDoc(ba, "--python-text");
-       BLI_argsPrintArgDoc(ba, "--python-console");
-       BLI_argsPrintArgDoc(ba, "--addons");
-
 #ifdef WIN32
        BLI_argsPrintArgDoc(ba, "-R");
        BLI_argsPrintArgDoc(ba, "-r");
@@ -333,7 +365,7 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
        printf("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
 
        printf("Argument Order:\n");
-       printf("Arguments are executed in the order they are given. eg\n");
+       printf("\targuments are executed in the order they are given. eg\n");
        printf("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
        printf("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
        printf("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
@@ -344,7 +376,7 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
        printf("  $BLENDER_USER_CONFIG      Directory for user configuration files.\n");
        printf("  $BLENDER_USER_SCRIPTS     Directory for user scripts.\n");
        printf("  $BLENDER_SYSTEM_SCRIPTS   Directory for system wide scripts.\n");
-       printf("  $Directory for user data files (icons, translations, ..).\n");
+       printf("  $BLENDER_USER_DATAFILES   Directory for user data files (icons, translations, ..).\n");
        printf("  $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
        printf("  $BLENDER_SYSTEM_PYTHON    Directory for system python libraries.\n");
 #ifdef WIN32
@@ -398,10 +430,13 @@ static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
        G.debug |= G_DEBUG;  /* std output printf's */
        printf(BLEND_VERSION_STRING_FMT);
        MEM_set_memory_debug();
+#ifdef DEBUG
+       BLI_mempool_set_memory_debug();
+#endif
 
 #ifdef WITH_BUILDINFO
        printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
-#endif // WITH_BUILDINFO
+#endif
 
        BLI_argsPrint(data);
        return 0;
@@ -422,6 +457,21 @@ static int debug_mode_libmv(int UNUSED(argc), const char **UNUSED(argv), void *U
 }
 #endif
 
+#ifdef WITH_CYCLES_LOGGING
+static int debug_mode_cycles(int UNUSED(argc), const char **UNUSED(argv),
+                             void *UNUSED(data))
+{
+       CCL_start_debug_logging();
+       return 0;
+}
+#endif
+
+static int debug_mode_memory(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
+{
+       MEM_set_memory_debug();
+       return 0;
+}
+
 static int set_debug_value(int argc, const char **argv, void *UNUSED(data))
 {
        if (argc > 1) {
@@ -485,7 +535,7 @@ static void blender_crash_handler_backtrace(FILE *fp)
 #undef SIZE
 }
 
-#elif defined(_MSV_VER)
+#elif defined(_MSC_VER)
 
 static void blender_crash_handler_backtrace(FILE *fp)
 {
@@ -501,10 +551,10 @@ static void blender_crash_handler_backtrace(FILE *fp)
 
        process = GetCurrentProcess();
 
-       SymInitialize(process, NULL, TRUE);
+       SymInitialize(process, NULL, true);
 
        nframes = CaptureStackBackTrace(0, SIZE, stack, NULL);
-       symbolinfo = MEM_callocN(sizeof(SYMBOL_INFO) + MAXSYMBOL * sizeof( char ), "crash Symbol table");
+       symbolinfo = MEM_callocN(sizeof(SYMBOL_INFO) + MAXSYMBOL * sizeof(char), "crash Symbol table");
        symbolinfo->MaxNameLen = MAXSYMBOL - 1;
        symbolinfo->SizeOfStruct = sizeof(SYMBOL_INFO);
 
@@ -535,7 +585,7 @@ static void blender_crash_handler(int signum)
                char fname[FILE_MAX];
 
                if (!G.main->name[0]) {
-                       BLI_make_file_string("/", fname, BLI_temporary_dir(), "crash.blend");
+                       BLI_make_file_string("/", fname, BLI_temp_dir_base(), "crash.blend");
                }
                else {
                        BLI_strncpy(fname, G.main->name, sizeof(fname));
@@ -556,23 +606,22 @@ static void blender_crash_handler(int signum)
        char fname[FILE_MAX];
 
        if (!G.main->name[0]) {
-               BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), "blender.crash.txt");
+               BLI_join_dirfile(fname, sizeof(fname), BLI_temp_dir_base(), "blender.crash.txt");
        }
        else {
-               BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), BLI_path_basename(G.main->name));
+               BLI_join_dirfile(fname, sizeof(fname), BLI_temp_dir_base(), BLI_path_basename(G.main->name));
                BLI_replace_extension(fname, sizeof(fname), ".crash.txt");
        }
 
        printf("Writing: %s\n", fname);
        fflush(stdout);
 
-       BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Revision: %s\n", BLEND_VERSION_ARG,
-#ifdef BUILD_DATE
-                    build_rev
+#ifndef BUILD_DATE
+       BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Unknown revision\n", BLEND_VERSION_ARG);
 #else
-                    "Unknown"
+       BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Commit date: %s %s, Hash %s\n",
+                    BLEND_VERSION_ARG, build_commit_date, build_commit_time, build_hash);
 #endif
-                    );
 
        /* open the crash log */
        errno = 0;
@@ -591,6 +640,8 @@ static void blender_crash_handler(int signum)
                fclose(fp);
        }
 
+       /* Delete content of temp dir! */
+       BLI_temp_dir_session_purge();
 
        /* really crash */
        signal(signum, SIG_DFL);
@@ -634,6 +685,11 @@ static int playback_mode(int argc, const char **argv, void *UNUSED(data))
 {
        /* not if -b was given first */
        if (G.background == 0) {
+#ifdef WITH_FFMPEG
+               /* Setup FFmpeg with current debug flags. */
+               IMB_ffmpeg_init();
+#endif
+
                WM_main_playanim(argc, argv); /* not the same argc and argv as before */
                exit(0); /* 2.4x didn't do this */
        }
@@ -741,7 +797,7 @@ static int set_audio(int argc, const char **argv, void *UNUSED(data))
 static int set_output(int argc, const char **argv, void *data)
 {
        bContext *C = data;
-       if (argc >= 1) {
+       if (argc > 1) {
                Scene *scene = CTX_data_scene(C);
                if (scene) {
                        BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
@@ -777,6 +833,9 @@ static int set_engine(int argc, const char **argv, void *data)
                                if (BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
                                        BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
                                }
+                               else {
+                                       printf("\nError: engine not found '%s'\n", argv[1]);
+                               }
                        }
                        else {
                                printf("\nError: no blend loaded. order the arguments so '-E  / --engine ' is after a blend is loaded.\n");
@@ -832,7 +891,7 @@ static int set_threads(int argc, const char **argv, void *UNUSED(data))
                return 1;
        }
        else {
-               printf("\nError: you must specify a number of threads between 0 and 8 '-t  / --threads'.\n");
+               printf("\nError: you must specify a number of threads between 0 and %d '-t / --threads'.\n", BLENDER_MAX_THREADS);
                return 0;
        }
 }
@@ -844,6 +903,8 @@ static int set_verbosity(int argc, const char **argv, void *UNUSED(data))
 
 #ifdef WITH_LIBMV
                libmv_setLoggingVerbosity(level);
+#elif defined(WITH_CYCLES_LOGGING)
+               CCL_logging_verbosity_set(level);
 #else
                (void)level;
 #endif
@@ -859,7 +920,7 @@ static int set_verbosity(int argc, const char **argv, void *UNUSED(data))
 static int set_extension(int argc, const char **argv, void *data)
 {
        bContext *C = data;
-       if (argc >= 1) {
+       if (argc > 1) {
                Scene *scene = CTX_data_scene(C);
                if (scene) {
                        if (argv[1][0] == '0') {
@@ -964,6 +1025,7 @@ static int render_frame(int argc, const char **argv, void *data)
                                        break;
                        }
 
+                       BLI_begin_threaded_malloc();
                        BKE_reports_init(&reports, RPT_PRINT);
 
                        frame = CLAMPIS(frame, MINAFRAME, MAXFRAME);
@@ -971,6 +1033,7 @@ static int render_frame(int argc, const char **argv, void *data)
                        RE_SetReports(re, &reports);
                        RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
                        RE_SetReports(re, NULL);
+                       BLI_end_threaded_malloc();
                        return 1;
                }
                else {
@@ -992,10 +1055,12 @@ static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *d
                Main *bmain = CTX_data_main(C);
                Render *re = RE_NewRender(scene->id.name);
                ReportList reports;
+               BLI_begin_threaded_malloc();
                BKE_reports_init(&reports, RPT_PRINT);
                RE_SetReports(re, &reports);
                RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
                RE_SetReports(re, NULL);
+               BLI_end_threaded_malloc();
        }
        else {
                printf("\nError: no blend loaded. cannot use '-a'.\n");
@@ -1214,19 +1279,24 @@ static int load_file(int UNUSED(argc), const char **argv, void *data)
        BLI_path_cwd(filename);
 
        if (G.background) {
-               int retval = BKE_read_file(C, filename, NULL);
+               int retval;
+
+               BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
+
+               retval = BKE_read_file(C, filename, NULL);
 
                /* we successfully loaded a blend file, get sure that
                 * pointcache works */
                if (retval != BKE_READ_FILE_FAIL) {
                        wmWindowManager *wm = CTX_wm_manager(C);
+                       Main *bmain = CTX_data_main(C);
 
                        /* special case, 2.4x files */
-                       if (wm == NULL && CTX_data_main(C)->wm.first == NULL) {
+                       if (wm == NULL && BLI_listbase_is_empty(&bmain->wm)) {
                                extern void wm_add_default(bContext *C);
 
                                /* wm_add_default() needs the screen to be set. */
-                               CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
+                               CTX_wm_screen_set(C, bmain->screen.first);
                                wm_add_default(C);
                        }
 
@@ -1235,7 +1305,10 @@ static int load_file(int UNUSED(argc), const char **argv, void *data)
                        G.relbase_valid = 1;
                        if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm);  /* reset wm */
 
-                       DAG_on_visible_update(CTX_data_main(C), TRUE);
+                       /* WM_file_read would call normally */
+                       ED_editors_init(C);
+                       DAG_on_visible_update(bmain, true);
+                       BKE_scene_update_tagged(bmain->eval_ctx, bmain, CTX_data_scene(C));
                }
                else {
                        /* failed to load file, stop processing arguments */
@@ -1245,11 +1318,11 @@ static int load_file(int UNUSED(argc), const char **argv, void *data)
                /* WM_file_read() runs normally but since we're in background mode do here */
 #ifdef WITH_PYTHON
                /* run any texts that were loaded in and flagged as modules */
-               BPY_driver_reset();
-               BPY_app_handlers_reset(FALSE);
-               BPY_modules_load_user(C);
+               BPY_python_reset(C);
 #endif
 
+               BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST);
+
                /* happens for the UI on file reading too (huh? (ton))*/
                // XXX          BKE_reset_undo();
                //                      BKE_write_undo("original");     /* save current state */
@@ -1259,6 +1332,7 @@ static int load_file(int UNUSED(argc), const char **argv, void *data)
                 * a file - this should do everything a 'load file' does */
                ReportList reports;
                BKE_reports_init(&reports, RPT_PRINT);
+               WM_file_autoexec_init(filename);
                WM_file_read(C, filename, &reports);
                BKE_reports_clear(&reports);
        }
@@ -1338,7 +1412,7 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
 #undef PY_ENABLE_AUTO
 #undef PY_DISABLE_AUTO
        
-       BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
+       BLI_argsAdd(ba, 1, "-b", "--background", "\n\tRun in background (often used for UI-less rendering)", background_mode, NULL);
 
        BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
 
@@ -1363,9 +1437,14 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
 #ifdef WITH_LIBMV
        BLI_argsAdd(ba, 1, NULL, "--debug-libmv", "\n\tEnable debug messages from libmv library", debug_mode_libmv, NULL);
 #endif
+#ifdef WITH_CYCLES_LOGGING
+       BLI_argsAdd(ba, 1, NULL, "--debug-cycles", "\n\tEnable debug messages from Cycles", debug_mode_cycles, NULL);
+#endif
+       BLI_argsAdd(ba, 1, NULL, "--debug-memory", "\n\tEnable fully guarded memory allocation and debugging", debug_mode_memory, NULL);
 
        BLI_argsAdd(ba, 1, NULL, "--debug-value", "<value>\n\tSet debug value of <value> on startup\n", set_debug_value, NULL);
        BLI_argsAdd(ba, 1, NULL, "--debug-jobs",  "\n\tEnable time profiling for background jobs.", debug_mode_generic, (void *)G_DEBUG_JOBS);
+       BLI_argsAdd(ba, 1, NULL, "--debug-depsgraph", "\n\tEnable debug messages from dependency graph", debug_mode_generic, (void *)G_DEBUG_DEPSGRAPH);
 
        BLI_argsAdd(ba, 1, NULL, "--verbose", "<verbose>\n\tSet logging verbosity level.", set_verbosity, NULL);
 
@@ -1426,14 +1505,23 @@ char **environ = NULL;
 #  endif
 #endif
 
-
+/**
+ * Blender's main function responsabilities are:
+ * - setup subsystems.
+ * - handle arguments.
+ * - run WM_main() event loop,
+ *   or exit when running in background mode.
+ */
+int main(
+       int argc,
 #ifdef WIN32
-int main(int argc, const char **UNUSED(argv_c)) /* Do not mess with const */
+        const char **UNUSED(argv_c)
 #else
-int main(int argc, const char **argv)
+        const char **argv
 #endif
+         )
 {
-       bContext *C = CTX_create();
+       bContext *C;
        SYS_SystemHandle syshandle;
 
 #ifndef WITH_PYTHON_MODULE
@@ -1441,15 +1529,64 @@ int main(int argc, const char **argv)
 #endif
 
 #ifdef WIN32
+       /* FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM (fixed in SP1). Just disable it. */
+#  if defined(_MSC_VER) && _MSC_VER >= 1800 && defined(_M_X64)
+       _set_FMA3_enable(0);
+#  endif
+
+       /* Win32 Unicode Args */
+       /* NOTE: cannot use guardedalloc malloc here, as it's not yet initialized
+        *       (it depends on the args passed in, which is what we're getting here!)
+        */
        wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
+       char **argv = malloc(argc * sizeof(char *));
        int argci = 0;
-       char **argv = MEM_mallocN(argc * sizeof(char *), "argv array");
+       
        for (argci = 0; argci < argc; argci++) {
                argv[argci] = alloc_utf_8_from_16(argv_16[argci], 0);
        }
+       
        LocalFree(argv_16);
 #endif
 
+       /* NOTE: Special exception for guarded allocator type switch:
+        *       we need to perform switch from lock-free to fully
+        *       guarded allocator before any allocation happened.
+        */
+       {
+               int i;
+               for (i = 0; i < argc; i++) {
+                       if (STREQ(argv[i], "--debug") || STREQ(argv[i], "-d") ||
+                           STREQ(argv[i], "--debug-memory"))
+                       {
+                               printf("Switching to fully guarded memory allocator.\n");
+                               MEM_use_guarded_allocator();
+                               break;
+                       }
+                       else if (STREQ(argv[i], "--")) {
+                               break;
+                       }
+               }
+       }
+
+#ifdef BUILD_DATE
+       {
+               time_t temp_time = build_commit_timestamp;
+               struct tm *tm = gmtime(&temp_time);
+               if (LIKELY(tm)) {
+                       strftime(build_commit_date, sizeof(build_commit_date), "%Y-%m-%d", tm);
+                       strftime(build_commit_time, sizeof(build_commit_time), "%H:%M", tm);
+               }
+               else {
+                       const char *unknown = "date-unknown";
+                       BLI_strncpy(build_commit_date, unknown, sizeof(build_commit_date));
+                       BLI_strncpy(build_commit_time, unknown, sizeof(build_commit_time));
+               }
+       }
+#endif
+
+       C = CTX_create();
+
 #ifdef WITH_PYTHON_MODULE
 #ifdef __APPLE__
        environ = *_NSGetEnviron();
@@ -1467,24 +1604,11 @@ int main(int argc, const char **argv)
 
 #ifdef WITH_LIBMV
        libmv_initLogging(argv[0]);
+#elif defined(WITH_CYCLES_LOGGING)
+       CCL_init_logging(argv[0]);
 #endif
 
        setCallbacks();
-#if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
-       /* patch to ignore argument finder gives us (pid?) */
-       if (argc == 2 && strncmp(argv[1], "-psn_", 5) == 0) {
-               extern int GHOST_HACK_getFirstFile(char buf[]);
-               static char firstfilebuf[512];
-
-               argc = 1;
-
-               if (GHOST_HACK_getFirstFile(firstfilebuf)) {
-                       argc = 2;
-                       argv[1] = firstfilebuf;
-               }
-       }
-
-#endif
 
 #ifdef __FreeBSD__
        fpsetmask(0);
@@ -1499,6 +1623,8 @@ int main(int argc, const char **argv)
 
        IMB_init();
        BKE_images_init();
+       BKE_modifier_init();
+       DAG_init();
 
        BKE_brush_system_init();
 
@@ -1535,6 +1661,7 @@ int main(int argc, const char **argv)
 
        RE_engines_init();
        init_nodesystem();
+       psys_init_rng();
        /* end second init */
 
 
@@ -1565,11 +1692,7 @@ int main(int argc, const char **argv)
 
                /* this is properly initialized with user defs, but this is default */
                /* call after loading the startup.blend so we can read U.tempdir */
-               BLI_init_temporary_dir(U.tempdir);
-
-#ifdef WITH_SDL
-               BLI_setenv("SDL_VIDEODRIVER", "dummy");
-#endif
+               BLI_temp_dir_init(U.tempdir);
        }
        else {
 #ifndef WITH_PYTHON_MODULE
@@ -1579,7 +1702,7 @@ int main(int argc, const char **argv)
                WM_init(C, argc, (const char **)argv);
 
                /* don't use user preferences temp dir */
-               BLI_init_temporary_dir(NULL);
+               BLI_temp_dir_init(NULL);
        }
 #ifdef WITH_PYTHON
        /**
@@ -1623,7 +1746,7 @@ int main(int argc, const char **argv)
        while (argci) {
                free(argv[--argci]);
        }
-       MEM_freeN(argv);
+       free(argv);
        argv = NULL;
 #endif
 
@@ -1636,11 +1759,21 @@ int main(int argc, const char **argv)
                WM_exit(C);
        }
        else {
-               if ((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC)) {
-                       if (WM_init_game(C))
-                               return 0;
+               if (G.fileflags & G_FILE_AUTOPLAY) {
+                       if (G.f & G_SCRIPT_AUTOEXEC) {
+                               if (WM_init_game(C)) {
+                                       return 0;
+                               }
+                       }
+                       else {
+                               if (!(G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET)) {
+                                       G.f |= G_SCRIPT_AUTOEXEC_FAIL;
+                                       BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Game AutoStart");
+                               }
+                       }
                }
-               else if (!G.file_loaded) {
+
+               if (!G.file_loaded) {
                        WM_init_splash(C);
                }
        }
@@ -1653,17 +1786,11 @@ int main(int argc, const char **argv)
 #ifdef WITH_PYTHON_MODULE
 void main_python_exit(void)
 {
-       WM_exit((bContext *)evil_C);
+       WM_exit_ext((bContext *)evil_C, true);
        evil_C = NULL;
 }
 #endif
 
-static void error_cb(const char *err)
-{
-       
-       printf("%s\n", err);    /* XXX do this in WM too */
-}
-
 static void mem_error_cb(const char *errorStr)
 {
        fputs(errorStr, stderr);
@@ -1674,11 +1801,4 @@ static void setCallbacks(void)
 {
        /* Error output from the alloc routines: */
        MEM_set_error_callback(mem_error_cb);
-
-
-       /* BLI_blenlib: */
-
-       BLI_setErrorCallBack(error_cb); /* */
-// XXX BLI_setInterruptCallBack(blender_test_break);
-
 }