Blender V5.0
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->compositing_node_group && update_scene_data) {
191 ntreeCompositUpdateRLayers(scene->compositing_node_group);
192 }
193 }
195}
196
198{
199 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
200 ED_render_engine_area_exit(bmain, area);
201 }
202}
203
205
206/* -------------------------------------------------------------------- */
214
215static void material_changed(Main *bmain, Material *ma)
216{
217 /* icons */
219 ED_previews_tag_dirty_by_id(*bmain, ma->id);
220}
221
222static void lamp_changed(Main *bmain, Light *la)
223{
224 /* icons */
226 ED_previews_tag_dirty_by_id(*bmain, la->id);
227}
228
229static void texture_changed(Main *bmain, Tex *tex)
230{
231 Scene *scene;
232
233 /* icons */
235 ED_previews_tag_dirty_by_id(*bmain, tex->id);
236
237 for (scene = static_cast<Scene *>(bmain->scenes.first); scene;
238 scene = static_cast<Scene *>(scene->id.next))
239 {
240 /* paint overlays */
241 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
242 BKE_paint_invalidate_overlay_tex(scene, view_layer, tex);
243 }
244 /* find compositing nodes */
245 if (scene->compositing_node_group) {
246 for (bNode *node : scene->compositing_node_group->all_nodes()) {
247 if (node->id == &tex->id) {
249 }
250 }
251 }
252 }
253
254 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
255 if (ELEM(tex, brush->mtex.tex, brush->mask_mtex.tex)) {
257 }
258 }
259}
260
261static void world_changed(Main *bmain, World *wo)
262{
263 /* icons */
265 ED_previews_tag_dirty_by_id(*bmain, wo->id);
266}
267
268static void image_changed(Main *bmain, Image *ima)
269{
270 Tex *tex;
271
272 /* icons */
274 ED_previews_tag_dirty_by_id(*bmain, ima->id);
275
276 /* textures */
277 for (tex = static_cast<Tex *>(bmain->textures.first); tex;
278 tex = static_cast<Tex *>(tex->id.next))
279 {
280 if (tex->type == TEX_IMAGE && tex->ima == ima) {
281 texture_changed(bmain, tex);
282 }
283 }
284}
285
286static void scene_changed(Main *bmain, Scene *scene)
287{
288 Object *ob;
289
290 /* glsl */
291 for (ob = static_cast<Object *>(bmain->objects.first); ob;
292 ob = static_cast<Object *>(ob->id.next))
293 {
294 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
296 ED_paint_proj_mesh_data_check(*scene, *ob, nullptr, nullptr, nullptr, nullptr);
297 }
298 }
299}
300
301static void update_sequencer(const DEGEditorUpdateContext *update_ctx, Main *bmain, ID *id)
302{
303 if (ELEM(id->recalc,
304 0,
312 {
313 return;
314 }
315 Scene *changed_scene = update_ctx->scene;
316
317 if (GS(id->name) != ID_SCE) {
319 }
320
321 /* Invalidate VSE cache in `changed_scene`, because strip animation may have been updated. */
322 if (GS(id->name) == ID_AC) {
323 Editing *ed = blender::seq::editing_get(changed_scene);
324 if (ed != nullptr && blender::seq::animation_keyframes_exist(changed_scene) &&
325 &changed_scene->adt->action->id == id)
326 {
327 blender::seq::prefetch_stop(changed_scene);
330 }
331 }
332
333 /* Invalidate cache for strips that use this compositing tree as a modifier. */
334 if (GS(id->name) == ID_NT) {
335 const bNodeTree *node_tree = reinterpret_cast<const bNodeTree *>(id);
336 if (node_tree->type == NTREE_COMPOSIT) {
338 }
339 }
340}
341
343{
344 /* this can be called from render or baking thread when a python script makes
345 * changes, in that case we don't want to do any editor updates, and making
346 * GPU changes is not possible because OpenGL only works in the main thread */
347 if (!BLI_thread_is_main()) {
348 return;
349 }
350 Main *bmain = update_ctx->bmain;
351 /* Internal ID update handlers. */
352 switch (GS(id->name)) {
353 case ID_MA:
354 material_changed(bmain, (Material *)id);
355 break;
356 case ID_TE:
357 texture_changed(bmain, (Tex *)id);
358 break;
359 case ID_WO:
360 world_changed(bmain, (World *)id);
361 break;
362 case ID_LA:
363 lamp_changed(bmain, (Light *)id);
364 break;
365 case ID_IM:
366 image_changed(bmain, (Image *)id);
367 break;
368 case ID_SCE:
369 scene_changed(bmain, (Scene *)id);
370 break;
371 case ID_BR:
372 BKE_brush_tag_unsaved_changes(reinterpret_cast<Brush *>(id));
373 break;
374 default:
375 break;
376 }
377
378 update_sequencer(update_ctx, bmain, id);
379}
380
void BKE_brush_tag_unsaved_changes(Brush *brush)
Definition brush.cc:764
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:259
Depsgraph * BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3416
#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(...)
Main * DEG_get_bmain(const Depsgraph *graph)
Scene * DEG_get_input_scene(const Depsgraph *graph)
@ ID_RECALC_AUDIO_FPS
Definition DNA_ID.h:1127
@ ID_RECALC_AUDIO_LISTENER
Definition DNA_ID.h:1130
@ ID_RECALC_FRAME_CHANGE
Definition DNA_ID.h:1125
@ ID_RECALC_AUDIO
Definition DNA_ID.h:1132
@ ID_RECALC_SELECT
Definition DNA_ID.h:1101
@ ID_RECALC_AUDIO_MUTE
Definition DNA_ID.h:1129
@ ID_RECALC_AUDIO_VOLUME
Definition DNA_ID.h:1128
@ ID_TE
@ ID_IM
@ ID_NT
@ ID_LA
@ ID_SCE
@ ID_BR
@ ID_WO
@ ID_MA
@ ID_AC
@ NTREE_COMPOSIT
@ 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:61
#define C
Definition RandGen.cpp:29
BPy_StructRNA * depsgraph
#define GS(x)
RenderEngine * RE_view_engine_get(const ViewRender *view_render)
void tag_update_id(ID *id)
Definition node_draw.cc:211
void prefetch_stop(Scene *scene)
Definition prefetch.cc:310
void cache_cleanup_final(Scene *scene)
void relations_invalidate_compositor_modifiers(const Main *bmain, const bNodeTree *node_tree)
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:286
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:414
unsigned int recalc
Definition DNA_ID.h:445
char name[258]
Definition DNA_ID.h:432
void * next
Definition DNA_ID.h:417
void * first
ListBase brushes
Definition BKE_main.hh:302
ListBase scenes
Definition BKE_main.hh:278
ListBase wm
Definition BKE_main.hh:307
ListBase textures
Definition BKE_main.hh:285
ListBase materials
Definition BKE_main.hh:284
ListBase screens
Definition BKE_main.hh:292
ListBase objects
Definition BKE_main.hh:280
struct ViewRender * view_render
void(* view_update)(struct RenderEngine *engine, const struct bContext *context, struct Depsgraph *depsgraph)
Definition RE_engine.h:100
RenderEngineType * type
Definition RE_engine.h:130
struct bNodeTree * compositing_node_group
ListBase view_layers
struct AnimData * adt
ListBase regionbase
struct Image * ima
ListBase areabase
bScreen * WM_window_get_active_screen(const wmWindow *win)