diff options
Diffstat (limited to 'source/blender/editors/render/render_update.c')
-rw-r--r-- | source/blender/editors/render/render_update.c | 206 |
1 files changed, 124 insertions, 82 deletions
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 4e02ff77a31..f7ede251873 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -38,9 +38,12 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_view3d_types.h" +#include "DNA_workspace_types.h" #include "DNA_world_types.h" #include "DNA_windowmanager_types.h" +#include "DRW_engine.h" + #include "BLI_listbase.h" #include "BLI_threads.h" #include "BLI_utildefines.h" @@ -48,12 +51,15 @@ #include "BKE_context.h" #include "BKE_DerivedMesh.h" #include "BKE_icons.h" +#include "BKE_layer.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_node.h" #include "BKE_paint.h" #include "BKE_scene.h" +#include "BKE_workspace.h" +#include "GPU_lamp.h" #include "GPU_material.h" #include "GPU_buffers.h" @@ -64,16 +70,23 @@ #include "ED_render.h" #include "ED_view3d.h" +#include "DEG_depsgraph.h" + +#include "WM_api.h" + #include "render_intern.h" // own include extern Material defmaterial; /***************************** Render Engines ********************************/ -void ED_render_scene_update(Main *bmain, Scene *scene, int updated) +void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int updated) { /* viewport rendering update on data changes, happens after depsgraph * updates if there was any change. context is set to the 3d view */ + Main *bmain = update_ctx->bmain; + Scene *scene = update_ctx->scene; + ViewLayer *view_layer = update_ctx->view_layer; bContext *C; wmWindowManager *wm; wmWindow *win; @@ -102,26 +115,24 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) wm = bmain->wm.first; for (win = wm->windows.first; win; win = win->next) { - bScreen *sc = win->screen; + bScreen *sc = WM_window_get_active_screen(win); ScrArea *sa; ARegion *ar; CTX_wm_window_set(C, win); - + WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); + ViewRender *view_render = BKE_viewrender_get(win->scene, workspace); + for (sa = sc->areabase.first; sa; sa = sa->next) { if (sa->spacetype != SPACE_VIEW3D) continue; for (ar = sa->regionbase.first; ar; ar = ar->next) { - RegionView3D *rv3d; - RenderEngine *engine; - - if (ar->regiontype != RGN_TYPE_WINDOW) + if (ar->regiontype != RGN_TYPE_WINDOW) { continue; - - rv3d = ar->regiondata; - engine = rv3d->render_engine; - + } + RegionView3D *rv3d = ar->regiondata; + RenderEngine *engine = rv3d->render_engine; /* call update if the scene changed, or if the render engine * tagged itself for update (e.g. because it was busy at the * time of the last update) */ @@ -133,6 +144,24 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) engine->flag &= ~RE_ENGINE_DO_UPDATE; engine->type->view_update(engine, C); + + } + else { + RenderEngineType *engine_type = RE_engines_find(view_render->engine_id); + if ((engine_type->flag & RE_USE_LEGACY_PIPELINE) == 0) { + if (updated) { + DRW_notify_view_update( + (&(DRWUpdateContext){ + .bmain = bmain, + .depsgraph = update_ctx->depsgraph, + .scene = scene, + .view_layer = view_layer, + .ar = ar, + .v3d = (View3D *)sa->spacedata.first, + .engine_type = engine_type + })); + } + } } } } @@ -143,23 +172,6 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) recursive_check = false; } -void ED_render_scene_update_pre(Main *bmain, Scene *scene, bool time) -{ - /* Blender internal might access to the data which is gonna to be freed - * by the scene update functions. This applies for example to simulation - * data like smoke and fire. - */ - if (time && !BKE_scene_use_new_shading_nodes(scene)) { - bScreen *sc; - ScrArea *sa; - for (sc = bmain->screen.first; sc; sc = sc->id.next) { - for (sa = sc->areabase.first; sa; sa = sa->next) { - ED_render_engine_area_exit(bmain, sa); - } - } - } -} - void ED_render_engine_area_exit(Main *bmain, ScrArea *sa) { /* clear all render engines in this area */ @@ -179,18 +191,23 @@ void ED_render_engine_area_exit(Main *bmain, ScrArea *sa) void ED_render_engine_changed(Main *bmain) { /* on changing the render engine type, clear all running render engines */ - bScreen *sc; - ScrArea *sa; - Scene *scene; - - for (sc = bmain->screen.first; sc; sc = sc->id.next) - for (sa = sc->areabase.first; sa; sa = sa->next) + for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) { + for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { ED_render_engine_area_exit(bmain, sa); - + } + } RE_FreePersistentData(); - - for (scene = bmain->scene.first; scene; scene = scene->id.next) { - ED_render_id_flush_update(bmain, &scene->id); + /* Inform all render engines and draw managers. */ + DEGEditorUpdateContext update_ctx = {NULL}; + update_ctx.bmain = bmain; + for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + update_ctx.scene = scene; + LINKLIST_FOREACH(ViewLayer *, view_layer, &scene->view_layers) { + /* TDODO(sergey): Iterate over depsgraphs instead? */ + update_ctx.depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true); + update_ctx.view_layer = view_layer; + ED_render_id_flush_update(&update_ctx, &scene->id); + } if (scene->nodetree) { ntreeCompositUpdateRLayers(scene->nodetree); } @@ -198,7 +215,7 @@ void ED_render_engine_changed(Main *bmain) } /***************************** Updates *********************************** - * ED_render_id_flush_update gets called from DAG_id_tag_update, to do * + * ED_render_id_flush_update gets called from DEG_id_tag_update, to do * * editor level updates when the ID changes. when these ID blocks are in * * the dependency graph, we can get rid of the manual dependency checks */ @@ -295,8 +312,11 @@ static void material_changed(Main *bmain, Material *ma) BKE_icon_changed(BKE_icon_id_ensure(&ma->id)); /* glsl */ - if (ma->gpumaterial.first) - GPU_material_free(&ma->gpumaterial); + if (ma->id.recalc & ID_RECALC) { + if (!BLI_listbase_is_empty(&ma->gpumaterial)) { + GPU_material_free(&ma->gpumaterial); + } + } /* find node materials using this */ for (parent = bmain->mat.first; parent; parent = parent->id.next) { @@ -344,7 +364,6 @@ static void material_changed(Main *bmain, Material *ma) static void lamp_changed(Main *bmain, Lamp *la) { Object *ob; - Material *ma; /* icons */ BKE_icon_changed(BKE_icon_id_ensure(&la->id)); @@ -354,10 +373,6 @@ static void lamp_changed(Main *bmain, Lamp *la) if (ob->data == la && ob->gpulamp.first) GPU_lamp_free(ob); - for (ma = bmain->mat.first; ma; ma = ma->id.next) - if (ma->gpumaterial.first) - GPU_material_free(&ma->gpumaterial); - if (defmaterial.gpumaterial.first) GPU_material_free(&defmaterial.gpumaterial); } @@ -378,6 +393,7 @@ static void texture_changed(Main *bmain, Tex *tex) Lamp *la; World *wo; Scene *scene; + ViewLayer *view_layer; Object *ob; bNode *node; bool texture_draw = false; @@ -386,8 +402,11 @@ static void texture_changed(Main *bmain, Tex *tex) BKE_icon_changed(BKE_icon_id_ensure(&tex->id)); /* paint overlays */ - for (scene = bmain->scene.first; scene; scene = scene->id.next) - BKE_paint_invalidate_overlay_tex(scene, tex); + for (scene = bmain->scene.first; scene; scene = scene->id.next) { + for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { + BKE_paint_invalidate_overlay_tex(scene, view_layer, tex); + } + } /* find materials */ for (ma = bmain->mat.first; ma; ma = ma->id.next) { @@ -468,23 +487,23 @@ static void texture_changed(Main *bmain, Tex *tex) } } -static void world_changed(Main *bmain, World *wo) +static void world_changed(Main *UNUSED(bmain), World *wo) { - Material *ma; - /* icons */ BKE_icon_changed(BKE_icon_id_ensure(&wo->id)); - - /* glsl */ - for (ma = bmain->mat.first; ma; ma = ma->id.next) - if (ma->gpumaterial.first) - GPU_material_free(&ma->gpumaterial); - if (defmaterial.gpumaterial.first) - GPU_material_free(&defmaterial.gpumaterial); - - if (wo->gpumaterial.first) - GPU_material_free(&wo->gpumaterial); + /* XXX temporary flag waiting for depsgraph proper tagging */ + wo->update_flag = 1; + + /* glsl */ + if (wo->id.recalc & ID_RECALC) { + if (!BLI_listbase_is_empty(&defmaterial.gpumaterial)) { + GPU_material_free(&defmaterial.gpumaterial); + } + if (!BLI_listbase_is_empty(&wo->gpumaterial)) { + GPU_material_free(&wo->gpumaterial); + } + } } static void image_changed(Main *bmain, Image *ima) @@ -503,41 +522,29 @@ static void image_changed(Main *bmain, Image *ima) static void scene_changed(Main *bmain, Scene *scene) { Object *ob; - Material *ma; - World *wo; /* glsl */ for (ob = bmain->object.first; ob; ob = ob->id.next) { - if (ob->gpulamp.first) - GPU_lamp_free(ob); - if (ob->mode & OB_MODE_TEXTURE_PAINT) { BKE_texpaint_slots_refresh_object(scene, ob); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); GPU_drawobject_free(ob->derivedFinal); } } - - for (ma = bmain->mat.first; ma; ma = ma->id.next) - if (ma->gpumaterial.first) - GPU_material_free(&ma->gpumaterial); - - for (wo = bmain->world.first; wo; wo = wo->id.next) - if (wo->gpumaterial.first) - GPU_material_free(&wo->gpumaterial); - - if (defmaterial.gpumaterial.first) - GPU_material_free(&defmaterial.gpumaterial); } -void ED_render_id_flush_update(Main *bmain, ID *id) +void ED_render_id_flush_update(const DEGEditorUpdateContext *update_ctx, ID *id) { /* this can be called from render or baking thread when a python script makes * changes, in that case we don't want to do any editor updates, and making * GPU changes is not possible because OpenGL only works in the main thread */ - if (!BLI_thread_is_main()) + if (!BLI_thread_is_main()) { 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); @@ -563,7 +570,42 @@ void ED_render_id_flush_update(Main *bmain, 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); + } + } + } + } } @@ -572,6 +614,6 @@ void ED_render_internal_init(void) RenderEngineType *ret = RE_engines_find(RE_engine_id_BLENDER_RENDER); ret->view_update = render_view3d_update; - ret->view_draw = render_view3d_draw; + ret->render_to_view = render_view3d_draw; } |