[Glamor] [PATCH 2/9] glamor-composite: Use glDrawElements to reduce the count of vertices.

zhigang.gong at linux.intel.com zhigang.gong at linux.intel.com
Sun Jan 8 21:36:04 PST 2012


From: Zhigang Gong <zhigang.gong at linux.intel.com>

To split a rectangle (0,1,2,3) to two separated triangles need to feed
6 vertices, (0,1,2) and (0,2,3). use glDrawElements can reuse the shared
vertices.

Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
---
 src/glamor_gl_dispatch.c |    2 +
 src/glamor_gl_dispatch.h |    6 ++++-
 src/glamor_priv.h        |    2 +-
 src/glamor_render.c      |   59 ++++++++++++++++++++++++++++++++--------------
 4 files changed, 49 insertions(+), 20 deletions(-)

diff --git a/src/glamor_gl_dispatch.c b/src/glamor_gl_dispatch.c
index 788562c..5a47b45 100644
--- a/src/glamor_gl_dispatch.c
+++ b/src/glamor_gl_dispatch.c
@@ -16,6 +16,7 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glViewport, get_proc_address);
 	INIT_FUNC(dispatch, glRasterPos2i, get_proc_address);
 	INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
+	INIT_FUNC(dispatch, glDrawElements, get_proc_address);
 	INIT_FUNC(dispatch, glReadPixels, get_proc_address);
 	INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
 	INIT_FUNC(dispatch, glPixelStorei, get_proc_address);
@@ -37,6 +38,7 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glGenBuffers, get_proc_address);
 	INIT_FUNC(dispatch, glBufferData, get_proc_address);
 	INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
+	INIT_FUNC(dispatch, glMapBufferRange, get_proc_address);
 	INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
 	INIT_FUNC(dispatch, glBindBuffer, get_proc_address);
 	INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address);
