[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