[Bf-blender-cvs] [a6b6689c0ab] blender2.8: Draw manager: Listen to depsgraph's ID update callbacks

Sergey Sharybin noreply at git.blender.org
Wed Nov 29 11:08:56 CET 2017


Commit: a6b6689c0ab769bfdf4db932e4afd75ac0d42e10
Author: Sergey Sharybin
Date:   Tue Nov 28 17:05:52 2017 +0100
Branches: blender2.8
https://developer.blender.org/rBa6b6689c0ab769bfdf4db932e4afd75ac0d42e10

Draw manager: Listen to depsgraph's ID update callbacks

This replaces dedicated flag which wasn't clean who sets it and who clears it,
and which was also trying to re-implement existing functionality in a way.

Flushing is not currently very efficient but there are ways to speed this up
a lot, but needs more investigation.

===================================================================

M	source/blender/draw/DRW_engine.h
M	source/blender/draw/engines/basic/basic_engine.c
M	source/blender/draw/engines/clay/clay_engine.c
M	source/blender/draw/engines/eevee/eevee_data.c
M	source/blender/draw/engines/eevee/eevee_engine.c
M	source/blender/draw/engines/eevee/eevee_lightprobes.c
M	source/blender/draw/engines/eevee/eevee_lights.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/external/external_engine.c
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager.c
M	source/blender/editors/render/render_update.c

===================================================================

diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index f3e1bf5ceac..ba0f8681f10 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -34,6 +34,7 @@ struct Main;
 struct Material;
 struct Scene;
 struct DrawEngineType;
+struct ID;
 struct IDProperty;
 struct bContext;
 struct Object;
@@ -78,6 +79,7 @@ typedef struct DRWUpdateContext {
 	struct RenderEngineType *engine_type;
 } DRWUpdateContext;
 void DRW_notify_view_update(const DRWUpdateContext *update_ctx);
+void DRW_notify_id_update(const DRWUpdateContext *update_ctx, struct ID *id);
 
 void DRW_draw_view(const struct bContext *C);
 
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index 92ffa8a1794..b41420ab95b 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -263,6 +263,7 @@ DrawEngineType draw_engine_basic_type = {
 	NULL,
 	&BASIC_draw_scene,
 	NULL,
+	NULL,
 };
 
 /* Note: currently unused, we may want to register so we can see this when debugging the view. */
diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c
index fe81e1e484c..27ae4639e8b 100644
--- a/source/blender/draw/engines/clay/clay_engine.c
+++ b/source/blender/draw/engines/clay/clay_engine.c
@@ -916,6 +916,7 @@ DrawEngineType draw_engine_clay_type = {
 	NULL,
 	&CLAY_draw_scene,
 	NULL,
+	NULL,
 };
 
 RenderEngineType DRW_engine_viewport_clay_type = {
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index 6b95844591d..c105567ddb3 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -109,6 +109,7 @@ EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob)
 
 	if (*pedata == NULL) {
 		*pedata = MEM_callocN(sizeof(**pedata), "EEVEE_LightProbeEngineData");
+		(*pedata)->need_full_update = true;
 		(*pedata)->need_update = true;
 	}
 
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index f059fbe2268..300a10d7b09 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -128,8 +128,6 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
 			}
 			else {
 				BLI_addtail(&sldata->shadow_casters, BLI_genericNodeN(ob));
-				EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(ob);
-				oedata->need_update = ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0);
 			}
 		}
 	}
@@ -287,6 +285,26 @@ static void EEVEE_view_update(void *vedata)
 	}
 }
 
