Fix T53598: OpenGL Render Animation does not update shadows
General idea of the fix: skip the whole draw manager callback madness which was used to tag object's engine specific data as dirty. Use generic recalc flag in ObjectEngineData structure instead. This gives us the following benefits; - Sovles mentioned bug report. - Avoids whole interface lookup for opened viewports for EVERY changed ID. - Fixes missing updates when viewport is temporarily invisible. Reviewers: dfelinto, fclem Differential Revision: https://developer.blender.org/D3028
This commit is contained in:
parent
006c66b1ff
commit
9577ebde79
Notes:
blender-bot
2023-02-14 06:19:33 +01:00
Referenced by commit bfe88006a3
, Remove unused function
Referenced by issue #53598, OpenGL Render Animation does not update shadows
|
@ -36,6 +36,7 @@
|
|||
#include <deque>
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
|
@ -207,10 +208,21 @@ BLI_INLINE OperationDepsNode *flush_schedule_children(
|
|||
return result;
|
||||
}
|
||||
|
||||
void flush_engine_data_update(ID *id)
|
||||
{
|
||||
if (GS(id->name) != ID_OB) {
|
||||
return;
|
||||
}
|
||||
Object *object = (Object *)id;
|
||||
BLI_LISTBASE_FOREACH(ObjectEngineData *, engine_data, &object->drawdata) {
|
||||
engine_data->recalc |= id->recalc;
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: It will also accumulate flags from changed components. */
|
||||
BLI_INLINE void flush_editors_id_update(Main *bmain,
|
||||
Depsgraph *graph,
|
||||
const DEGEditorUpdateContext *update_ctx)
|
||||
void flush_editors_id_update(Main *bmain,
|
||||
Depsgraph *graph,
|
||||
const DEGEditorUpdateContext *update_ctx)
|
||||
{
|
||||
foreach (IDDepsNode *id_node, graph->id_nodes) {
|
||||
if (id_node->done != ID_STATE_MODIFIED) {
|
||||
|
@ -241,6 +253,8 @@ BLI_INLINE void flush_editors_id_update(Main *bmain,
|
|||
/* Inform editors. */
|
||||
if (deg_copy_on_write_is_expanded(id_cow)) {
|
||||
deg_editors_id_update(update_ctx, id_cow);
|
||||
/* Inform draw engines that something was changed. */
|
||||
flush_engine_data_update(id_cow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -294,30 +294,38 @@ static void eevee_view_update(void *vedata)
|
|||
}
|
||||
}
|
||||
|
||||
static void eevee_id_update(void *UNUSED(vedata), ID *id)
|
||||
static void eevee_id_object_update(void *UNUSED(vedata), Object *object)
|
||||
{
|
||||
/* This is a bit mask of components which update is to be ignored. */
|
||||
const int ignore_updates = ID_RECALC_COLLECTIONS;
|
||||
/* Check whether we have to do anything here. */
|
||||
if ((id->recalc & ~ignore_updates) == 0) {
|
||||
return;
|
||||
const int allowed_updates = ~ignore_updates;
|
||||
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(object);
|
||||
if (ped != NULL && (ped->engine_data.recalc & allowed_updates) != 0) {
|
||||
ped->need_full_update = true;
|
||||
ped->engine_data.recalc = 0;
|
||||
}
|
||||
EEVEE_LampEngineData *led = EEVEE_lamp_data_get(object);
|
||||
if (led != NULL && (led->engine_data.recalc & allowed_updates) != 0) {
|
||||
led->need_update = true;
|
||||
led->engine_data.recalc = 0;
|
||||
}
|
||||
EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(object);
|
||||
if (oedata != NULL && (oedata->engine_data.recalc & allowed_updates) != 0) {
|
||||
oedata->need_update = true;
|
||||
oedata->engine_data.recalc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void eevee_id_update(void *vedata, ID *id)
|
||||
{
|
||||
/* Handle updates based on ID type. */
|
||||
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;
|
||||
}
|
||||
switch (GS(id->name)) {
|
||||
case ID_OB:
|
||||
eevee_id_object_update(vedata, (Object *)id);
|
||||
break;
|
||||
default:
|
||||
/* pass */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2868,6 +2868,10 @@ static void drw_engines_cache_populate(Object *ob)
|
|||
DrawEngineType *engine = link->data;
|
||||
ViewportEngineData *data = DRW_viewport_engine_data_ensure(engine);
|
||||
|
||||
if (engine->id_update) {
|
||||
engine->id_update(data, &ob->id);
|
||||
}
|
||||
|
||||
if (engine->cache_populate) {
|
||||
engine->cache_populate(data, ob);
|
||||
}
|
||||
|
|
|
@ -542,8 +542,6 @@ 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:
|
||||
|
@ -570,42 +568,6 @@ 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 *view_render = BKE_viewrender_get(win->scene, workspace);
|
||||
for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
|
||||
if (sa->spacetype != SPACE_VIEW3D) {
|
||||
continue;
|
||||
}
|
||||
for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
|
||||
if (ar->regiontype != RGN_TYPE_WINDOW) {
|
||||
continue;
|
||||
}
|
||||
RenderEngineType *engine_type = RE_engines_find(view_render->engine_id);
|
||||
DRW_notify_id_update(
|
||||
(&(DRWUpdateContext){
|
||||
.bmain = bmain,
|
||||
.scene = scene,
|
||||
.view_layer = view_layer,
|
||||
.ar = ar,
|
||||
.v3d = (View3D *)sa->spacedata.first,
|
||||
.engine_type = engine_type
|
||||
}),
|
||||
id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -86,6 +86,8 @@ typedef struct ObjectEngineData {
|
|||
struct DrawEngineType *engine_type;
|
||||
/* Only nested data, NOT the engine data itself. */
|
||||
ObjectEngineDataFreeCb free;
|
||||
/* Accumulated recalc flags, which corresponds to ID->recalc flags. */
|
||||
int recalc;
|
||||
} ObjectEngineData;
|
||||
|
||||
#define MAX_VGROUP_NAME 64
|
||||
|
|
Loading…
Reference in New Issue