Blender V4.3
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
9#include <cstdlib>
10#include <cstring>
11
12#include "DNA_cachefile_types.h"
13#include "DNA_light_types.h"
14#include "DNA_material_types.h"
15#include "DNA_node_types.h"
16#include "DNA_object_types.h"
17#include "DNA_scene_types.h"
18#include "DNA_screen_types.h"
19#include "DNA_space_types.h"
20#include "DNA_view3d_types.h"
22#include "DNA_world_types.h"
23
24#include "DRW_engine.hh"
25
26#include "BLI_listbase.h"
27#include "BLI_threads.h"
28#include "BLI_utildefines.h"
29
30#include "BKE_brush.hh"
31#include "BKE_context.hh"
32#include "BKE_icons.h"
33#include "BKE_main.hh"
34#include "BKE_material.h"
35#include "BKE_paint.hh"
36#include "BKE_scene.hh"
37
38#include "NOD_composite.hh"
39
40#include "RE_engine.h"
41#include "RE_pipeline.h"
42
43#include "ED_node.hh"
44#include "ED_node_preview.hh"
45#include "ED_paint.hh"
46#include "ED_render.hh"
47#include "ED_view3d.hh"
48
49#include "DEG_depsgraph.hh"
51
52#include "WM_api.hh"
53
54#include <cstdio>
55
56/* -------------------------------------------------------------------- */
61 wmWindow *window,
62 ScrArea *area,
63 const bool updated)
64{
68
69 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
70 if (region->regiontype != RGN_TYPE_WINDOW) {
71 continue;
72 }
73
74 View3D *v3d = static_cast<View3D *>(area->spacedata.first);
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. */
83 bContext *C = CTX_create();
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 if (!updated) {
102 continue;
103 }
104
105 DRWUpdateContext drw_context = {nullptr};
106 drw_context.bmain = bmain;
107 drw_context.depsgraph = depsgraph;
108 drw_context.scene = scene;
109 drw_context.view_layer = view_layer;
110 drw_context.region = region;
111 drw_context.v3d = v3d;
112 drw_context.engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
113 DRW_notify_view_update(&drw_context);
114 }
115}
116
117void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, const bool updated)
118{
119 Main *bmain = update_ctx->bmain;
120 static bool recursive_check = false;
121
122 /* don't do this render engine update if we're updating the scene from
123 * other threads doing e.g. rendering or baking jobs */
124 if (!BLI_thread_is_main()) {
125 return;
126 }
127
128 /* don't call this recursively for frame updates */
129 if (recursive_check) {
130 return;
131 }
132
133 /* Do not call if no WM available, see #42688. */
134 if (BLI_listbase_is_empty(&bmain->wm)) {
135 return;
136 }
137
138 recursive_check = true;
139
140 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
141 LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
142 bScreen *screen = WM_window_get_active_screen(window);
143
144 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
145 if (area->spacetype == SPACE_VIEW3D) {
146 ED_render_view3d_update(update_ctx->depsgraph, window, area, updated);
147 }
148 }
149 }
150
151 recursive_check = false;
152}
153
155{
156 /* clear all render engines in this area */
157 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
158
159 if (area->spacetype != SPACE_VIEW3D) {
160 return;
161 }
162
163 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
164 if (region->regiontype != RGN_TYPE_WINDOW || !(region->regiondata)) {
165 continue;
166 }
168 }
169}
170
171void ED_render_engine_changed(Main *bmain, const bool update_scene_data)
172{
173 /* on changing the render engine type, clear all running render engines */
174 for (bScreen *screen = static_cast<bScreen *>(bmain->screens.first); screen;
175 screen = static_cast<bScreen *>(screen->id.next))
176 {
177 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
178 ED_render_engine_area_exit(bmain, area);
179 }
180 }
181 /* Stop and invalidate all shader previews. */
182 ED_preview_kill_jobs(static_cast<wmWindowManager *>(bmain->wm.first), bmain);
183 LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
185 }
186 RE_FreePersistentData(nullptr);
187 /* Inform all render engines and draw managers. */
188 DEGEditorUpdateContext update_ctx = {nullptr};
189 update_ctx.bmain = bmain;
190 for (Scene *scene = static_cast<Scene *>(bmain->scenes.first); scene;
191 scene = static_cast<Scene *>(scene->id.next))
192 {
193 update_ctx.scene = scene;
194 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
195 /* TDODO(sergey): Iterate over depsgraphs instead? */
196 update_ctx.depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
197 update_ctx.view_layer = view_layer;
198 ED_render_id_flush_update(&update_ctx, &scene->id);
199 }
200 if (scene->nodetree && update_scene_data) {
201 ntreeCompositUpdateRLayers(scene->nodetree);
202 }
203 }
204
205 /* Update #CacheFiles to ensure that procedurals are properly taken into account. */
206 LISTBASE_FOREACH (CacheFile *, cachefile, &bmain->cachefiles) {
207 /* Only update cache-files which are set to use a render procedural.
208 * We do not use #BKE_cachefile_uses_render_procedural here as we need to update regardless of
209 * the current engine or its settings. */
210 if (cachefile->use_render_procedural) {
212 /* Rebuild relations so that modifiers are reconnected to or disconnected from the
213 * cache-file. */
215 }
216 }
217}
218
220{
221 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
222 ED_render_engine_area_exit(bmain, area);
223 }
224}
225
228/* -------------------------------------------------------------------- */
237static void material_changed(Main *bmain, Material *ma)
238{
239 /* icons */
241 ED_previews_tag_dirty_by_id(*bmain, ma->id);
242}
243
244static void lamp_changed(Main *bmain, Light *la)
245{
246 /* icons */
248 ED_previews_tag_dirty_by_id(*bmain, la->id);
249}
250
251static void texture_changed(Main *bmain, Tex *tex)
252{
253 Scene *scene;
254
255 /* icons */
258
259 for (scene = static_cast<Scene *>(bmain->scenes.first); scene;
260 scene = static_cast<Scene *>(scene->id.next))
261 {
262 /* paint overlays */
263 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
264 BKE_paint_invalidate_overlay_tex(scene, view_layer, tex);
265 }
266 /* find compositing nodes */
267 if (scene->use_nodes && scene->nodetree) {
268 LISTBASE_FOREACH (bNode *, node, &scene->nodetree->nodes) {
269 if (node->id == &tex->id) {
270 ED_node_tag_update_id(&scene->id);
271 }
272 }
273 }
274 }
275}
276
277static void world_changed(Main *bmain, World *wo)
278{
279 /* icons */
281 ED_previews_tag_dirty_by_id(*bmain, wo->id);
282}
283
284static void image_changed(Main *bmain, Image *ima)
285{
286 Tex *tex;
287
288 /* icons */
290 ED_previews_tag_dirty_by_id(*bmain, ima->id);
291
292 /* textures */
293 for (tex = static_cast<Tex *>(bmain->textures.first); tex;
294 tex = static_cast<Tex *>(tex->id.next))
295 {
296 if (tex->type == TEX_IMAGE && tex->ima == ima) {
297 texture_changed(bmain, tex);
298 }
299 }
300}
301
302static void scene_changed(Main *bmain, Scene *scene)
303{
304 Object *ob;
305
306 /* glsl */
307 for (ob = static_cast<Object *>(bmain->objects.first); ob;
308 ob = static_cast<Object *>(ob->id.next))
309 {
310 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
312 ED_paint_proj_mesh_data_check(*scene, *ob, nullptr, nullptr, nullptr, nullptr);
313 }
314 }
315}
316
318{
319 /* this can be called from render or baking thread when a python script makes
320 * changes, in that case we don't want to do any editor updates, and making
321 * GPU changes is not possible because OpenGL only works in the main thread */
322 if (!BLI_thread_is_main()) {
323 return;
324 }
325 Main *bmain = update_ctx->bmain;
326 /* Internal ID update handlers. */
327 switch (GS(id->name)) {
328 case ID_MA:
329 material_changed(bmain, (Material *)id);
330 break;
331 case ID_TE:
332 texture_changed(bmain, (Tex *)id);
333 break;
334 case ID_WO:
335 world_changed(bmain, (World *)id);
336 break;
337 case ID_LA:
338 lamp_changed(bmain, (Light *)id);
339 break;
340 case ID_IM:
341 image_changed(bmain, (Image *)id);
342 break;
343 case ID_SCE:
344 scene_changed(bmain, (Scene *)id);
345 break;
346 case ID_BR:
347 BKE_brush_tag_unsaved_changes(reinterpret_cast<Brush *>(id));
348 break;
349 default:
350 break;
351 }
352}
353
void BKE_brush_tag_unsaved_changes(Brush *brush)
Definition brush.cc:621
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:205
int BKE_icon_id_ensure(struct ID *id)
Definition icons.cc:268
General operations, lookup, etc. for materials.
void BKE_material_make_node_previews_dirty(struct Material *ma)
void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob)
void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const Tex *tex)
Definition paint.cc:253
Depsgraph * BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3377
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
int BLI_thread_is_main(void)
Definition threads.cc:179
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
ViewLayer * DEG_get_input_view_layer(const Depsgraph *graph)
Main * DEG_get_bmain(const Depsgraph *graph)
Scene * DEG_get_input_scene(const Depsgraph *graph)
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ 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
void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
void ED_node_tag_update_id(ID *id)
Definition node_draw.cc:174
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)
RenderEngineType * ED_view3d_engine_type(const Scene *scene, int drawtype)
@ RE_ENGINE_DO_UPDATE
Definition RE_engine.h:66
const Depsgraph * depsgraph
RenderEngine * RE_view_engine_get(const ViewRender *view_render)
#define GS(x)
Definition iris.cc:202
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 image_changed(Main *bmain, Image *ima)
void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, const bool updated)
void RE_FreePersistentData(const Scene *scene)
Depsgraph * depsgraph
Definition DRW_engine.hh:49
ViewLayer * view_layer
Definition DRW_engine.hh:51
ARegion * region
Definition DRW_engine.hh:52
RenderEngineType * engine_type
Definition DRW_engine.hh:54
Definition DNA_ID.h:413
void * next
Definition DNA_ID.h:416
void * first
ListBase scenes
Definition BKE_main.hh:210
ListBase wm
Definition BKE_main.hh:239
ListBase textures
Definition BKE_main.hh:217
ListBase materials
Definition BKE_main.hh:216
ListBase screens
Definition BKE_main.hh:225
ListBase objects
Definition BKE_main.hh:212
ListBase cachefiles
Definition BKE_main.hh:245
struct ViewRender * view_render
void(* view_update)(struct RenderEngine *engine, const struct bContext *context, struct Depsgraph *depsgraph)
Definition RE_engine.h:105
RenderEngineType * type
Definition RE_engine.h:134
struct Image * ima
View3DShading shading
bScreen * WM_window_get_active_screen(const wmWindow *win)