+static void EEVEE_id_update(void *UNUSED(vedata), ID *id)
+{
+	const ID_Type id_type = GS(id->name);
+	if (id_type == ID_OB) {
+		Object *object = (Object *)id;
+		EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(object);
+		if (ped != NULL) {
+			ped->need_full_update = true;
+		}
+		EEVEE_LampEngineData *led = EEVEE_lamp_data_get(object);
+		if (led != NULL) {
+			led->need_update = true;
+		}
+		EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(object);
+		if (oedata != NULL) {
+			oedata->need_update = true;
+		}
+	}
+}
+
 static void EEVEE_engine_free(void)
 {
 	EEVEE_bloom_free();
@@ -395,6 +413,7 @@ DrawEngineType draw_engine_eevee_type = {
 	&EEVEE_draw_scene,
 	NULL, //&EEVEE_draw_scene
 	&EEVEE_view_update,
+	&EEVEE_id_update,
 };
 
 RenderEngineType DRW_engine_viewport_eevee_type = {
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index a58e6e20c58..1441c173a21 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -490,7 +490,9 @@ void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
 
 	ped->num_cell = probe->grid_resolution_x * probe->grid_resolution_y * probe->grid_resolution_z;
 
-	if ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0) {
+	if (ped->need_full_update) {
+		ped->need_full_update = false;
+
 		ped->need_update = true;
 		ped->probe_id = 0;
 
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index e57c5a6db41..7cc3e86384e 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -257,10 +257,6 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
 		Lamp *la = (Lamp *)ob->data;
 		EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob);
 
-		if ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0) {
-			led->need_update = true;
-		}
-
 		MEM_SAFE_FREE(led->storage);
 
 		if (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY)) {
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 8e754e71506..281e9e2fce1 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -568,7 +568,19 @@ typedef struct EEVEE_LampEngineData {
 } EEVEE_LampEngineData;
 
 typedef struct EEVEE_LightProbeEngineData {
+	/* NOTE: need_full_update is set by dependency graph when the probe or it's
+	 * object is updated. This triggers full probe update, including it's
+	 * "progressive" GI refresh.
+	 *
+	 * need_update is always set to truth when need_full_update is tagged, but
+	 * might also be forced to be kept truth during GI refresh stages.
+	 *
+	 * TODO(sergey): Is there a way to avoid two flags here, or at least make
+	 * it more clear what's going on here?
+	 */
+	bool need_full_update;
 	bool need_update;
+
 	bool ready_to_shade;
 	int updated_cells;
 	int updated_lvl;
diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c
index bdf53fd3046..2127dbe1f63 100644
--- a/source/blender/draw/engines/external/external_engine.c
+++ b/source/blender/draw/engines/external/external_engine.c
@@ -217,6 +217,7 @@ DrawEngineType draw_engine_external_type = {
 	NULL,
 	&EXTERNAL_draw_scene,
 	NULL,
+	NULL,
 };
 
 /* Note: currently unused, we should not register unless we want to see this when debugging the view. */
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 793608c62a9..f9ee87dfd89 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -138,6 +138,7 @@ typedef struct DrawEngineType {
 	void (*draw_scene)(void *vedata);
 
 	void (*view_update)(void *vedata);
+	void (*id_update)(void *vedata, struct ID *id);
 } DrawEngineType;
 
 #ifndef __DRW_ENGINE_H__
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 5eb88123208..0986e4c48b4 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -3259,6 +3259,46 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
 
 /** \} */
 
+/** \name ID Update
+ * \{ */
+
+/* TODO(sergey): This code is run for each changed ID (including the ones which
+ * are changed indirectly via update flush. Need to find a way to make this to
+ * run really fast, hopefully without any memory allocations on a heap
+ * Idea here could be to run every known engine's id_update() and make them
+ * do nothing if there is no engine-specific data yet.
+ */
+void DRW_notify_id_update(const DRWUpdateContext *update_ctx, ID *id)
+{
+	RenderEngineType *engine_type = update_ctx->engine_type;
+	ARegion *ar = update_ctx->ar;
+	View3D *v3d = update_ctx->v3d;
+	RegionView3D *rv3d = ar->regiondata;
+	Scene *scene = update_ctx->scene;
+	ViewLayer *view_layer = update_ctx->view_layer;
+	if (rv3d->viewport == NULL) {
+		return;
+	}
+	/* Reset before using it. */
+	memset(&DST, 0x0, sizeof(DST));
+	DST.viewport = rv3d->viewport;
+	DST.draw_ctx = (DRWContextState){
+		ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, NULL,
+	};
+	DRW_engines_enable(scene, view_layer, engine_type);
+	for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+		DrawEngineType *draw_engine = link->data;
+		ViewportEngineData *data = DRW_viewport_engine_data_get(draw_engine);
+		if (draw_engine->id_update) {
+			draw_engine->id_update(data, id);
+		}
+	}
+	DST.viewport = NULL;
+	DRW_engines_disable();
+}
+
+/** \} */
+
 /* -------------------------------------------------------------------- */
 
 /** \name Main Draw Loops (DRW_draw)
@@ -3329,8 +3369,6 @@ void DRW_draw_render_loop_ex(
 		DEG_OBJECT_ITER(graph, ob, DEG_OBJECT_ITER_FLAG_ALL);
 		{
 			DRW_engines_cache_populate(ob);
-			/* XXX find a better place for this. maybe Depsgraph? */
-			ob->deg_update_flag = 0;
 		}
 		DEG_OBJECT_ITER_END
 
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index bd2acb1c8bd..a391b13a000 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -539,7 +539,9 @@ void ED_render_id_flush_update(const DEGEditorUpdateContext *update_ctx, ID *id)
 		return;
 	}
 	Main *bmain = update_ctx->bmain;
-
+	Scene *scene = update_ctx->scene;
+	ViewLayer *view_layer = update_ctx->view_layer;
+	/* Internal ID update handlers. */
 	switch (GS(id->name)) {
 		case ID_MA:
 			material_changed(bmain, (Material *)id);
@@ -565,7 +567,42 @@ void ED_render_id_flush_update(const DEGEditorUpdateContext *update_ctx, ID *id)
 			render_engine_flag_changed(bmain, RE_ENGINE_UPDATE_OTHER);
 			break;
 	}
-	
+	/* Inform all draw managers about changes.
+	 *
+	 * TODO(sergey): This code is run for every updated ID, via flushing
+	 * mechanism. How can we avoid iterating over the whole interface for
+	 * every of those IDs? One of the ideas would be to call draw manager's
+	 * ID update which is not bound to any of contexts.
+	 */
+	{
+		wmWindowManager *wm = bmain->wm.first;
+		for (wmWindow *win = wm->windows.first; win; win = win->next) {
+			bScreen *sc = WM_window_get_active_screen(win);
+			WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
+			ViewRender *vie

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list