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_brush_types.h"
13#include "DNA_cachefile_types.h"
14#include "DNA_light_types.h"
15#include "DNA_material_types.h"
16#include "DNA_node_types.h"
17#include "DNA_object_types.h"
18#include "DNA_scene_types.h"
19#include "DNA_screen_types.h"
20#include "DNA_space_types.h"
21#include "DNA_view3d_types.h"
23#include "DNA_world_types.h"
24
25#include "DRW_engine.hh"
26
27#include "BLI_listbase.h"
28#include "BLI_threads.h"
29
30#include "BKE_brush.hh"
31#include "BKE_context.hh"
32#include "BKE_icons.h"
33#include "BKE_main.hh"
35#include "BKE_material.hh"
36#include "BKE_node_runtime.hh"
37#include "BKE_paint.hh"
38#include "BKE_scene.hh"
39
40#include "NOD_composite.hh"
41
42#include "RE_engine.h"
43#include "RE_pipeline.h"
44
45#include "SEQ_relations.hh"
46
47#include "ED_node.hh"
48#include "ED_node_preview.hh"
49#include "ED_paint.hh"
50#include "ED_render.hh"
51#include "ED_view3d.hh"
52
53#include "DEG_depsgraph.hh"
55
56#include "WM_api.hh"
57
58/* -------------------------------------------------------------------- */
61
63 wmWindow *window,
64 ScrArea *area,
65 const bool updated)
66{
69
70 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
71 if (region->regiontype != RGN_TYPE_WINDOW) {
72 continue;
73 }
74
75 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
76 RenderEngine *engine = rv3d->view_render ? RE_view_engine_get(rv3d->view_render) : nullptr;
77
78 /* call update if the scene changed, or if the render engine
79 * tagged itself for update (e.g. because it was busy at the
80 * time of the last update) */
81 if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) {
82 /* Create temporary context to execute callback in. */
84 CTX_data_main_set(C, bmain);
85 CTX_data_scene_set(C, scene);
86 CTX_wm_manager_set(C, static_cast<wmWindowManager *>(bmain->wm.first));
87 CTX_wm_window_set(C, window);
89 CTX_wm_area_set(C, area);
90 CTX_wm_region_set(C, region);
91
92 engine->flag &= ~RE_ENGINE_DO_UPDATE;
93 /* NOTE: Important to pass non-updated depsgraph, This is because this function is called
94 * from inside dependency graph evaluation. Additionally, if we pass fully evaluated one
95 * we will lose updates stored in the graph. */
96 engine->type->view_update(engine, C, CTX_data_depsgraph_pointer(C));
97
98 CTX_free(C);
99 }
100 }
101}
102
103void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, const bool updated)
104{
105 Main *bmain = update_ctx->bmain;
106 static bool recursive_check = false;
107
108 /* don't do this render engine update if we're updating the scene from
109 * other threads doing e.g. rendering or baking jobs */
110 if (!BLI_thread_is_main()) {
111 return;
112 }
113
114 /* don't call this recursively for frame updates */
115 if (recursive_check) {
116 return;
117 }
118
119 /* Do not call if no WM available, see #42688. */
120 if (BLI_listbase_is_empty(&bmain->wm)) {
121 return;
122 }
123
124 recursive_check = true;
125
126 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
127 LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
128 bScreen *screen = WM_window_get_active_screen(window);
129
130 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
131 if (area->spacetype == SPACE_VIEW3D) {
132 ED_render_view3d_update(update_ctx->depsgraph, window, area, updated);
133 }
134 }
135 }
136
137 recursive_check = false;
138}
139
141{
142 /* clear all render engines in this area */
143 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
144
145 if (area->spacetype != SPACE_VIEW3D) {
146 return;
147 }
148
149 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
150 if (region->regiontype != RGN_TYPE_WINDOW || !(region->regiondata)) {
151 continue;
152 }
154 }
155}
156
157void ED_render_engine_changed(Main *bmain, const bool update_scene_data)
158{
159 /* on changing the render engine type, clear all running render engines */
160 for (bScreen *screen = static_cast<bScreen *>(bmain->screens.first); screen;
161 screen = static_cast<bScreen *>(screen->id.next))
162 {
163 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
164 ED_render_engine_area_exit(bmain, area);
165 }
166 }
167 /* Stop and invalidate all shader previews. */
168 ED_preview_kill_jobs(static_cast<wmWindowManager *>(bmain->wm.first), bmain);
169 LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
171 }
172 RE_FreePersistentData(nullptr);
173 /* Inform all render engines and draw managers. */
174 DEGEditorUpdateContext update_ctx = {nullptr};
175 update_ctx.bmain = bmain;
176 for (Scene *scene = static_cast<Scene *>(bmain->scenes.first); scene;
177 scene = static_cast<Scene *>(scene->id.next))
178 {
179 update_ctx.scene = scene;
180 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
181 /* TDODO(sergey): Iterate over depsgraphs instead? */
182 update_ctx.depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
183 update_ctx.view_layer = view_layer;
184 ED_render_id_flush_update(&update_ctx, &scene->id);
185 }
186 if (scene->nodetree && update_scene_data) {
187 ntreeCompositUpdateRLayers(scene->nodetree);
188 }
189 }
191
192 /* Update #CacheFiles to ensure that procedurals are properly taken into account. */
193 LISTBASE_FOREACH (CacheFile *, cachefile, &bmain->cachefiles) {
194 /* Only update cache-files which are set to use a render procedural.
195 * We do not use #BKE_cachefile_uses_render_procedural here as we need to update regardless of
196 * the current engine or its settings. */
197 if (cachefile->use_render_procedural) {
199 /* Rebuild relations so that modifiers are reconnected to or disconnected from the
200 * cache-file. */
202 }
203 }
204}
205
207{
208 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
209 ED_render_engine_area_exit(bmain, area);
210 }
211}
212
214
215/* -------------------------------------------------------------------- */
223
224static void material_changed(Main *bmain, Material *ma)
225{
226 /* icons */
228 ED_previews_tag_dirty_by_id(*bmain, ma->id);
229}
230
231static void lamp_changed(Main *bmain, Light *la)
232{
233 /* icons */
235 ED_previews_tag_dirty_by_id(*bmain, la->id);
236}
237
238static void texture_changed(Main *bmain, Tex *tex)
239{
240 Scene *scene;
241
242 /* icons */
244 ED_previews_tag_dirty_by_id(*bmain, tex->id);
245
246 for (scene = static_cast<Scene *>(bmain->scenes.first); scene;
247 scene = static_cast<Scene *>(scene->id.next))
248 {
249 /* paint overlays */
250 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
251 BKE_paint_invalidate_overlay_tex(scene, view_layer, tex);
252 }
253 /* find compositing nodes */
254 if (scene->use_nodes && scene->nodetree) {
255 for (bNode *node : scene->nodetree->all_nodes()) {
256 if (node->id == &tex->id) {
258 }
259 }
260 }
261 }
262
263 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
264 if (ELEM(tex, brush->mtex.tex, brush->mask_mtex.tex)) {
266 }
267 }
268}
269
270static void world_changed(Main *bmain, World *wo)
271{
272 /* icons */
274 ED_previews_tag_dirty_by_id(*bmain, wo->id);
275}
276
277static void image_changed(Main *bmain, Image *ima)
278{
279 Tex *tex;
280
281 /* icons */
283 ED_previews_tag_dirty_by_id(*bmain, ima->id);
284
285 /* textures */
286 for (tex = static_cast<Tex *>(bmain->textures.first); tex;
287 tex = static_cast<Tex *>(tex->id.next))
288 {
289 if (tex->type == TEX_IMAGE && tex->ima == ima) {
290 texture_changed(bmain, tex);
291 }
292 }
293}
294
295static void scene_changed(Main *bmain, Scene *scene)
296{
297 Object *ob;
298
299 /* glsl */
300 for (ob = static_cast<Object *>(bmain->objects.first); ob;
301 ob = static_cast<Object *>(ob->id.next))
302 {
303 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
305 ED_paint_proj_mesh_data_check(*scene, *ob, nullptr, nullptr, nullptr, nullptr);
306 }
307 }
308}
309
310static void update_sequencer(const DEGEditorUpdateContext *update_ctx, Main *bmain, ID *id)
311{
312 if (ELEM(id->recalc,
313 0,
321 {
322 return;
323 }
324
325 if (GS(id->name) != ID_SCE) {
327 }
328}
329
331{
332 /* this can be called from render or baking thread when a python script makes
333 * changes, in that case we don't want to do any editor updates, and making
334 * GPU changes is not possible because OpenGL only works in the main thread */
335 if (!BLI_thread_is_main()) {
336 return;
337 }
338 Main *bmain = update_ctx->bmain;
339 /* Internal ID update handlers. */
340 switch (GS(id->name)) {
341 case ID_MA:
342 material_changed(bmain, (Material *)id);
343 break;
344 case ID_TE:
345 texture_changed(bmain, (Tex *)id);
346 break;
347 case ID_WO:
348 world_changed(bmain, (World *)id);
349 break;
350 case ID_LA:
351 lamp_changed(bmain, (Light *)id);
352 break;
353 case ID_IM:
354 image_changed(bmain, (Image *)id);
355 break;
356 case ID_SCE:
357 scene_changed(bmain, (Scene *)id);
358 break;
359 case ID_BR:
360 BKE_brush_tag_unsaved_changes(reinterpret_cast<Brush *>(id));
361 break;
362 default:
363 break;
364 }
365
366 update_sequencer(update_ctx, bmain, id);
367}
368
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
@ 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 relations_invalidate_scene_strips(const Main *bmain, const Scene *scene_target)
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)
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
ListBase regionbase
struct Image * ima
ListBase areabase
bScreen * WM_window_get_active_screen(const wmWindow *win)