Blender  V2.93
creator.c
Go to the documentation of this file.
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 
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #ifdef WIN32
28 # include "utfconv.h"
29 # include <windows.h>
30 #endif
31 
32 #if defined(WITH_TBB_MALLOC) && defined(_MSC_VER) && defined(NDEBUG)
33 # pragma comment(lib, "tbbmalloc_proxy.lib")
34 # pragma comment(linker, "/include:__TBB_malloc_proxy")
35 #endif
36 
37 #include "MEM_guardedalloc.h"
38 
39 #include "CLG_log.h"
40 
41 #include "DNA_genfile.h"
42 
43 #include "BLI_args.h"
44 #include "BLI_string.h"
45 #include "BLI_system.h"
46 #include "BLI_task.h"
47 #include "BLI_threads.h"
48 #include "BLI_utildefines.h"
49 
50 /* Mostly initialization functions. */
51 #include "BKE_appdir.h"
52 #include "BKE_blender.h"
53 #include "BKE_brush.h"
54 #include "BKE_cachefile.h"
55 #include "BKE_callbacks.h"
56 #include "BKE_context.h"
57 #include "BKE_font.h"
58 #include "BKE_global.h"
59 #include "BKE_gpencil_modifier.h"
60 #include "BKE_idtype.h"
61 #include "BKE_image.h"
62 #include "BKE_material.h"
63 #include "BKE_modifier.h"
64 #include "BKE_node.h"
65 #include "BKE_particle.h"
66 #include "BKE_shader_fx.h"
67 #include "BKE_sound.h"
68 #include "BKE_volume.h"
69 
70 #include "DEG_depsgraph.h"
71 
72 #include "IMB_imbuf.h" /* For #IMB_init. */
73 
74 #include "RE_engine.h"
75 #include "RE_texture.h"
76 
77 #include "ED_datafiles.h"
78 
79 #include "WM_api.h"
80 #include "WM_toolsystem.h"
81 
82 #include "RNA_define.h"
83 
84 #ifdef WITH_FREESTYLE
85 # include "FRS_freestyle.h"
86 #endif
87 
88 #include <signal.h>
89 
90 #ifdef __FreeBSD__
91 # include <floatingpoint.h>
92 #endif
93 
94 #ifdef WITH_BINRELOC
95 # include "binreloc.h"
96 #endif
97 
98 #ifdef WITH_LIBMV
99 # include "libmv-capi.h"
100 #endif
101 
102 #ifdef WITH_CYCLES_LOGGING
103 # include "CCL_api.h"
104 #endif
105 
106 #ifdef WITH_SDL_DYNLOAD
107 # include "sdlew.h"
108 #endif
109 
110 #include "creator_intern.h" /* Own include. */
111 
112 /* -------------------------------------------------------------------- */
116 /* written to by 'creator_args.c' */
117 struct ApplicationState app_state = {
118  .signal =
119  {
120  .use_crash_handler = true,
121  .use_abort_handler = true,
122  },
123  .exit_code_on_error =
124  {
125  .python = 0,
126  },
127 };
128 
131 /* -------------------------------------------------------------------- */
138 static void callback_mem_error(const char *errorStr)
139 {
140  fputs(errorStr, stderr);
141  fflush(stderr);
142 }
143 
144 static void main_callback_setup(void)
145 {
146  /* Error output from the guarded allocation routines. */
148 }
149 
150 /* free data on early exit (if Python calls 'sys.exit()' while parsing args for eg). */
153 #ifdef WIN32
154  const char **argv;
155  int argv_num;
156 #endif
157 };
158 
159 static void callback_main_atexit(void *user_data)
160 {
161  struct CreatorAtExitData *app_init_data = user_data;
162 
163  if (app_init_data->ba) {
164  BLI_args_destroy(app_init_data->ba);
165  app_init_data->ba = NULL;
166  }
167 
168 #ifdef WIN32
169  if (app_init_data->argv) {
170  while (app_init_data->argv_num) {
171  free((void *)app_init_data->argv[--app_init_data->argv_num]);
172  }
173  free((void *)app_init_data->argv);
174  app_init_data->argv = NULL;
175  }
176 #endif
177 }
178 
179 static void callback_clg_fatal(void *fp)
180 {
182 }
183 
186 /* -------------------------------------------------------------------- */
193 #ifdef WITH_PYTHON_MODULE
194 
195 /* Called in `bpy_interface.c` when building as a Python module. */
196 int main_python_enter(int argc, const char **argv);
197 void main_python_exit(void);
198 
199 /* Rename the 'main' function, allowing Python initialization to call it. */
200 # define main main_python_enter
201 static void *evil_C = NULL;
202 
203 # ifdef __APPLE__
204 /* Environment is not available in macOS shared libraries. */
205 # include <crt_externs.h>
206 char **environ = NULL;
207 # endif /* __APPLE__ */
208 
209 #endif /* WITH_PYTHON_MODULE */
210 
213 /* -------------------------------------------------------------------- */
224 int main(int argc,
225 #ifdef WIN32
226  const char **UNUSED(argv_c)
227 #else
228  const char **argv
229 #endif
230 )
231 {
232  bContext *C;
233 
234 #ifndef WITH_PYTHON_MODULE
235  bArgs *ba;
236 #endif
237 
238 #ifdef WIN32
239  char **argv;
240  int argv_num;
241 #endif
242 
243  /* --- end declarations --- */
244 
245  /* Ensure we free data on early-exit. */
246  struct CreatorAtExitData app_init_data = {NULL};
248 
249  /* Un-buffered `stdout` makes `stdout` and `stderr` better synchronized, and helps
250  * when stepping through code in a debugger (prints are immediately
251  * visible). However disabling buffering causes lock contention on windows
252  * see T76767 for details, since this is a debugging aid, we do not enable
253  * the un-buffered behavior for release builds. */
254 #ifndef NDEBUG
255  setvbuf(stdout, NULL, _IONBF, 0);
256 #endif
257 
258 #ifdef WIN32
259  /* We delay loading of OPENMP so we can set the policy here. */
260 # if defined(_MSC_VER)
261  _putenv_s("OMP_WAIT_POLICY", "PASSIVE");
262 # endif
263 
264  /* Win32 Unicode Arguments. */
265  /* NOTE: cannot use `guardedalloc` allocation here, as it's not yet initialized
266  * (it depends on the arguments passed in, which is what we're getting here!)
267  */
268  {
269  wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
270  argv = malloc(argc * sizeof(char *));
271  for (argv_num = 0; argv_num < argc; argv_num++) {
272  argv[argv_num] = alloc_utf_8_from_16(argv_16[argv_num], 0);
273  }
274  LocalFree(argv_16);
275 
276  /* free on early-exit */
277  app_init_data.argv = argv;
278  app_init_data.argv_num = argv_num;
279  }
280 #endif /* WIN32 */
281 
282  /* NOTE: Special exception for guarded allocator type switch:
283  * we need to perform switch from lock-free to fully
284  * guarded allocator before any allocation happened.
285  */
286  {
287  int i;
288  for (i = 0; i < argc; i++) {
289  if (STR_ELEM(argv[i], "-d", "--debug", "--debug-memory", "--debug-all")) {
290  printf("Switching to fully guarded memory allocator.\n");
292  break;
293  }
294  if (STREQ(argv[i], "--")) {
295  break;
296  }
297  }
299  }
300 
301 #ifdef BUILD_DATE
302  {
303  time_t temp_time = build_commit_timestamp;
304  struct tm *tm = gmtime(&temp_time);
305  if (LIKELY(tm)) {
306  strftime(build_commit_date, sizeof(build_commit_date), "%Y-%m-%d", tm);
307  strftime(build_commit_time, sizeof(build_commit_time), "%H:%M", tm);
308  }
309  else {
310  const char *unknown = "date-unknown";
313  }
314  }
315 #endif
316 
317 #ifdef WITH_SDL_DYNLOAD
318  sdlewInit();
319 #endif
320 
321  /* Initialize logging. */
322  CLG_init();
324 
325  C = CTX_create();
326 
327 #ifdef WITH_PYTHON_MODULE
328 # ifdef __APPLE__
329  environ = *_NSGetEnviron();
330 # endif
331 
332 # undef main
333  evil_C = C;
334 #endif
335 
336 #ifdef WITH_BINRELOC
337  br_init(NULL);
338 #endif
339 
340 #ifdef WITH_LIBMV
341  libmv_initLogging(argv[0]);
342 #elif defined(WITH_CYCLES_LOGGING)
343  CCL_init_logging(argv[0]);
344 #endif
345 
347 
348 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE) && !defined(WITH_HEADLESS)
349  /* Patch to ignore argument finder gives us (PID?) */
350  if (argc == 2 && STRPREFIX(argv[1], "-psn_")) {
351  extern int GHOST_HACK_getFirstFile(char buf[]);
352  static char firstfilebuf[512];
353 
354  argc = 1;
355 
356  if (GHOST_HACK_getFirstFile(firstfilebuf)) {
357  argc = 2;
358  argv[1] = firstfilebuf;
359  }
360  }
361 #endif
362 
363 #ifdef __FreeBSD__
364  fpsetmask(0);
365 #endif
366 
367  /* Initialize path to executable. */
369 
372 
374 
375  BKE_blender_globals_init(); /* blender.c */
376 
377  BKE_idtype_init();
379  BKE_images_init();
385 
388 
390 
391  /* First test for background-mode (#Global.background) */
392 #ifndef WITH_PYTHON_MODULE
393  ba = BLI_args_create(argc, (const char **)argv); /* skip binary path */
394 
395  /* Ensure we free on early exit. */
396  app_init_data.ba = ba;
397 
398  main_args_setup(C, ba);
399 
400  /* Begin argument parsing, ignore leaks so arguments that call #exit
401  * (such as '--version' & '--help') don't report leaks. */
403 
404  /* Parse environment handling arguments. */
406 
407 #else
408  /* Using preferences or user startup makes no sense for #WITH_PYTHON_MODULE. */
409  G.factory_startup = true;
410 #endif
411 
412  /* After parsing #ARG_PASS_ENVIRONMENT such as `--env-*`,
413  * since they impact `BKE_appdir` behavior. */
414  BKE_appdir_init();
415 
416  /* After parsing number of threads argument. */
418 
419  /* Initialize sub-systems that use `BKE_appdir.h`. */
420  IMB_init();
421 
422 #ifndef WITH_PYTHON_MODULE
423  /* First test for background-mode (#Global.background) */
425 
427 #endif
428 
429 #ifdef WITH_FFMPEG
430  /* Keep after #ARG_PASS_SETTINGS since debug flags are checked. */
431  IMB_ffmpeg_init();
432 #endif
433 
434  /* After #ARG_PASS_SETTINGS arguments, this is so #WM_main_playanim skips #RNA_init. */
435  RNA_init();
436 
437  RE_engines_init();
440  /* End second initialization. */
441 
442 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
443  /* Python module mode ALWAYS runs in background-mode (for now). */
444  G.background = true;
445 #else
446  if (G.background) {
448  }
449 #endif
450 
451  /* Background render uses this font too. */
453 
454  /* Initialize FFMPEG if built in, also needed for background-mode if videos are
455  * rendered via FFMPEG. */
457 
459 
460 #ifndef WITH_PYTHON_MODULE
461  if (G.background == 0) {
463  }
465 #endif
466 
467  WM_init(C, argc, (const char **)argv);
468 
469 #ifndef WITH_PYTHON
470  printf(
471  "\n* WARNING * - Blender compiled without Python!\n"
472  "this is not intended for typical usage\n\n");
473 #endif
474 
475  CTX_py_init_set(C, true);
477 
478 #ifdef WITH_FREESTYLE
479  /* Initialize Freestyle. */
480  FRS_init();
482 #endif
483 
484  /* OK we are ready for it */
485 #ifndef WITH_PYTHON_MODULE
486  /* Handles #ARG_PASS_FINAL. */
487  main_args_setup_post(C, ba);
488 #endif
489 
490  /* Explicitly free data allocated for argument parsing:
491  * - 'ba'
492  * - 'argv' on WIN32.
493  */
494  callback_main_atexit(&app_init_data);
496 
497  /* End argument parsing, allow memory leaks to be printed. */
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 #ifndef WITH_PYTHON_MODULE
512  if (G.background) {
513  /* Using window-manager API in background-mode is a bit odd, but works fine. */
514  WM_exit(C);
515  }
516  else {
517  if (!G.file_loaded) {
518  WM_init_splash(C);
519  }
520  WM_main(C);
521  }
522 #endif /* WITH_PYTHON_MODULE */
523 
524  return 0;
525 } /* End of `int main(...)` function. */
526 
527 #ifdef WITH_PYTHON_MODULE
528 void main_python_exit(void)
529 {
530  WM_exit_ex((bContext *)evil_C, true);
531  evil_C = NULL;
532 }
533 #endif
534 
void BKE_appdir_init(void)
Definition: appdir.c:111
void BKE_appdir_program_path_init(const char *argv0)
Definition: appdir.c:873
Blender util stuff.
void BKE_blender_atexit_register(void(*func)(void *user_data), void *user_data)
Definition: blender.c:400
void BKE_blender_atexit_unregister(void(*func)(void *user_data), const void *user_data)
Definition: blender.c:409
void BKE_blender_globals_init(void)
Definition: blender.c:159
void BKE_brush_system_init(void)
Definition: brush.c:420
void BKE_cachefiles_init(void)
Definition: cachefile.c:154
void BKE_callback_global_init(void)
Definition: callbacks.c:83
bContext * CTX_create(void)
Definition: context.c:105
void CTX_py_init_set(bContext *C, bool value)
Definition: context.c:219
void BKE_vfont_builtin_register(void *mem, int size)
Definition: font.c:227
void BKE_gpencil_modifier_init(void)
void BKE_idtype_init(void)
Definition: idtype.c:125
void BKE_images_init(void)
Definition: image.c:431
General operations, lookup, etc. for materials.
void BKE_materials_init(void)
Definition: material.c:1856
void BKE_modifier_init(void)
void BKE_node_system_init(void)
Definition: node.cc:5003
void BKE_particle_init_rng(void)
Definition: particle.c:523
void BKE_shaderfx_init(void)
Definition: shader_fx.c:73
void BKE_sound_init_once(void)
Volume datablock.
void BKE_volumes_init(void)
Definition: volume.cc:496
A general argument parsing module.
void BLI_args_parse(struct bArgs *ba, int pass, BA_ArgCallback default_cb, void *data)
Definition: BLI_args.c:289
void BLI_args_destroy(struct bArgs *ba)
Definition: BLI_args.c:130
struct bArgs * BLI_args_create(int argc, const char **argv)
Definition: BLI_args.c:115
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:116
#define STR_ELEM(...)
Definition: BLI_string.h:218
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
void BLI_system_backtrace(FILE *fp)
Definition: system.c:79
void BLI_task_scheduler_init(void)
void BLI_threadapi_init(void)
Definition: threads.cc:143
void BLI_thread_put_process_on_fast_node(void)
Definition: threads.cc:902
#define STRPREFIX(a, b)
#define UNUSED(x)
#define STREQ(a, b)
#define LIKELY(x)
void CLG_fatal_fn_set(void(*fatal_fn)(void *file_handle))
Definition: clog.c:740
void CLG_init(void)
Definition: clog.c:708
void DEG_register_node_types(void)
blenloader genfile private function prototypes
void DNA_sdna_current_init(void)
Definition: dna_genfile.c:592
char datatoc_bfont_pfb[]
int datatoc_bfont_pfb_size
void FRS_set_context(struct bContext *C)
void FRS_init(void)
int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
void IMB_ffmpeg_init(void)
void IMB_init(void)
Definition: module.c:30
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:39
void CCL_init_logging(const char *argv0)
char build_commit_date[]
Definition: buildinfo.c:49
char build_commit_time[]
Definition: buildinfo.c:50
ulong build_commit_timestamp
Definition: buildinfo.c:48
static void callback_main_atexit(void *user_data)
Definition: creator.c:159
int main(int argc, const char **argv)
Definition: creator.c:224
struct ApplicationState app_state
Definition: creator.c:117
static void main_callback_setup(void)
Definition: creator.c:144
static void callback_mem_error(const char *errorStr)
Definition: creator.c:138
static void callback_clg_fatal(void *fp)
Definition: creator.c:179
void main_args_setup(bContext *C, bArgs *ba)
void main_args_setup_post(bContext *C, bArgs *ba)
void main_signal_setup_background(void)
@ ARG_PASS_ENVIRONMENT
@ ARG_PASS_SETTINGS_FORCE
@ ARG_PASS_SETTINGS_GUI
@ ARG_PASS_SETTINGS
void main_signal_setup(void)
void * user_data
void RE_engines_init(void)
Definition: engine.c:74
void MEM_use_memleak_detection(bool enabled)
void MEM_init_memleak_detection(void)
void libmv_initLogging(const char *argv0)
Definition: logging.cc:36
void MEM_use_guarded_allocator(void)
Definition: mallocn.c:148
void(* MEM_set_error_callback)(void(*func)(const char *))
Definition: mallocn.c:56
void RNA_init(void)
Definition: rna_access.c:75
struct ApplicationState::@1182 signal
Definition: BLI_args.c:61
void RE_texture_rng_init(void)
char * alloc_utf_8_from_16(const wchar_t *in16, size_t add)
Definition: utfconv.c:285
#define G(x, y, z)
void WM_main(bContext *C)
Definition: wm.c:636
void WM_keyconfig_init(bContext *C)
Definition: wm.c:448
void WM_init_splash(bContext *C)
Definition: wm_init_exit.c:398
void WM_exit_ex(bContext *C, const bool do_python)
Definition: wm_init_exit.c:473
void WM_exit(bContext *C)
Main exit function to close Blender ordinarily.
Definition: wm_init_exit.c:679
void WM_init(bContext *C, int argc, const char **argv)
Definition: wm_init_exit.c:225