glamor-composite: Use glDrawElements to reduce the count of vertices.

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@linux.intel.com>
This commit is contained in:
Zhigang Gong 2012-01-08 08:45:08 +08:00 committed by Eric Anholt
parent 9dafd6fce5
commit 4cd07871a4
4 changed files with 49 additions and 20 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
@ -645,10 +672,6 @@ glamor_emit_composite_rect(ScreenPtr screen,
dst_coords, 1);
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);