diff --git a/src/glamor_gl_dispatch.h b/src/glamor_gl_dispatch.h
index 5f1831a..8fcb3dc 100644
--- a/src/glamor_gl_dispatch.h
+++ b/src/glamor_gl_dispatch.h
@@ -10,6 +10,9 @@ typedef struct glamor_gl_dispatch {
 	/* Vertex Array */
 	void (*glDrawArrays) (GLenum mode, GLint first, GLsizei count);
 
+	/* Elements Array*/
+	void (*glDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices);
+
 	/* Raster functions */
 	void (*glReadPixels) (GLint x, GLint y,
 			      GLsizei width, GLsizei height,
@@ -55,7 +58,8 @@ typedef struct glamor_gl_dispatch {
 	void (*glBufferData) (GLenum target, GLsizeiptr size,
 			      const GLvoid * data, GLenum usage);
 	GLvoid *(*glMapBuffer) (GLenum target, GLenum access);
-	 GLboolean(*glUnmapBuffer) (GLenum target);
+	GLvoid *(*glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+	GLboolean(*glUnmapBuffer) (GLenum target);
 	void (*glBindBuffer) (GLenum target, GLuint buffer);
 	void (*glDeleteBuffers) (GLsizei n, const GLuint * buffers);
 
diff --git a/src/glamor_priv.h b/src/glamor_priv.h
index 08db631..f3b0996 100644
--- a/src/glamor_priv.h
+++ b/src/glamor_priv.h
@@ -158,7 +158,7 @@ typedef struct glamor_screen_private {
 
 	int yInverted;
 	int screen_fbo;
-	GLuint vbo;
+	GLuint vbo, ebo;
 	int vbo_offset;
 	int vbo_size;
 	char *vb;
diff --git a/src/glamor_render.c b/src/glamor_render.c
index 34317a5..522b1a1 100644
--- a/src/glamor_render.c
+++ b/src/glamor_render.c
@@ -288,7 +288,7 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct
 	return shader;
 }
 
-#define GLAMOR_COMPOSITE_VBO_SIZE 8192
+#define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
 
 static void
 glamor_reset_composite_vbo(ScreenPtr screen)
@@ -296,18 +296,44 @@ glamor_reset_composite_vbo(ScreenPtr screen)
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_priv->vbo_offset = 0;
-	glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_SIZE;
+	glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2;
 	glamor_priv->render_nr_verts = 0;
 }
 
+static void
+glamor_init_eb(unsigned short *eb, int vert_cnt)
+{
+	int i, j;
+	for(i = 0, j = 0; j < vert_cnt; i += 6, j += 4)
+	{
+		eb[i] = j;
+		eb[i + 1] = j + 1;
+		eb[i + 2] = j + 2;
+		eb[i + 3] = j;
+		eb[i + 4] = j + 2;
+		eb[i + 5] = j + 3;
+	}
+}
+
 
 void
 glamor_init_composite_shaders(ScreenPtr screen)
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_priv->vb = malloc(GLAMOR_COMPOSITE_VBO_SIZE);
-	assert(glamor_priv->vb != NULL);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	unsigned short *eb;
+
+	dispatch->glGenBuffers(1, &glamor_priv->vbo);
+	dispatch->glGenBuffers(1, &glamor_priv->ebo);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+	dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+			       GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2,
+			       NULL, GL_DYNAMIC_DRAW);
+	eb = dispatch->glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+	glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+	dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
 	glamor_reset_composite_vbo(screen);
 }
 
@@ -542,6 +568,12 @@ glamor_setup_composite_vbo(ScreenPtr screen)
 		glamor_priv->vb_stride += 2 * sizeof(float);
 
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+	dispatch->glBufferData(GL_ARRAY_BUFFER,
+			       GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2,
+			       NULL, GL_DYNAMIC_DRAW);
+
+	glamor_priv->vb = dispatch->glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
 					GL_FALSE, glamor_priv->vb_stride,
@@ -609,11 +641,9 @@ glamor_flush_composite_rects(ScreenPtr screen)
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 	if (!glamor_priv->render_nr_verts)
 		return;
-	dispatch->glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
-			       glamor_priv->vb, GL_STREAM_DRAW);
-
-	dispatch->glDrawArrays(GL_TRIANGLES, 0,
-			       glamor_priv->render_nr_verts);
+	dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+	dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
+				 GL_UNSIGNED_SHORT, NULL);
 	glamor_reset_composite_vbo(screen);
 }
 
@@ -627,15 +657,12 @@ glamor_emit_composite_rect(ScreenPtr screen,
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
-	if (glamor_priv->vbo_offset + 6 * glamor_priv->vb_stride >
+	if (glamor_priv->vbo_offset + 4 * glamor_priv->vb_stride >
 	    glamor_priv->vbo_size) {
 		glamor_flush_composite_rects(screen);
 	}
 
 	if (glamor_priv->vbo_offset == 0) {
-		if (glamor_priv->vbo == 0)
-			dispatch->glGenBuffers(1, &glamor_priv->vbo);
-
 		glamor_setup_composite_vbo(screen);
 	}
 
@@ -646,10 +673,6 @@ glamor_emit_composite_rect(ScreenPtr screen,
 	glamor_emit_composite_vert(screen, src_coords, mask_coords,
 				   dst_coords, 2);
 	glamor_emit_composite_vert(screen, src_coords, mask_coords,
-				   dst_coords, 0);
-	glamor_emit_composite_vert(screen, src_coords, mask_coords,
-				   dst_coords, 2);
-	glamor_emit_composite_vert(screen, src_coords, mask_coords,
 				   dst_coords, 3);
 }
 
@@ -969,7 +992,6 @@ glamor_composite_with_shader(CARD8 op,
 
 	dispatch->glUseProgram(shader->prog);
 
-
 	if (key.source == SHADER_SOURCE_SOLID) {
 		glamor_set_composite_solid(dispatch, source_solid_color,
 					   shader->source_uniform_location);
@@ -1079,6 +1101,7 @@ glamor_composite_with_shader(CARD8 op,
 	glamor_flush_composite_rects(screen);
 
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
-- 
1.7.4.4



More information about the Glamor mailing list