Blender V4.5
render_update.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10#include <cstring>
11
12#include "DNA_anim_types.h"
13#include "DNA_brush_types.h"
14#include "DNA_cachefile_types.h"
15#include "DNA_light_types.h"
16#include "DNA_material_types.h"
17#include "DNA_node_types.h"
18#include "DNA_object_types.h"
19#include "DNA_scene_types.h"
20#include "DNA_screen_types.h"
21#include "DNA_space_types.h"
22#include "DNA_view3d_types.h"
24#include "DNA_world_types.h"
25
26#include "DRW_engine.hh"
27
28#include "BLI_listbase.h"
29#include "BLI_threads.h"
30
31#include "BKE_brush.hh"
32#include "BKE_context.hh"
33#include "BKE_icons.h"
34#include "BKE_main.hh"
36#include "BKE_material.hh"
37#include "BKE_node_runtime.hh"
38#include "BKE_paint.hh"
39#include "BKE_scene.hh"
40
41#include "NOD_composite.hh"
42
43#include "RE_engine.h"
44#include "RE_pipeline.h"
45
46#include "SEQ_animation.hh"
47#include "SEQ_prefetch.hh"
48#include "SEQ_relations.hh"
49#include "SEQ_sequencer.hh"
50
51#include "ED_node.hh"
52#include "ED_node_preview.hh"
53#include "ED_paint.hh"
54#include "ED_render.hh"
55#include "ED_view3d.hh"
56
57#include "DEG_depsgraph.hh"
59
60#include "WM_api.hh"
61
62/* -------------------------------------------------------------------- */
65
67 wmWindow *window,
68 ScrArea *area,
69 const bool updated)
70{
73
74 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
75 if (region->regiontype != RGN_TYPE_WINDOW) {
76 continue;
77 }
78
79 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
80 RenderEngine *engine = rv3d->view_render ? RE_view_engine_get(rv3d->view_render) : nullptr;
81
82 /* call update if the scene changed, or if the render engine
83 * tagged itself for update (e.g. because it was busy at the
84 * time of the last update) */
85 if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) {
86 /* Create temporary context to execute callback in. */
88 CTX_data_main_set(C, bmain);
89 CTX_data_scene_set(C, scene);
90 CTX_wm_manager_set(C, static_cast<wmWindowManager *>(bmain->wm.first));
91 CTX_wm_window_set(C, window);
93 CTX_wm_area_set(C, area);
94 CTX_wm_region_set(C, region);
95
96 engine->flag &= ~RE_ENGINE_DO_UPDATE;
97 /* NOTE: Important to pass non-updated depsgraph, This is because this function is called
98 * from inside dependency graph evaluation. Additionally, if we pass fully evaluated one
99 * we will lose updates stored in the graph. */
100 engine->type->view_update(engine, C, CTX_data_depsgraph_pointer(C));
101
102 CTX_free(C);
103 }
104 }
105}
106
107void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, const bool updated)
108{
109 Main *bmain = update_ctx->bmain;
110 static bool recursive_check = false;
111
112 /* don't do this render engine update if we're updating the scene from
113 * other threads doing e.g. rendering or baking jobs */
114 if (!BLI_thread_is_main()) {
115 return;
116 }
117
118 /* don't call this recursively for frame updates */
119 if (recursive_check) {
120 return;
121 }
122
123 /* Do not call if no WM available, see #42688. */
124 if (BLI_listbase_is_empty(&bmain->wm)) {
125 return;
126 }
127
128 recursive_check = true;
129
130 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
131 LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
132 bScreen *screen = WM_window_get_active_screen(window);
133
134 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
135 if (area->spacetype == SPACE_VIEW3D) {
136 ED_render_view3d_update(update_ctx->depsgraph, window, area, updated);
137 }
138 }
139 }
140
141 recursive_check = false;
142}
143
145{
146 /* clear all render engines in this area */
147 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
148
149 if (area->spacetype != SPACE_VIEW3D) {
150 return;
151 }
152
153 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
154 if (region->regiontype != RGN_TYPE_WINDOW || !(region->regiondata)) {
155 continue;
156 }
158 }
159}
160
161void ED_render_engine_changed(Main *bmain, const bool update_scene_data)
162{
163 /* on changing the render engine type, clear all running render engines */
164 for (bScreen *screen = static_cast<bScreen *>(bmain->screens.first); screen;
165 screen = static_cast<bScreen *>(screen->id.next))
166 {
167 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
168 ED_render_engine_area_exit(bmain, area);
169 }
170 }
171 /* Stop and invalidate all shader previews. */
172 ED_preview_kill_jobs(static_cast<wmWindowManager *>(bmain->wm.first), bmain);
173 LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
175 }
176 RE_FreePersistentData(nullptr);
177 /* Inform all render engines and draw managers. */
178 DEGEditorUpdateContext update_ctx = {nullptr};
179 update_ctx.bmain = bmain;
180 for (Scene *scene = static_cast<Scene *>(bmain->scenes.first); scene;
181 scene = static_cast<Scene *>(scene->id.next))
182 {
183 update_ctx.scene = scene;
184 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
185 /* TDODO(sergey): Iterate over depsgraphs instead? */
186 update_ctx.depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
187 update_ctx.view_layer = view_layer;
188 ED_render_id_flush_update(&update_ctx, &scene->id);
189 }
190 if (scene->nodetree && update_scene_data) {
191 ntreeCompositUpdateRLayers(scene->nodetree);
192 }
193 }
195
196 /* Update #CacheFiles to ensure that procedurals are properly taken into account. */
197 LISTBASE_FOREACH (CacheFile *, cachefile, &bmain->cachefiles) {
198 /* Only update cache-files which are set to use a render procedural.
199 * We do not use #BKE_cachefile_uses_render_procedural here as we need to update regardless of
200 * the current engine or its settings. */
201 if (cachefile->use_render_procedural) {
203 /* Rebuild relations so that modifiers are reconnected to or disconnected from the
204 * cache-file. */
206 }
207 }
208}
209
211{
212 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
213 ED_render_engine_area_exit(bmain, area);
214 }
215}
216
218
219/* -------------------------------------------------------------------- */
227
228static void material_changed(Main *bmain, Material *ma)
229{
230 /* icons */
232 ED_previews_tag_dirty_by_id(*bmain, ma->id);
233}
234
235static void lamp_changed(Main *bmain, Light *la)
236{
237 /* icons */
239 ED_previews_tag_dirty_by_id(*bmain, la->id);
240}
241
242static void texture_changed(Main *bmain, Tex *tex)
243{
244 Scene *scene;
245
246 /* icons */
248 ED_previews_tag_dirty_by_id(*bmain, tex->id);
249
250 for (scene = static_cast<Scene *>(bmain->scenes.first); scene;
251 scene = static_cast<Scene *>(scene->id.next))
252 {
253 /* paint overlays */
254 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
255 BKE_paint_invalidate_overlay_tex(scene, view_layer, tex);
256 }
257 /* find compositing nodes */
258 if (scene->use_nodes && scene->nodetree) {
259 for (bNode *node : scene->nodetree->all_nodes()) {
260 if (node->id == &tex->id) {
262 }
263 }
264 }
265 }
266
267 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
268 if (ELEM(tex, brush->mtex.tex, brush->mask_mtex.tex)) {
270 }
271 }
272}
273
274static void world_changed(Main *bmain, World *wo)
275{
276 /* icons */
278 ED_previews_tag_dirty_by_id(*bmain, wo->id);
279}
280
281static void image_changed(Main *bmain, Image *ima)
282{
283 Tex *tex;
284
285 /* icons */
287 ED_previews_tag_dirty_by_id(*bmain, ima->id);
288
289 /* textures */
290 for (tex = static_cast<Tex *>(bmain->textures.first); tex;
291 tex = static_cast<Tex *>(tex->id.next))
292 {
293 if (tex->type == TEX_IMAGE && tex->ima == ima) {
294 texture_changed(bmain, tex);
295 }
296 }
297}
298
299static void scene_changed(Main *bmain, Scene *scene)
300{
301 Object *ob;
302
303 /* glsl */
304 for (ob = static_cast<Object *>(bmain->objects.first); ob;
305 ob = static_cast<Object *>(ob->id.next))
306 {
307 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
309 ED_paint_proj_mesh_data_check(*scene, *ob, nullptr, nullptr, nullptr, nullptr);
310 }
311 }
312}
313
314static void update_sequencer(const DEGEditorUpdateContext *update_ctx, Main *bmain, ID *id)
315{
316 if (ELEM(id->recalc,
317 0,
325 {
326 return;
327 }
328 Scene *changed_scene = update_ctx->scene;
329
330 if (GS(id->name) != ID_SCE) {
332 }
333
334 /* Invalidate VSE cache in `changed_scene`, because strip animation may have been updated. */
335 if (GS(id->name) == ID_AC) {
336 Editing *ed = blender::seq::editing_get(changed_scene);
337 if (ed != nullptr && blender::seq::animation_keyframes_exist(changed_scene) &&
338 &changed_scene->adt->action->id == id)
339 {
340 blender::seq::prefetch_stop(changed_scene);
343 }
344 }
345}
346
348{
349 /* this can be called from render or baking thread when a python script makes
350 * changes, in that case we don't want to do any editor updates, and making
351 * GPU changes is not possible because OpenGL only works in the main thread */
352 if (!BLI_thread_is_main()) {
353 return;
354 }
355 Main *bmain = update_ctx->bmain;
356 /* Internal ID update handlers. */
357 switch (GS(id->name)) {
358 case ID_MA:
359 material_changed(bmain, (Material *)id);
360 break;
361 case ID_TE:
362 texture_changed(bmain, (Tex *)id);
363 break;
364 case ID_WO:
365 world_changed(bmain, (World *)id);
366 break;
367 case ID_LA:
368 lamp_changed(bmain, (Light *)id);
369 break;
370 case ID_IM:
371 image_changed(bmain, (Image *)id);
372 break;
373 case ID_SCE:
374 scene_changed(bmain, (Scene *)id);
375 break;
376 case ID_BR:
377 BKE_brush_tag_unsaved_changes(reinterpret_cast<Brush *>(id));
378 break;
379 default:
380 break;
381 }
382
383 update_sequencer(update_ctx, bmain, id);
384}
385
void BKE_brush_tag_unsaved_changes(Brush *brush)
Definition brush.cc:720
void CTX_data_main_set(bContext *C, Main *bmain)
void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
void CTX_free(bContext *C)
void CTX_wm_screen_set(bContext *C, bScreen *screen)
void CTX_data_scene_set(bContext *C, Scene *scene)
void CTX_wm_window_set(bContext *C, wmWindow *win)
void CTX_wm_area_set(bContext *C, ScrArea *area)
void CTX_wm_region_set(bContext *C, ARegion *region)
bContext * CTX_create()
void BKE_icon_changed(int icon_id)
Definition icons.cc:204
int BKE_icon_id_ensure(struct ID *id)
Definition icons.cc:267
void BKE_main_ensure_invariants(Main &bmain, std::optional< blender::Span< ID * > > modified_ids=std::nullopt)
General operations, lookup, etc. for materials.
void BKE_texpaint_slots_refresh_object(Scene *scene, Object *ob)
void BKE_material_make_node_previews_dirty(Material *ma)
void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const Tex *tex)
Definition paint.cc:250
Depsgraph * BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3427
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
int BLI_thread_is_main(void)
Definition threads.cc:179
#define ELEM(...)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
Main * DEG_get_bmain(const Depsgraph *graph)
Scene * DEG_get_input_scene(const Depsgraph *graph)
@ ID_RECALC_AUDIO_FPS
Definition DNA_ID.h:1035
@ ID_RECALC_AUDIO_LISTENER
Definition DNA_ID.h:1038
@ ID_RECALC_FRAME_CHANGE
Definition DNA_ID.h:1033
@ ID_RECALC_AUDIO
Definition DNA_ID.h:1040
@ ID_RECALC_SELECT
Definition DNA_ID.h:1009
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1026
@ ID_RECALC_AUDIO_MUTE
Definition DNA_ID.h:1037
@ ID_RECALC_AUDIO_VOLUME
Definition DNA_ID.h:1036
@ ID_TE
@ ID_IM
@ ID_LA
@ ID_SCE
@ ID_BR
@ ID_WO
@ ID_MA
@ ID_AC
@ OB_MODE_TEXTURE_PAINT
Object is a sort of wrapper for general info.
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
@ TEX_IMAGE
bool ED_paint_proj_mesh_data_check(Scene &scene, Object &ob, bool *r_has_uvs, bool *r_has_mat, bool *r_has_tex, bool *r_has_stencil)
void ED_preview_kill_jobs(wmWindowManager *wm, Main *bmain)
void ED_previews_tag_dirty_by_id(const Main &bmain, const ID &id)
void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *region)
@ RE_ENGINE_DO_UPDATE
Definition RE_engine.h:62
#define C
Definition RandGen.cpp:29
BPy_StructRNA * depsgraph
#define GS(a)
RenderEngine * RE_view_engine_get(const ViewRender *view_render)
void tag_update_id(ID *id)
Definition node_draw.cc:194
void prefetch_stop(Scene *scene)
Definition prefetch.cc:283
void cache_cleanup_final(Scene *scene)
void relations_invalidate_scene_strips(const Main *bmain, const Scene *scene_target)
bool animation_keyframes_exist(const Scene *scene)
Definition animation.cc:25
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:272
void cache_cleanup_intra(Scene *scene)
void ntreeCompositUpdateRLayers(bNodeTree *ntree)
static void material_changed(Main *bmain, Material *ma)
static void texture_changed(Main *bmain, Tex *tex)
static void scene_changed(Main *bmain, Scene *scene)
static void lamp_changed(Main *bmain, Light *la)
void ED_render_engine_area_exit(Main *bmain, ScrArea *area)
void ED_render_view3d_update(Depsgraph *depsgraph, wmWindow *window, ScrArea *area, const bool updated)
void ED_render_id_flush_update(const DEGEditorUpdateContext *update_ctx, ID *id)
static void world_changed(Main *bmain, World *wo)
void ED_render_view_layer_changed(Main *bmain, bScreen *screen)
void ED_render_engine_changed(Main *bmain, const bool update_scene_data)
static void update_sequencer(const DEGEditorUpdateContext *update_ctx, Main *bmain, ID *id)
static void image_changed(Main *bmain, Image *ima)
void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, const bool updated)
void RE_FreePersistentData(const Scene *scene)
bAction * action
Definition DNA_ID.h:404
unsigned int recalc
Definition DNA_ID.h:427
void * next
Definition DNA_ID.h:407
char name[66]
Definition DNA_ID.h:415
void * first
ListBase brushes
Definition BKE_main.hh:271
ListBase scenes
Definition BKE_main.hh:245
ListBase wm
Definition BKE_main.hh:276
ListBase textures
Definition BKE_main.hh:252
ListBase materials
Definition BKE_main.hh:251
ListBase screens
Definition BKE_main.hh:261
ListBase objects
Definition BKE_main.hh:247
ListBase cachefiles
Definition BKE_main.hh:283
struct ViewRender * view_render
void(* view_update)(struct RenderEngine *engine, const struct bContext *context, struct Depsgraph *depsgraph)
Definition RE_engine.h:101
RenderEngineType * type
Definition RE_engine.h:131
struct bNodeTree * nodetree
ListBase view_layers
struct AnimData * adt
ListBase regionbase
struct Image * ima
ListBase areabase
bScreen * WM_window_get_active_screen(const wmWindow *win)