[Glamor] [PATCH 18/34] glamor: Extract the streamed vertex data code used by Render. (v2)

Alex Deucher alexdeucher at gmail.com
Fri Feb 28 10:02:13 PST 2014


From: Eric Anholt <eric at anholt.net>

We should be uploading any vertex data using this kind of upload
style, since it saves a bunch of extra copies of our vertex data.

Ported from Eric's glamor xserver tree.

v2: fix composite_vbo_offset init in trapezoid rendering

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 src/Makefile.am        |  1 +
 src/glamor.h           |  1 +
 src/glamor_priv.h      | 10 ++++++
 src/glamor_render.c    | 67 ++++++++--------------------------
 src/glamor_trapezoid.c | 68 ++++++++++-------------------------
 src/glamor_vbo.c       | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 141 insertions(+), 103 deletions(-)
 create mode 100644 src/glamor_vbo.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 2fd521f..4f476d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,6 +42,7 @@ libglamor_la_SOURCES = \
 	glamor_pixmap.c\
 	glamor_largepixmap.c\
 	glamor_picture.c\
+	glamor_vbo.c \
 	glamor_window.c\
 	glamor_gl_dispatch.c\
 	glamor_fbo.c\
diff --git a/src/glamor.h b/src/glamor.h
index 1bb48ed..0172d57 100644
--- a/src/glamor.h
+++ b/src/glamor.h
@@ -315,6 +315,7 @@ extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
 extern _X_EXPORT int glamor_create_gc(GCPtr gc);
 
 extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable);
