Re: [PATCH 22/27] glamor: Improve the performance of PolyGlyphBlt.

2014-03-12 Thread Markus Wick
Are we able to add cached textures to CharInfoPtr? If not, then this 
would be the ideal use case for texture_arrays ;)
Again, using GL_POINTS and check for every bit on CPU isn't the way to 
go.


Am 2014-03-11 22:30, schrieb Eric Anholt:

Using the same idea as the previous PushPixels code, just make points
for each point in the glyph.  This is an advantage over the pushpixels
fallback because we can batch the BO mappings and draw calls across
glyphs.

Improves performance of x11perf -f8text by 773.389% +/- 3.50754% 
(n=10).


Signed-off-by: Eric Anholt e...@anholt.net
---
 glamor/glamor_glyphblt.c | 138 
+++

 1 file changed, 138 insertions(+)

diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 0a99a95..5d785a0 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -27,6 +27,141 @@
  */

 #include glamor_priv.h
+#include dixfontstr.h
+
+static Bool
+glamor_poly_glyph_blt_pixels(DrawablePtr drawable, GCPtr gc,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci)
+{
+ScreenPtr screen = drawable-pScreen;
+glamor_screen_private *glamor_priv = 
glamor_get_screen_private(screen);

+PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+glamor_pixmap_private *pixmap_priv;
+int off_x, off_y;
+GLfloat xscale, yscale;
+float color[4];
+unsigned long fg_pixel = gc-fgPixel;
+char *vbo_offset;
+RegionPtr clip;
+int num_points, max_points;
+float *points = NULL;
+
+x += drawable-x;
+y += drawable-y;
+
+if (gc-fillStyle != FillSolid) {
+glamor_fallback(gc fillstyle not solid\n);
+return FALSE;
+}
+
+pixmap_priv = glamor_get_pixmap_private(pixmap);
+if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+return FALSE;
+
+glamor_get_context(glamor_priv);
+if (!glamor_set_alu(screen, gc-alu)) {
+if (gc-alu == GXclear)
+fg_pixel = 0;
+else {
+glamor_fallback(unsupported alu %x\n, gc-alu);
+glamor_put_context(glamor_priv);
+return FALSE;
+}
+}
+
+if (!glamor_set_planemask(pixmap, gc-planemask)) {
+glamor_fallback(Failed to set planemask in %s.\n, 
__FUNCTION__);

+glamor_put_context(glamor_priv);
+return FALSE;
+}
+
+glamor_get_drawable_deltas(drawable, pixmap, off_x, off_y);
+
+glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale);
+
+glUseProgram(glamor_priv-solid_prog);
+
+glamor_get_rgba_from_pixel(fg_pixel,
+   color[0], color[1], color[2], 
color[3],

+   format_for_pixmap(pixmap));
+glUniform4fv(glamor_priv-solid_color_uniform_location, 1, color);
+
+clip = fbGetCompositeClip(gc);
+
+glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+max_points = 500;
+num_points = 0;
+while (nglyph--) {
+CharInfoPtr charinfo = *ppci++;
+int w = GLYPHWIDTHPIXELS(charinfo);
+int h = GLYPHHEIGHTPIXELS(charinfo);
+uint8_t *glyphbits = FONTGLYPHBITS(NULL, charinfo);
+
+if (w  h) {
+int glyph_x = x + charinfo-metrics.leftSideBearing;
+int glyph_y = y - charinfo-metrics.ascent;
+int glyph_stride = GLYPHWIDTHBYTESPADDED(charinfo);
+int xx, yy;
+
+for (yy = 0; yy  h; yy++) {
+uint8_t *glyph_row = glyphbits + glyph_stride * yy;
+for (xx = 0; xx  w; xx++) {
+int pt_x_i = glyph_x + xx;
+int pt_y_i = glyph_y + yy;
+float pt_x_f, pt_y_f;
+if (!(glyph_row[xx / 8]  (1  xx % 8)))
+continue;
+
+if (!RegionContainsPoint(clip, pt_x_i, pt_y_i, 
NULL))

+continue;
+
+if (!num_points) {
+points = glamor_get_vbo_space(screen,
+  max_points * 2
* sizeof(float),
+  vbo_offset);
+
+glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, 
GL_FLOAT,
+  GL_FALSE, 2 * 
sizeof(float),

+  vbo_offset);
+}
+
+pt_x_f = v_from_x_coord_x(xscale, pt_x_i + off_x + 
0.5);

+if (glamor_priv-yInverted)
+pt_y_f = v_from_x_coord_y_inverted(yscale,
pt_y_i + off_y + 0.5);
+else
+pt_y_f = v_from_x_coord_y(yscale, pt_y_i +
off_y + 0.5);
+
+points[num_points * 2 + 0] = pt_x_f;
+points[num_points * 2 + 1] = pt_y_f;
+num_points++;
+
+if (num_points == max_points) {
+  

[PATCH 22/27] glamor: Improve the performance of PolyGlyphBlt.

2014-03-11 Thread Eric Anholt
Using the same idea as the previous PushPixels code, just make points
for each point in the glyph.  This is an advantage over the pushpixels
fallback because we can batch the BO mappings and draw calls across
glyphs.

Improves performance of x11perf -f8text by 773.389% +/- 3.50754% (n=10).

Signed-off-by: Eric Anholt e...@anholt.net
---
 glamor/glamor_glyphblt.c | 138 +++
 1 file changed, 138 insertions(+)

diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 0a99a95..5d785a0 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -27,6 +27,141 @@
  */
 
 #include glamor_priv.h
+#include dixfontstr.h
+
+static Bool
+glamor_poly_glyph_blt_pixels(DrawablePtr drawable, GCPtr gc,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci)
+{
+ScreenPtr screen = drawable-pScreen;
+glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+glamor_pixmap_private *pixmap_priv;
+int off_x, off_y;
+GLfloat xscale, yscale;
+float color[4];
+unsigned long fg_pixel = gc-fgPixel;
+char *vbo_offset;
+RegionPtr clip;
+int num_points, max_points;
+float *points = NULL;
+
+x += drawable-x;
+y += drawable-y;
+
+if (gc-fillStyle != FillSolid) {
+glamor_fallback(gc fillstyle not solid\n);
+return FALSE;
+}
+
+pixmap_priv = glamor_get_pixmap_private(pixmap);
+if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+return FALSE;
+
+glamor_get_context(glamor_priv);
+if (!glamor_set_alu(screen, gc-alu)) {
+if (gc-alu == GXclear)
+fg_pixel = 0;
+else {
+glamor_fallback(unsupported alu %x\n, gc-alu);
+glamor_put_context(glamor_priv);
+return FALSE;
+}
+}
+
+if (!glamor_set_planemask(pixmap, gc-planemask)) {
+glamor_fallback(Failed to set planemask in %s.\n, __FUNCTION__);
+glamor_put_context(glamor_priv);
+return FALSE;
+}
+
+glamor_get_drawable_deltas(drawable, pixmap, off_x, off_y);
+
+glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale);
+
+glUseProgram(glamor_priv-solid_prog);
+
+glamor_get_rgba_from_pixel(fg_pixel,
+   color[0], color[1], color[2], color[3],
+   format_for_pixmap(pixmap));
+glUniform4fv(glamor_priv-solid_color_uniform_location, 1, color);
+
+clip = fbGetCompositeClip(gc);
+
+glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+max_points = 500;
+num_points = 0;
+while (nglyph--) {
+CharInfoPtr charinfo = *ppci++;
+int w = GLYPHWIDTHPIXELS(charinfo);
+int h = GLYPHHEIGHTPIXELS(charinfo);
+uint8_t *glyphbits = FONTGLYPHBITS(NULL, charinfo);
+
+if (w  h) {
+int glyph_x = x + charinfo-metrics.leftSideBearing;
+int glyph_y = y - charinfo-metrics.ascent;
+int glyph_stride = GLYPHWIDTHBYTESPADDED(charinfo);
+int xx, yy;
+
+for (yy = 0; yy  h; yy++) {
+uint8_t *glyph_row = glyphbits + glyph_stride * yy;
+for (xx = 0; xx  w; xx++) {
+int pt_x_i = glyph_x + xx;
+int pt_y_i = glyph_y + yy;
+float pt_x_f, pt_y_f;
+if (!(glyph_row[xx / 8]  (1  xx % 8)))
+continue;
+
+if (!RegionContainsPoint(clip, pt_x_i, pt_y_i, NULL))
+continue;
+
+if (!num_points) {
+points = glamor_get_vbo_space(screen,
+  max_points * 2 * 
sizeof(float),
+  vbo_offset);
+
+glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+  GL_FALSE, 2 * sizeof(float),
+  vbo_offset);
+}
+
+pt_x_f = v_from_x_coord_x(xscale, pt_x_i + off_x + 0.5);
+if (glamor_priv-yInverted)
+pt_y_f = v_from_x_coord_y_inverted(yscale, pt_y_i + 
off_y + 0.5);
+else
+pt_y_f = v_from_x_coord_y(yscale, pt_y_i + off_y + 
0.5);
+
+points[num_points * 2 + 0] = pt_x_f;
+points[num_points * 2 + 1] = pt_y_f;
+num_points++;
+
+if (num_points == max_points) {
+glamor_put_vbo_space(screen);
+glDrawArrays(GL_POINTS, 0, num_points);
+num_points = 0;
+}
+}
+}
+}
+
+x +=