Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2020-03-11 19:07:43 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-03-11 19:12:16 +0300
commitc476c36e400883d929a7149def8dcb6ad6157a86 (patch)
treec19c43ad1ed82f333c08bee7d2096024fed812dd /source/blender/draw/engines/workbench/workbench_engine.c
parentf01bc597a8e6bf5df19f1af0c422918c96b25e41 (diff)
Workbench Simplification Refactor
This patch is (almost) a complete rewrite of workbench engine. The features remain unchanged but the code quality is greatly improved. Hair shading is brighter but also more correct. This also introduce the concept of `DRWShaderLibrary` to make a simple include system inside the GLSL files. Differential Revision: https://developer.blender.org/D7060
Diffstat (limited to 'source/blender/draw/engines/workbench/workbench_engine.c')
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c547
1 files changed, 543 insertions, 4 deletions
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 62a192bbb25..b91ca7cf070 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -19,18 +19,557 @@
/** \file
* \ingroup draw_engine
*
- * Simple engine for drawing color and/or depth.
- * When we only need simple flat shaders.
+ * Workbench Engine:
+ *
+ * Optimized engine to draw the working viewport with solid and transparent geometry.
*/
#include "DRW_render.h"
+#include "BLI_alloca.h"
+
+#include "BKE_modifier.h"
+#include "BKE_object.h"
+#include "BKE_paint.h"
+#include "BKE_particle.h"
+
+#include "DNA_image_types.h"
+#include "DNA_fluid_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_node_types.h"
+
#include "workbench_engine.h"
#include "workbench_private.h"
#define WORKBENCH_ENGINE "BLENDER_WORKBENCH"
-/* Note: currently unused, we may want to register so we can see this when debugging the view. */
+void workbench_engine_init(void *ved)
+{
+ WORKBENCH_Data *vedata = ved;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_TextureList *txl = vedata->txl;
+
+ workbench_shader_library_ensure();
+
+ if (!stl->wpd) {
+ stl->wpd = MEM_callocN(sizeof(*stl->wpd), __func__);
+ stl->wpd->view_updated = true;
+ }
+
+ WORKBENCH_PrivateData *wpd = stl->wpd;
+ workbench_private_data_init(wpd);
+ workbench_update_world_ubo(wpd);
+
+ if (txl->dummy_image_tx == NULL) {
+ float fpixel[4] = {1.0f, 0.0f, 1.0f, 1.0f};
+ txl->dummy_image_tx = DRW_texture_create_2d(1, 1, GPU_RGBA8, 0, fpixel);
+ }
+ wpd->dummy_image_tx = txl->dummy_image_tx;
+
+ if (OBJECT_ID_PASS_ENABLED(wpd)) {
+ wpd->object_id_tx = DRW_texture_pool_query_fullscreen(GPU_R16UI, &draw_engine_workbench);
+ }
+ else {
+ /* Dont free because it's a pool texture. */
+ wpd->object_id_tx = NULL;
+ }
+
+ workbench_opaque_engine_init(vedata);
+ workbench_transparent_engine_init(vedata);
+ workbench_dof_engine_init(vedata);
+ workbench_antialiasing_engine_init(vedata);
+ workbench_volume_engine_init(vedata);
+}
+
+void workbench_cache_init(void *ved)
+{
+ WORKBENCH_Data *vedata = ved;
+
+ workbench_opaque_cache_init(vedata);
+ workbench_transparent_cache_init(vedata);
+ workbench_shadow_cache_init(vedata);
+ workbench_cavity_cache_init(vedata);
+ workbench_outline_cache_init(vedata);
+ workbench_dof_cache_init(vedata);
+ workbench_antialiasing_cache_init(vedata);
+ workbench_volume_cache_init(vedata);
+}
+
+/* TODO(fclem) DRW_cache_object_surface_material_get needs a refactor to allow passing NULL
+ * instead of gpumat_array. Avoiding all this boilerplate code. */
+static struct GPUBatch **workbench_object_surface_material_get(Object *ob)
+{
+ const int materials_len = DRW_cache_object_material_count_get(ob);
+ struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
+ memset(gpumat_array, 0, sizeof(*gpumat_array) * materials_len);
+
+ return DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len);
+}
+
+static void workbench_cache_sculpt_populate(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ eV3DShadingColorType color_type)
+{
+ const bool use_vcol = ELEM(color_type, V3D_SHADING_VERTEX_COLOR);
+ const bool use_single_drawcall = !ELEM(color_type, V3D_SHADING_MATERIAL_COLOR);
+ BLI_assert(wpd->shading.color_type != V3D_SHADING_TEXTURE_COLOR);
+
+ if (use_single_drawcall) {
+ DRWShadingGroup *grp = workbench_material_setup(wpd, ob, 0, color_type, NULL);
+ DRW_shgroup_call_sculpt(grp, ob, false, false, use_vcol);
+ }
+ else {
+ const int materials_len = DRW_cache_object_material_count_get(ob);
+ struct DRWShadingGroup **shgrps = BLI_array_alloca(shgrps, materials_len);
+ for (int i = 0; i < materials_len; i++) {
+ shgrps[i] = workbench_material_setup(wpd, ob, i + 1, color_type, NULL);
+ }
+ DRW_shgroup_call_sculpt_with_materials(shgrps, ob, false);
+ }
+}
+
+static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object *ob)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const Scene *scene = draw_ctx->scene;
+ const ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
+ const bool use_single_drawcall = imapaint->mode == IMAGEPAINT_MODE_IMAGE;
+
+ if (use_single_drawcall) {
+ struct GPUBatch *geom = DRW_cache_mesh_surface_texpaint_single_get(ob);
+ if (geom) {
+ Image *ima = imapaint->canvas;
+ int interp = (imapaint->interp == IMAGEPAINT_INTERP_LINEAR) ? SHD_INTERP_LINEAR :
+ SHD_INTERP_CLOSEST;
+
+ DRWShadingGroup *grp = workbench_image_setup(wpd, ob, 0, ima, NULL, interp);
+ DRW_shgroup_call(grp, geom, ob);
+ }
+ }
+ else {
+ struct GPUBatch **geoms = DRW_cache_mesh_surface_texpaint_get(ob);
+ if (geoms) {
+ const int materials_len = DRW_cache_object_material_count_get(ob);
+ for (int i = 0; i < materials_len; i++) {
+ DRWShadingGroup *grp = workbench_image_setup(wpd, ob, i + 1, NULL, NULL, 0);
+ DRW_shgroup_call(grp, geoms[i], ob);
+ }
+ }
+ }
+}
+
+static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ eV3DShadingColorType color_type,
+ bool *r_transp)
+{
+ const bool use_tex = ELEM(color_type, V3D_SHADING_TEXTURE_COLOR);
+ const bool use_vcol = ELEM(color_type, V3D_SHADING_VERTEX_COLOR);
+ const bool use_single_drawcall = !ELEM(
+ color_type, V3D_SHADING_MATERIAL_COLOR, V3D_SHADING_TEXTURE_COLOR);
+
+ if (use_single_drawcall) {
+ struct GPUBatch *geom = (use_vcol) ? DRW_cache_mesh_surface_vertpaint_get(ob) :
+ DRW_cache_object_surface_get(ob);
+ if (geom) {
+ DRWShadingGroup *grp = workbench_material_setup(wpd, ob, 0, color_type, r_transp);
+ DRW_shgroup_call(grp, geom, ob);
+ }
+ }
+ else {
+ struct GPUBatch **geoms = (use_tex) ? DRW_cache_mesh_surface_texpaint_get(ob) :
+ workbench_object_surface_material_get(ob);
+ if (geoms) {
+ const int materials_len = DRW_cache_object_material_count_get(ob);
+ for (int i = 0; i < materials_len; i++) {
+ DRWShadingGroup *grp = workbench_material_setup(wpd, ob, i + 1, color_type, r_transp);
+ DRW_shgroup_call(grp, geoms[i], ob);
+ }
+ }
+ }
+}
+
+static void workbench_cache_hair_populate(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ ModifierData *md,
+ eV3DShadingColorType color_type,
+ bool use_texpaint_mode)
+{
+ ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
+ ParticleSettings *part = psys->part;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const Scene *scene = draw_ctx->scene;
+
+ const ImagePaintSettings *imapaint = use_texpaint_mode ? &scene->toolsettings->imapaint : NULL;
+ Image *ima = (imapaint && imapaint->mode == IMAGEPAINT_MODE_IMAGE) ? imapaint->canvas : NULL;
+ int interp = (imapaint && imapaint->interp == IMAGEPAINT_INTERP_LINEAR) ? SHD_INTERP_LINEAR :
+ SHD_INTERP_CLOSEST;
+ DRWShadingGroup *grp = (use_texpaint_mode) ?
+ workbench_image_hair_setup(wpd, ob, part->omat, ima, NULL, interp) :
+ workbench_material_hair_setup(wpd, ob, part->omat, color_type);
+
+ DRW_shgroup_hair_create_sub(ob, psys, md, grp);
+}
+
+/* Decide what colortype to draw the object with.
+ * In some cases it can be overwritten by workbench_material_setup(). */
+static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ bool *r_sculpt_pbvh,
+ bool *r_texpaint_mode,
+ bool *r_draw_shadow)
+{
+ eV3DShadingColorType color_type = wpd->shading.color_type;
+ const Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const bool is_active = (ob == draw_ctx->obact);
+ const bool is_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
+ !DRW_state_is_image_render();
+ const bool is_render = DRW_state_is_image_render() && (draw_ctx->v3d == NULL);
+ const bool is_texpaint_mode = is_active && (wpd->ctx_mode == CTX_MODE_PAINT_TEXTURE);
+ const bool is_vertpaint_mode = is_active && (wpd->ctx_mode == CTX_MODE_PAINT_VERTEX);
+
+ if ((color_type == V3D_SHADING_TEXTURE_COLOR) && (ob->dt < OB_TEXTURE)) {
+ color_type = V3D_SHADING_MATERIAL_COLOR;
+ }
+ /* Disable color mode if data layer is unavailable. */
+ if ((color_type == V3D_SHADING_TEXTURE_COLOR) && (me == NULL || me->mloopuv == NULL)) {
+ color_type = V3D_SHADING_MATERIAL_COLOR;
+ }
+ if ((color_type == V3D_SHADING_VERTEX_COLOR) && (me == NULL || me->mloopcol == NULL)) {
+ color_type = V3D_SHADING_OBJECT_COLOR;
+ }
+
+ *r_sculpt_pbvh = is_sculpt_pbvh;
+ *r_texpaint_mode = false;
+
+ if (!is_sculpt_pbvh && !is_render) {
+ /* Force texture or vertex mode if object is in paint mode. */
+ if (is_texpaint_mode && me && me->mloopuv) {
+ color_type = V3D_SHADING_TEXTURE_COLOR;
+ *r_texpaint_mode = true;
+ }
+ else if (is_vertpaint_mode && me && me->mloopcol) {
+ color_type = V3D_SHADING_VERTEX_COLOR;
+ }
+ }
+
+ if (r_draw_shadow) {
+ *r_draw_shadow = (ob->dtx & OB_DRAW_NO_SHADOW_CAST) == 0 && SHADOW_ENABLED(wpd);
+ /* Currently unsupported in sculpt mode. We could revert to the slow
+ * method in this case but I'm not sure if it's a good idea given that
+ * sculpted meshes are heavy to begin with. */
+ if (is_sculpt_pbvh) {
+ *r_draw_shadow = false;
+ }
+
+ if (is_active && DRW_object_use_hide_faces(ob)) {
+ *r_draw_shadow = false;
+ }
+ }
+
+ return color_type;
+}
+
+void workbench_cache_populate(void *ved, Object *ob)
+{
+ WORKBENCH_Data *vedata = ved;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PrivateData *wpd = stl->wpd;
+
+ if (!DRW_object_is_renderable(ob)) {
+ return;
+ }
+
+ if (ob->type == OB_MESH && ob->modifiers.first != NULL) {
+ bool use_sculpt_pbvh, use_texpaint_mode;
+ int color_type = workbench_color_type_get(wpd, ob, &use_sculpt_pbvh, &use_texpaint_mode, NULL);
+
+ LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
+ if (md->type != eModifierType_ParticleSystem) {
+ continue;
+ }
+ ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
+ continue;
+ }
+ ParticleSettings *part = psys->part;
+ const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
+
+ if (draw_as == PART_DRAW_PATH) {
+ workbench_cache_hair_populate(wpd, ob, md, color_type, use_texpaint_mode);
+ }
+ }
+ }
+
+ if (!(ob->base_flag & BASE_FROM_DUPLI)) {
+ ModifierData *md = modifiers_findByType(ob, eModifierType_Fluid);
+ if (md && modifier_isEnabled(wpd->scene, md, eModifierMode_Realtime)) {
+ FluidModifierData *fmd = (FluidModifierData *)md;
+ if (fmd->domain && fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) {
+ workbench_volume_cache_populate(vedata, wpd->scene, ob, md);
+ return; /* Do not draw solid in this case. */
+ }
+ }
+ }
+
+ if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
+ return;
+ }
+
+ if ((ob->dt < OB_SOLID) && !DRW_state_is_scene_render()) {
+ return;
+ }
+
+ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
+ bool use_sculpt_pbvh, use_texpaint_mode, draw_shadow, has_transp_mat = false;
+ eV3DShadingColorType color_type = workbench_color_type_get(
+ wpd, ob, &use_sculpt_pbvh, &use_texpaint_mode, &draw_shadow);
+
+ if (use_sculpt_pbvh) {
+ workbench_cache_sculpt_populate(wpd, ob, color_type);
+ }
+ else if (use_texpaint_mode) {
+ workbench_cache_texpaint_populate(wpd, ob);
+ }
+ else {
+ workbench_cache_common_populate(wpd, ob, color_type, &has_transp_mat);
+ }
+
+ if (draw_shadow) {
+ workbench_shadow_cache_populate(vedata, ob, has_transp_mat);
+ }
+ }
+}
+
+void workbench_cache_finish(void *ved)
+{
+ WORKBENCH_Data *vedata = ved;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_PrivateData *wpd = stl->wpd;
+
+ /* TODO(fclem) Only do this when really needed. */
+ {
+ /* HACK we allocate the infront depth here to avoid the overhead when if is not needed. */
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ DRW_texture_ensure_fullscreen_2d(&dtxl->depth_in_front, GPU_DEPTH24_STENCIL8, 0);
+
+ GPU_framebuffer_ensure_config(&dfbl->in_front_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front),
+ GPU_ATTACHMENT_TEXTURE(dtxl->color),
+ });
+
+ GPU_framebuffer_ensure_config(&fbl->opaque_infront_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front),
+ GPU_ATTACHMENT_TEXTURE(wpd->material_buffer_tx),
+ GPU_ATTACHMENT_TEXTURE(wpd->normal_buffer_tx),
+ GPU_ATTACHMENT_TEXTURE(wpd->object_id_tx),
+ });
+
+ GPU_framebuffer_ensure_config(&fbl->transp_accum_infront_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front),
+ GPU_ATTACHMENT_TEXTURE(wpd->accum_buffer_tx),
+ GPU_ATTACHMENT_TEXTURE(wpd->reveal_buffer_tx),
+ });
+ }
+
+ if (wpd->object_id_tx) {
+ GPU_framebuffer_ensure_config(&fbl->id_clear_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(wpd->object_id_tx),
+ });
+ }
+ else {
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->id_clear_fb);
+ }
+
+ workbench_update_material_ubos(wpd);
+
+ /* TODO don't free reuse next redraw. */
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 2; j++) {
+ for (int k = 0; k < 2; k++) {
+ if (wpd->prepass[i][j][k].material_hash) {
+ BLI_ghash_free(wpd->prepass[i][j][k].material_hash, NULL, NULL);
+ wpd->prepass[i][j][k].material_hash = NULL;
+ }
+ }
+ }
+ }
+}
+
+/* Used by viewport rendering & final rendering.
+ * Do one render loop iteration (i.e: One TAA sample). */
+void workbench_draw_sample(void *ved)
+{
+ WORKBENCH_Data *vedata = ved;
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
+ WORKBENCH_PassList *psl = vedata->psl;
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ float clear_col_with_alpha[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+
+ const bool do_render = workbench_antialiasing_setup(vedata);
+ const bool xray_is_visible = wpd->shading.xray_alpha > 0.0f;
+ const bool do_transparent_infront_pass = !DRW_pass_is_empty(psl->transp_accum_infront_ps);
+ const bool do_transparent_pass = !DRW_pass_is_empty(psl->transp_accum_ps);
+ const bool do_opaque_infront_pass = !DRW_pass_is_empty(psl->opaque_infront_ps);
+ const bool do_opaque_pass = !DRW_pass_is_empty(psl->opaque_ps) || do_opaque_infront_pass;
+
+ if (dfbl->in_front_fb) {
+ GPU_framebuffer_bind(dfbl->in_front_fb);
+ GPU_framebuffer_clear_depth(dfbl->in_front_fb, 1.0f);
+ }
+
+ if (do_render) {
+ GPU_framebuffer_bind(dfbl->default_fb);
+ GPU_framebuffer_clear_color_depth_stencil(dfbl->default_fb, wpd->background_color, 1.0f, 0x00);
+
+ if (fbl->id_clear_fb) {
+ GPU_framebuffer_bind(fbl->id_clear_fb);
+ GPU_framebuffer_clear_color(fbl->id_clear_fb, clear_col);
+ }
+
+ if (do_opaque_pass) {
+ GPU_framebuffer_bind(fbl->opaque_fb);
+ DRW_draw_pass(psl->opaque_ps);
+
+ if (psl->shadow_ps[0]) {
+ DRW_draw_pass(psl->shadow_ps[0]);
+ DRW_draw_pass(psl->shadow_ps[1]);
+ }
+
+ if (do_opaque_infront_pass) {
+ GPU_framebuffer_bind(fbl->opaque_infront_fb);
+ DRW_draw_pass(psl->opaque_infront_ps);
+
+ GPU_framebuffer_bind(fbl->opaque_fb);
+ DRW_draw_pass(psl->merge_infront_ps);
+ }
+
+ GPU_framebuffer_bind(dfbl->default_fb);
+ DRW_draw_pass(psl->composite_ps);
+
+ if (psl->cavity_ps) {
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ DRW_draw_pass(psl->cavity_ps);
+ }
+ }
+
+ workbench_volume_draw_pass(vedata);
+
+ if (xray_is_visible) {
+ if (do_transparent_pass) {
+ GPU_framebuffer_bind(fbl->transp_accum_fb);
+ GPU_framebuffer_clear_color(fbl->transp_accum_fb, clear_col_with_alpha);
+
+ DRW_draw_pass(psl->transp_accum_ps);
+
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ DRW_draw_pass(psl->transp_resolve_ps);
+ }
+
+ if (do_transparent_infront_pass) {
+ GPU_framebuffer_bind(fbl->transp_accum_infront_fb);
+ GPU_framebuffer_clear_color(fbl->transp_accum_infront_fb, clear_col_with_alpha);
+
+ DRW_draw_pass(psl->transp_accum_infront_ps);
+
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ DRW_draw_pass(psl->transp_resolve_ps);
+ }
+ }
+
+ workbench_transparent_draw_depth_pass(vedata);
+
+ if (psl->outline_ps) {
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ DRW_draw_pass(psl->outline_ps);
+ }
+
+ workbench_dof_draw_pass(vedata);
+ }
+
+ workbench_antialiasing_draw_pass(vedata);
+}
+
+/* Viewport rendering. */
+static void workbench_draw_scene(void *ved)
+{
+ WORKBENCH_Data *vedata = ved;
+ WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
+
+ if (DRW_state_is_opengl_render()) {
+ while (wpd->taa_sample < max_ii(1, wpd->taa_sample_len)) {
+ workbench_update_world_ubo(wpd);
+
+ workbench_draw_sample(vedata);
+ }
+ }
+ else {
+ workbench_draw_sample(vedata);
+ }
+
+ workbench_draw_finish(vedata);
+}
+
+void workbench_draw_finish(void *ved)
+{
+ WORKBENCH_Data *vedata = ved;
+ workbench_volume_draw_finish(vedata);
+}
+
+static void workbench_engine_free(void)
+{
+ workbench_shader_free();
+}
+
+static void workbench_view_update(void *vedata)
+{
+ WORKBENCH_Data *data = vedata;
+ workbench_antialiasing_view_updated(data);
+}
+
+static void workbench_id_update(void *UNUSED(vedata), struct ID *id)
+{
+ if (GS(id->name) == ID_OB) {
+ WORKBENCH_ObjectData *oed = (WORKBENCH_ObjectData *)DRW_drawdata_get(id,
+ &draw_engine_workbench);
+ if (oed != NULL && oed->dd.recalc != 0) {
+ oed->shadow_bbox_dirty = (oed->dd.recalc & ID_RECALC_ALL) != 0;
+ oed->dd.recalc = 0;
+ }
+ }
+}
+
+static const DrawEngineDataSize workbench_data_size = DRW_VIEWPORT_DATA_SIZE(WORKBENCH_Data);
+
+DrawEngineType draw_engine_workbench = {
+ NULL,
+ NULL,
+ N_("Workbench"),
+ &workbench_data_size,
+ &workbench_engine_init,
+ &workbench_engine_free,
+ &workbench_cache_init,
+ &workbench_cache_populate,
+ &workbench_cache_finish,
+ &workbench_draw_scene,
+ &workbench_view_update,
+ &workbench_id_update,
+ &workbench_render,
+};
+
RenderEngineType DRW_engine_viewport_workbench_type = {
NULL,
NULL,
@@ -44,7 +583,7 @@ RenderEngineType DRW_engine_viewport_workbench_type = {
NULL,
NULL,
&workbench_render_update_passes,
- &draw_engine_workbench_solid,
+ &draw_engine_workbench,
{NULL, NULL, NULL},
};