From 14d3dd83ec048fe823fce382c806ddb71e761e8c Mon Sep 17 00:00:00 2001 From: Stanislav Vorobiov Date: Wed, 15 Jan 2014 15:41:54 +0400 Subject: [PATCH] YaGL: Avoid extra glBufferData call on glVertexAttribPointer If we just keep array size then it's possible to avoid calling glBufferData before glBufferSubData, this was the reason FPS dropped a bit comparing to old glVertexAttribPointer implementation Change-Id: I1a6cf8ff5f8f4a8a5f0f375259bff00d01e58b10 --- hw/yagl/yagl_apis/gles/yagl_gles_api_ts.c | 10 ++++++-- hw/yagl/yagl_apis/gles/yagl_gles_api_ts.h | 13 +++++++++- hw/yagl/yagl_apis/gles/yagl_host_gles_calls.c | 25 +++++++++++++------ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.c b/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.c index 7a49eb5065..8a2c418a79 100644 --- a/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.c +++ b/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.c @@ -44,9 +44,15 @@ void yagl_gles_api_ts_init(struct yagl_gles_api_ts *gles_api_ts, void yagl_gles_api_ts_cleanup(struct yagl_gles_api_ts *gles_api_ts) { if (gles_api_ts->num_arrays > 0) { + uint32_t i; + yagl_ensure_ctx(0); - gles_api_ts->driver->DeleteBuffers(gles_api_ts->num_arrays, - gles_api_ts->arrays); + + for (i = 0; i < gles_api_ts->num_arrays; ++i) { + gles_api_ts->driver->DeleteBuffers(1, + &gles_api_ts->arrays[i].vbo); + } + yagl_unensure_ctx(0); } diff --git a/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.h b/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.h index ebb7a9915f..faf6d83ce0 100644 --- a/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.h +++ b/hw/yagl/yagl_apis/gles/yagl_gles_api_ts.h @@ -35,13 +35,24 @@ struct yagl_gles_driver; struct yagl_gles_api_ps; +/* + * OpenGL 3.1+ core profile doesn't allow one to + * call glVertexAttribPointer and friends without a VBO, thus, + * we need to have a backing VBO in order to support GLESv2. + */ +struct yagl_gles_array +{ + GLuint vbo; + uint32_t size; +}; + struct yagl_gles_api_ts { struct yagl_gles_driver *driver; struct yagl_gles_api_ps *ps; - GLuint *arrays; + struct yagl_gles_array *arrays; uint32_t num_arrays; }; diff --git a/hw/yagl/yagl_apis/gles/yagl_host_gles_calls.c b/hw/yagl/yagl_apis/gles/yagl_host_gles_calls.c index 2a9aa020bf..21f7495ebf 100644 --- a/hw/yagl/yagl_apis/gles/yagl_host_gles_calls.c +++ b/hw/yagl/yagl_apis/gles/yagl_host_gles_calls.c @@ -68,9 +68,11 @@ static GLuint yagl_gles_bind_array(uint32_t indx, int32_t data_count) { GLuint current_vbo; + uint32_t size; if (indx >= gles_api_ts->num_arrays) { - GLuint *arrays; + struct yagl_gles_array *arrays; + uint32_t i; arrays = g_malloc((indx + 1) * sizeof(arrays[0])); @@ -78,8 +80,10 @@ static GLuint yagl_gles_bind_array(uint32_t indx, gles_api_ts->arrays, gles_api_ts->num_arrays * sizeof(arrays[0])); - gles_api_ts->driver->GenBuffers(indx + 1 - gles_api_ts->num_arrays, - &arrays[gles_api_ts->num_arrays]); + for (i = gles_api_ts->num_arrays; i <= indx; ++i) { + gles_api_ts->driver->GenBuffers(1, &arrays[i].vbo); + arrays[i].size = 0; + } g_free(gles_api_ts->arrays); @@ -90,11 +94,18 @@ static GLuint yagl_gles_bind_array(uint32_t indx, gles_api_ts->driver->GetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)¤t_vbo); - gles_api_ts->driver->BindBuffer(GL_ARRAY_BUFFER, gles_api_ts->arrays[indx]); + gles_api_ts->driver->BindBuffer(GL_ARRAY_BUFFER, gles_api_ts->arrays[indx].vbo); + + size = first * stride + data_count; + + if (size > gles_api_ts->arrays[indx].size) { + gles_api_ts->driver->BufferData(GL_ARRAY_BUFFER, + size, NULL, + GL_STREAM_DRAW); + gles_api_ts->arrays[indx].size = size; + } + - gles_api_ts->driver->BufferData(GL_ARRAY_BUFFER, - first * stride + data_count, NULL, - GL_STREAM_DRAW); gles_api_ts->driver->BufferSubData(GL_ARRAY_BUFFER, first * stride, data_count, data); -- 2.34.1