Changeset View
Changeset View
Standalone View
Standalone View
source/blender/render/intern/source/pipeline.c
| Show All 15 Lines | |||||
| * The Original Code is Copyright (C) 2006 Blender Foundation. | * The Original Code is Copyright (C) 2006 Blender Foundation. | ||||
| * All rights reserved. | * All rights reserved. | ||||
| */ | */ | ||||
| /** \file | /** \file | ||||
| * \ingroup render | * \ingroup render | ||||
| */ | */ | ||||
| #include <CLG_log.h> | |||||
| #include <errno.h> | #include <errno.h> | ||||
| #include <limits.h> | #include <limits.h> | ||||
| #include <math.h> | #include <math.h> | ||||
| #include <stddef.h> | #include <stddef.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| #include "DNA_anim_types.h" | #include "DNA_anim_types.h" | ||||
| ▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | |||||
| * - also read external files etc | * - also read external files etc | ||||
| * | * | ||||
| * 5) Image Files | * 5) Image Files | ||||
| * - save file or append in movie | * - save file or append in movie | ||||
| */ | */ | ||||
| /* ********* globals ******** */ | /* ********* globals ******** */ | ||||
| CLG_LOGREF_DECLARE_GLOBAL(RENDER_LOG, "render"); | |||||
| /* here we store all renders */ | /* here we store all renders */ | ||||
| static struct { | static struct { | ||||
| ListBase renderlist; | ListBase renderlist; | ||||
| } RenderGlobal = {{NULL, NULL}}; | } RenderGlobal = {{NULL, NULL}}; | ||||
| /* ********* callbacks ******** */ | /* ********* callbacks ******** */ | ||||
| static void render_callback_exec_null(Render *re, Main *bmain, eCbEvent evt) | static void render_callback_exec_null(Render *re, Main *bmain, eCbEvent evt) | ||||
| Show All 39 Lines | |||||
| static void float_nothing(void *UNUSED(arg), float UNUSED(val)) | static void float_nothing(void *UNUSED(arg), float UNUSED(val)) | ||||
| { | { | ||||
| } | } | ||||
| static int default_break(void *UNUSED(arg)) | static int default_break(void *UNUSED(arg)) | ||||
| { | { | ||||
| return G.is_break == true; | return G.is_break == true; | ||||
| } | } | ||||
| static void stats_background(void *UNUSED(arg), RenderStats *rs) | |||||
| { | |||||
| uintptr_t mem_in_use, peak_memory; | |||||
| float megs_used_memory, megs_peak_memory; | |||||
| char info_time_str[32]; | |||||
| mem_in_use = MEM_get_memory_in_use(); | |||||
| peak_memory = MEM_get_peak_memory(); | |||||
| megs_used_memory = (mem_in_use) / (1024.0 * 1024.0); | |||||
| megs_peak_memory = (peak_memory) / (1024.0 * 1024.0); | |||||
| fprintf(stdout, | |||||
| TIP_("Fra:%d Mem:%.2fM (Peak %.2fM) "), | |||||
| rs->cfra, | |||||
| megs_used_memory, | |||||
| megs_peak_memory); | |||||
| BLI_timecode_string_from_time_simple( | |||||
| info_time_str, sizeof(info_time_str), PIL_check_seconds_timer() - rs->starttime); | |||||
| fprintf(stdout, TIP_("| Time:%s | "), info_time_str); | |||||
| if (rs->infostr) { | |||||
| fprintf(stdout, "%s", rs->infostr); | |||||
| } | |||||
| else { | |||||
| fprintf(stdout, | |||||
| TIP_("Sce: %s Ve:%d Fa:%d La:%d"), | |||||
| rs->scene_name, | |||||
| rs->totvert, | |||||
| rs->totface, | |||||
| rs->totlamp); | |||||
| } | |||||
| /* Flush stdout to be sure python callbacks are printing stuff after blender. */ | |||||
| fflush(stdout); | |||||
| /* NOTE: using G_MAIN seems valid here??? | |||||
| * Not sure it's actually even used anyway, we could as well pass NULL? */ | |||||
| BKE_callback_exec_null(G_MAIN, BKE_CB_EVT_RENDER_STATS); | |||||
| fputc('\n', stdout); | |||||
| fflush(stdout); | |||||
| } | |||||
| static void render_print_save_message(ReportList *reports, const char *name, int ok, int err) | static void render_print_save_message(ReportList *reports, const char *name, int ok, int err) | ||||
| { | { | ||||
| if (ok) { | if (ok) { | ||||
| /* no need to report, just some helpful console info */ | /* no need to report, just some helpful console info */ | ||||
| printf("Saved: '%s'\n", name); | CLOG_INFO(RENDER_LOG, "Saved: '%s'", name); | ||||
| } | } | ||||
| else { | else { | ||||
| /* report on error since users will want to know what failed */ | /* report on error since users will want to know what failed */ | ||||
| BKE_reportf(reports, RPT_ERROR, "Render error (%s) cannot save: '%s'", strerror(err), name); | BKE_reportf(reports, RPT_ERROR, "Render error (%s) cannot save: '%s'", strerror(err), name); | ||||
| } | } | ||||
| } | } | ||||
| static int render_imbuf_write_stamp_test(ReportList *reports, | static int render_imbuf_write_stamp_test(ReportList *reports, | ||||
| ▲ Show 20 Lines • Show All 365 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| /* set default empty callbacks */ | /* set default empty callbacks */ | ||||
| re->display_init = result_nothing; | re->display_init = result_nothing; | ||||
| re->display_clear = result_nothing; | re->display_clear = result_nothing; | ||||
| re->display_update = result_rcti_nothing; | re->display_update = result_rcti_nothing; | ||||
| re->current_scene_update = current_scene_nothing; | re->current_scene_update = current_scene_nothing; | ||||
| re->progress = float_nothing; | re->progress = float_nothing; | ||||
| re->test_break = default_break; | re->test_break = default_break; | ||||
| if (G.background) { | |||||
| re->stats_draw = stats_background; | |||||
| } | |||||
| else { | |||||
| re->stats_draw = stats_nothing; | re->stats_draw = stats_nothing; | ||||
| } | |||||
| /* clear callback handles */ | /* clear callback handles */ | ||||
| re->dih = re->dch = re->duh = re->sdh = re->prh = re->tbh = NULL; | re->dih = re->dch = re->duh = re->sdh = re->prh = re->tbh = NULL; | ||||
| } | } | ||||
| /* only call this while you know it will remove the link too */ | /* only call this while you know it will remove the link too */ | ||||
| void RE_FreeRender(Render *re) | void RE_FreeRender(Render *re) | ||||
| { | { | ||||
| if (re->engine) { | if (re->engine) { | ||||
| ▲ Show 20 Lines • Show All 1,377 Lines • ▼ Show 20 Lines | if (render_init_from_main(re, &scene->r, bmain, scene, single_layer, camera_override, 0, 0)) { | ||||
| render_init_depsgraph(re); | render_init_depsgraph(re); | ||||
| do_render_all_options(re); | do_render_all_options(re); | ||||
| if (write_still && !G.is_break) { | if (write_still && !G.is_break) { | ||||
| if (BKE_imtype_is_movie(rd.im_format.imtype)) { | if (BKE_imtype_is_movie(rd.im_format.imtype)) { | ||||
| /* operator checks this but in case its called from elsewhere */ | /* operator checks this but in case its called from elsewhere */ | ||||
| printf("Error: cant write single images with a movie format!\n"); | CLOG_ERROR(RENDER_LOG, "Can not write single images with a movie format!"); | ||||
| } | } | ||||
| else { | else { | ||||
| char name[FILE_MAX]; | char name[FILE_MAX]; | ||||
| BKE_image_path_from_imformat(name, | BKE_image_path_from_imformat(name, | ||||
| rd.pic, | rd.pic, | ||||
| BKE_main_blendfile_path(bmain), | BKE_main_blendfile_path(bmain), | ||||
| scene->r.cfra, | scene->r.cfra, | ||||
| &rd.im_format, | &rd.im_format, | ||||
| ▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | for (view_id = 0, rv = rr->views.first; rv; rv = rv->next, view_id++) { | ||||
| IMB_freeImBuf(ibuf); | IMB_freeImBuf(ibuf); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { /* R_IMF_VIEWS_STEREO_3D */ | else { /* R_IMF_VIEWS_STEREO_3D */ | ||||
| BLI_assert(scene->r.im_format.views_format == R_IMF_VIEWS_STEREO_3D); | BLI_assert(scene->r.im_format.views_format == R_IMF_VIEWS_STEREO_3D); | ||||
| if (rd->im_format.imtype == R_IMF_IMTYPE_MULTILAYER) { | if (rd->im_format.imtype == R_IMF_IMTYPE_MULTILAYER) { | ||||
| printf("Stereo 3D not supported for MultiLayer image: %s\n", name); | /* TODO (grzelins) sounds like report, not log */ | ||||
| CLOG_ERROR(RENDER_LOG, "Stereo 3D not supported for MultiLayer image: %s", name); | |||||
| } | } | ||||
| else { | else { | ||||
| ImBuf *ibuf_arr[3] = {NULL}; | ImBuf *ibuf_arr[3] = {NULL}; | ||||
| const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; | const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; | ||||
| int i; | int i; | ||||
| for (i = 0; i < 2; i++) { | for (i = 0; i < 2; i++) { | ||||
| int view_id = BLI_findstringindex(&rr->views, names[i], offsetof(RenderView, name)); | int view_id = BLI_findstringindex(&rr->views, names[i], offsetof(RenderView, name)); | ||||
| ▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | for (view_id = 0; view_id < totvideos; view_id++) { | ||||
| ibuf->x, | ibuf->x, | ||||
| ibuf->y, | ibuf->y, | ||||
| suffix, | suffix, | ||||
| reports); | reports); | ||||
| /* imbuf knows which rects are not part of ibuf */ | /* imbuf knows which rects are not part of ibuf */ | ||||
| IMB_freeImBuf(ibuf); | IMB_freeImBuf(ibuf); | ||||
| } | } | ||||
| printf("Append frame %d\n", scene->r.cfra); | CLOG_VERBOSE(RENDER_LOG, 1, "Append frame %d", scene->r.cfra); | ||||
| } | } | ||||
| else { /* R_IMF_VIEWS_STEREO_3D */ | else { /* R_IMF_VIEWS_STEREO_3D */ | ||||
| const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; | const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; | ||||
| ImBuf *ibuf_arr[3] = {NULL}; | ImBuf *ibuf_arr[3] = {NULL}; | ||||
| int i; | int i; | ||||
| BLI_assert((totvideos == 1) && (scene->r.im_format.views_format == R_IMF_VIEWS_STEREO_3D)); | BLI_assert((totvideos == 1) && (scene->r.im_format.views_format == R_IMF_VIEWS_STEREO_3D)); | ||||
| Show All 34 Lines | static int do_write_image_or_movie(Render *re, | ||||
| Main *bmain, | Main *bmain, | ||||
| Scene *scene, | Scene *scene, | ||||
| bMovieHandle *mh, | bMovieHandle *mh, | ||||
| const int totvideos, | const int totvideos, | ||||
| const char *name_override) | const char *name_override) | ||||
| { | { | ||||
| char name[FILE_MAX]; | char name[FILE_MAX]; | ||||
| RenderResult rres; | RenderResult rres; | ||||
| double render_time; | |||||
| bool ok = true; | bool ok = true; | ||||
| RE_AcquireResultImageViews(re, &rres); | RE_AcquireResultImageViews(re, &rres); | ||||
| re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime; | |||||
| if (CLOG_CHECK_IN_USE(RENDER_LOG)) { | |||||
| BLI_timecode_string_from_time_simple(name, sizeof(name), re->i.lastframetime); | |||||
| CLOG_INFO(RENDER_LOG, "Render time: %s", name); | |||||
| /* Flush stdout to be sure python callbacks are printing stuff after blender. */ | |||||
| fflush(stdout); | |||||
| } | |||||
| /* write movie or image */ | /* write movie or image */ | ||||
| if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { | if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { | ||||
| RE_WriteRenderViewsMovie( | RE_WriteRenderViewsMovie( | ||||
| re->reports, &rres, scene, &re->r, mh, re->movie_ctx_arr, totvideos, false); | re->reports, &rres, scene, &re->r, mh, re->movie_ctx_arr, totvideos, false); | ||||
| } | } | ||||
| else { | else { | ||||
| if (name_override) { | if (name_override) { | ||||
| BLI_strncpy(name, name_override, sizeof(name)); | BLI_strncpy(name, name_override, sizeof(name)); | ||||
| Show All 10 Lines | else { | ||||
| } | } | ||||
| /* write images as individual images or stereo */ | /* write images as individual images or stereo */ | ||||
| ok = RE_WriteRenderViewsImage(re->reports, &rres, scene, true, name); | ok = RE_WriteRenderViewsImage(re->reports, &rres, scene, true, name); | ||||
| } | } | ||||
| RE_ReleaseResultImageViews(re, &rres); | RE_ReleaseResultImageViews(re, &rres); | ||||
| render_time = re->i.lastframetime; | |||||
| re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime; | |||||
| BLI_timecode_string_from_time_simple(name, sizeof(name), re->i.lastframetime); | |||||
| printf(" Time: %s", name); | |||||
| /* Flush stdout to be sure python callbacks are printing stuff after blender. */ | |||||
| fflush(stdout); | |||||
| /* NOTE: using G_MAIN seems valid here??? | /* NOTE: using G_MAIN seems valid here??? | ||||
| * Not sure it's actually even used anyway, we could as well pass NULL? */ | * Not sure it's actually even used anyway, we could as well pass NULL? */ | ||||
| render_callback_exec_null(re, G_MAIN, BKE_CB_EVT_RENDER_STATS); | render_callback_exec_null(re, G_MAIN, BKE_CB_EVT_RENDER_STATS); | ||||
| BLI_timecode_string_from_time_simple(name, sizeof(name), re->i.lastframetime - render_time); | if (CLOG_CHECK_IN_USE(RENDER_LOG)) { | ||||
| printf(" (Saving: %s)\n", name); | BLI_timecode_string_from_time_simple( | ||||
| name, sizeof(name), PIL_check_seconds_timer() - re->i.starttime - re->i.lastframetime); | |||||
| if (ok) { | |||||
| CLOG_INFO(RENDER_LOG, "Saving time: %s", name); | |||||
| } | |||||
| else { | |||||
| CLOG_STR_ERROR(RENDER_LOG, "Saving failed"); | |||||
| } | |||||
| fputc('\n', stdout); | /* TODO (grzelins) needed or not needed? say hello to CLOG */ | ||||
| fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */ | fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */ | ||||
| } | |||||
| return ok; | return ok; | ||||
| } | } | ||||
| static void get_videos_dimensions(const Render *re, | static void get_videos_dimensions(const Render *re, | ||||
| const RenderData *rd, | const RenderData *rd, | ||||
| size_t *r_width, | size_t *r_width, | ||||
| size_t *r_height) | size_t *r_height) | ||||
| ▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | for (nfra = sfra, scene->r.cfra = sfra; scene->r.cfra <= efra; scene->r.cfra++) { | ||||
| (rd.scemode & R_EXTENSION) != 0, | (rd.scemode & R_EXTENSION) != 0, | ||||
| true, | true, | ||||
| NULL); | NULL); | ||||
| } | } | ||||
| if (rd.mode & R_NO_OVERWRITE) { | if (rd.mode & R_NO_OVERWRITE) { | ||||
| if (!is_multiview_name) { | if (!is_multiview_name) { | ||||
| if (BLI_exists(name)) { | if (BLI_exists(name)) { | ||||
| printf("skipping existing frame \"%s\"\n", name); | CLOG_INFO(RENDER_LOG, "skipping existing frame \"%s\"", name); | ||||
| totskipped++; | totskipped++; | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| SceneRenderView *srv; | SceneRenderView *srv; | ||||
| bool is_skip = false; | bool is_skip = false; | ||||
| char filepath[FILE_MAX]; | char filepath[FILE_MAX]; | ||||
| for (srv = scene->r.views.first; srv; srv = srv->next) { | for (srv = scene->r.views.first; srv; srv = srv->next) { | ||||
| if (!BKE_scene_multiview_is_render_view_active(&scene->r, srv)) { | if (!BKE_scene_multiview_is_render_view_active(&scene->r, srv)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| BKE_scene_multiview_filepath_get(srv, name, filepath); | BKE_scene_multiview_filepath_get(srv, name, filepath); | ||||
| if (BLI_exists(filepath)) { | if (BLI_exists(filepath)) { | ||||
| is_skip = true; | is_skip = true; | ||||
| printf("skipping existing frame \"%s\" for view \"%s\"\n", filepath, srv->name); | CLOG_INFO(RENDER_LOG, | ||||
| "skipping existing frame \"%s\" for view \"%s\"", | |||||
| filepath, | |||||
| srv->name); | |||||
| } | } | ||||
| } | } | ||||
| if (is_skip) { | if (is_skip) { | ||||
| totskipped++; | totskipped++; | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 207 Lines • ▼ Show 20 Lines | void RE_layer_load_from_file( | ||||
| /* multiview: since the API takes no 'view', we use the first combined pass found */ | /* multiview: since the API takes no 'view', we use the first combined pass found */ | ||||
| for (rpass = layer->passes.first; rpass; rpass = rpass->next) { | for (rpass = layer->passes.first; rpass; rpass = rpass->next) { | ||||
| if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) { | if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (rpass == NULL) { | if (rpass == NULL) { | ||||
| /* TODO (grzelins) this looks like log wrapped in report. Convert to log? similar issues below */ | |||||
| BKE_reportf(reports, | BKE_reportf(reports, | ||||
| RPT_ERROR, | RPT_ERROR, | ||||
| "%s: no Combined pass found in the render layer '%s'", | "%s: no Combined pass found in the render layer '%s'", | ||||
| __func__, | __func__, | ||||
| filename); | filename); | ||||
| } | } | ||||
| if (ibuf && (ibuf->rect || ibuf->rect_float)) { | if (ibuf && (ibuf->rect || ibuf->rect_float)) { | ||||
| ▲ Show 20 Lines • Show All 160 Lines • Show Last 20 Lines | |||||