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