+
 /* Glamor rendering/drawing functions with XXX_nf.
  * nf means no fallback within glamor internal if possible. If glamor
  * fail to accelerate the operation, glamor will return a false, and the
diff --git a/src/glamor_priv.h b/src/glamor_priv.h
index 8c118cb..35c6ce2 100644
--- a/src/glamor_priv.h
+++ b/src/glamor_priv.h
@@ -250,6 +250,7 @@ typedef struct glamor_screen_private {
 	GLuint vbo, ebo;
 	Bool vbo_mapped;
 	int vbo_offset;
+	int composite_vbo_offset;
 	int vbo_size;
 	char *vb;
 	int vb_stride;
@@ -801,6 +802,15 @@ glamor_triangles(CARD8 op,
 
 void glamor_pixmap_init(ScreenPtr screen);
 void glamor_pixmap_fini(ScreenPtr screen);
+
+/* glamor_vbo.c */
+
+void *
+glamor_get_vbo_space(ScreenPtr screen, int size, char **vbo_offset);
+
+void
+glamor_put_vbo_space(ScreenPtr screen);
+
 /** 
  * Download a pixmap's texture to cpu memory. If success,
  * One copy of current pixmap's texture will be put into
diff --git a/src/glamor_render.c b/src/glamor_render.c
index f7610bd..9bf1b07 100644
--- a/src/glamor_render.c
+++ b/src/glamor_render.c
@@ -726,6 +726,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch;
 	int vert_size;
+	char *vbo_offset;
 
 	glamor_priv->render_nr_verts = 0;
 	glamor_priv->vb_stride = 2 * sizeof(float);
@@ -737,46 +738,22 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 	vert_size = n_verts * glamor_priv->vb_stride;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
-			glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
-				glamor_priv->vb_stride;
-			glamor_priv->vbo_offset = 0;
-			dispatch->glBufferData(GL_ARRAY_BUFFER,
-					       glamor_priv->vbo_size,
-					       NULL, GL_STREAM_DRAW);
-		}
-
-		glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER,
-							     glamor_priv->vbo_offset,
-							     vert_size,
-							     GL_MAP_WRITE_BIT |
-							     GL_MAP_UNSYNCHRONIZED_BIT |
-							     GL_MAP_INVALIDATE_RANGE_BIT);
-		assert(glamor_priv->vb != NULL);
-		glamor_priv->vb -= glamor_priv->vbo_offset;
-		glamor_priv->vbo_mapped = TRUE;
-	} else
-		glamor_priv->vbo_offset = 0;
+	glamor_get_vbo_space(screen, vert_size, &vbo_offset);
+	glamor_priv->composite_vbo_offset = 0;
 
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, glamor_priv->vb_stride,
-					(void *) ((long)
-						  glamor_priv->vbo_offset));
+					GL_FALSE,
+					glamor_priv->vb_stride,
+					vbo_offset);
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
 	if (glamor_priv->has_source_coords) {
 		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
 						GL_FLOAT, GL_FALSE,
 						glamor_priv->vb_stride,
-						(void *) ((long)
-							  glamor_priv->vbo_offset
-							  +
-							  2 *
-							  sizeof(float)));
+						vbo_offset + 2 * sizeof(float));
 		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	}
 
@@ -784,12 +761,8 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2,
 						GL_FLOAT, GL_FALSE,
 						glamor_priv->vb_stride,
-						(void *) ((long)
-							  glamor_priv->vbo_offset
-							  +
-							  (glamor_priv->has_source_coords
-							   ? 4 : 2) *
-							  sizeof(float)));
+						vbo_offset + (glamor_priv->has_source_coords ?
+							      4 : 2) * sizeof(float));
 		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
 	}
 	glamor_put_dispatch(glamor_priv);
@@ -803,7 +776,7 @@ glamor_emit_composite_vert(ScreenPtr screen,
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	float *vb = (float *) (glamor_priv->vb + glamor_priv->vbo_offset);
+	float *vb = (float *) (glamor_priv->vb + glamor_priv->composite_vbo_offset);
 	int j = 0;
 
 	vb[j++] = dst_coords[i * 2 + 0];
@@ -818,7 +791,7 @@ glamor_emit_composite_vert(ScreenPtr screen,
 	}
 
 	glamor_priv->render_nr_verts++;
-	glamor_priv->vbo_offset += glamor_priv->vb_stride;
+	glamor_priv->composite_vbo_offset += glamor_priv->vb_stride;
 }
 
 
@@ -831,18 +804,7 @@ glamor_flush_composite_rects(ScreenPtr screen)
 	glamor_gl_dispatch *dispatch;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-	    if (glamor_priv->vbo_mapped) {
-		dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
-		glamor_priv->vbo_mapped = FALSE;
-	    }
-	} else {
-
-		dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-		dispatch->glBufferData(GL_ARRAY_BUFFER,
-				       glamor_priv->vbo_offset,
-				       glamor_priv->vb, GL_DYNAMIC_DRAW);
-	}
+	glamor_put_vbo_space(screen);
 
 	if (!glamor_priv->render_nr_verts)
 		return;
@@ -1400,8 +1362,7 @@ glamor_composite_with_shader(CARD8 op,
 
 			DEBUGF("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n",
 				x_dest, y_dest, x_source, y_source,x_mask,y_mask,width,height);
-			vertices = (float*)(glamor_priv->vb + glamor_priv->vbo_offset);
-			assert(glamor_priv->vbo_offset < glamor_priv->vbo_size - glamor_priv->vb_stride);
+			vertices = (float *) (glamor_priv->vb + glamor_priv->composite_vbo_offset);
 			glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale,
 						     dst_yscale,
 						     x_dest, y_dest,
@@ -1427,7 +1388,7 @@ glamor_composite_with_shader(CARD8 op,
 					glamor_priv->yInverted, vertices, vb_stride);
 			}
 			glamor_priv->render_nr_verts += 4;
-			glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
+			glamor_priv->composite_vbo_offset += glamor_priv->vb_stride * 4;
 			rects++;
 		}
 		glamor_flush_composite_rects(screen);
diff --git a/src/glamor_trapezoid.c b/src/glamor_trapezoid.c
index e1ca252..cce7eb6 100644
--- a/src/glamor_trapezoid.c
+++ b/src/glamor_trapezoid.c
@@ -204,15 +204,7 @@ glamor_flush_composite_triangles(ScreenPtr screen)
 	glamor_gl_dispatch *dispatch;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-		dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
-	else {
-
-		dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-		dispatch->glBufferData(GL_ARRAY_BUFFER,
-		        glamor_priv->vbo_offset,
-		        glamor_priv->vb, GL_DYNAMIC_DRAW);
-	}
+	glamor_put_vbo_space(screen);
 
 	if (!glamor_priv->render_nr_verts)
 		return;
@@ -572,6 +564,7 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
 	glamor_gl_dispatch *dispatch;
 	int stride;
 	int vert_size;
+	char *vbo_offset;
 
 	glamor_priv->render_nr_verts = 0;
 
@@ -600,58 +593,39 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
 
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
-			glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
-				glamor_priv->vb_stride;
-			glamor_priv->vbo_offset = 0;
-			dispatch->glBufferData(GL_ARRAY_BUFFER,
-					       glamor_priv->vbo_size,
-					       NULL, GL_STREAM_DRAW);
-		}
-
-		glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER,
-		                                             glamor_priv->vbo_offset,
-		                                             vert_size,
-		                                             GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
-
-		assert(glamor_priv->vb != NULL);
-		glamor_priv->vb -= glamor_priv->vbo_offset;
-	} else {
-		glamor_priv->vbo_offset = 0;
-	}
+	glamor_get_vbo_space(screen, vert_size, &vbo_offset);
+	glamor_priv->composite_vbo_offset = 0;
 
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
 	/* Set the vertex pointer. */
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-	        GL_FALSE, glamor_priv->vb_stride,
-	        (void *) ((long)glamor_priv->vbo_offset));
+					GL_FALSE, glamor_priv->vb_stride,
+					vbo_offset);
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 	stride = 2;
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-	        GL_FALSE, glamor_priv->vb_stride,
-	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
+					GL_FALSE, glamor_priv->vb_stride,
+					vbo_offset + stride * sizeof(float));
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	stride += 2;
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT,
-	        GL_FALSE, glamor_priv->vb_stride,
-	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
+					GL_FALSE, glamor_priv->vb_stride,
+					vbo_offset + stride * sizeof(float));
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
 	stride += 2;
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT,
-	        GL_FALSE, glamor_priv->vb_stride,
-	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
+					GL_FALSE, glamor_priv->vb_stride,
+					vbo_offset + stride * sizeof(float));
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
 	stride += 4;
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT,
-	        GL_FALSE, glamor_priv->vb_stride,
-	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
+					GL_FALSE, glamor_priv->vb_stride,
+					vbo_offset + stride * sizeof(float));
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
 
 	glamor_put_dispatch(glamor_priv);
