YaGL: Avoid extra glBufferData call on glVertexAttribPointer 64/15064/1
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Wed, 15 Jan 2014 11:41:54 +0000 (15:41 +0400)
committerStanislav Vorobiov <s.vorobiov@samsung.com>
Wed, 15 Jan 2014 11:41:54 +0000 (15:41 +0400)
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
hw/yagl/yagl_apis/gles/yagl_gles_api_ts.h
hw/yagl/yagl_apis/gles/yagl_host_gles_calls.c

index 7a49eb5065767f8b4b000f788e26e78a5d846909..8a2c418a79ce4d80ea50e6b8280fb6edab3ff4a7 100644 (file)
@@ -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);
     }
 
index ebb7a9915f387585e63dc5a02a6c6c303b17dad5..faf6d83ce05503a2b649e8ab017a6ddab59e01bf 100644 (file)
 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;
 };
 
index 2a9aa020bf0af270a103f5c65761ab04b8a3b9bb..21f7495ebfbc4a4c63ae6b3477a7aa1d19fed8c6 100644 (file)
@@ -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*)&current_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);