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