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:
Diffstat (limited to 'source/blender/draw/intern/draw_manager.c')
-rw-r--r--source/blender/draw/intern/draw_manager.c382
1 files changed, 216 insertions, 166 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 5ae0351cdd3..45e4c2a575e 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -51,6 +51,8 @@
#include "BKE_pbvh.h"
#include "BKE_pointcache.h"
#include "BKE_pointcloud.h"
+#include "BKE_screen.h"
+#include "BKE_subdiv_modifier.h"
#include "BKE_volume.h"
#include "DNA_camera_types.h"
@@ -68,6 +70,7 @@
#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
#include "GPU_matrix.h"
+#include "GPU_shader_shared.h"
#include "GPU_state.h"
#include "GPU_uniform_buffer.h"
#include "GPU_viewport.h"
@@ -84,10 +87,12 @@
#include "wm_window.h"
#include "draw_color_management.h"
+#include "draw_manager.h"
#include "draw_manager_profiling.h"
#include "draw_manager_testing.h"
#include "draw_manager_text.h"
#include "draw_shader.h"
+#include "draw_subdivision.h"
#include "draw_texture_pool.h"
/* only for callbacks */
@@ -112,8 +117,10 @@
/** Render State: No persistent data between draw calls. */
DRWManager DST = {NULL};
-static ListBase DRW_engines = {NULL, NULL};
-static int g_registered_engine_len = 0;
+static struct {
+ ListBase /*DRWRegisteredDrawEngine*/ engines;
+ int len;
+} g_registered_engines = {{NULL}};
static void drw_state_prepare_clean_for_draw(DRWManager *dst)
{
@@ -169,7 +176,8 @@ static void drw_task_graph_deinit(void)
{
BLI_task_graph_work_and_wait(DST.task_graph);
- BLI_gset_free(DST.delayed_extraction, (void (*)(void *key))drw_batch_cache_generate_requested);
+ BLI_gset_free(DST.delayed_extraction,
+ (void (*)(void *key))drw_batch_cache_generate_requested_evaluated_mesh);
DST.delayed_extraction = NULL;
BLI_task_graph_work_and_wait(DST.task_graph);
@@ -199,31 +207,12 @@ bool DRW_object_is_renderable(const Object *ob)
return true;
}
-/* Does `ob` needs to be rendered in edit mode.
- *
- * When using duplicate linked meshes, objects that are not in edit-mode will be drawn as
- * it is in edit mode, when another object with the same mesh is in edit mode.
- * This will not be the case when one of the objects are influenced by modifiers. */
bool DRW_object_is_in_edit_mode(const Object *ob)
{
if (BKE_object_is_in_editmode(ob)) {
if (ob->type == OB_MESH) {
if ((ob->mode & OB_MODE_EDIT) == 0) {
- Mesh *me = (Mesh *)ob->data;
- BMEditMesh *embm = me->edit_mesh;
- /* Sanity check when rendering in multiple windows. */
- if (embm && embm->mesh_eval_final == NULL) {
- return false;
- }
- /* Do not draw ob with edit overlay when edit data is present and is modified. */
- if (embm && embm->mesh_eval_cage && (embm->mesh_eval_cage != embm->mesh_eval_final)) {
- return false;
- }
- /* Check if the object that we are drawing is modified. */
- if (!DEG_is_original_id(&me->id)) {
- return false;
- }
- return true;
+ return false;
}
}
return true;
@@ -231,10 +220,6 @@ bool DRW_object_is_in_edit_mode(const Object *ob)
return false;
}
-/**
- * Return whether this object is visible depending if
- * we are rendering or drawing in the viewport.
- */
int DRW_object_visibility_in_active_context(const Object *ob)
{
const eEvaluationMode mode = DRW_state_is_scene_render() ? DAG_EVAL_RENDER : DAG_EVAL_VIEWPORT;
@@ -317,7 +302,6 @@ struct DupliObject *DRW_object_get_dupli(const Object *UNUSED(ob))
/** \name Viewport (DRW_viewport)
* \{ */
-/* WARNING: only use for custom pipeline. 99% of the time, you don't want to use this. */
void DRW_render_viewport_size_set(const int size[2])
{
DST.size[0] = size[0];
@@ -439,7 +423,7 @@ DRWData *DRW_viewport_data_create(void)
}
for (int i = 0; i < 2; i++) {
- drw_data->view_data[i] = DRW_view_data_create(&DRW_engines);
+ drw_data->view_data[i] = DRW_view_data_create(&g_registered_engines.engines);
}
return drw_data;
}
@@ -561,8 +545,9 @@ static void drw_manager_init(DRWManager *dst, GPUViewport *viewport, const int s
drw_viewport_data_reset(dst->vmempool);
+ bool do_validation = true;
if (size == NULL && viewport == NULL) {
- /* Avoid division by 0. Engines will either overide this or not use it. */
+ /* Avoid division by 0. Engines will either override this or not use it. */
dst->size[0] = 1.0f;
dst->size[1] = 1.0f;
}
@@ -576,11 +561,15 @@ static void drw_manager_init(DRWManager *dst, GPUViewport *viewport, const int s
BLI_assert(size);
dst->size[0] = size[0];
dst->size[1] = size[1];
+ /* Fix case when used in DRW_cache_restart(). */
+ do_validation = false;
}
dst->inv_size[0] = 1.0f / dst->size[0];
dst->inv_size[1] = 1.0f / dst->size[1];
- DRW_view_data_texture_list_size_validate(dst->view_data_active, (int[2]){UNPACK2(dst->size)});
+ if (do_validation) {
+ DRW_view_data_texture_list_size_validate(dst->view_data_active, (int[2]){UNPACK2(dst->size)});
+ }
if (viewport) {
DRW_view_data_default_lists_from_viewport(dst->view_data_active, viewport);
@@ -726,7 +715,7 @@ static void drw_duplidata_load(Object *ob)
void **value;
if (!BLI_ghash_ensure_p(DST.dupli_ghash, key, &value)) {
- *value = MEM_callocN(sizeof(void *) * g_registered_engine_len, __func__);
+ *value = MEM_callocN(sizeof(void *) * g_registered_engines.len, __func__);
/* TODO: Meh a bit out of place but this is nice as it is
* only done once per instance type. */
@@ -741,7 +730,7 @@ static void drw_duplidata_load(Object *ob)
static void duplidata_value_free(void *val)
{
void **dupli_datas = val;
- for (int i = 0; i < g_registered_engine_len; i++) {
+ for (int i = 0; i < g_registered_engines.len; i++) {
MEM_SAFE_FREE(dupli_datas[i]);
}
MEM_freeN(val);
@@ -755,8 +744,11 @@ static void duplidata_key_free(void *key)
}
else {
Object temp_object = *dupli_key->ob;
+ /* Do not modify the original bound-box. */
+ temp_object.runtime.bb = NULL;
BKE_object_replace_data_on_shallow_copy(&temp_object, dupli_key->ob_data);
drw_batch_cache_generate_requested(&temp_object);
+ MEM_SAFE_FREE(temp_object.runtime.bb);
}
MEM_freeN(key);
}
@@ -769,14 +761,13 @@ static void drw_duplidata_free(void)
}
}
-/* Return NULL if not a dupli or a pointer of pointer to the engine data */
void **DRW_duplidata_get(void *vedata)
{
if (DST.dupli_source == NULL) {
return NULL;
}
ViewportEngineData *ved = (ViewportEngineData *)vedata;
- DrawEngineType *engine_type = (DrawEngineType *)ved->engine_type;
+ DRWRegisteredDrawEngine *engine_type = (DRWRegisteredDrawEngine *)ved->engine_type;
return &DST.dupli_datas[engine_type->index];
}
@@ -865,9 +856,6 @@ static bool id_can_have_drawdata(const ID *id)
return id_type_can_have_drawdata(GS(id->name));
}
-/* Get DrawData from the given ID-block. In order for this to work, we assume that
- * the DrawData pointer is stored in the struct in the same fashion as in IdDdtTemplate.
- */
DrawDataList *DRW_drawdatalist_from_id(ID *id)
{
/* only some ID-blocks have this info for now, so we cast the
@@ -1139,7 +1127,6 @@ static void drw_engines_draw_text(void)
}
}
-/* Draw render engine info. */
void DRW_draw_region_engine_info(int xoffset, int *yoffset, int line_height)
{
DRW_ENABLED_ENGINE_ITER (DST.view_data_active, engine, data) {
@@ -1332,7 +1319,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
.object_mode = OB_MODE_OBJECT,
};
- /* Custom lightweight init to avoid reseting the mempools. */
+ /* Custom lightweight initialize to avoid resetting the memory-pools. */
DST.viewport = viewport;
DST.vmempool = drw_viewport_data_ensure(DST.viewport);
@@ -1358,6 +1345,61 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
BLI_ticket_mutex_unlock(DST.gl_context_mutex);
}
+/* update a viewport which belongs to a GPUOffscreen */
+static void drw_notify_view_update_offscreen(struct Depsgraph *depsgraph,
+ RenderEngineType *engine_type,
+ ARegion *region,
+ View3D *v3d,
+ GPUViewport *viewport)
+{
+
+ if (viewport && GPU_viewport_do_update(viewport)) {
+
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
+ RegionView3D *rv3d = region->regiondata;
+
+ const bool gpencil_engine_needed = drw_gpencil_engine_needed(depsgraph, v3d);
+
+ /* Reset before using it. */
+ drw_state_prepare_clean_for_draw(&DST);
+
+ DST.draw_ctx = (DRWContextState){
+ .region = region,
+ .rv3d = rv3d,
+ .v3d = v3d,
+ .scene = scene,
+ .view_layer = view_layer,
+ .obact = OBACT(view_layer),
+ .engine_type = engine_type,
+ .depsgraph = depsgraph,
+ };
+
+ /* Custom lightweight initialize to avoid resetting the memory-pools. */
+ DST.viewport = viewport;
+ DST.vmempool = drw_viewport_data_ensure(DST.viewport);
+
+ /* Separate update for each stereo view. */
+ int view_count = GPU_viewport_is_stereo_get(viewport) ? 2 : 1;
+ for (int view = 0; view < view_count; view++) {
+ DST.view_data_active = DST.vmempool->view_data[view];
+
+ drw_engines_enable(view_layer, engine_type, gpencil_engine_needed);
+ drw_engines_data_validate();
+
+ DRW_ENABLED_ENGINE_ITER (DST.view_data_active, draw_engine, data) {
+ if (draw_engine->view_update) {
+ draw_engine->view_update(data);
+ }
+ }
+
+ drw_engines_disable();
+ }
+
+ drw_manager_exit(&DST);
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1415,6 +1457,27 @@ void DRW_draw_callbacks_post_scene(void)
ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.region, REGION_DRAW_POST_VIEW);
+#ifdef WITH_XR_OPENXR
+ /* XR callbacks (controllers, custom draw functions) for session mirror. */
+ if ((v3d->flag & V3D_XR_SESSION_MIRROR) != 0) {
+ if ((v3d->flag2 & V3D_XR_SHOW_CONTROLLERS) != 0) {
+ ARegionType *art = WM_xr_surface_controller_region_type_get();
+ if (art) {
+ ED_region_surface_draw_cb_draw(art, REGION_DRAW_POST_VIEW);
+ }
+ }
+ if ((v3d->flag2 & V3D_XR_SHOW_CUSTOM_OVERLAYS) != 0) {
+ SpaceType *st = BKE_spacetype_from_id(SPACE_VIEW3D);
+ if (st) {
+ ARegionType *art = BKE_regiontype_from_id(st, RGN_TYPE_XR);
+ if (art) {
+ ED_region_surface_draw_cb_draw(art, REGION_DRAW_POST_VIEW);
+ }
+ }
+ }
+ }
+#endif
+
/* Callback can be nasty and do whatever they want with the state.
* Don't trust them! */
DRW_state_reset();
@@ -1461,6 +1524,46 @@ void DRW_draw_callbacks_post_scene(void)
ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, region, true);
GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
+
+#ifdef WITH_XR_OPENXR
+ if ((v3d->flag & V3D_XR_SESSION_SURFACE) != 0) {
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+
+ DRW_state_reset();
+
+ GPU_framebuffer_bind(dfbl->overlay_fb);
+
+ GPU_matrix_projection_set(rv3d->winmat);
+ GPU_matrix_set(rv3d->viewmat);
+
+ /* XR callbacks (controllers, custom draw functions) for session surface. */
+ if (((v3d->flag2 & V3D_XR_SHOW_CONTROLLERS) != 0) ||
+ ((v3d->flag2 & V3D_XR_SHOW_CUSTOM_OVERLAYS) != 0)) {
+ GPU_depth_test(GPU_DEPTH_NONE);
+ GPU_apply_state();
+
+ if ((v3d->flag2 & V3D_XR_SHOW_CONTROLLERS) != 0) {
+ ARegionType *art = WM_xr_surface_controller_region_type_get();
+ if (art) {
+ ED_region_surface_draw_cb_draw(art, REGION_DRAW_POST_VIEW);
+ }
+ }
+ if ((v3d->flag2 & V3D_XR_SHOW_CUSTOM_OVERLAYS) != 0) {
+ SpaceType *st = BKE_spacetype_from_id(SPACE_VIEW3D);
+ if (st) {
+ ARegionType *art = BKE_regiontype_from_id(st, RGN_TYPE_XR);
+ if (art) {
+ ED_region_surface_draw_cb_draw(art, REGION_DRAW_POST_VIEW);
+ }
+ }
+ }
+
+ DRW_state_reset();
+ }
+
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
+ }
+#endif
}
}
@@ -1479,9 +1582,6 @@ struct DRWTextStore *DRW_text_cache_ensure(void)
/** \name Main Draw Loops (DRW_draw)
* \{ */
-/* Everything starts here.
- * This function takes care of calling all cache and rendering functions
- * for each relevant engine / mode engine. */
void DRW_draw_view(const bContext *C)
{
View3D *v3d = CTX_wm_view3d(C);
@@ -1509,10 +1609,6 @@ void DRW_draw_view(const bContext *C)
}
}
-/**
- * Used for both regular and off-screen drawing.
- * Need to reset DST before calling this function
- */
void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
RenderEngineType *engine_type,
ARegion *region,
@@ -1659,9 +1755,6 @@ void DRW_draw_render_loop(struct Depsgraph *depsgraph,
DRW_draw_render_loop_ex(depsgraph, engine_type, region, v3d, viewport, NULL);
}
-/**
- * \param viewport: can be NULL, in this case we create one.
- */
void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
RenderEngineType *engine_type,
ARegion *region,
@@ -1672,11 +1765,14 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
GPUOffScreen *ofs,
GPUViewport *viewport)
{
- /* Create temporary viewport if needed. */
+ /* Create temporary viewport if needed or update the existing viewport. */
GPUViewport *render_viewport = viewport;
if (viewport == NULL) {
render_viewport = GPU_viewport_create();
}
+ else {
+ drw_notify_view_update_offscreen(depsgraph, engine_type, region, v3d, render_viewport);
+ }
GPU_viewport_bind_from_offscreen(render_viewport, ofs);
@@ -1690,12 +1786,12 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
DRW_draw_render_loop_ex(depsgraph, engine_type, region, v3d, render_viewport, NULL);
if (draw_background) {
- /* HACK(fclem): In this case we need to make sure the final alpha is 1.
+ /* HACK(@fclem): In this case we need to make sure the final alpha is 1.
* We use the blend mode to ensure that. A better way to fix that would
* be to do that in the color-management shader. */
GPU_offscreen_bind(ofs, false);
GPU_clear_color(0.0f, 0.0f, 0.0f, 1.0f);
- /* Premult Alpha over black background. */
+ /* Pre-multiply alpha over black background. */
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
}
@@ -1720,7 +1816,6 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
}
}
-/* Helper to check if exit object type to render. */
bool DRW_render_check_grease_pencil(Depsgraph *depsgraph)
{
if (!drw_gpencil_engine_needed(depsgraph, NULL)) {
@@ -1949,9 +2044,6 @@ void DRW_render_object_iter(
drw_task_graph_deinit();
}
-/* Assume a valid gl context is bound (and that the gl_context_mutex has been acquired).
- * This function only setup DST and execute the given function.
- * Warning: similar to DRW_render_to_image you cannot use default lists (dfbl & dtxl). */
void DRW_custom_pipeline(DrawEngineType *draw_engine_type,
struct Depsgraph *depsgraph,
void (*callback)(void *vedata, void *user_data),
@@ -1997,8 +2089,6 @@ void DRW_custom_pipeline(DrawEngineType *draw_engine_type,
drw_manager_exit(&DST);
}
-/* Used when the render engine want to redo another cache populate inside the same render frame.
- */
void DRW_cache_restart(void)
{
drw_manager_init(&DST, DST.viewport, (int[2]){UNPACK2(DST.size)});
@@ -2189,7 +2279,6 @@ static void draw_select_framebuffer_depth_only_setup(const int size[2])
}
}
-/* Must run after all instance datas have been added. */
void DRW_render_instance_buffer_finish(void)
{
BLI_assert_msg(!DST.buffer_finish_called, "DRW_render_instance_buffer_finish called twice!");
@@ -2198,7 +2287,6 @@ void DRW_render_instance_buffer_finish(void)
drw_resource_buffer_finish(DST.vmempool);
}
-/* WARNING: Changing frame might free the ViewLayerEngineData */
void DRW_render_set_time(RenderEngine *engine, Depsgraph *depsgraph, int frame, float subframe)
{
RE_engine_frame_set(engine, frame, subframe);
@@ -2206,9 +2294,6 @@ void DRW_render_set_time(RenderEngine *engine, Depsgraph *depsgraph, int frame,
DST.draw_ctx.view_layer = DEG_get_evaluated_view_layer(depsgraph);
}
-/**
- * object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing).
- */
void DRW_draw_select_loop(struct Depsgraph *depsgraph,
ARegion *region,
View3D *v3d,
@@ -2437,16 +2522,17 @@ static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph,
ARegion *region,
View3D *v3d,
GPUViewport *viewport,
- const bool use_opengl_context)
+ const bool use_gpencil,
+ const bool use_basic,
+ const bool use_overlay)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RegionView3D *rv3d = region->regiondata;
- if (use_opengl_context) {
- DRW_opengl_context_enable();
- }
+ /* Reset before using it. */
+ drw_state_prepare_clean_for_draw(&DST);
DST.options.is_depth = true;
@@ -2462,6 +2548,18 @@ static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph,
.depsgraph = depsgraph,
};
drw_context_state_init();
+ drw_manager_init(&DST, viewport, NULL);
+
+ if (use_gpencil) {
+ use_drw_engine(&draw_engine_gpencil_type);
+ }
+ if (use_basic) {
+ drw_engines_enable_basic();
+ }
+ if (use_overlay) {
+ drw_engines_enable_overlays();
+ }
+
drw_task_graph_init();
/* Setup frame-buffer. */
@@ -2529,62 +2627,23 @@ static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph,
drw_engines_disable();
drw_manager_exit(&DST);
-
- /* Changing context. */
- if (use_opengl_context) {
- DRW_opengl_context_disable();
- }
}
-/**
- * object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
- */
void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
ARegion *region,
View3D *v3d,
GPUViewport *viewport)
{
- /* Reset before using it. */
- drw_state_prepare_clean_for_draw(&DST);
-
- /* Required by `drw_manager_init()` */
- DST.draw_ctx.region = region;
- DST.draw_ctx.rv3d = region->regiondata;
- drw_manager_init(&DST, viewport, NULL);
-
- /* Get list of enabled engines */
- {
- /* Required by `DRW_state_draw_support()` */
- DST.draw_ctx.v3d = v3d;
-
- drw_engines_enable_basic();
- if (DRW_state_draw_support()) {
- drw_engines_enable_overlays();
- }
- }
-
- drw_draw_depth_loop_impl(depsgraph, region, v3d, viewport, false);
+ drw_draw_depth_loop_impl(
+ depsgraph, region, v3d, viewport, false, true, DRW_state_draw_support());
}
-/**
- * Converted from ED_view3d_draw_depth_gpencil (legacy drawing).
- */
void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
ARegion *region,
View3D *v3d,
GPUViewport *viewport)
{
- /* Reset before using it. */
- drw_state_prepare_clean_for_draw(&DST);
-
- /* Required by `drw_manager_init()` */
- DST.draw_ctx.region = region;
- DST.draw_ctx.rv3d = region->regiondata;
- drw_manager_init(&DST, viewport, NULL);
-
- use_drw_engine(&draw_engine_gpencil_type);
-
- drw_draw_depth_loop_impl(depsgraph, region, v3d, viewport, false);
+ drw_draw_depth_loop_impl(depsgraph, region, v3d, viewport, true, false, false);
}
void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, const rcti *rect)
@@ -2661,9 +2720,6 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons
drw_manager_exit(&DST);
}
-/**
- * Clears the Depth Buffer and draws only the specified object.
- */
void DRW_draw_depth_object(
Scene *scene, ARegion *region, View3D *v3d, GPUViewport *viewport, Object *object)
{
@@ -2687,11 +2743,15 @@ void DRW_draw_depth_object(
GPU_framebuffer_clear_depth(depth_fb, 1.0f);
GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
- const float(*world_clip_planes)[4] = NULL;
- if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
+ struct GPUClipPlanes planes;
+ const bool use_clipping_planes = RV3D_CLIPPING_ENABLED(v3d, rv3d);
+ if (use_clipping_planes) {
GPU_clip_distances(6);
ED_view3d_clipping_local(rv3d, object->obmat);
- world_clip_planes = rv3d->clip_local;
+ for (int i = 0; i < 6; i++) {
+ copy_v4_v4(planes.world[i], rv3d->clip_local[i]);
+ }
+ copy_m4_m4(planes.ModelMatrix, object->obmat);
}
drw_batch_cache_validate(object);
@@ -2713,14 +2773,19 @@ void DRW_draw_depth_object(
BLI_task_graph_work_and_wait(task_graph);
BLI_task_graph_free(task_graph);
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
- GPU_SHADER_CFG_DEFAULT;
+ const eGPUShaderConfig sh_cfg = use_clipping_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
- if (world_clip_planes != NULL) {
- GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes);
+
+ GPUUniformBuf *ubo = NULL;
+ if (use_clipping_planes) {
+ ubo = GPU_uniformbuf_create_ex(sizeof(struct GPUClipPlanes), &planes, __func__);
+ GPU_batch_uniformbuf_bind(batch, "clipPlanes", ubo);
}
GPU_batch_draw(batch);
+ GPU_uniformbuf_free(ubo);
+
} break;
case OB_CURVE:
case OB_SURF:
@@ -2736,7 +2801,6 @@ void DRW_draw_depth_object(
GPU_framebuffer_restore();
GPU_framebuffer_free(depth_fb);
- DRW_opengl_context_disable();
}
/** \} */
@@ -2745,19 +2809,12 @@ void DRW_draw_depth_object(
/** \name Draw Manager State (DRW_state)
* \{ */
-/**
- * When false, drawing doesn't output to a pixel buffer
- * eg: Occlusion queries, or when we have setup a context to draw in already.
- */
bool DRW_state_is_fbo(void)
{
return ((DST.default_framebuffer != NULL) || DST.options.is_image_render) &&
!DRW_state_is_depth() && !DRW_state_is_select();
}
-/**
- * For when engines need to know if this is drawing for selection or not.
- */
bool DRW_state_is_select(void)
{
return DST.options.is_select;
@@ -2773,27 +2830,17 @@ bool DRW_state_is_depth(void)
return DST.options.is_depth;
}
-/**
- * Whether we are rendering for an image
- */
bool DRW_state_is_image_render(void)
{
return DST.options.is_image_render;
}
-/**
- * Whether we are rendering only the render engine,
- * or if we should also render the mode engines.
- */
bool DRW_state_is_scene_render(void)
{
BLI_assert(DST.options.is_scene_render ? DST.options.is_image_render : true);
return DST.options.is_scene_render;
}
-/**
- * Whether we are rendering simple opengl render
- */
bool DRW_state_is_opengl_render(void)
{
return DST.options.is_image_render && !DST.options.is_scene_render;
@@ -2808,28 +2855,18 @@ bool DRW_state_is_playback(void)
return false;
}
-/**
- * Is the user navigating the region.
- */
bool DRW_state_is_navigating(void)
{
const RegionView3D *rv3d = DST.draw_ctx.rv3d;
return (rv3d) && (rv3d->rflag & (RV3D_NAVIGATING | RV3D_PAINTING));
}
-/**
- * Should text draw in this mode?
- */
bool DRW_state_show_text(void)
{
return (DST.options.is_select) == 0 && (DST.options.is_depth) == 0 &&
(DST.options.is_scene_render) == 0 && (DST.options.draw_text) == 0;
}
-/**
- * Should draw support elements
- * Objects center, selection outline, probe data, ...
- */
bool DRW_state_draw_support(void)
{
View3D *v3d = DST.draw_ctx.v3d;
@@ -2837,9 +2874,6 @@ bool DRW_state_draw_support(void)
((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0);
}
-/**
- * Whether we should render the background
- */
bool DRW_state_draw_background(void)
{
return DST.options.draw_background;
@@ -2869,9 +2903,12 @@ bool DRW_engine_render_support(DrawEngineType *draw_engine_type)
void DRW_engine_register(DrawEngineType *draw_engine_type)
{
- BLI_addtail(&DRW_engines, draw_engine_type);
- g_registered_engine_len = BLI_listbase_count(&DRW_engines);
- draw_engine_type->index = g_registered_engine_len - 1;
+ DRWRegisteredDrawEngine *draw_engine = MEM_mallocN(sizeof(DRWRegisteredDrawEngine), __func__);
+ draw_engine->draw_engine = draw_engine_type;
+ draw_engine->index = g_registered_engines.len;
+
+ BLI_addtail(&g_registered_engines.engines, draw_engine);
+ g_registered_engines.len = BLI_listbase_count(&g_registered_engines.engines);
}
void DRW_engines_register(void)
@@ -2919,11 +2956,32 @@ void DRW_engines_register(void)
BKE_volume_batch_cache_dirty_tag_cb = DRW_volume_batch_cache_dirty_tag;
BKE_volume_batch_cache_free_cb = DRW_volume_batch_cache_free;
+
+ BKE_subsurf_modifier_free_gpu_cache_cb = DRW_subdiv_cache_free;
}
}
+static void drw_registered_engines_free(void)
+{
+ DRWRegisteredDrawEngine *next;
+ for (DRWRegisteredDrawEngine *type = g_registered_engines.engines.first; type; type = next) {
+ next = type->next;
+ BLI_remlink(&R_engines, type);
+
+ if (type->draw_engine->engine_free) {
+ type->draw_engine->engine_free();
+ }
+ MEM_freeN(type);
+ }
+
+ BLI_listbase_clear(&g_registered_engines.engines);
+ g_registered_engines.len = 0;
+}
+
void DRW_engines_free(void)
{
+ drw_registered_engines_free();
+
if (DST.gl_context == NULL) {
/* Nothing has been setup. Nothing to clear.
* Otherwise, DRW_opengl_context_enable can
@@ -2942,16 +3000,6 @@ void DRW_engines_free(void)
DRW_stats_free();
DRW_globals_free();
- DrawEngineType *next;
- for (DrawEngineType *type = DRW_engines.first; type; type = next) {
- next = type->next;
- BLI_remlink(&R_engines, type);
-
- if (type->engine_free) {
- type->engine_free();
- }
- }
-
DRW_UBO_FREE_SAFE(G_draw.block_ubo);
DRW_UBO_FREE_SAFE(G_draw.view_ubo);
DRW_TEXTURE_FREE_SAFE(G_draw.ramp);
@@ -3079,6 +3127,8 @@ void DRW_opengl_context_disable_ex(bool restore)
void DRW_opengl_context_enable(void)
{
+ /* TODO: should be replace by a more elegant alternative. */
+
if (G.background && DST.gl_context == NULL) {
WM_init_opengl();
}
@@ -3107,7 +3157,6 @@ void DRW_opengl_render_context_disable(void *re_gl_context)
BLI_ticket_mutex_unlock(DST.gl_context_mutex);
}
-/* Needs to be called AFTER DRW_opengl_render_context_enable() */
void DRW_gpu_render_context_enable(void *re_gpu_context)
{
/* If thread is main you should use DRW_opengl_context_enable(). */
@@ -3116,7 +3165,6 @@ void DRW_gpu_render_context_enable(void *re_gpu_context)
GPU_context_active_set(re_gpu_context);
}
-/* Needs to be called BEFORE DRW_opengl_render_context_disable() */
void DRW_gpu_render_context_disable(void *UNUSED(re_gpu_context))
{
GPU_flush();
@@ -3161,6 +3209,8 @@ void DRW_xr_drawing_end(void)
#endif
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Internal testing API for gtests
* \{ */