@@ -1437,7 +1411,8 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 
 			miTrapezoidBounds(1, ptrap, &one_trap_bound);
 
-			vertices = (float*)(glamor_priv->vb + glamor_priv->vbo_offset) + 2;
+			vertices = (float*)(glamor_priv->vb +
+					    glamor_priv->composite_vbo_offset) + 2;
 			glamor_set_tcoords_ext((pixmap_priv->base.pixmap->drawable.width),
 			        (pixmap_priv->base.pixmap->drawable.height),
 			        (one_trap_bound.x1),
@@ -1519,7 +1494,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 			       right_slope);
 
 			glamor_priv->render_nr_verts += 4;
-			glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
+			glamor_priv->composite_vbo_offset += glamor_priv->vb_stride * 4;
 		}
 
 		i += mrect;
@@ -1528,14 +1503,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 		if (!glamor_priv->render_nr_verts)
 			continue;
 
-		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-			dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
-		else {
-			dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-			dispatch->glBufferData(GL_ARRAY_BUFFER,
-			        glamor_priv->vbo_offset,
-			        glamor_priv->vb, GL_DYNAMIC_DRAW);
-		}
+		glamor_put_vbo_space(screen);
 
 #ifndef GLAMOR_GLES2
 		dispatch->glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts,
diff --git a/src/glamor_vbo.c b/src/glamor_vbo.c
new file mode 100644
index 0000000..3689379
--- /dev/null
+++ b/src/glamor_vbo.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * @file glamor_vbo.c
+ *
+ * Helpers for managing streamed vertex bufffers used in glamor.
+ */
+
+#include "glamor_priv.h"
+
+void *
+glamor_get_vbo_space(ScreenPtr screen, int size, char **vbo_offset)
+{
+	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch;
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+	    if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) {
+		glamor_priv->vbo_size = MAX(65536, size);
+		glamor_priv->vbo_offset = 0;
+		dispatch->glBufferData(GL_ARRAY_BUFFER,
+				       glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
+	    }
+
+	    glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER,
+							 glamor_priv->vbo_offset,
+							 size,
+							 GL_MAP_WRITE_BIT |
+							 GL_MAP_UNSYNCHRONIZED_BIT |
+							 GL_MAP_INVALIDATE_RANGE_BIT);
+	    assert(glamor_priv->vb != NULL);
+	    *vbo_offset = (void *)(uintptr_t)glamor_priv->vbo_offset;
+	    glamor_priv->vbo_mapped = TRUE;
+	} else {
+	    /* Return a pointer to the statically allocated non-VBO
+	     * memory. We'll upload it through glBufferData() later.
+	     */
+	    if (glamor_priv->vbo_size < size) {
+		glamor_priv->vbo_size = size;
+		free(glamor_priv->vb);
+		glamor_priv->vb = XNFalloc(size);
+	    }
+	    *vbo_offset = NULL;
+	    glamor_priv->vbo_offset = 0;
+	}
+
+	glamor_put_dispatch(glamor_priv);
+
+	return glamor_priv->vb;
+}
+
+void
+glamor_put_vbo_space(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch;
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+	    if (glamor_priv->vbo_mapped) {
+		dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+		glamor_priv->vbo_mapped = FALSE;
+	    }
+	} else {
+	    dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+	    dispatch->glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
+				   glamor_priv->vb, GL_DYNAMIC_DRAW);
+	}
+
+	glamor_put_dispatch(glamor_priv);
+}
-- 
1.8.3.1



More information about the Glamor mailing list