[Bf-blender-cvs] [b847861b6cb] greasepencil-refactor: GPencil: Refactor: Reuse GPENCIL_MaterialPool across multiple objects
Clément Foucault
noreply at git.blender.org
Sun Jan 19 02:13:04 CET 2020
Commit: b847861b6cb26be89a451ab87e50ccbd4629ea1d
Author: Clément Foucault
Date: Sun Jan 19 02:12:50 2020 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rBb847861b6cb26be89a451ab87e50ccbd4629ea1d
GPencil: Refactor: Reuse GPENCIL_MaterialPool across multiple objects
This minimize the number of UBO we create and the number of UBO switching
we have to do to render each objects.
===================================================================
M source/blender/draw/engines/gpencil/gpencil_draw_data.c
M source/blender/draw/engines/gpencil/gpencil_engine.c
M source/blender/draw/engines/gpencil/gpencil_engine.h
M source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
M source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
M source/blender/makesdna/DNA_gpencil_types.h
===================================================================
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
index 70404bcbf6d..ef4efc40ecc 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
@@ -53,6 +53,7 @@ static GPENCIL_MaterialPool *gpencil_material_pool_add(GPENCIL_PrivateData *pd)
{
GPENCIL_MaterialPool *matpool = BLI_memblock_alloc(pd->gp_material_pool);
matpool->next = NULL;
+ matpool->used_count = 0;
if (matpool->ubo == NULL) {
matpool->ubo = GPU_uniformbuffer_create(sizeof(matpool->mat_data), NULL, NULL);
}
@@ -232,9 +233,17 @@ GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Obje
{
GPENCIL_MaterialPool *matpool = pd->last_material_pool;
- /* TODO reuse matpool for objects with small material count. */
- if (true) {
+ int mat_len = max_ii(1, ob->totcol);
+
+ bool reuse_matpool = matpool && ((matpool->used_count + mat_len) <= GP_MATERIAL_BUFFER_LEN);
+
+ if (reuse_matpool) {
+ /* Share the matpool with other objects. Return offset to first material. */
+ *ofs = matpool->used_count;
+ }
+ else {
matpool = gpencil_material_pool_add(pd);
+ *ofs = 0;
}
/* Force vertex color in solid mode with vertex paint mode. Same behavior as meshes. */
@@ -244,12 +253,13 @@ GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Obje
pd->v3d_color_type;
GPENCIL_MaterialPool *pool = matpool;
- for (int i = 0; i < max_ii(1, ob->totcol); i++) {
- int mat_id = (i % GP_MATERIAL_BUFFER_LEN);
- if ((i > 0) && (mat_id == 0)) {
+ for (int i = 0; i < mat_len; i++) {
+ if ((i > 0) && (pool->used_count == GP_MATERIAL_BUFFER_LEN)) {
pool->next = gpencil_material_pool_add(pd);
pool = pool->next;
}
+ int mat_id = pool->used_count++;
+
gpMaterial *mat_data = &pool->mat_data[mat_id];
MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, i + 1);
@@ -337,8 +347,6 @@ GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Obje
}
}
- *ofs = 0;
-
return matpool;
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index f1438e45755..c91c0af002f 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -452,6 +452,7 @@ static void gp_layer_cache_populate(bGPDlayer *gpl,
DRW_shgroup_uniform_texture(iter->grp, "gpFillTexture", iter->tex_fill);
DRW_shgroup_uniform_texture(iter->grp, "gpStrokeTexture", iter->tex_stroke);
DRW_shgroup_uniform_texture(iter->grp, "gpSceneDepthTexture", iter->pd->scene_depth_tx);
+ DRW_shgroup_uniform_int_copy(iter->grp, "gpMaterialOffset", iter->mat_ofs);
DRW_shgroup_uniform_bool_copy(iter->grp, "strokeOrder3d", is_stroke_order_3d);
DRW_shgroup_uniform_vec3_copy(iter->grp, "gpNormal", iter->tgp_ob->plane_normal);
DRW_shgroup_uniform_vec2_copy(iter->grp, "sizeViewportInv", DRW_viewport_invert_size_get());
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 71b91e042d2..558e3c3fbeb 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -111,6 +111,8 @@ typedef struct GPENCIL_MaterialPool {
/* Texture per material. NULL means none. */
struct GPUTexture *tex_fill[GP_MATERIAL_BUFFER_LEN];
struct GPUTexture *tex_stroke[GP_MATERIAL_BUFFER_LEN];
+ /* Number of material used in this pool. */
+ int used_count;
} GPENCIL_MaterialPool;
typedef struct GPENCIL_LightPool {
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
index 8062c5c26bb..ed44d53140a 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
@@ -180,13 +180,15 @@ float stroke_round_cap_mask(vec2 p1, vec2 p2, float thickness)
uniform vec2 sizeViewport;
uniform vec2 sizeViewportInv;
-#ifdef GPU_VERTEX_SHADER
-
/* Per Object */
uniform bool strokeOrder3d;
+uniform float gpMaterialOffset;
uniform float thicknessScale;
uniform float thicknessWorldScale;
-# define thicknessIsScreenSpace (thicknessWorldScale < 0.0)
+#define thicknessIsScreenSpace (thicknessWorldScale < 0.0)
+#define MATERIAL(m) materials[m]
+
+#ifdef GPU_VERTEX_SHADER
/* Per Layer */
uniform float thicknessOffset;
@@ -321,8 +323,8 @@ void stroke_vertex()
# ifdef GP_MATERIAL_BUFFER_LEN
if (m != -1.0) {
- is_dot = GP_FLAG_TEST(materials[m].flag, GP_STROKE_ALIGNMENT);
- is_squares = !GP_FLAG_TEST(materials[m].flag, GP_STROKE_DOTS);
+ is_dot = GP_FLAG_TEST(MATERIAL(m).flag, GP_STROKE_ALIGNMENT);
+ is_squares = !GP_FLAG_TEST(MATERIAL(m).flag, GP_STROKE_DOTS);
}
# endif
@@ -367,7 +369,7 @@ void stroke_vertex()
if (is_dot) {
# ifdef GP_MATERIAL_BUFFER_LEN
- int alignement = materials[m].flag & GP_STROKE_ALIGNMENT;
+ int alignement = MATERIAL(m).flag & GP_STROKE_ALIGNMENT;
# endif
vec2 x_axis;
@@ -428,19 +430,19 @@ void stroke_vertex()
finalUvs.x = (use_curr) ? uv1.z : uv2.z;
# ifdef GP_MATERIAL_BUFFER_LEN
- finalUvs.x *= materials[m].stroke_u_scale;
+ finalUvs.x *= MATERIAL(m).stroke_u_scale;
# endif
}
# ifdef GP_MATERIAL_BUFFER_LEN
vec4 vert_col = (use_curr) ? col1 : col2;
float vert_strength = abs((use_curr) ? strength1 : strength2);
- vec4 stroke_col = materials[m].stroke_color;
- float mix_tex = materials[m].stroke_texture_mix;
+ vec4 stroke_col = MATERIAL(m).stroke_color;
+ float mix_tex = MATERIAL(m).stroke_texture_mix;
color_output(stroke_col, vert_col, vert_strength, mix_tex);
- matFlag = materials[m].flag & ~GP_FILL_FLAGS;
+ matFlag = MATERIAL(m).flag & ~GP_FILL_FLAGS;
# endif
if (strokeOrder3d) {
@@ -448,7 +450,7 @@ void stroke_vertex()
depth = -1.0;
}
# ifdef GP_MATERIAL_BUFFER_LEN
- else if (GP_FLAG_TEST(materials[m].flag, GP_STROKE_OVERLAP)) {
+ else if (GP_FLAG_TEST(MATERIAL(m).flag, GP_STROKE_OVERLAP)) {
/* Use the index of the point as depth.
* This means the stroke can overlap itself. */
depth = (point_id1 + 1.0) * 0.0000002;
@@ -475,21 +477,21 @@ void fill_vertex()
# ifdef GP_MATERIAL_BUFFER_LEN
int m = int(ma1.x);
- vec4 fill_col = materials[m].fill_color;
- float mix_tex = materials[m].fill_texture_mix;
+ vec4 fill_col = MATERIAL(m).fill_color;
+ float mix_tex = MATERIAL(m).fill_texture_mix;
/* Special case: We don't modulate alpha in gradient mode. */
- if (GP_FLAG_TEST(materials[m].flag, GP_FILL_GRADIENT_USE)) {
+ if (GP_FLAG_TEST(MATERIAL(m).flag, GP_FILL_GRADIENT_USE)) {
fill_col.a = 1.0;
}
color_output(fill_col, fcol1, 1.0, mix_tex);
- matFlag = materials[m].flag & GP_FILL_FLAGS;
+ matFlag = MATERIAL(m).flag & GP_FILL_FLAGS;
matFlag |= m << GP_MATID_SHIFT;
- vec2 loc = materials[m].fill_uv_offset.xy;
- mat2x2 rot_scale = mat2x2(materials[m].fill_uv_rot_scale.xy, materials[m].fill_uv_rot_scale.zw);
+ vec2 loc = MATERIAL(m).fill_uv_offset.xy;
+ mat2x2 rot_scale = mat2x2(MATERIAL(m).fill_uv_rot_scale.xy, MATERIAL(m).fill_uv_rot_scale.zw);
finalUvs = rot_scale * uv1.xy + loc;
# endif
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
index 1d41533fd47..bca922ec018 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
@@ -72,7 +72,7 @@ void main()
bool radial = GP_FLAG_TEST(matFlag, GP_FILL_GRADIENT_RADIAL);
float fac = clamp(radial ? length(finalUvs * 2.0 - 1.0) : finalUvs.x, 0.0, 1.0);
int matid = matFlag >> GP_MATID_SHIFT;
- col = mix(materials[matid].fill_color, materials[matid].fill_mix_color, fac);
+ col = mix(MATERIAL(matid).fill_color, MATERIAL(matid).fill_mix_color, fac);
}
else /* SOLID */ {
col = vec4(1.0);
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index fca7d4bdfd4..dd84e5ca193 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -36,9 +36,7 @@ struct MDeformVert;
#define GP_DEFAULT_GRID_LINES 4
#define GP_MAX_INPUT_SAMPLES 10
-/* TODO(fclem) grow this number back when grouping different objects' material together
- * is implemented. */
-#define GP_MATERIAL_BUFFER_LEN 16
+#define GP_MATERIAL_BUFFER_LEN 256
/* ***************************************** */
/* GP Stroke Points */
More information about the Bf-blender-cvs
mailing list