From 49aa5e3ea4eecea0562c05a4e52962985a56e510 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 10 Sep 2014 16:17:52 -0700 Subject: [PATCH] glamor: Use vertex array objects Core contexts require the use of vertex array objects, so switch both glamor and ephyr/glamor over. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt Signed-off-by: Dave Airlie --- glamor/glamor.c | 2 + glamor/glamor_priv.h | 2 + glamor/glamor_vbo.c | 9 ++++ hw/kdrive/ephyr/ephyr_glamor_glx.c | 86 +++++++++++++++++++++--------- 4 files changed, 75 insertions(+), 24 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 81aba2d81..0b5ebef1d 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -574,6 +574,8 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP || epoxy_gl_version() >= 30 || epoxy_has_gl_extension("GL_NV_pack_subimage"); + glamor_priv->has_vertex_array_object = + epoxy_has_gl_extension("GL_ARB_vertex_array_object"); glamor_setup_debug_output(screen); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index a190e67b1..8ed53e7fb 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -201,6 +201,7 @@ typedef struct glamor_screen_private { Bool has_unpack_subimage; Bool has_rw_pbo; Bool use_quads; + Bool has_vertex_array_object; int max_fbo_size; struct xorg_list @@ -247,6 +248,7 @@ typedef struct glamor_screen_private { char *glyph_defines; /** Vertex buffer for all GPU rendering. */ + GLuint vao; GLuint vbo; /** Next offset within the VBO that glamor_get_vbo_space() will use. */ int vbo_offset; diff --git a/glamor/glamor_vbo.c b/glamor/glamor_vbo.c index ba60ce660..b8db0092b 100644 --- a/glamor/glamor_vbo.c +++ b/glamor/glamor_vbo.c @@ -174,6 +174,11 @@ glamor_init_vbo(ScreenPtr screen) glamor_make_current(glamor_priv); glGenBuffers(1, &glamor_priv->vbo); + if (glamor_priv->has_vertex_array_object) { + glGenVertexArrays(1, &glamor_priv->vao); + glBindVertexArray(glamor_priv->vao); + } else + glamor_priv->vao = 0; } void @@ -183,6 +188,10 @@ glamor_fini_vbo(ScreenPtr screen) glamor_make_current(glamor_priv); + if (glamor_priv->vao != 0) { + glDeleteVertexArrays(1, &glamor_priv->vao); + glamor_priv->vao = 0; + } if (!glamor_priv->has_map_buffer_range) free(glamor_priv->vb); } diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c index 582e3af96..30c524564 100644 --- a/hw/kdrive/ephyr/ephyr_glamor_glx.c +++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c @@ -71,6 +71,8 @@ struct ephyr_glamor { /* Size of the window that we're rendering to. */ unsigned width, height; + + GLuint vao, vbo; }; static GLint @@ -189,47 +191,53 @@ ephyr_glamor_set_texture(struct ephyr_glamor *glamor, uint32_t tex) glamor->tex = tex; } +static void +ephyr_glamor_set_vertices(struct ephyr_glamor *glamor) +{ + glVertexAttribPointer(glamor->texture_shader_position_loc, + 2, GL_FLOAT, FALSE, 0, (void *) 0); + glVertexAttribPointer(glamor->texture_shader_texcoord_loc, + 2, GL_FLOAT, FALSE, 0, (void *) (sizeof (float) * 8)); + + glEnableVertexAttribArray(glamor->texture_shader_position_loc); + glEnableVertexAttribArray(glamor->texture_shader_texcoord_loc); +} + +static void +ephyr_glamor_clear_vertices(struct ephyr_glamor *glamor) +{ + glDisableVertexAttribArray(glamor->texture_shader_position_loc); + glDisableVertexAttribArray(glamor->texture_shader_texcoord_loc); +} + void ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor, struct pixman_region16 *damage) { - /* Redraw the whole screen, since glXSwapBuffers leaves the back - * buffer undefined. - */ - static const float position[] = { - -1, -1, - 1, -1, - 1, 1, - -1, 1, - }; - static const float texcoords[] = { - 0, 1, - 1, 1, - 1, 0, - 0, 0, - }; + GLint old_vao; glXMakeCurrent(dpy, glamor->glx_win, glamor->ctx); + if (glamor->vao) { + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao); + glBindVertexArray(glamor->vao); + } else + ephyr_glamor_set_vertices(glamor); + glBindFramebuffer(GL_FRAMEBUFFER, 0); glUseProgram(glamor->texture_shader); glViewport(0, 0, glamor->width, glamor->height); if (!ephyr_glamor_gles2) glDisable(GL_COLOR_LOGIC_OP); - glVertexAttribPointer(glamor->texture_shader_position_loc, - 2, GL_FLOAT, FALSE, 0, position); - glVertexAttribPointer(glamor->texture_shader_texcoord_loc, - 2, GL_FLOAT, FALSE, 0, texcoords); - glEnableVertexAttribArray(glamor->texture_shader_position_loc); - glEnableVertexAttribArray(glamor->texture_shader_texcoord_loc); - glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, glamor->tex); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(glamor->texture_shader_position_loc); - glDisableVertexAttribArray(glamor->texture_shader_texcoord_loc); + if (glamor->vao) + glBindVertexArray(old_vao); + else + ephyr_glamor_clear_vertices(glamor); glXSwapBuffers(dpy, glamor->glx_win); } @@ -271,6 +279,18 @@ ephyr_glamor_process_event(xcb_generic_event_t *xev) struct ephyr_glamor * ephyr_glamor_glx_screen_init(xcb_window_t win) { + static const float position[] = { + -1, -1, + 1, -1, + 1, 1, + -1, 1, + 0, 1, + 1, 1, + 1, 0, + 0, 0, + }; + GLint old_vao; + GLXContext ctx; struct ephyr_glamor *glamor; GLXWindow glx_win; @@ -312,6 +332,24 @@ ephyr_glamor_glx_screen_init(xcb_window_t win) glamor->glx_win = glx_win; ephyr_glamor_setup_texturing_shader(glamor); + if (epoxy_has_gl_extension("GL_ARB_vertex_array_object")) { + glGenVertexArrays(1, &glamor->vao); + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao); + glBindVertexArray(glamor->vao); + } else + glamor->vao = 0; + + glGenBuffers(1, &glamor->vbo); + + glBindBuffer(GL_ARRAY_BUFFER, glamor->vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof (position), position, GL_STATIC_DRAW); + + if (glamor->vao) { + ephyr_glamor_set_vertices(glamor); + glBindVertexArray(old_vao); + } else + glBindBuffer(GL_ARRAY_BUFFER, 0); + return glamor; }