Merge branch 'blender2.7'
[blender.git] / source / creator / creator.c
1 /*
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.
6  *
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.
11  *
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.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file \ingroup creator
21  */
22
23 #include <stdlib.h>
24 #include <string.h>
25
26 #ifdef WIN32
27 #  if defined(_MSC_VER) && defined(_M_X64)
28 #    include <math.h> /* needed for _set_FMA3_enable */
29 #  endif
30 #  include <windows.h>
31 #  include "utfconv.h"
32 #endif
33
34 #include "MEM_guardedalloc.h"
35
36 #include "CLG_log.h"
37
38 #include "DNA_genfile.h"
39
40 #include "BLI_args.h"
41 #include "BLI_threads.h"
42 #include "BLI_utildefines.h"
43 #include "BLI_callbacks.h"
44 #include "BLI_string.h"
45 #include "BLI_system.h"
46
47 /* mostly init functions */
48 #include "BKE_appdir.h"
49 #include "BKE_blender.h"
50 #include "BKE_brush.h"
51 #include "BKE_cachefile.h"
52 #include "BKE_context.h"
53 #include "BKE_font.h"
54 #include "BKE_global.h"
55 #include "BKE_material.h"
56 #include "BKE_modifier.h"
57 #include "BKE_gpencil_modifier.h"
58 #include "BKE_node.h"
59 #include "BKE_shader_fx.h"
60 #include "BKE_sound.h"
61 #include "BKE_image.h"
62 #include "BKE_particle.h"
63
64 #include "DEG_depsgraph.h"
65
66 #include "IMB_imbuf.h"  /* for IMB_init */
67
68 #include "RE_engine.h"
69 #include "RE_render_ext.h"
70
71 #include "ED_datafiles.h"
72
73 #include "WM_api.h"
74 #include "WM_toolsystem.h"
75
76 #include "RNA_define.h"
77
78 #ifdef WITH_FREESTYLE
79 #  include "FRS_freestyle.h"
80 #endif
81
82 #include <signal.h>
83
84 #ifdef __FreeBSD__
85 #  include <floatingpoint.h>
86 #endif
87
88 #ifdef WITH_BINRELOC
89 #  include "binreloc.h"
90 #endif
91
92 #ifdef WITH_LIBMV
93 #  include "libmv-capi.h"
94 #endif
95
96 #ifdef WITH_CYCLES_LOGGING
97 #  include "CCL_api.h"
98 #endif
99
100 #ifdef WITH_SDL_DYNLOAD
101 #  include "sdlew.h"
102 #endif
103
104 #include "creator_intern.h"  /* own include */
105
106
107 /*      Local Function prototypes */
108 #ifdef WITH_PYTHON_MODULE
109 int  main_python_enter(int argc, const char **argv);
110 void main_python_exit(void);
111 #endif
112
113 /* written to by 'creator_args.c' */
114 struct ApplicationState app_state = {
115         .signal = {
116                 .use_crash_handler = true,
117                 .use_abort_handler = true,
118         },
119         .exit_code_on_error = {
120                 .python = 0,
121         },
122 };
123
124 /* -------------------------------------------------------------------- */
125 /** \name Application Level Callbacks
126  *
127  * Initialize callbacks for the modules that need them.
128  *
129  * \{ */
130
131 static void callback_mem_error(const char *errorStr)
132 {
133         fputs(errorStr, stderr);
134         fflush(stderr);
135 }
136
137 static void main_callback_setup(void)
138 {
139         /* Error output from the alloc routines: */
140         MEM_set_error_callback(callback_mem_error);
141 }
142
143 /* free data on early exit (if Python calls 'sys.exit()' while parsing args for eg). */
144 struct CreatorAtExitData {
145         bArgs *ba;
146 #ifdef WIN32
147         const char **argv;
148         int argv_num;
149 #endif
150 };
151
152 static void callback_main_atexit(void *user_data)
153 {
154         struct CreatorAtExitData *app_init_data = user_data;
155
156         if (app_init_data->ba) {
157                 BLI_argsFree(app_init_data->ba);
158                 app_init_data->ba = NULL;
159         }
160
161 #ifdef WIN32
162         if (app_init_data->argv) {
163                 while (app_init_data->argv_num) {
164                         free((void *)app_init_data->argv[--app_init_data->argv_num]);
165                 }
166                 free((void *)app_init_data->argv);
167                 app_init_data->argv = NULL;
168         }
169 #endif
170 }
171
172 static void callback_clg_fatal(void *fp)
173 {
174         BLI_system_backtrace(fp);
175 }
176
177 /** \} */
178
179
180 /* -------------------------------------------------------------------- */
181 /** \name Main Function
182  * \{ */
183
184 #ifdef WITH_PYTHON_MODULE
185 /* allow python module to call main */
186 #  define main main_python_enter
187 static void *evil_C = NULL;
188
189 #  ifdef __APPLE__
190      /* environ is not available in mac shared libraries */
191 #    include <crt_externs.h>
192 char **environ = NULL;
193 #  endif
194 #endif
195
196 /**
197  * Blender's main function responsibilities are:
198  * - setup subsystems.
199  * - handle arguments.
200  * - run #WM_main() event loop,
201  *   or exit immediately when running in background mode.
202  */
203 int main(
204         int argc,
205 #ifdef WIN32
206         const char **UNUSED(argv_c)
207 #else
208         const char **argv
209 #endif
210         )
211 {
212         bContext *C;
213
214 #ifndef WITH_PYTHON_MODULE
215         bArgs *ba;
216 #endif
217
218 #ifdef WIN32
219         char **argv;
220         int argv_num;
221 #endif
222
223         /* --- end declarations --- */
224
225         /* ensure we free data on early-exit */
226         struct CreatorAtExitData app_init_data = {NULL};
227         BKE_blender_atexit_register(callback_main_atexit, &app_init_data);
228
229         /* Unbuffered stdout makes stdout and stderr better synchronized, and helps
230          * when stepping through code in a debugger (prints are immediately
231          * visible). */
232         setvbuf(stdout, NULL, _IONBF, 0);
233
234 #ifdef WIN32
235         /* We delay loading of openmp so we can set the policy here. */
236 # if defined(_MSC_VER)
237         _putenv_s("OMP_WAIT_POLICY", "PASSIVE");
238 # endif
239
240         /* FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM
241          * (fixed in SP1). Just disable it. */
242 #  if defined(_MSC_VER) && defined(_M_X64)
243         _set_FMA3_enable(0);
244 #  endif
245
246         /* Win32 Unicode Args */
247         /* NOTE: cannot use guardedalloc malloc here, as it's not yet initialized
248          *       (it depends on the args passed in, which is what we're getting here!)
249          */
250         {
251                 wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
252                 argv = malloc(argc * sizeof(char *));
253                 for (argv_num = 0; argv_num < argc; argv_num++) {
254                         argv[argv_num] = alloc_utf_8_from_16(argv_16[argv_num], 0);
255                 }
256                 LocalFree(argv_16);
257
258                 /* free on early-exit */
259                 app_init_data.argv = argv;
260                 app_init_data.argv_num = argv_num;
261         }
262 #endif  /* WIN32 */
263
264         /* NOTE: Special exception for guarded allocator type switch:
265          *       we need to perform switch from lock-free to fully
266          *       guarded allocator before any allocation happened.
267          */
268         {
269                 int i;
270                 for (i = 0; i < argc; i++) {
271                         if (STREQ(argv[i], "--debug") || STREQ(argv[i], "-d") ||
272                             STREQ(argv[i], "--debug-memory") || STREQ(argv[i], "--debug-all"))
273                         {
274                                 printf("Switching to fully guarded memory allocator.\n");
275                                 MEM_use_guarded_allocator();
276                                 break;
277                         }
278                         else if (STREQ(argv[i], "--")) {
279                                 break;
280                         }
281                 }
282         }
283
284 #ifdef BUILD_DATE
285         {
286                 time_t temp_time = build_commit_timestamp;
287                 struct tm *tm = gmtime(&temp_time);
288                 if (LIKELY(tm)) {
289                         strftime(build_commit_date, sizeof(build_commit_date), "%Y-%m-%d", tm);
290                         strftime(build_commit_time, sizeof(build_commit_time), "%H:%M", tm);
291                 }
292                 else {
293                         const char *unknown = "date-unknown";
294                         BLI_strncpy(build_commit_date, unknown, sizeof(build_commit_date));
295                         BLI_strncpy(build_commit_time, unknown, sizeof(build_commit_time));
296                 }
297         }
298 #endif
299
300 #ifdef WITH_SDL_DYNLOAD
301         sdlewInit();
302 #endif
303
304         /* Initialize logging */
305         CLG_init();
306         CLG_fatal_fn_set(callback_clg_fatal);
307
308         C = CTX_create();
309
310 #ifdef WITH_PYTHON_MODULE
311 #ifdef __APPLE__
312         environ = *_NSGetEnviron();
313 #endif
314
315 #undef main
316         evil_C = C;
317 #endif
318
319
320
321 #ifdef WITH_BINRELOC
322         br_init(NULL);
323 #endif
324
325 #ifdef WITH_LIBMV
326         libmv_initLogging(argv[0]);
327 #elif defined(WITH_CYCLES_LOGGING)
328         CCL_init_logging(argv[0]);
329 #endif
330
331         main_callback_setup();
332
333 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
334         /* patch to ignore argument finder gives us (pid?) */
335         if (argc == 2 && STREQLEN(argv[1], "-psn_", 5)) {
336                 extern int GHOST_HACK_getFirstFile(char buf[]);
337                 static char firstfilebuf[512];
338
339                 argc = 1;
340
341                 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
342                         argc = 2;
343                         argv[1] = firstfilebuf;
344                 }
345         }
346 #endif
347
348 #ifdef __FreeBSD__
349         fpsetmask(0);
350 #endif
351
352         /* initialize path to executable */
353         BKE_appdir_program_path_init(argv[0]);
354
355         BLI_threadapi_init();
356         BLI_thread_put_process_on_fast_node();
357
358         DNA_sdna_current_init();
359
360         BKE_blender_globals_init();  /* blender.c */
361
362         IMB_init();
363         BKE_cachefiles_init();
364         BKE_images_init();
365         BKE_modifier_init();
366         BKE_gpencil_modifier_init();
367         BKE_shaderfx_init();
368         DEG_register_node_types();
369
370         BKE_brush_system_init();
371         RE_texture_rng_init();
372
373
374         BLI_callback_global_init();
375
376         /* first test for background */
377 #ifndef WITH_PYTHON_MODULE
378         ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
379
380         /* ensure we free on early exit */
381         app_init_data.ba = ba;
382
383         main_args_setup(C, ba);
384
385         BLI_argsParse(ba, 1, NULL, NULL);
386
387         main_signal_setup();
388
389 #else
390         /* using preferences or user startup makes no sense for py-as-module */
391         G.factory_startup = true;
392 #endif
393
394 #ifdef WITH_FFMPEG
395         IMB_ffmpeg_init();
396 #endif
397
398         /* after level 1 args, this is so playanim skips RNA init */
399         RNA_init();
400
401         RE_engines_init();
402         init_nodesystem();
403         psys_init_rng();
404         /* end second init */
405
406
407 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
408         G.background = true; /* python module mode ALWAYS runs in background mode (for now) */
409 #else
410         if (G.background) {
411                 main_signal_setup_background();
412         }
413 #endif
414
415         /* background render uses this font too */
416         BKE_vfont_builtin_register(datatoc_bfont_pfb, datatoc_bfont_pfb_size);
417
418         /* Initialize ffmpeg if built in, also needed for bg mode if videos are
419          * rendered via ffmpeg */
420         BKE_sound_init_once();
421
422         init_def_material();
423
424         if (G.background == 0) {
425 #ifndef WITH_PYTHON_MODULE
426                 BLI_argsParse(ba, 2, NULL, NULL);
427                 BLI_argsParse(ba, 3, NULL, NULL);
428 #endif
429                 WM_init(C, argc, (const char **)argv);
430
431                 /* this is properly initialized with user defs, but this is default */
432                 /* call after loading the startup.blend so we can read U.tempdir */
433                 BKE_tempdir_init(U.tempdir);
434         }
435         else {
436 #ifndef WITH_PYTHON_MODULE
437                 BLI_argsParse(ba, 3, NULL, NULL);
438 #endif
439
440                 WM_init(C, argc, (const char **)argv);
441
442                 /* don't use user preferences temp dir */
443                 BKE_tempdir_init(NULL);
444         }
445 #ifdef WITH_PYTHON
446         /**
447          * NOTE: the U.pythondir string is NULL until WM_init() is executed,
448          * so we provide the BPY_ function below to append the user defined
449          * python-dir to Python's sys.path at this point.  Simply putting
450          * WM_init() before #BPY_python_start() crashes Blender at startup.
451          */
452
453         /* TODO - U.pythondir */
454 #else
455         printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
456 #endif
457
458         CTX_py_init_set(C, 1);
459         WM_keyconfig_init(C);
460
461 #ifdef WITH_FREESTYLE
462         /* initialize Freestyle */
463         FRS_initialize();
464         FRS_set_context(C);
465 #endif
466
467         /* OK we are ready for it */
468 #ifndef WITH_PYTHON_MODULE
469         main_args_setup_post(C, ba);
470
471         if (G.background == 0) {
472                 if (!G.file_loaded)
473                         if (U.uiflag2 & USER_KEEP_SESSION)
474                                 WM_recover_last_session(C, NULL);
475         }
476
477 #endif
478
479         /* Explicitly free data allocated for argument parsing:
480          * - 'ba'
481          * - 'argv' on WIN32.
482          */
483         callback_main_atexit(&app_init_data);
484         BKE_blender_atexit_unregister(callback_main_atexit, &app_init_data);
485
486         /* paranoid, avoid accidental re-use */
487 #ifndef WITH_PYTHON_MODULE
488         ba = NULL;
489         (void)ba;
490 #endif
491
492 #ifdef WIN32
493         argv = NULL;
494         (void)argv;
495 #endif
496
497 #ifdef WITH_PYTHON_MODULE
498         return 0; /* keep blender in background mode running */
499 #endif
500
501         if (G.background) {
502                 /* Using window-manager API in background mode is a bit odd, but works fine. */
503                 WM_exit(C);
504         }
505         else {
506                 if (!G.file_loaded) {
507                         WM_init_splash(C);
508                 }
509         }
510
511         WM_main(C);
512
513         return 0;
514 } /* end of int main(argc, argv) */
515
516 #ifdef WITH_PYTHON_MODULE
517 void main_python_exit(void)
518 {
519         WM_exit_ext((bContext *)evil_C, true);
520         evil_C = NULL;
521 }
522 #endif
523
524 /** \} */