Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/render/render_internal.c
| Show First 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | |||||
| #include "IMB_colormanagement.h" | #include "IMB_colormanagement.h" | ||||
| #include "IMB_imbuf_types.h" | #include "IMB_imbuf_types.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RNA_define.h" | #include "RNA_define.h" | ||||
| #include "BLO_undofile.h" | #include "BLO_undofile.h" | ||||
| #include "GPU_extensions.h" | |||||
| #include "render_intern.h" | #include "render_intern.h" | ||||
| /* Render Callbacks */ | /* Render Callbacks */ | ||||
| static int render_break(void *rjv); | static int render_break(void *rjv); | ||||
| typedef struct RenderJob { | typedef struct RenderJob { | ||||
| Main *main; | Main *main; | ||||
| Scene *scene; | Scene *scene; | ||||
| ▲ Show 20 Lines • Show All 788 Lines • ▼ Show 20 Lines | static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| RenderEngineType *re_type = RE_engines_find(scene->r.engine); | RenderEngineType *re_type = RE_engines_find(scene->r.engine); | ||||
| Render *re; | Render *re; | ||||
| wmJob *wm_job; | wmJob *wm_job; | ||||
| RenderJob *rj; | RenderJob *rj; | ||||
| Image *ima; | Image *ima; | ||||
| const bool is_animation = RNA_boolean_get(op->ptr, "animation"); | const bool is_animation = RNA_boolean_get(op->ptr, "animation"); | ||||
| const bool is_write_still = RNA_boolean_get(op->ptr, "write_still"); | const bool is_write_still = RNA_boolean_get(op->ptr, "write_still"); | ||||
| const bool use_viewport = RNA_boolean_get(op->ptr, "use_viewport"); | const bool use_viewport = RNA_boolean_get(op->ptr, "use_viewport"); | ||||
| /* Do not render inside a job when GPU Context is needed, but GPU has to run on the main | |||||
| * thread. */ | |||||
| const bool use_wm_job = !((re_type->flag & RE_USE_GPU_CONTEXT) && | |||||
| (GPU_main_thread_workaround())); | |||||
| View3D *v3d = use_viewport ? CTX_wm_view3d(C) : NULL; | View3D *v3d = use_viewport ? CTX_wm_view3d(C) : NULL; | ||||
| struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL; | struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL; | ||||
| const char *name; | const char *name; | ||||
| ScrArea *area; | ScrArea *area; | ||||
| /* Cannot do render if there is not this function. */ | /* Cannot do render if there is not this function. */ | ||||
| if (re_type->render == NULL) { | if (re_type->render == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| ▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| /* setup job */ | /* setup job */ | ||||
| if (RE_seq_render_active(scene, &scene->r)) { | if (RE_seq_render_active(scene, &scene->r)) { | ||||
| name = "Sequence Render"; | name = "Sequence Render"; | ||||
| } | } | ||||
| else { | else { | ||||
| name = "Render"; | name = "Render"; | ||||
| } | } | ||||
| /* get a render result image, and make sure it is empty */ | |||||
| ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result"); | |||||
| BKE_image_signal(rj->main, ima, NULL, IMA_SIGNAL_FREE); | |||||
| BKE_image_backup_render(rj->scene, ima, true); | |||||
| rj->image = ima; | |||||
| re = RE_NewSceneRender(scene); | |||||
| RE_test_break_cb(re, rj, render_breakjob); | |||||
| RE_draw_lock_cb(re, rj, render_drawlock); | |||||
| RE_display_update_cb(re, rj, image_rect_update); | |||||
| RE_current_scene_update_cb(re, rj, current_scene_update); | |||||
| RE_stats_draw_cb(re, rj, image_renderinfo_cb); | |||||
| RE_progress_cb(re, rj, render_progress_update); | |||||
| rj->re = re; | |||||
| /* setup new render */ | |||||
| if (use_wm_job) { | |||||
| wm_job = WM_jobs_get(CTX_wm_manager(C), | wm_job = WM_jobs_get(CTX_wm_manager(C), | ||||
| CTX_wm_window(C), | CTX_wm_window(C), | ||||
| scene, | scene, | ||||
| name, | name, | ||||
| WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, | WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, | ||||
| WM_JOB_TYPE_RENDER); | WM_JOB_TYPE_RENDER); | ||||
| WM_jobs_customdata_set(wm_job, rj, render_freejob); | WM_jobs_customdata_set(wm_job, rj, render_freejob); | ||||
| WM_jobs_timer(wm_job, 0.2, NC_SCENE | ND_RENDER_RESULT, 0); | WM_jobs_timer(wm_job, 0.2, NC_SCENE | ND_RENDER_RESULT, 0); | ||||
| WM_jobs_callbacks(wm_job, render_startjob, NULL, NULL, render_endjob); | WM_jobs_callbacks(wm_job, render_startjob, NULL, NULL, render_endjob); | ||||
| if (RNA_struct_property_is_set(op->ptr, "layer")) { | if (RNA_struct_property_is_set(op->ptr, "layer")) { | ||||
| WM_jobs_delay_start(wm_job, 0.2); | WM_jobs_delay_start(wm_job, 0.2); | ||||
| } | } | ||||
| /* get a render result image, and make sure it is empty */ | |||||
| ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result"); | |||||
| BKE_image_signal(rj->main, ima, NULL, IMA_SIGNAL_FREE); | |||||
| BKE_image_backup_render(rj->scene, ima, true); | |||||
| rj->image = ima; | |||||
| /* setup new render */ | |||||
| re = RE_NewSceneRender(scene); | |||||
| RE_test_break_cb(re, rj, render_breakjob); | |||||
| RE_draw_lock_cb(re, rj, render_drawlock); | |||||
| RE_display_update_cb(re, rj, image_rect_update); | |||||
| RE_current_scene_update_cb(re, rj, current_scene_update); | |||||
| RE_stats_draw_cb(re, rj, image_renderinfo_cb); | |||||
| RE_progress_cb(re, rj, render_progress_update); | |||||
| RE_gl_context_create(re); | RE_gl_context_create(re); | ||||
| rj->re = re; | |||||
| G.is_break = false; | G.is_break = false; | ||||
| /* store actual owner of job, so modal operator could check for it, | /* store actual owner of job, so modal operator could check for it, | ||||
| * the reason of this is that active scene could change when rendering | * the reason of this is that active scene could change when rendering | ||||
| * several layers from compositor [#31800] | * several layers from compositor [#31800] | ||||
| */ | */ | ||||
| op->customdata = scene; | op->customdata = scene; | ||||
| WM_jobs_start(CTX_wm_manager(C), wm_job); | WM_jobs_start(CTX_wm_manager(C), wm_job); | ||||
| WM_cursor_wait(0); | WM_cursor_wait(0); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); | WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); | ||||
| /* we set G.is_rendering here already instead of only in the job, this ensure | /* we set G.is_rendering here already instead of only in the job, this ensure | ||||
| * main loop or other scene updates are disabled in time, since they may | * main loop or other scene updates are disabled in time, since they may | ||||
| * have started before the job thread */ | * have started before the job thread */ | ||||
| G.is_rendering = true; | G.is_rendering = true; | ||||
| /* add modal handler for ESC */ | /* add modal handler for ESC */ | ||||
| WM_event_add_modal_handler(C, op); | WM_event_add_modal_handler(C, op); | ||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| else { | |||||
| short stop = 0; | |||||
| short do_update = 0; | |||||
| float progress = 0.0f; | |||||
| render_startjob(rj, &stop, &do_update, &progress); | |||||
| render_endjob(rj); | |||||
| render_freejob(rj); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| } | |||||
| /* contextual render, using current scene, view3d? */ | /* contextual render, using current scene, view3d? */ | ||||
| void RENDER_OT_render(wmOperatorType *ot) | void RENDER_OT_render(wmOperatorType *ot) | ||||
| { | { | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "Render"; | ot->name = "Render"; | ||||
| ▲ Show 20 Lines • Show All 110 Lines • Show Last 20 Lines | |||||