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.c287
1 files changed, 163 insertions, 124 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 3d8a7bb1e30..6387cecc01f 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -33,6 +33,7 @@
#include "BKE_anim.h"
#include "BKE_colortools.h"
+#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_editmesh.h"
#include "BKE_global.h"
@@ -41,6 +42,7 @@
#include "BKE_main.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
+#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_paint.h"
@@ -65,7 +67,6 @@
#include "GPU_uniformbuffer.h"
#include "GPU_viewport.h"
#include "GPU_matrix.h"
-#include "GPU_select.h"
#include "IMB_colormanagement.h"
@@ -98,10 +99,6 @@
#include "DRW_select_buffer.h"
-#ifdef USE_GPU_SELECT
-# include "GPU_select.h"
-#endif
-
/** Render State: No persistent data between draw calls. */
DRWManager DST = {NULL};
@@ -540,8 +537,11 @@ static void drw_viewport_cache_resize(void)
GPU_texture_free(*tex);
}
- BLI_memblock_clear(DST.vmempool->calls, NULL);
- BLI_memblock_clear(DST.vmempool->states, NULL);
+ BLI_memblock_clear(DST.vmempool->commands, NULL);
+ BLI_memblock_clear(DST.vmempool->commands_small, NULL);
+ BLI_memblock_clear(DST.vmempool->callbuffers, NULL);
+ BLI_memblock_clear(DST.vmempool->obmats, NULL);
+ BLI_memblock_clear(DST.vmempool->obinfos, NULL);
BLI_memblock_clear(DST.vmempool->cullstates, NULL);
BLI_memblock_clear(DST.vmempool->shgroups, NULL);
BLI_memblock_clear(DST.vmempool->uniforms, NULL);
@@ -589,28 +589,28 @@ static void drw_context_state_init(void)
}
}
-static DRWCallState *draw_unit_state_create(void)
+static void draw_unit_state_create(void)
{
- DRWCallState *state = BLI_memblock_alloc(DST.vmempool->states);
- state->flag = 0;
- state->matflag = 0;
+ DRWObjectInfos *infos = BLI_memblock_alloc(DST.vmempool->obinfos);
+ DRWObjectMatrix *mats = BLI_memblock_alloc(DST.vmempool->obmats);
+ DRWCullingState *culling = BLI_memblock_alloc(DST.vmempool->cullstates);
- unit_m4(state->model);
- unit_m4(state->modelinverse);
+ unit_m4(mats->model);
+ unit_m4(mats->modelinverse);
- copy_v3_fl(state->orcotexfac[0], 0.0f);
- copy_v3_fl(state->orcotexfac[1], 1.0f);
+ copy_v3_fl(infos->orcotexfac[0], 0.0f);
+ copy_v3_fl(infos->orcotexfac[1], 1.0f);
- state->ob_index = 0;
- state->ob_random = 0.0f;
- copy_v3_fl(state->ob_color, 1.0f);
+ infos->ob_index = 0;
+ infos->ob_random = 0.0f;
+ infos->ob_neg_scale = 1.0f;
+ copy_v3_fl(infos->ob_color, 1.0f);
/* TODO(fclem) get rid of this. */
- state->culling = BLI_memblock_alloc(DST.vmempool->cullstates);
- state->culling->bsphere.radius = -1.0f;
- state->culling->user_data = NULL;
+ culling->bsphere.radius = -1.0f;
+ culling->user_data = NULL;
- return state;
+ DRW_handle_increment(&DST.resource_handle);
}
/* It also stores viewport variable to an immutable place: DST
@@ -635,33 +635,48 @@ static void drw_viewport_var_init(void)
DST.vmempool = GPU_viewport_mempool_get(DST.viewport);
- if (DST.vmempool->calls == NULL) {
- DST.vmempool->calls = BLI_memblock_create(sizeof(DRWCall));
+ if (DST.vmempool->commands == NULL) {
+ DST.vmempool->commands = BLI_memblock_create(sizeof(DRWCommandChunk));
+ }
+ if (DST.vmempool->commands_small == NULL) {
+ DST.vmempool->commands_small = BLI_memblock_create(sizeof(DRWCommandSmallChunk));
+ }
+ if (DST.vmempool->callbuffers == NULL) {
+ DST.vmempool->callbuffers = BLI_memblock_create(sizeof(DRWCallBuffer));
+ }
+ if (DST.vmempool->obmats == NULL) {
+ uint chunk_len = sizeof(DRWObjectMatrix) * DRW_RESOURCE_CHUNK_LEN;
+ DST.vmempool->obmats = BLI_memblock_create_ex(sizeof(DRWObjectMatrix), chunk_len);
}
- if (DST.vmempool->states == NULL) {
- DST.vmempool->states = BLI_memblock_create(sizeof(DRWCallState));
+ if (DST.vmempool->obinfos == NULL) {
+ uint chunk_len = sizeof(DRWObjectInfos) * DRW_RESOURCE_CHUNK_LEN;
+ DST.vmempool->obinfos = BLI_memblock_create_ex(sizeof(DRWObjectInfos), chunk_len);
}
if (DST.vmempool->cullstates == NULL) {
- DST.vmempool->cullstates = BLI_memblock_create(sizeof(DRWCullingState));
+ uint chunk_len = sizeof(DRWCullingState) * DRW_RESOURCE_CHUNK_LEN;
+ DST.vmempool->cullstates = BLI_memblock_create_ex(sizeof(DRWCullingState), chunk_len);
}
if (DST.vmempool->shgroups == NULL) {
DST.vmempool->shgroups = BLI_memblock_create(sizeof(DRWShadingGroup));
}
if (DST.vmempool->uniforms == NULL) {
- DST.vmempool->uniforms = BLI_memblock_create(sizeof(DRWUniform));
+ DST.vmempool->uniforms = BLI_memblock_create(sizeof(DRWUniformChunk));
}
if (DST.vmempool->views == NULL) {
DST.vmempool->views = BLI_memblock_create(sizeof(DRWView));
}
if (DST.vmempool->passes == NULL) {
- DST.vmempool->passes = BLI_memblock_create(sizeof(DRWPass));
+ uint chunk_len = sizeof(DRWPass) * DRW_RESOURCE_CHUNK_LEN;
+ DST.vmempool->passes = BLI_memblock_create_ex(sizeof(DRWPass), chunk_len);
}
if (DST.vmempool->images == NULL) {
DST.vmempool->images = BLI_memblock_create(sizeof(GPUTexture *));
}
- /* Alloc default unit state */
- DST.unit_state = draw_unit_state_create();
+ DST.resource_handle = 0;
+ DST.pass_handle = 0;
+
+ draw_unit_state_create();
DST.idatalist = GPU_viewport_instance_data_list_get(DST.viewport);
DRW_instance_data_list_reset(DST.idatalist);
@@ -675,8 +690,6 @@ static void drw_viewport_var_init(void)
DST.default_framebuffer = NULL;
DST.vmempool = NULL;
-
- DST.unit_state = NULL;
}
DST.primary_view_ct = 0;
@@ -719,6 +732,10 @@ static void drw_viewport_var_init(void)
G_draw.view_ubo = DRW_uniformbuffer_create(sizeof(DRWViewUboStorage), NULL);
}
+ if (DST.draw_list == NULL) {
+ DST.draw_list = GPU_draw_list_create(DRW_DRAWLIST_LEN);
+ }
+
memset(DST.object_instance_data, 0x0, sizeof(DST.object_instance_data));
}
@@ -1023,7 +1040,7 @@ void DRW_cache_free_old_batches(Main *bmain)
for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
- Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false);
+ Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, false);
if (depsgraph == NULL) {
continue;
}
@@ -1102,7 +1119,7 @@ static void drw_engines_world_update(Scene *scene)
static void drw_engines_cache_populate(Object *ob)
{
- DST.ob_state = NULL;
+ DST.ob_handle = 0;
/* HACK: DrawData is copied by COW from the duplicated object.
* This is valid for IDs that cannot be instantiated but this
@@ -1548,6 +1565,20 @@ void DRW_draw_view(const bContext *C)
DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, C);
}
+static bool is_object_visible_in_viewport(View3D *v3d, Object *ob)
+{
+ if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
+ return false;
+ }
+
+ if ((v3d->flag & V3D_LOCAL_COLLECTIONS) &&
+ ((v3d->local_collections_uuid & ob->runtime.local_collections_bits) == 0)) {
+ return false;
+ }
+
+ return true;
+}
+
/**
* Used for both regular and off-screen drawing.
* Need to reset DST before calling this function
@@ -1623,7 +1654,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
continue;
}
- if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
+ if (!is_object_visible_in_viewport(v3d, ob)) {
continue;
}
DST.dupli_parent = data_.dupli_parent;
@@ -1766,7 +1797,9 @@ void DRW_draw_render_loop(struct Depsgraph *depsgraph,
DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, NULL);
}
-/* @viewport CAN be NULL, in this case we create one. */
+/**
+ * \param viewport: can be NULL, in this case we create one.
+ */
void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
RenderEngineType *engine_type,
ARegion *ar,
@@ -1904,6 +1937,8 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
RenderResult *render_result = RE_engine_get_result(engine);
RenderLayer *render_layer = RE_GetRenderLayer(render_result, view_layer->name);
+ DST.buffer_finish_called = false;
+
DRW_render_gpencil_to_image(engine, render_layer, &render_rect);
/* Force cache to reset. */
@@ -2014,13 +2049,15 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
RE_SetActiveRenderView(render, render_view->name);
drw_view_reset();
engine_type->draw_engine->render_to_image(data, engine, render_layer, &render_rect);
+ DST.buffer_finish_called = false;
+
/* grease pencil: render result is merged in the previous render result. */
if (DRW_render_check_grease_pencil(depsgraph)) {
DRW_state_reset();
drw_view_reset();
DRW_render_gpencil_to_image(engine, render_layer, &render_rect);
+ DST.buffer_finish_called = false;
}
- DST.buffer_finish_called = false;
}
RE_engine_end_result(engine, render_result, false, false, false);
@@ -2066,7 +2103,7 @@ void DRW_render_object_iter(
if ((object_type_exclude_viewport & (1 << ob->type)) == 0) {
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
- DST.ob_state = NULL;
+ DST.ob_handle = 0;
drw_duplidata_load(DST.dupli_source);
if (!DST.dupli_source) {
@@ -2173,6 +2210,7 @@ void DRW_render_instance_buffer_finish(void)
BLI_assert(!DST.buffer_finish_called && "DRW_render_instance_buffer_finish called twice!");
DST.buffer_finish_called = true;
DRW_instance_buffer_finish(DST.idatalist);
+ drw_resource_buffer_finish(DST.vmempool);
}
/**
@@ -2196,7 +2234,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
Object *obact = OBACT(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(obact);
#ifndef USE_GPU_SELECT
- UNUSED_VARS(vc, scene, view_layer, v3d, ar, rect);
+ UNUSED_VARS(scene, view_layer, v3d, ar, rect);
#else
RegionView3D *rv3d = ar->regiondata;
@@ -2204,24 +2242,43 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
drw_state_prepare_clean_for_draw(&DST);
bool use_obedit = false;
- int obedit_mode = 0;
+ /* obedit_ctx_mode is used for selecting the right draw engines */
+ eContextObjectMode obedit_ctx_mode;
+ /* object_mode is used for filtering objects in the depsgraph */
+ eObjectMode object_mode;
+ int object_type = 0;
if (obedit != NULL) {
+ object_type = obedit->type;
+ object_mode = obedit->mode;
if (obedit->type == OB_MBALL) {
use_obedit = true;
- obedit_mode = CTX_MODE_EDIT_METABALL;
+ obedit_ctx_mode = CTX_MODE_EDIT_METABALL;
}
else if (obedit->type == OB_ARMATURE) {
use_obedit = true;
- obedit_mode = CTX_MODE_EDIT_ARMATURE;
+ obedit_ctx_mode = CTX_MODE_EDIT_ARMATURE;
}
}
if (v3d->overlay.flag & V3D_OVERLAY_BONE_SELECT) {
if (!(v3d->flag2 & V3D_HIDE_OVERLAYS)) {
/* Note: don't use "BKE_object_pose_armature_get" here, it breaks selection. */
Object *obpose = OBPOSE_FROM_OBACT(obact);
+ if (obpose == NULL) {
+ Object *obweight = OBWEIGHTPAINT_FROM_OBACT(obact);
+ if (obweight) {
+ /* Only use Armature pose selection, when connected armature is in pose mode. */
+ Object *ob_armature = modifiers_isDeformedByArmature(obweight);
+ if (ob_armature && ob_armature->mode == OB_MODE_POSE) {
+ obpose = ob_armature;
+ }
+ }
+ }
+
if (obpose) {
use_obedit = true;
- obedit_mode = CTX_MODE_POSE;
+ object_type = obpose->type;
+ object_mode = obpose->mode;
+ obedit_ctx_mode = CTX_MODE_POSE;
}
}
}
@@ -2235,8 +2292,8 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
/* Get list of enabled engines */
if (use_obedit) {
- drw_engines_enable_from_paint_mode(obedit_mode);
- drw_engines_enable_from_mode(obedit_mode);
+ drw_engines_enable_from_paint_mode(obedit_ctx_mode);
+ drw_engines_enable_from_mode(obedit_ctx_mode);
}
else if (!draw_surface) {
/* grease pencil selection */
@@ -2283,7 +2340,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
drw_engines_world_update(scene);
if (use_obedit) {
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, object_type, object_mode, ob_iter) {
drw_engines_cache_populate(ob_iter);
}
FOREACH_OBJECT_IN_MODE_END;
@@ -2293,10 +2350,9 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
v3d->object_type_exclude_select);
bool filter_exclude = false;
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
- if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
+ if (!is_object_visible_in_viewport(v3d, ob)) {
continue;
}
-
if ((ob->base_flag & BASE_SELECTABLE) &&
(object_type_exclude_select & (1 << ob->type)) == 0) {
if (object_filter_fn != NULL) {
@@ -2386,8 +2442,38 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
/**
* object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
*/
-static void drw_draw_depth_loop_imp(void)
+static void drw_draw_depth_loop_imp(struct Depsgraph *depsgraph,
+ ARegion *ar,
+ View3D *v3d,
+ GPUViewport *viewport,
+ const bool use_opengl_context)
{
+ 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 = ar->regiondata;
+
+ if (use_opengl_context) {
+ DRW_opengl_context_enable();
+ }
+
+ DST.viewport = viewport;
+ DST.options.is_depth = true;
+
+ /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
+ DST.draw_ctx = (DRWContextState){
+ .ar = ar,
+ .rv3d = rv3d,
+ .v3d = v3d,
+ .scene = scene,
+ .view_layer = view_layer,
+ .obact = OBACT(view_layer),
+ .engine_type = engine_type,
+ .depsgraph = depsgraph,
+ };
+
+ drw_engines_data_validate();
+
/* Setup framebuffer */
DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(
DST.viewport);
@@ -2409,17 +2495,14 @@ static void drw_draw_depth_loop_imp(void)
drw_engines_cache_init();
drw_engines_world_update(DST.draw_ctx.scene);
- View3D *v3d = DST.draw_ctx.v3d;
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (DST.draw_ctx.depsgraph, ob) {
if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
continue;
}
-
- if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
+ if (!is_object_visible_in_viewport(v3d, ob)) {
continue;
}
-
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
drw_duplidata_load(DST.dupli_source);
@@ -2447,6 +2530,20 @@ static void drw_draw_depth_loop_imp(void)
/* TODO: Reading depth for operators should be done here. */
GPU_framebuffer_restore();
+
+ drw_engines_disable();
+
+ drw_viewport_cache_resize();
+
+#ifdef DEBUG
+ /* Avoid accidental reuse. */
+ drw_state_ensure_not_reused(&DST);
+#endif
+
+ /* Changin context */
+ if (use_opengl_context) {
+ DRW_opengl_context_disable();
+ }
}
/**
@@ -2458,55 +2555,18 @@ void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
GPUViewport *viewport,
bool use_opengl_context)
{
- 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 = ar->regiondata;
-
- if (use_opengl_context) {
- DRW_opengl_context_enable();
- }
-
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
- DST.viewport = viewport;
- DST.options.is_depth = true;
-
- /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
- DST.draw_ctx = (DRWContextState){
- .ar = ar,
- .rv3d = rv3d,
- .v3d = v3d,
- .scene = scene,
- .view_layer = view_layer,
- .obact = OBACT(view_layer),
- .engine_type = engine_type,
- .depsgraph = depsgraph,
- };
-
/* Get list of enabled engines */
{
drw_engines_enable_basic();
if (DRW_state_draw_support()) {
drw_engines_enable_from_object_mode();
}
- drw_engines_data_validate();
}
- drw_draw_depth_loop_imp();
-
- drw_engines_disable();
-
-#ifdef DEBUG
- /* Avoid accidental reuse. */
- drw_state_ensure_not_reused(&DST);
-#endif
-
- /* Changin context */
- if (use_opengl_context) {
- DRW_opengl_context_disable();
- }
+ drw_draw_depth_loop_imp(depsgraph, ar, v3d, viewport, use_opengl_context);
}
/**
@@ -2517,43 +2577,12 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
View3D *v3d,
GPUViewport *viewport)
{
- Scene *scene = DEG_get_evaluated_scene(depsgraph);
- ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
- RegionView3D *rv3d = ar->regiondata;
-
- DRW_opengl_context_enable();
-
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
- DST.viewport = viewport;
- DST.options.is_depth = true;
-
- /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
- DST.draw_ctx = (DRWContextState){
- .ar = ar,
- .rv3d = rv3d,
- .v3d = v3d,
- .scene = scene,
- .view_layer = view_layer,
- .obact = OBACT(view_layer),
- .depsgraph = depsgraph,
- };
-
use_drw_engine(&draw_engine_gpencil_type);
- drw_engines_data_validate();
-
- drw_draw_depth_loop_imp();
-
- drw_engines_disable();
-
-#ifdef DEBUG
- /* Avoid accidental reuse. */
- drw_state_ensure_not_reused(&DST);
-#endif
- /* Changin context */
- DRW_opengl_context_disable();
+ drw_draw_depth_loop_imp(depsgraph, ar, v3d, viewport, true);
}
void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *ar, View3D *v3d, const rcti *rect)
@@ -2601,7 +2630,13 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *ar, View3D *v3d, const rc
drw_engines_cache_finish();
+#if 0 /* This is a workaround to a nasty bug that seems to be a nasty driver bug. (See T69377) */
DRW_render_instance_buffer_finish();
+#else
+ DST.buffer_finish_called = true;
+ // DRW_instance_buffer_finish(DST.idatalist);
+ drw_resource_buffer_finish(DST.vmempool);
+#endif
}
/* Start Drawing */
@@ -2905,6 +2940,10 @@ void DRW_engines_free(void)
MEM_SAFE_FREE(DST.uniform_names.buffer);
+ if (DST.draw_list) {
+ GPU_draw_list_discard(DST.draw_list);
+ }
+
DRW_opengl_context_disable();
}