[Bf-blender-cvs] [cca1e1b707c] blender2.8: UV/Image Editor: Optimize UV Drawing

Germano noreply at git.blender.org
Thu Mar 15 17:36:49 CET 2018


Commit: cca1e1b707c2d34244d3da87efcd78775c4eb048
Author: Germano
Date:   Thu Mar 15 13:36:16 2018 -0300
Branches: blender2.8
https://developer.blender.org/rBcca1e1b707c2d34244d3da87efcd78775c4eb048

UV/Image Editor: Optimize UV Drawing

Use batchs to store the entire buffer of loops before drawing.
These batchs can be stored in the mesh draw cache later.

===================================================================

M	intern/gawain/src/gwn_immediate.c
M	source/blender/editors/uvedit/uvedit_draw.c

===================================================================

diff --git a/intern/gawain/src/gwn_immediate.c b/intern/gawain/src/gwn_immediate.c
index f063665b423..c6df3ada018 100644
--- a/intern/gawain/src/gwn_immediate.c
+++ b/intern/gawain/src/gwn_immediate.c
@@ -277,8 +277,6 @@ Gwn_Batch* immBeginBatch(Gwn_PrimType prim_type, unsigned vertex_ct)
 	imm.batch = GWN_batch_create(prim_type, verts, NULL);
 	imm.batch->phase = GWN_BATCH_BUILDING;
 
-	GWN_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface);
-
 	return imm.batch;
 	}
 
@@ -398,6 +396,7 @@ void immEnd(void)
 			// TODO: resize only if vertex count is much smaller
 			}
 
+		GWN_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface);
 		imm.batch->phase = GWN_BATCH_READY_TO_DRAW;
 		imm.batch = NULL; // don't free, batch belongs to caller
 		}
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index b4d32b3d03a..cb8aa9660cf 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -59,6 +59,7 @@
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_query.h"
 
+#include "GPU_batch.h"
 #include "GPU_immediate.h"
 #include "GPU_immediate_util.h"
 #include "GPU_matrix.h"
@@ -73,7 +74,7 @@
 
 #include "uvedit_intern.h"
 
-static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset, const uint shdr_pos);
+static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, const uint shdr_pos);
 
 void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
 {
@@ -160,8 +161,6 @@ static void draw_uvs_shadow(Object *obedit)
 {
 	BMEditMesh *em = BKE_editmesh_from_object(obedit);
 	BMesh *bm = em->bm;
-	BMFace *efa;
-	BMIter iter;
 
 	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
 
@@ -172,9 +171,7 @@ static void draw_uvs_shadow(Object *obedit)
 	/* draws the mesh when painting */
 	immUniformThemeColor(TH_UV_SHADOW);
 
-	BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
-		draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset, pos);
-	}
+	draw_uvs_lineloop_bmfaces(bm, cd_loop_uv_offset, pos);
 
 	immUnbindProgram();
 }
@@ -384,18 +381,43 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
 	BLI_buffer_free(&tf_uvorig_buf);
 }
 
-static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset, const uint shdr_pos)
+static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, const uint shdr_pos)
 {
-	BMIter liter;
+	BMIter iter, liter;
+	BMFace *efa;
 	BMLoop *l;
 	MLoopUV *luv;
 
-	immBegin(GWN_PRIM_LINE_LOOP, efa->len);
+	/* For more efficiency first transfer the entire buffer to vram. */
+	Gwn_Batch *uv_batch = immBeginBatchAtMost(GWN_PRIM_LINE_LOOP, bm->totloop);
+
+	BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
+		if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
+			continue;
+
+		BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
+			luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+			immVertex2fv(shdr_pos, luv->uv);
+		}
+	}
+	immEnd();
 
-	BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
-		luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-		immVertex2fv(shdr_pos, luv->uv);
+	/* Then draw each face contour separately. */
+	GWN_batch_program_use_begin(uv_batch);
+	unsigned int index = 0;
+	BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
+		if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
+			continue;
+
+		GWN_batch_draw_range_ex(uv_batch, index, efa->len, false);
+		index += efa->len;
 	}
+	GWN_batch_program_use_end(uv_batch);
+
+	GWN_vertbuf_discard(uv_batch->verts[0]);
+	GWN_batch_discard(uv_batch);
+
+	immUnbindProgram();
 
 	immEnd();
 }
@@ -615,7 +637,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
 	BMLoop *l;
 	BMIter iter, liter;
 	MLoopUV *luv;
-	unsigned char col1[4], col2[4];
+	float col1[4], col2[4];
 	float pointsize;
 	int drawfaces, interpedges;
 	Image *ima = sima->image;
