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')
-rw-r--r--source/blender/draw/engines/overlay/overlay_armature.c6
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_curve_point_vert.glsl2
-rw-r--r--source/blender/draw/intern/draw_cache.c5
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c464
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h20
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curve.c7
-rw-r--r--source/blender/draw/intern/draw_manager.c12
-rw-r--r--source/blender/draw/intern/draw_manager.h3
-rw-r--r--source/blender/draw/intern/shaders/common_globals_lib.glsl14
10 files changed, 313 insertions, 222 deletions
diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c
index 95fd918f8c1..481dec340ba 100644
--- a/source/blender/draw/engines/overlay/overlay_armature.c
+++ b/source/blender/draw/engines/overlay/overlay_armature.c
@@ -510,7 +510,7 @@ static void drw_shgroup_bone_envelope(ArmatureDrawContext *ctx,
/* Custom (geometry) */
extern void drw_batch_cache_validate(Object *custom);
-extern void drw_batch_cache_generate_requested(Object *custom);
+extern void drw_batch_cache_generate_requested_delayed(Object *custom);
BLI_INLINE DRWCallBuffer *custom_bone_instance_shgroup(ArmatureDrawContext *ctx,
DRWShadingGroup *grp,
@@ -567,7 +567,7 @@ static void drw_shgroup_bone_custom_solid(ArmatureDrawContext *ctx,
}
/* TODO(fclem) needs to be moved elsewhere. */
- drw_batch_cache_generate_requested(custom);
+ drw_batch_cache_generate_requested_delayed(custom);
}
static void drw_shgroup_bone_custom_wire(ArmatureDrawContext *ctx,
@@ -591,7 +591,7 @@ static void drw_shgroup_bone_custom_wire(ArmatureDrawContext *ctx,
}
/* TODO(fclem) needs to be moved elsewhere. */
- drw_batch_cache_generate_requested(custom);
+ drw_batch_cache_generate_requested_delayed(custom);
}
static void drw_shgroup_bone_custom_empty(ArmatureDrawContext *ctx,
diff --git a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl b/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl
index 306fbb473ee..a400aadb052 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl
@@ -52,7 +52,7 @@ void main()
bool edge_selected = (((vertFlag[1] | vertFlag[0]) & VERT_SELECTED) != 0);
bool handle_selected = (showCurveHandles &&
- (((vertFlag[1] | vertFlag[0]) & HANDLE_SELECTED) != 0));
+ (((vertFlag[1] | vertFlag[0]) & VERT_SELECTED_BEZT_HANDLE) != 0));
/* If handle type is only selected and the edge is not selected, don't show. */
if ((curveHandleDisplay != CURVE_HANDLE_ALL) && (!handle_selected)) {
diff --git a/source/blender/draw/engines/overlay/shaders/edit_curve_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_curve_point_vert.glsl
index b1e1c0879a5..a811fcca0d4 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_curve_point_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_curve_point_vert.glsl
@@ -37,7 +37,7 @@ void main()
#endif
bool show_handle = showCurveHandles;
- if ((curveHandleDisplay == CURVE_HANDLE_SELECTED) && ((data & HANDLE_SELECTED) == 0)) {
+ if ((curveHandleDisplay == CURVE_HANDLE_SELECTED) && ((data & VERT_SELECTED_BEZT_HANDLE) == 0)) {
show_handle = false;
}
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index c23ea3d7c82..af5b9cd05dd 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -3552,6 +3552,11 @@ void drw_batch_cache_generate_requested(Object *ob)
}
}
+void drw_batch_cache_generate_requested_delayed(Object *ob)
+{
+ BLI_gset_add(DST.delayed_extraction, ob);
+}
+
void DRW_batch_cache_free_old(Object *ob, int ctime)
{
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 06462d5b9c5..f3dc8f0fd2a 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -134,6 +134,183 @@ typedef struct MeshRenderData {
float (*poly_normals)[3];
int *lverts, *ledges;
} MeshRenderData;
+
+static void mesh_render_data_update_loose_geom(MeshRenderData *mr,
+ const eMRIterType iter_type,
+ const eMRDataType UNUSED(data_flag))
+{
+ if (mr->extract_type != MR_EXTRACT_BMESH) {
+ /* Mesh */
+ if (iter_type & (MR_ITER_LEDGE | MR_ITER_LVERT)) {
+ mr->vert_loose_len = 0;
+ mr->edge_loose_len = 0;
+
+ BLI_bitmap *lvert_map = BLI_BITMAP_NEW(mr->vert_len, "lvert map");
+
+ mr->ledges = MEM_mallocN(mr->edge_len * sizeof(int), __func__);
+ const MEdge *medge = mr->medge;
+ for (int e = 0; e < mr->edge_len; e++, medge++) {
+ if (medge->flag & ME_LOOSEEDGE) {
+ mr->ledges[mr->edge_loose_len++] = e;
+ }
+ /* Tag verts as not loose. */
+ BLI_BITMAP_ENABLE(lvert_map, medge->v1);
+ BLI_BITMAP_ENABLE(lvert_map, medge->v2);
+ }
+ if (mr->edge_loose_len < mr->edge_len) {
+ mr->ledges = MEM_reallocN(mr->ledges, mr->edge_loose_len * sizeof(*mr->ledges));
+ }
+
+ mr->lverts = MEM_mallocN(mr->vert_len * sizeof(*mr->lverts), __func__);
+ for (int v = 0; v < mr->vert_len; v++) {
+ if (!BLI_BITMAP_TEST(lvert_map, v)) {
+ mr->lverts[mr->vert_loose_len++] = v;
+ }
+ }
+ if (mr->vert_loose_len < mr->vert_len) {
+ mr->lverts = MEM_reallocN(mr->lverts, mr->vert_loose_len * sizeof(*mr->lverts));
+ }
+
+ MEM_freeN(lvert_map);
+
+ mr->loop_loose_len = mr->vert_loose_len + mr->edge_loose_len * 2;
+ }
+ }
+ else {
+ /* BMesh */
+ BMesh *bm = mr->bm;
+ if (iter_type & (MR_ITER_LEDGE | MR_ITER_LVERT)) {
+ int elem_id;
+ BMIter iter;
+ BMVert *eve;
+ BMEdge *ede;
+ mr->vert_loose_len = 0;
+ mr->edge_loose_len = 0;
+
+ mr->lverts = MEM_mallocN(mr->vert_len * sizeof(*mr->lverts), __func__);
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, elem_id) {
+ if (eve->e == NULL) {
+ mr->lverts[mr->vert_loose_len++] = elem_id;
+ }
+ }
+ if (mr->vert_loose_len < mr->vert_len) {
+ mr->lverts = MEM_reallocN(mr->lverts, mr->vert_loose_len * sizeof(*mr->lverts));
+ }
+
+ mr->ledges = MEM_mallocN(mr->edge_len * sizeof(*mr->ledges), __func__);
+ BM_ITER_MESH_INDEX (ede, &iter, bm, BM_EDGES_OF_MESH, elem_id) {
+ if (ede->l == NULL) {
+ mr->ledges[mr->edge_loose_len++] = elem_id;
+ }
+ }
+ if (mr->edge_loose_len < mr->edge_len) {
+ mr->ledges = MEM_reallocN(mr->ledges, mr->edge_loose_len * sizeof(*mr->ledges));
+ }
+
+ mr->loop_loose_len = mr->vert_loose_len + mr->edge_loose_len * 2;
+ }
+ }
+}
+
+/* Part of the creation of the MeshRenderData that happens in a thread. */
+static void mesh_render_data_update_looptris(MeshRenderData *mr,
+ const eMRIterType iter_type,
+ const eMRDataType data_flag)
+{
+ Mesh *me = mr->me;
+ if (mr->extract_type != MR_EXTRACT_BMESH) {
+ /* Mesh */
+ if ((iter_type & MR_ITER_LOOPTRI) || (data_flag & MR_DATA_LOOPTRI)) {
+ mr->mlooptri = MEM_mallocN(sizeof(*mr->mlooptri) * mr->tri_len, "MR_DATATYPE_LOOPTRI");
+ BKE_mesh_recalc_looptri(
+ me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mr->mlooptri);
+ }
+ }
+ else {
+ /* BMesh */
+ if ((iter_type & MR_ITER_LOOPTRI) || (data_flag & MR_DATA_LOOPTRI)) {
+ /* Edit mode ensures this is valid, no need to calculate. */
+ BLI_assert((mr->bm->totloop == 0) || (mr->edit_bmesh->looptris != NULL));
+ }
+ }
+}
+
+static void mesh_render_data_update_normals(MeshRenderData *mr,
+ const eMRIterType UNUSED(iter_type),
+ const eMRDataType data_flag)
+{
+ Mesh *me = mr->me;
+ const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0;
+ const float split_angle = is_auto_smooth ? me->smoothresh : (float)M_PI;
+
+ if (mr->extract_type != MR_EXTRACT_BMESH) {
+ /* Mesh */
+ if (data_flag & (MR_DATA_POLY_NOR | MR_DATA_LOOP_NOR | MR_DATA_TAN_LOOP_NOR)) {
+ mr->poly_normals = MEM_mallocN(sizeof(*mr->poly_normals) * mr->poly_len, __func__);
+ BKE_mesh_calc_normals_poly((MVert *)mr->mvert,
+ NULL,
+ mr->vert_len,
+ mr->mloop,
+ mr->mpoly,
+ mr->loop_len,
+ mr->poly_len,
+ mr->poly_normals,
+ true);
+ }
+ if (((data_flag & MR_DATA_LOOP_NOR) && is_auto_smooth) || (data_flag & MR_DATA_TAN_LOOP_NOR)) {
+ mr->loop_normals = MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__);
+ short(*clnors)[2] = CustomData_get_layer(&mr->me->ldata, CD_CUSTOMLOOPNORMAL);
+ BKE_mesh_normals_loop_split(mr->me->mvert,
+ mr->vert_len,
+ mr->me->medge,
+ mr->edge_len,
+ mr->me->mloop,
+ mr->loop_normals,
+ mr->loop_len,
+ mr->me->mpoly,
+ mr->poly_normals,
+ mr->poly_len,
+ is_auto_smooth,
+ split_angle,
+ NULL,
+ clnors,
+ NULL);
+ }
+ }
+ else {
+ /* BMesh */
+ if (data_flag & MR_DATA_POLY_NOR) {
+ /* Use bmface->no instead. */
+ }
+ if (((data_flag & MR_DATA_LOOP_NOR) && is_auto_smooth) || (data_flag & MR_DATA_TAN_LOOP_NOR)) {
+
+ const float(*vert_coords)[3] = NULL;
+ const float(*vert_normals)[3] = NULL;
+ const float(*poly_normals)[3] = NULL;
+
+ if (mr->edit_data && mr->edit_data->vertexCos) {
+ vert_coords = mr->bm_vert_coords;
+ vert_normals = mr->bm_vert_normals;
+ poly_normals = mr->bm_poly_normals;
+ }
+
+ mr->loop_normals = MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__);
+ int clnors_offset = CustomData_get_offset(&mr->bm->ldata, CD_CUSTOMLOOPNORMAL);
+ BM_loops_calc_normal_vcos(mr->bm,
+ vert_coords,
+ vert_normals,
+ poly_normals,
+ is_auto_smooth,
+ split_angle,
+ mr->loop_normals,
+ NULL,
+ NULL,
+ clnors_offset,
+ false);
+ }
+ }
+}
+
static MeshRenderData *mesh_render_data_create(Mesh *me,
const bool is_editmode,
const bool is_paint_mode,
@@ -141,7 +318,9 @@ static MeshRenderData *mesh_render_data_create(Mesh *me,
const bool do_final,
const bool do_uvedit,
const DRW_MeshCDMask *UNUSED(cd_used),
- const ToolSettings *ts)
+ const ToolSettings *ts,
+ const eMRIterType iter_type,
+ const eMRDataType data_flag)
{
MeshRenderData *mr = MEM_callocN(sizeof(*mr), __func__);
mr->toolsettings = ts;
@@ -249,165 +428,11 @@ static MeshRenderData *mesh_render_data_create(Mesh *me,
mr->poly_len = bm->totface;
mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len);
}
+ mesh_render_data_update_loose_geom(mr, iter_type, data_flag);
return mr;
}
-/* Part of the creation of the MeshRenderData that happens in a thread. */
-static void mesh_render_data_update(MeshRenderData *mr,
- const eMRIterType iter_type,
- const eMRDataType data_flag)
-{
- Mesh *me = mr->me;
- const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0;
- const float split_angle = is_auto_smooth ? me->smoothresh : (float)M_PI;
-
- if (mr->extract_type != MR_EXTRACT_BMESH) {
- /* Mesh */
- if (data_flag & (MR_DATA_POLY_NOR | MR_DATA_LOOP_NOR | MR_DATA_TAN_LOOP_NOR)) {
- mr->poly_normals = MEM_mallocN(sizeof(*mr->poly_normals) * mr->poly_len, __func__);
- BKE_mesh_calc_normals_poly((MVert *)mr->mvert,
- NULL,
- mr->vert_len,
- mr->mloop,
- mr->mpoly,
- mr->loop_len,
- mr->poly_len,
- mr->poly_normals,
- true);
- }
- if (((data_flag & MR_DATA_LOOP_NOR) && is_auto_smooth) || (data_flag & MR_DATA_TAN_LOOP_NOR)) {
- mr->loop_normals = MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__);
- short(*clnors)[2] = CustomData_get_layer(&mr->me->ldata, CD_CUSTOMLOOPNORMAL);
- BKE_mesh_normals_loop_split(mr->me->mvert,
- mr->vert_len,
- mr->me->medge,
- mr->edge_len,
- mr->me->mloop,
- mr->loop_normals,
- mr->loop_len,
- mr->me->mpoly,
- mr->poly_normals,
- mr->poly_len,
- is_auto_smooth,
- split_angle,
- NULL,
- clnors,
- NULL);
- }
- if ((iter_type & MR_ITER_LOOPTRI) || (data_flag & MR_DATA_LOOPTRI)) {
- mr->mlooptri = MEM_mallocN(sizeof(*mr->mlooptri) * mr->tri_len, "MR_DATATYPE_LOOPTRI");
- BKE_mesh_recalc_looptri(mr->me->mloop,
- mr->me->mpoly,
- mr->me->mvert,
- mr->me->totloop,
- mr->me->totpoly,
- mr->mlooptri);
- }
- if (iter_type & (MR_ITER_LEDGE | MR_ITER_LVERT)) {
- mr->vert_loose_len = 0;
- mr->edge_loose_len = 0;
-
- BLI_bitmap *lvert_map = BLI_BITMAP_NEW(mr->vert_len, "lvert map");
-
- mr->ledges = MEM_mallocN(mr->edge_len * sizeof(int), __func__);
- const MEdge *medge = mr->medge;
- for (int e = 0; e < mr->edge_len; e++, medge++) {
- if (medge->flag & ME_LOOSEEDGE) {
- mr->ledges[mr->edge_loose_len++] = e;
- }
- /* Tag verts as not loose. */
- BLI_BITMAP_ENABLE(lvert_map, medge->v1);
- BLI_BITMAP_ENABLE(lvert_map, medge->v2);
- }
- if (mr->edge_loose_len < mr->edge_len) {
- mr->ledges = MEM_reallocN(mr->ledges, mr->edge_loose_len * sizeof(*mr->ledges));
- }
-
- mr->lverts = MEM_mallocN(mr->vert_len * sizeof(*mr->lverts), __func__);
- for (int v = 0; v < mr->vert_len; v++) {
- if (!BLI_BITMAP_TEST(lvert_map, v)) {
- mr->lverts[mr->vert_loose_len++] = v;
- }
- }
- if (mr->vert_loose_len < mr->vert_len) {
- mr->lverts = MEM_reallocN(mr->lverts, mr->vert_loose_len * sizeof(*mr->lverts));
- }
-
- MEM_freeN(lvert_map);
-
- mr->loop_loose_len = mr->vert_loose_len + mr->edge_loose_len * 2;
- }
- }
- else {
- /* BMesh */
- BMesh *bm = mr->bm;
- if (data_flag & MR_DATA_POLY_NOR) {
- /* Use bmface->no instead. */
- }
- if (((data_flag & MR_DATA_LOOP_NOR) && is_auto_smooth) || (data_flag & MR_DATA_TAN_LOOP_NOR)) {
-
- const float(*vert_coords)[3] = NULL;
- const float(*vert_normals)[3] = NULL;
- const float(*poly_normals)[3] = NULL;
-
- if (mr->edit_data && mr->edit_data->vertexCos) {
- vert_coords = mr->bm_vert_coords;
- vert_normals = mr->bm_vert_normals;
- poly_normals = mr->bm_poly_normals;
- }
-
- mr->loop_normals = MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__);
- int clnors_offset = CustomData_get_offset(&mr->bm->ldata, CD_CUSTOMLOOPNORMAL);
- BM_loops_calc_normal_vcos(mr->bm,
- vert_coords,
- vert_normals,
- poly_normals,
- is_auto_smooth,
- split_angle,
- mr->loop_normals,
- NULL,
- NULL,
- clnors_offset,
- false);
- }
- if ((iter_type & MR_ITER_LOOPTRI) || (data_flag & MR_DATA_LOOPTRI)) {
- /* Edit mode ensures this is valid, no need to calculate. */
- BLI_assert((bm->totloop == 0) || (mr->edit_bmesh->looptris != NULL));
- }
- if (iter_type & (MR_ITER_LEDGE | MR_ITER_LVERT)) {
- int elem_id;
- BMIter iter;
- BMVert *eve;
- BMEdge *ede;
- mr->vert_loose_len = 0;
- mr->edge_loose_len = 0;
-
- mr->lverts = MEM_mallocN(mr->vert_len * sizeof(*mr->lverts), __func__);
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, elem_id) {
- if (eve->e == NULL) {
- mr->lverts[mr->vert_loose_len++] = elem_id;
- }
- }
- if (mr->vert_loose_len < mr->vert_len) {
- mr->lverts = MEM_reallocN(mr->lverts, mr->vert_loose_len * sizeof(*mr->lverts));
- }
-
- mr->ledges = MEM_mallocN(mr->edge_len * sizeof(*mr->ledges), __func__);
- BM_ITER_MESH_INDEX (ede, &iter, bm, BM_EDGES_OF_MESH, elem_id) {
- if (ede->l == NULL) {
- mr->ledges[mr->edge_loose_len++] = elem_id;
- }
- }
- if (mr->edge_loose_len < mr->edge_len) {
- mr->ledges = MEM_reallocN(mr->ledges, mr->edge_loose_len * sizeof(*mr->ledges));
- }
-
- mr->loop_loose_len = mr->vert_loose_len + mr->edge_loose_len * 2;
- }
- }
-}
-
static void mesh_render_data_free(MeshRenderData *mr)
{
MEM_SAFE_FREE(mr->mlooptri);
@@ -4533,10 +4558,16 @@ typedef struct ExtractUserData {
void *user_data;
} ExtractUserData;
+typedef enum ExtractTaskDataType {
+ EXTRACT_MESH_EXTRACT,
+ EXTRACT_LINES_LOOSE,
+} ExtractTaskDataType;
+
typedef struct ExtractTaskData {
void *next, *prev;
const MeshRenderData *mr;
const MeshExtract *extract;
+ ExtractTaskDataType tasktype;
eMRIterType iter_type;
int start, end;
/** Decremented each time a task is finished. */
@@ -4545,6 +4576,41 @@ typedef struct ExtractTaskData {
ExtractUserData *user_data;
} ExtractTaskData;
+static ExtractTaskData *extract_task_data_create_mesh_extract(const MeshRenderData *mr,
+ const MeshExtract *extract,
+ void *buf,
+ int32_t *task_counter)
+{
+ ExtractTaskData *taskdata = MEM_mallocN(sizeof(*taskdata), __func__);
+ taskdata->next = NULL;
+ taskdata->prev = NULL;
+ taskdata->tasktype = EXTRACT_MESH_EXTRACT;
+ taskdata->mr = mr;
+ taskdata->extract = extract;
+ taskdata->buf = buf;
+
+ /* ExtractUserData is shared between the iterations as it holds counters to detect if the
+ * extraction is finished. To make sure the duplication of the userdata does not create a new
+ * instance of the counters we allocate the userdata in its own container.
+ *
+ * This structure makes sure that when extract_init is called, that the user data of all
+ * iterations are updated. */
+ taskdata->user_data = MEM_callocN(sizeof(ExtractUserData), __func__);
+ taskdata->iter_type = mesh_extract_iter_type(extract);
+ taskdata->task_counter = task_counter;
+ taskdata->start = 0;
+ taskdata->end = INT_MAX;
+ return taskdata;
+}
+
+static ExtractTaskData *extract_task_data_create_lines_loose(const MeshRenderData *mr)
+{
+ ExtractTaskData *taskdata = MEM_callocN(sizeof(*taskdata), __func__);
+ taskdata->tasktype = EXTRACT_LINES_LOOSE;
+ taskdata->mr = mr;
+ return taskdata;
+}
+
static void extract_task_data_free(void *data)
{
ExtractTaskData *task_data = data;
@@ -4630,23 +4696,30 @@ BLI_INLINE void mesh_extract_iter(const MeshRenderData *mr,
static void extract_init(ExtractTaskData *data)
{
- data->user_data->user_data = data->extract->init(data->mr, data->buf);
+ if (data->tasktype == EXTRACT_MESH_EXTRACT) {
+ data->user_data->user_data = data->extract->init(data->mr, data->buf);
+ }
}
static void extract_run(void *__restrict taskdata)
{
ExtractTaskData *data = (ExtractTaskData *)taskdata;
- mesh_extract_iter(data->mr,
- data->iter_type,
- data->start,
- data->end,
- data->extract,
- data->user_data->user_data);
-
- /* If this is the last task, we do the finish function. */
- int remainin_tasks = atomic_sub_and_fetch_int32(data->task_counter, 1);
- if (remainin_tasks == 0 && data->extract->finish != NULL) {
- data->extract->finish(data->mr, data->buf, data->user_data->user_data);
+ if (data->tasktype == EXTRACT_MESH_EXTRACT) {
+ mesh_extract_iter(data->mr,
+ data->iter_type,
+ data->start,
+ data->end,
+ data->extract,
+ data->user_data->user_data);
+
+ /* If this is the last task, we do the finish function. */
+ int remainin_tasks = atomic_sub_and_fetch_int32(data->task_counter, 1);
+ if (remainin_tasks == 0 && data->extract->finish != NULL) {
+ data->extract->finish(data->mr, data->buf, data->user_data->user_data);
+ }
+ }
+ else if (data->tasktype == EXTRACT_LINES_LOOSE) {
+ extract_lines_loose_subbuffer(data->mr);
}
}
@@ -4670,15 +4743,20 @@ typedef struct MeshRenderDataUpdateTaskData {
static void mesh_render_data_update_task_data_free(MeshRenderDataUpdateTaskData *taskdata)
{
BLI_assert(taskdata);
- mesh_render_data_free(taskdata->mr);
+ MeshRenderData *mr = taskdata->mr;
+ mesh_render_data_free(mr);
MEM_freeN(taskdata);
}
static void mesh_extract_render_data_node_exec(void *__restrict task_data)
{
MeshRenderDataUpdateTaskData *update_task_data = task_data;
- mesh_render_data_update(
- update_task_data->mr, update_task_data->iter_type, update_task_data->data_flag);
+ MeshRenderData *mr = update_task_data->mr;
+ const eMRIterType iter_type = update_task_data->iter_type;
+ const eMRDataType data_flag = update_task_data->data_flag;
+
+ mesh_render_data_update_normals(mr, iter_type, data_flag);
+ mesh_render_data_update_looptris(mr, iter_type, data_flag);
}
static struct TaskNode *mesh_extract_render_data_node_create(struct TaskGraph *task_graph,
@@ -4822,24 +4900,8 @@ static void extract_task_create(struct TaskGraph *task_graph,
}
/* Divide extraction of the VBO/IBO into sensible chunks of works. */
- ExtractTaskData *taskdata = MEM_mallocN(sizeof(*taskdata), "ExtractTaskData");
- taskdata->next = NULL;
- taskdata->prev = NULL;
- taskdata->mr = mr;
- taskdata->extract = extract;
- taskdata->buf = buf;
-
- /* ExtractUserData is shared between the iterations as it holds counters to detect if the
- * extraction is finished. To make sure the duplication of the userdata does not create a new
- * instance of the counters we allocate the userdata in its own container.
- *
- * This structure makes sure that when extract_init is called, that the user data of all
- * iterations are updated. */
- taskdata->user_data = MEM_callocN(sizeof(ExtractUserData), __func__);
- taskdata->iter_type = mesh_extract_iter_type(extract);
- taskdata->task_counter = task_counter;
- taskdata->start = 0;
- taskdata->end = INT_MAX;
+ ExtractTaskData *taskdata = extract_task_data_create_mesh_extract(
+ mr, extract, buf, task_counter);
/* Simple heuristic. */
const int chunk_size = 8192;
@@ -4980,14 +5042,26 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
TEST_ASSIGN(IBO, ibo, edituv_points);
TEST_ASSIGN(IBO, ibo, edituv_fdots);
+ if (do_lines_loose_subbuffer) {
+ iter_flag |= MR_ITER_LEDGE;
+ }
+
#undef TEST_ASSIGN
#ifdef DEBUG_TIME
double rdata_start = PIL_check_seconds_timer();
#endif
- MeshRenderData *mr = mesh_render_data_create(
- me, is_editmode, is_paint_mode, obmat, do_final, do_uvedit, cd_layer_used, ts);
+ MeshRenderData *mr = mesh_render_data_create(me,
+ is_editmode,
+ is_paint_mode,
+ obmat,
+ do_final,
+ do_uvedit,
+ cd_layer_used,
+ ts,
+ iter_flag,
+ data_flag);
mr->cache = cache; /* HACK */
mr->use_hide = use_hide;
mr->use_subsurf_fdots = use_subsurf_fdots;
@@ -5069,12 +5143,8 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
}
else {
if (do_lines_loose_subbuffer) {
- /* When `lines_loose` is requested without `lines` we can create the sub-buffer on the fly as
- * the `lines` buffer should then already be up-to-date.
- * (see `DRW_batch_requested(cache->batch.loose_edges, GPU_PRIM_LINES)` in
- * `DRW_mesh_batch_cache_create_requested`).
- */
- extract_lines_loose_subbuffer(mr);
+ ExtractTaskData *taskdata = extract_task_data_create_lines_loose(mr);
+ BLI_addtail(&single_threaded_task_data->task_datas, taskdata);
}
}
EXTRACT(ibo, points);
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 80649143537..191d75342d0 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -201,18 +201,19 @@ struct GPUBatch *DRW_mesh_batch_cache_get_edit_mesh_analysis(struct Mesh *me);
int DRW_mesh_material_count_get(struct Mesh *me);
+/* See 'common_globals_lib.glsl' for duplicate defines. */
+
/* Edit mesh bitflags (is this the right place?) */
enum {
VFLAG_VERT_ACTIVE = 1 << 0,
VFLAG_VERT_SELECTED = 1 << 1,
- VFLAG_EDGE_ACTIVE = 1 << 2,
- VFLAG_EDGE_SELECTED = 1 << 3,
- VFLAG_EDGE_SEAM = 1 << 4,
- VFLAG_EDGE_SHARP = 1 << 5,
- VFLAG_EDGE_FREESTYLE = 1 << 6,
- VFLAG_HANDLE_SELECTED = 1 << 7,
- /* Beware to not go over 1 << 7 (it's a byte flag)
- * (see gpu_shader_edit_mesh_overlay_geom.glsl) */
+ VFLAG_VERT_SELECTED_BEZT_HANDLE = 1 << 2,
+ VFLAG_EDGE_ACTIVE = 1 << 3,
+ VFLAG_EDGE_SELECTED = 1 << 4,
+ VFLAG_EDGE_SEAM = 1 << 5,
+ VFLAG_EDGE_SHARP = 1 << 6,
+ VFLAG_EDGE_FREESTYLE = 1 << 7,
+ /* Beware to not go over 1 << 7 (it's a byte flag). */
};
enum {
@@ -224,8 +225,7 @@ enum {
VFLAG_EDGE_UV_SELECT = 1 << 5,
VFLAG_FACE_UV_ACTIVE = 1 << 6,
VFLAG_FACE_UV_SELECT = 1 << 7,
- /* Beware to not go over 1 << 7 (it's a byte flag)
- * (see gpu_shader_edit_mesh_overlay_geom.glsl) */
+ /* Beware to not go over 1 << 7 (it's a byte flag). */
};
/* Particles */
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c
index c6112994b65..8798549a416 100644
--- a/source/blender/draw/intern/draw_cache_impl_curve.c
+++ b/source/blender/draw/intern/draw_cache_impl_curve.c
@@ -47,6 +47,7 @@
#include "draw_cache_impl.h" /* own include */
+/* See: edit_curve_point_vert.glsl for duplicate includes. */
#define SELECT 1
#define ACTIVE_NURB 1 << 2
#define BEZIER_HANDLE 1 << 3
@@ -698,7 +699,9 @@ static char beztriple_vflag_get(CurveRenderData *rdata,
SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert && nu_id == rdata->actnu), VFLAG_VERT_ACTIVE);
SET_FLAG_FROM_TEST(vflag, (nu_id == rdata->actnu), ACTIVE_NURB);
SET_FLAG_FROM_TEST(vflag, handle_point, BEZIER_HANDLE);
- SET_FLAG_FROM_TEST(vflag, handle_selected, VFLAG_HANDLE_SELECTED);
+ SET_FLAG_FROM_TEST(vflag, handle_selected, VFLAG_VERT_SELECTED_BEZT_HANDLE);
+ /* Setting flags that overlap with will cause the color id not to work properly. */
+ BLI_assert((vflag >> COLOR_SHIFT) == 0);
/* handle color id */
vflag |= col_id << COLOR_SHIFT;
return vflag;
@@ -711,6 +714,8 @@ static char bpoint_vflag_get(CurveRenderData *rdata, char flag, int v_idx, int n
SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert && nu_id == rdata->actnu), VFLAG_VERT_ACTIVE);
SET_FLAG_FROM_TEST(vflag, (nu_id == rdata->actnu), ACTIVE_NURB);
SET_FLAG_FROM_TEST(vflag, ((u % 2) == 0), EVEN_U_BIT);
+ /* Setting flags that overlap with will cause the color id not to work properly. */
+ BLI_assert((vflag >> COLOR_SHIFT) == 0);
vflag |= COLOR_NURB_ULINE_ID << COLOR_SHIFT;
return vflag;
}
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 2ba766f4729..10ef8d9c4c8 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -132,11 +132,17 @@ static void drw_task_graph_init(void)
{
BLI_assert(DST.task_graph == NULL);
DST.task_graph = BLI_task_graph_create();
+ DST.delayed_extraction = BLI_gset_ptr_new(__func__);
}
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);
+ DST.delayed_extraction = NULL;
+ BLI_task_graph_work_and_wait(DST.task_graph);
+
BLI_task_graph_free(DST.task_graph);
DST.task_graph = NULL;
}
@@ -1486,6 +1492,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
drw_duplidata_free();
drw_engines_cache_finish();
+ drw_task_graph_deinit();
DRW_render_instance_buffer_finish();
#ifdef USE_PROFILE
@@ -1494,7 +1501,6 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
#endif
}
- drw_task_graph_deinit();
DRW_stats_begin();
GPU_framebuffer_bind(DST.default_framebuffer);
@@ -2292,9 +2298,9 @@ static void drw_draw_depth_loop_imp(struct Depsgraph *depsgraph,
drw_duplidata_free();
drw_engines_cache_finish();
+ drw_task_graph_deinit();
DRW_render_instance_buffer_finish();
}
- drw_task_graph_deinit();
/* Start Drawing */
DRW_state_reset();
@@ -2411,6 +2417,7 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons
drw_engines_cache_finish();
+ drw_task_graph_deinit();
#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
@@ -2419,7 +2426,6 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons
drw_resource_buffer_finish(DST.vmempool);
#endif
}
- drw_task_graph_deinit();
/* Start Drawing */
DRW_state_reset();
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 6cae2a4f9f6..31a2dd7f0fe 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -548,6 +548,8 @@ typedef struct DRWManager {
#endif
struct TaskGraph *task_graph;
+ /* Contains list of objects that needs to be extracted from other objects. */
+ struct GSet *delayed_extraction;
/* ---------- Nothing after this point is cleared after use ----------- */
@@ -585,6 +587,7 @@ eDRWCommandType command_type_get(uint64_t *command_type_bits, int index);
void drw_batch_cache_validate(Object *ob);
void drw_batch_cache_generate_requested(struct Object *ob);
+void drw_batch_cache_generate_requested_delayed(Object *ob);
void drw_resource_buffer_finish(ViewportMemoryPool *vmempool);
diff --git a/source/blender/draw/intern/shaders/common_globals_lib.glsl b/source/blender/draw/intern/shaders/common_globals_lib.glsl
index a479a87e14b..40a527a6ba4 100644
--- a/source/blender/draw/intern/shaders/common_globals_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_globals_lib.glsl
@@ -123,6 +123,8 @@ layout(std140) uniform globalsBlock
#define sizeViewportInv (sizeViewport.zw)
+/* See: 'draw_cache_impl.h' for matching includes. */
+
/* data[0] (1st byte flags) */
#define FACE_ACTIVE (1 << 0)
#define FACE_SELECTED (1 << 1)
@@ -135,9 +137,9 @@ layout(std140) uniform globalsBlock
/* data[1] (2st byte flags) */
#define VERT_ACTIVE (1 << 0)
#define VERT_SELECTED (1 << 1)
-#define EDGE_ACTIVE (1 << 2)
-#define EDGE_SELECTED (1 << 3)
-#define EDGE_SEAM (1 << 4)
-#define EDGE_SHARP (1 << 5)
-#define EDGE_FREESTYLE (1 << 6)
-#define HANDLE_SELECTED (1 << 7)
+#define VERT_SELECTED_BEZT_HANDLE (1 << 2)
+#define EDGE_ACTIVE (1 << 3)
+#define EDGE_SELECTED (1 << 4)
+#define EDGE_SEAM (1 << 5)
+#define EDGE_SHARP (1 << 6)
+#define EDGE_FREESTYLE (1 << 7)