2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17 * All rights reserved.
20 /** \file creator/creator.c
28 # if defined(_MSC_VER) && defined(_M_X64)
29 # include <math.h> /* needed for _set_FMA3_enable */
35 #include "MEM_guardedalloc.h"
39 #include "DNA_genfile.h"
42 #include "BLI_threads.h"
43 #include "BLI_utildefines.h"
44 #include "BLI_callbacks.h"
45 #include "BLI_string.h"
46 #include "BLI_system.h"
48 /* mostly init functions */
49 #include "BKE_appdir.h"
50 #include "BKE_blender.h"
51 #include "BKE_brush.h"
52 #include "BKE_cachefile.h"
53 #include "BKE_context.h"
55 #include "BKE_global.h"
56 #include "BKE_material.h"
57 #include "BKE_modifier.h"
58 #include "BKE_gpencil_modifier.h"
60 #include "BKE_shader_fx.h"
61 #include "BKE_sound.h"
62 #include "BKE_image.h"
63 #include "BKE_particle.h"
65 #include "DEG_depsgraph.h"
67 #include "IMB_imbuf.h" /* for IMB_init */
69 #include "RE_engine.h"
70 #include "RE_render_ext.h"
72 #include "ED_datafiles.h"
75 #include "WM_toolsystem.h"
77 #include "RNA_define.h"
80 # include "FRS_freestyle.h"
86 # include <floatingpoint.h>
90 # include "binreloc.h"
94 # include "libmv-capi.h"
97 #ifdef WITH_CYCLES_LOGGING
101 #ifdef WITH_SDL_DYNLOAD
105 #include "creator_intern.h" /* own include */
108 /* Local Function prototypes */
109 #ifdef WITH_PYTHON_MODULE
110 int main_python_enter(int argc, const char **argv);
111 void main_python_exit(void);
114 /* written to by 'creator_args.c' */
115 struct ApplicationState app_state = {
117 .use_crash_handler = true,
118 .use_abort_handler = true,
120 .exit_code_on_error = {
125 /* -------------------------------------------------------------------- */
126 /** \name Application Level Callbacks
128 * Initialize callbacks for the modules that need them.
132 static void callback_mem_error(const char *errorStr)
134 fputs(errorStr, stderr);
138 static void main_callback_setup(void)
140 /* Error output from the alloc routines: */
141 MEM_set_error_callback(callback_mem_error);
144 /* free data on early exit (if Python calls 'sys.exit()' while parsing args for eg). */
145 struct CreatorAtExitData {
153 static void callback_main_atexit(void *user_data)
155 struct CreatorAtExitData *app_init_data = user_data;
157 if (app_init_data->ba) {
158 BLI_argsFree(app_init_data->ba);
159 app_init_data->ba = NULL;
163 if (app_init_data->argv) {
164 while (app_init_data->argv_num) {
165 free((void *)app_init_data->argv[--app_init_data->argv_num]);
167 free((void *)app_init_data->argv);
168 app_init_data->argv = NULL;
173 static void callback_clg_fatal(void *fp)
175 BLI_system_backtrace(fp);
181 /* -------------------------------------------------------------------- */
182 /** \name Main Function
185 #ifdef WITH_PYTHON_MODULE
186 /* allow python module to call main */
187 # define main main_python_enter
188 static void *evil_C = NULL;
191 /* environ is not available in mac shared libraries */
192 # include <crt_externs.h>
193 char **environ = NULL;
198 * Blender's main function responsibilities are:
199 * - setup subsystems.
200 * - handle arguments.
201 * - run #WM_main() event loop,
202 * or exit immediately when running in background mode.
207 const char **UNUSED(argv_c)
215 #ifndef WITH_PYTHON_MODULE
224 /* --- end declarations --- */
226 /* ensure we free data on early-exit */
227 struct CreatorAtExitData app_init_data = {NULL};
228 BKE_blender_atexit_register(callback_main_atexit, &app_init_data);
230 /* Unbuffered stdout makes stdout and stderr better synchronized, and helps
231 * when stepping through code in a debugger (prints are immediately
233 setvbuf(stdout, NULL, _IONBF, 0);
236 /* We delay loading of openmp so we can set the policy here. */
237 # if defined(_MSC_VER)
238 _putenv_s("OMP_WAIT_POLICY", "PASSIVE");
241 /* FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM
242 * (fixed in SP1). Just disable it. */
243 # if defined(_MSC_VER) && defined(_M_X64)
247 /* Win32 Unicode Args */
248 /* NOTE: cannot use guardedalloc malloc here, as it's not yet initialized
249 * (it depends on the args passed in, which is what we're getting here!)
252 wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
253 argv = malloc(argc * sizeof(char *));
254 for (argv_num = 0; argv_num < argc; argv_num++) {
255 argv[argv_num] = alloc_utf_8_from_16(argv_16[argv_num], 0);
259 /* free on early-exit */
260 app_init_data.argv = argv;
261 app_init_data.argv_num = argv_num;
265 /* NOTE: Special exception for guarded allocator type switch:
266 * we need to perform switch from lock-free to fully
267 * guarded allocator before any allocation happened.
271 for (i = 0; i < argc; i++) {
272 if (STREQ(argv[i], "--debug") || STREQ(argv[i], "-d") ||
273 STREQ(argv[i], "--debug-memory") || STREQ(argv[i], "--debug-all"))
275 printf("Switching to fully guarded memory allocator.\n");
276 MEM_use_guarded_allocator();
279 else if (STREQ(argv[i], "--")) {
287 time_t temp_time = build_commit_timestamp;
288 struct tm *tm = gmtime(&temp_time);
290 strftime(build_commit_date, sizeof(build_commit_date), "%Y-%m-%d", tm);
291 strftime(build_commit_time, sizeof(build_commit_time), "%H:%M", tm);
294 const char *unknown = "date-unknown";
295 BLI_strncpy(build_commit_date, unknown, sizeof(build_commit_date));
296 BLI_strncpy(build_commit_time, unknown, sizeof(build_commit_time));
301 #ifdef WITH_SDL_DYNLOAD
305 /* Initialize logging */
307 CLG_fatal_fn_set(callback_clg_fatal);
311 #ifdef WITH_PYTHON_MODULE
313 environ = *_NSGetEnviron();
327 libmv_initLogging(argv[0]);
328 #elif defined(WITH_CYCLES_LOGGING)
329 CCL_init_logging(argv[0]);
332 main_callback_setup();
334 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
335 /* patch to ignore argument finder gives us (pid?) */
336 if (argc == 2 && STREQLEN(argv[1], "-psn_", 5)) {
337 extern int GHOST_HACK_getFirstFile(char buf[]);
338 static char firstfilebuf[512];
342 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
344 argv[1] = firstfilebuf;
353 /* initialize path to executable */
354 BKE_appdir_program_path_init(argv[0]);
356 BLI_threadapi_init();
357 BLI_thread_put_process_on_fast_node();
359 DNA_sdna_current_init();
361 BKE_blender_globals_init(); /* blender.c */
364 BKE_cachefiles_init();
367 BKE_gpencil_modifier_init();
369 DEG_register_node_types();
371 BKE_brush_system_init();
372 RE_texture_rng_init();
375 BLI_callback_global_init();
377 /* first test for background */
378 #ifndef WITH_PYTHON_MODULE
379 ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
381 /* ensure we free on early exit */
382 app_init_data.ba = ba;
384 main_args_setup(C, ba);
386 BLI_argsParse(ba, 1, NULL, NULL);
391 /* using preferences or user startup makes no sense for py-as-module */
392 G.factory_startup = true;
399 /* after level 1 args, this is so playanim skips RNA init */
405 /* end second init */
408 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
409 G.background = true; /* python module mode ALWAYS runs in background mode (for now) */
412 main_signal_setup_background();
416 /* background render uses this font too */
417 BKE_vfont_builtin_register(datatoc_bfont_pfb, datatoc_bfont_pfb_size);
419 /* Initialize ffmpeg if built in, also needed for bg mode if videos are
420 * rendered via ffmpeg */
421 BKE_sound_init_once();
425 if (G.background == 0) {
426 #ifndef WITH_PYTHON_MODULE
427 BLI_argsParse(ba, 2, NULL, NULL);
428 BLI_argsParse(ba, 3, NULL, NULL);
430 WM_init(C, argc, (const char **)argv);
432 /* this is properly initialized with user defs, but this is default */
433 /* call after loading the startup.blend so we can read U.tempdir */
434 BKE_tempdir_init(U.tempdir);
437 #ifndef WITH_PYTHON_MODULE
438 BLI_argsParse(ba, 3, NULL, NULL);
441 WM_init(C, argc, (const char **)argv);
443 /* don't use user preferences temp dir */
444 BKE_tempdir_init(NULL);
448 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
449 * so we provide the BPY_ function below to append the user defined
450 * python-dir to Python's sys.path at this point. Simply putting
451 * WM_init() before #BPY_python_start() crashes Blender at startup.
454 /* TODO - U.pythondir */
456 printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
459 CTX_py_init_set(C, 1);
460 WM_keyconfig_init(C);
462 #ifdef WITH_FREESTYLE
463 /* initialize Freestyle */
468 /* OK we are ready for it */
469 #ifndef WITH_PYTHON_MODULE
470 main_args_setup_post(C, ba);
472 if (G.background == 0) {
474 if (U.uiflag2 & USER_KEEP_SESSION)
475 WM_recover_last_session(C, NULL);
480 /* Explicitly free data allocated for argument parsing:
484 callback_main_atexit(&app_init_data);
485 BKE_blender_atexit_unregister(callback_main_atexit, &app_init_data);
487 /* paranoid, avoid accidental re-use */
488 #ifndef WITH_PYTHON_MODULE
498 #ifdef WITH_PYTHON_MODULE
499 return 0; /* keep blender in background mode running */
503 /* Using window-manager API in background mode is a bit odd, but works fine. */
507 if (!G.file_loaded) {
515 } /* end of int main(argc, argv) */
517 #ifdef WITH_PYTHON_MODULE
518 void main_python_exit(void)
520 WM_exit_ext((bContext *)evil_C, true);