@@ -685,14 +707,14 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
 
 		if (tri_count && !(sima->flag & SI_NO_DRAWFACES)) {
 			/* draw transparent faces */
-			UI_GetThemeColor4ubv(TH_FACE, col1);
-			UI_GetThemeColor4ubv(TH_FACE_SELECT, col2);
+			UI_GetThemeColor4fv(TH_FACE, col1);
+			UI_GetThemeColor4fv(TH_FACE_SELECT, col2);
 			glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 			glEnable(GL_BLEND);
 
 			Gwn_VertFormat *format = immVertexFormat();
 			pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-			color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+			color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
 
 			immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
 
@@ -704,12 +726,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
 
 					if (efa == efa_act) {
 						/* only once */
-						unsigned char tmp_col[4];
-						UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, tmp_col);
-						immAttrib4ubv(color, tmp_col);
+						float tmp_col[4];
+						UI_GetThemeColor4fv(TH_EDITMESH_ACTIVE, tmp_col);
+						immAttrib4fv(color, tmp_col);
 					}
 					else {
-						immAttrib4ubv(color, is_select ? col2 : col1);
+						immAttrib4fv(color, is_select ? col2 : col1);
 					}
 
 					draw_uvs_looptri(em, &i, cd_loop_uv_offset, pos);
@@ -739,13 +761,11 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
 		glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 	}
 
-	glLineWidth(1);
+	pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 
 	switch (sima->dt_uv) {
 		case SI_UVDT_DASH:
 		{
-			const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-
 			immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
 
 			float viewport_size[4];
@@ -755,141 +775,160 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
 			immUniform1i("num_colors", 2);  /* "advanced" mode */
 			immUniformArray4fv("colors", (float *)(float[][4]){{0.56f, 0.56f, 0.56f, 1.0f}, {0.07f, 0.07f, 0.07f, 1.0f}}, 2);
 			immUniform1f("dash_width", 4.0f);
-
-			BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
-				if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
-					continue;
-
-				draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset, shdr_pos);
-			}
-
-			immUnbindProgram();
+			glLineWidth(1.0f);
 
 			break;
 		}
 		case SI_UVDT_BLACK: /* black/white */
 		case SI_UVDT_WHITE:
-			pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-
 			immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
 			if (sima->dt_uv == SI_UVDT_WHITE) {
 				immUniformColor3f(1.0f, 1.0f, 1.0f);
 			}
 			else {
 				immUniformColor3f(0.0f, 0.0f, 0.0f);
 			}
-
-			BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
-				if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
-					continue;
-
-				draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset, pos);
-			}
-
-			immUnbindProgram();
+			glLineWidth(1.0f);
 
 			break;
 		case SI_UVDT_OUTLINE:
-			pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-
 			immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
-			glLineWidth(3);
 			imm_cpack(0x0);
+			glLineWidth(3.0f);
 
-			BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
-				if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
-					continue;
+			break;
+	}
 
-				draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset, pos);
-			}
+	/* For more efficiency first transfer the entire buffer to vram. */
+	Gwn_Batch *uv_batch = immBeginBatchAtMost(GWN_PRIM_LINE_LOOP, bm->totloop);
+	Gwn_VertBuf* uv_vbo = uv_batch->verts[0];
+	BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
+		if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
+			continue;
 
-			immUnbindProgram();
+		BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
+			luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+			immVertex2fv(pos, luv->uv);
+		}
+	}
+	immEnd();
 
-			glLineWidth(1);
-			UI_GetThemeColor4ubv(TH_WIRE_EDIT, col2);
+	/* Then draw each face contour separately. */
+	GWN_batch_program_use_begin(uv_batch);
+	unsigned int index = 0, vbo_len_used;
+	BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
+		if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
+			continue;
 
-			if (me->drawflag & ME_DRAWEDGES) {
-				int sel;
-				UI_GetThemeColor4ubv(TH_EDGE_SELECT, col1);
+		GWN_batch_draw_range_ex(uv_batch, index, efa->len, false);
+		index += efa->len;
+	}
+	vbo_len_used = index;
+	GWN_batch_program_use_end(uv_batch);
+	immUnbindProgram();
 
-				Gwn_VertFormat *format = immVertexFormat();
-				pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-				color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
 
-				if (interpedges) {
-					immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+	if (sima->dt_uv == SI_UVDT_OUTLINE) {
+		glLineWidth(1.0f);
+		UI_GetThemeColor4fv(TH_WIRE_EDIT, col2);
 
-					BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
-						if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
-							continue;
+		if (me->drawflag & ME_DRAWEDGES) {
+			int sel;
+			UI_GetThemeColor4fv(TH_EDGE_SELECT, col1);
 
-						immBegin(GWN_PRIM_LINE_LOOP, efa->len);
+			if (interpedges) {
+				/* Create a color buffer. */
+				static Gwn_VertFormat format = {0};
+				static uint shdr_col;
+				if (format.attrib_ct == 0) {
+					shdr_col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+				}
 
-						BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
-							sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
-							immAttrib4ubv(color, sel ? (GLubyte *)col1 : (GLubyte *)col2);
+				Gwn_VertBuf *vbo_col = GWN_vertbuf_create_with_format(&format);
+				GWN_vertbuf_data_alloc(vbo_col, vbo_len_used);
 
-							luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-							immVertex2fv(pos, luv->uv);
-						}
+				index = 0;
+				BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
+					if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
+						continue;
 
-						immEnd();
+					BM_ITER_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list