[PATCH 13/16] glamor: Replace glamor_solid_boxes and glamor_solid with GC using code

Keith Packard keithp at keithp.com
Tue Apr 1 21:15:53 PDT 2014


This provides glamor_solid_boxes and glamor_solid using regular GC
operations instead of calling directly to underlying rendering
functions. This will allow the old rendering code to be removed.

Signed-off-by: Keith Packard <keithp at keithp.com>

fixup for utils

fixup for utils
---
 glamor/Makefile.am        |   2 +-
 glamor/glamor.c           |   2 -
 glamor/glamor_fill.c      | 361 ----------------------------------------------
 glamor/glamor_priv.h      |  28 ++--
 glamor/glamor_trapezoid.c |   9 +-
 glamor/glamor_utils.c     |  82 +++++++++++
 6 files changed, 98 insertions(+), 386 deletions(-)
 delete mode 100644 glamor/glamor_fill.c
 create mode 100644 glamor/glamor_utils.c

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index c78d6d4..61107bd 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -10,7 +10,6 @@ libglamor_la_SOURCES = \
 	glamor_copy.c \
 	glamor_core.c \
 	glamor_debug.h \
-	glamor_fill.c \
 	glamor_font.c \
 	glamor_glx.c \
 	glamor_glyphs.c \
@@ -42,6 +41,7 @@ libglamor_la_SOURCES = \
 	glamor_window.c\
 	glamor_fbo.c\
 	glamor_compositerects.c\
+	glamor_utils.c\
 	glamor_utils.h\
 	glamor.h
 
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 5975425..d45e6cc 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -496,7 +496,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
     glamor_init_vbo(screen);
     glamor_init_pixmap_fbo(screen);
-    glamor_init_solid_shader(screen);
     glamor_init_tile_shader(screen);
 #ifdef GLAMOR_TRAPEZOID_SHADER
     glamor_init_trapezoid_shader(screen);
@@ -529,7 +528,6 @@ glamor_release_screen_priv(ScreenPtr screen)
 #endif
     glamor_fini_vbo(screen);
     glamor_fini_pixmap_fbo(screen);
-    glamor_fini_solid_shader(screen);
     glamor_fini_tile_shader(screen);
 #ifdef GLAMOR_TRAPEZOID_SHADER
     glamor_fini_trapezoid_shader(screen);
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
deleted file mode 100644
index 4b32072..0000000
--- a/glamor/glamor_fill.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright © 2008 Intel Corporation
- * Copyright © 1998 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors:
- *    Eric Anholt <eric at anholt.net>
- *    Zhigang Gong <zhigang.gong at linux.intel.com>
- */
-
-#include "glamor_priv.h"
-
-/** @file glamor_fill.c
- *
- * GC fill implementation, based loosely on fb_fill.c
- */
-
-/**
- * Fills the given rectangle of a drawable with the GC's fill style.
- */
-Bool
-glamor_fill(DrawablePtr drawable,
-            GCPtr gc, int x, int y, int width, int height, Bool fallback)
-{
-    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
-    int off_x, off_y;
-    PixmapPtr sub_pixmap = NULL;
-    glamor_access_t sub_pixmap_access;
-    DrawablePtr saved_drawable = NULL;
-    int saved_x = x, saved_y = y;
-
-    glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
-
-    switch (gc->fillStyle) {
-    case FillSolid:
-        if (!glamor_solid(dst_pixmap,
-                          x + off_x,
-                          y + off_y,
-                          width, height, gc->alu, gc->planemask, gc->fgPixel))
-            goto fail;
-        break;
-    case FillStippled:
-    case FillOpaqueStippled:
-        if (!glamor_stipple(dst_pixmap,
-                            gc->stipple,
-                            x + off_x,
-                            y + off_y,
-                            width,
-                            height,
-                            gc->alu,
-                            gc->planemask,
-                            gc->fgPixel,
-                            gc->bgPixel, gc->patOrg.x, gc->patOrg.y))
-            goto fail;
-        break;
-    case FillTiled:
-        if (!glamor_tile(dst_pixmap,
-                         gc->tile.pixmap,
-                         x + off_x,
-                         y + off_y,
-                         width,
-                         height,
-                         gc->alu,
-                         gc->planemask,
-                         x - drawable->x - gc->patOrg.x,
-                         y - drawable->y - gc->patOrg.y))
-            goto fail;
-        break;
-    }
-    return TRUE;
-
- fail:
-    if (!fallback) {
-        if (glamor_ddx_fallback_check_pixmap(&dst_pixmap->drawable)
-            && glamor_ddx_fallback_check_gc(gc))
-            return FALSE;
-    }
-    /* Is it possible to set the access as WO? */
-
-    sub_pixmap_access = GLAMOR_ACCESS_RW;
-
-    sub_pixmap = glamor_get_sub_pixmap(dst_pixmap, x + off_x,
-                                       y + off_y, width, height,
-                                       sub_pixmap_access);
-
-    if (sub_pixmap != NULL) {
-        if (gc->fillStyle != FillSolid) {
-            gc->patOrg.x += (drawable->x - x);
-            gc->patOrg.y += (drawable->y - y);
-        }
-        saved_drawable = drawable;
-        drawable = &sub_pixmap->drawable;
-        saved_x = x;
-        saved_y = y;
-        x = 0;
-        y = 0;
-    }
-    if (glamor_prep_drawable(drawable, GLAMOR_ACCESS_RW) &&
-        glamor_prep_gc(gc)) {
-        fbFill(drawable, gc, x, y, width, height);
-    }
-    glamor_fini_gc(gc);
-    glamor_fini_drawable(drawable);
-
-    if (sub_pixmap != NULL) {
-        if (gc->fillStyle != FillSolid) {
-            gc->patOrg.x -= (saved_drawable->x - saved_x);
-            gc->patOrg.y -= (saved_drawable->y - saved_y);
-        }
-
-        x = saved_x;
-        y = saved_y;
-
-        glamor_put_sub_pixmap(sub_pixmap, dst_pixmap,
-                              x + off_x, y + off_y,
-                              width, height, sub_pixmap_access);
-    }
-
-    return TRUE;
-}
-
-void
-glamor_init_solid_shader(ScreenPtr screen)
-{
-    glamor_screen_private *glamor_priv;
-    const char *solid_vs =
-        "attribute vec4 v_position;"
-        "void main()\n"
-        "{\n"
-        "       gl_Position = v_position;\n"
-        "}\n";
-    const char *solid_fs =
-        GLAMOR_DEFAULT_PRECISION
-        "uniform vec4 color;\n"
-        "void main()\n"
-        "{\n"
-        "	gl_FragColor = color;\n"
-        "}\n";
-    GLint fs_prog, vs_prog;
-
-    glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
-    glamor_priv->solid_prog = glCreateProgram();
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs);
-    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs);
-    glAttachShader(glamor_priv->solid_prog, vs_prog);
-    glAttachShader(glamor_priv->solid_prog, fs_prog);
-
-    glBindAttribLocation(glamor_priv->solid_prog,
-                         GLAMOR_VERTEX_POS, "v_position");
-    glamor_link_glsl_prog(screen, glamor_priv->solid_prog, "solid");
-
-    glamor_priv->solid_color_uniform_location =
-        glGetUniformLocation(glamor_priv->solid_prog, "color");
-    glamor_put_context(glamor_priv);
-}
-
-void
-glamor_fini_solid_shader(ScreenPtr screen)
-{
-    glamor_screen_private *glamor_priv;
-
-    glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
-    glDeleteProgram(glamor_priv->solid_prog);
-    glamor_put_context(glamor_priv);
-}
-
-static void
-_glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
-{
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    GLfloat xscale, yscale;
-    float stack_vertices[32];
-    float *vertices = stack_vertices;
-    int valid_nbox = ARRAY_SIZE(stack_vertices) / (4 * 2);
-
-    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
-    glamor_get_context(glamor_priv);
-    glUseProgram(glamor_priv->solid_prog);
-
-    glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
-
-    pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
-
-    if (nbox > valid_nbox) {
-        int allocated_nbox;
-        float *new_vertices;
-
-        if (nbox > GLAMOR_COMPOSITE_VBO_VERT_CNT / 6)
-            allocated_nbox = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6;
-        else
-            allocated_nbox = nbox;
-        new_vertices = malloc(allocated_nbox * 4 * 2 * sizeof(float));
-        if (new_vertices) {
-            vertices = new_vertices;
-            valid_nbox = allocated_nbox;
-        }
-    }
-
-    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                          GL_FALSE, 2 * sizeof(float), vertices);
-    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
-    while (nbox) {
-        int box_cnt, i;
-        float *next_box;
-
-        next_box = vertices;
-        box_cnt = nbox > valid_nbox ? valid_nbox : nbox;
-        for (i = 0; i < box_cnt; i++) {
-            glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale,
-                                         box[i].x1, box[i].y1,
-                                         box[i].x2, box[i].y2,
-                                         glamor_priv->yInverted,
-                                         next_box);
-            next_box += 4 * 2;
-        }
-        if (box_cnt == 1)
-            glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
-        else {
-            if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-                glDrawRangeElements(GL_TRIANGLES, 0, box_cnt * 4, box_cnt * 6,
-                                    GL_UNSIGNED_SHORT, NULL);
-            } else {
-                glDrawElements(GL_TRIANGLES, box_cnt * 6, GL_UNSIGNED_SHORT,
-                               NULL);
-            }
-        }
-        nbox -= box_cnt;
-        box += box_cnt;
-    }
-
-    if (vertices != stack_vertices)
-        free(vertices);
-
-    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glamor_put_context(glamor_priv);
-    glamor_priv->state = RENDER_STATE;
-    glamor_priv->render_idle_cnt = 0;
-}
-
-/**
- * Fills the given rectangles of pixmap with an X pixel value.
- *
- * This is a helper used by other code after clipping and translation
- * of coordinates to a glamor backing pixmap.
- */
-Bool
-glamor_solid_boxes(PixmapPtr pixmap,
-                   BoxPtr box, int nbox, unsigned long fg_pixel)
-{
-    glamor_pixmap_private *pixmap_priv;
-    GLfloat color[4];
-
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-        return FALSE;
-
-    glamor_get_rgba_from_pixel(fg_pixel,
-                               &color[0],
-                               &color[1],
-                               &color[2], &color[3], format_for_pixmap(pixmap));
-
-    if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-        RegionRec region;
-        int n_region;
-        glamor_pixmap_clipped_regions *clipped_regions;
-        int i;
-
-        RegionInitBoxes(&region, box, nbox);
-        clipped_regions =
-            glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0,
-                                           0, 0);
-        for (i = 0; i < n_region; i++) {
-            BoxPtr inner_box;
-            int inner_nbox;
-
-            SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
-
-            inner_box = RegionRects(clipped_regions[i].region);
-            inner_nbox = RegionNumRects(clipped_regions[i].region);
-            _glamor_solid_boxes(pixmap, inner_box, inner_nbox, color);
-            RegionDestroy(clipped_regions[i].region);
-        }
-        free(clipped_regions);
-        RegionUninit(&region);
-    }
-    else
-        _glamor_solid_boxes(pixmap, box, nbox, color);
-
-    return TRUE;
-}
-
-/**
- * Fills a rectangle of a pixmap with an X pixel value.
- *
- * This is a helper used by other glamor code mostly for clearing of
- * buffers to 0.
- */
-Bool
-glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-             unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
-{
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_pixmap_private *pixmap_priv;
-    BoxRec box;
-
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-        return FALSE;
-
-    if (!glamor_set_planemask(pixmap, planemask)) {
-        glamor_fallback("Failedto set planemask  in glamor_solid.\n");
-        return FALSE;
-    }
-
-    glamor_get_context(glamor_priv);
-    if (!glamor_set_alu(screen, alu)) {
-        if (alu == GXclear)
-            fg_pixel = 0;
-        else {
-            glamor_fallback("unsupported alu %x\n", alu);
-            glamor_put_context(glamor_priv);
-            return FALSE;
-        }
-    }
-    box.x1 = x;
-    box.y1 = y;
-    box.x2 = x + width;
-    box.y2 = y + height;
-    glamor_solid_boxes(pixmap, &box, 1, fg_pixel);
-
-    glamor_set_alu(screen, GXcopy);
-    glamor_put_context(glamor_priv);
-
-    return TRUE;
-}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index aa71267..43c3eda 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -217,10 +217,6 @@ typedef struct glamor_screen_private {
         fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
     unsigned long fbo_cache_watermark;
 
-    /* glamor_solid */
-    GLint solid_prog;
-    GLint solid_color_uniform_location;
-
     /* glamor point shader */
     glamor_program point_prog;
 
@@ -670,18 +666,6 @@ Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
 
-/* glamor_fill.c */
-Bool glamor_fill(DrawablePtr drawable,
-                 GCPtr gc, int x, int y, int width, int height, Bool fallback);
-Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-                  unsigned char alu, unsigned long planemask,
-                  unsigned long fg_pixel);
-Bool glamor_solid_boxes(PixmapPtr pixmap,
-                        BoxPtr box, int nbox, unsigned long fg_pixel);
-
-void glamor_init_solid_shader(ScreenPtr screen);
-void glamor_fini_solid_shader(ScreenPtr screen);
-
 /* glamor_glyphs.c */
 Bool glamor_realize_glyph_caches(ScreenPtr screen);
 void glamor_glyphs_fini(ScreenPtr screen);
@@ -1032,6 +1016,18 @@ void glamor_composite_rectangles(CARD8 op,
 extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen,
                                              struct glamor_context *glamor_ctx);
 
+/* glamor_util.c */
+
+void
+glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+             unsigned char alu, unsigned long planemask,
+             unsigned long fg_pixel);
+
+void
+glamor_solid_boxes(PixmapPtr pixmap,
+                   BoxPtr box, int nbox, unsigned long fg_pixel);
+
+
 /* glamor_xv */
 typedef struct {
     uint32_t transform_index;
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index c76b8bb..1c8eddd 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -1399,12 +1399,9 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
     }
 
     /* First, clear all to zero */
-    if (!glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
-                      pixmap_priv->base.pixmap->drawable.height,
-                      GXclear, 0xFFFFFFFF, 0)) {
-        DEBUGF("glamor_solid failed, fallback\n");
-        return FALSE;
-    }
+    glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
+                 pixmap_priv->base.pixmap->drawable.height,
+                 GXclear, 0xFFFFFFFF, 0);
 
     glamor_get_context(glamor_priv);
 
diff --git a/glamor/glamor_utils.c b/glamor/glamor_utils.c
new file mode 100644
index 0000000..5459d79
--- /dev/null
+++ b/glamor/glamor_utils.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "glamor_priv.h"
+
+void
+glamor_solid_boxes(PixmapPtr pixmap,
+                   BoxPtr box, int nbox, unsigned long fg_pixel)
+{
+    DrawablePtr drawable = &pixmap->drawable;
+    GCPtr gc;
+    xRectangle *rect;
+    int n;
+
+    rect = malloc(nbox * sizeof (xRectangle));
+    if (!rect)
+        return;
+    for (n = 0; n < nbox; n++) {
+        rect[n].x = box[n].x1;
+        rect[n].y = box[n].y1;
+        rect[n].width = box[n].x2 - box[n].x1;
+        rect[n].height = box[n].y2 - box[n].y1;
+    }
+
+    gc = GetScratchGC(drawable->depth, drawable->pScreen);
+    if (gc) {
+        ChangeGCVal vals[1];
+
+        vals[0].val = fg_pixel;
+        ChangeGC(NullClient, gc, GCForeground, vals);
+        ValidateGC(drawable, gc);
+        gc->ops->PolyFillRect(drawable, gc, nbox, rect);
+        FreeScratchGC(gc);
+    }
+    free(rect);
+}
+
+void
+glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+             unsigned char alu, unsigned long planemask,
+             unsigned long fg_pixel)
+{
+    DrawablePtr drawable = &pixmap->drawable;
+    GCPtr gc;
+    ChangeGCVal vals[3];
+    xRectangle rect;
+
+    vals[0].val = alu;
+    vals[1].val = planemask;
+    vals[2].val = fg_pixel;
+    gc = GetScratchGC(drawable->depth, drawable->pScreen);
+    if (!gc)
+        return;
+    ChangeGC(NullClient, gc, GCFunction|GCPlaneMask|GCForeground, vals);
+    ValidateGC(drawable, gc);
+    rect.x = x;
+    rect.y = y;
+    rect.width = width;
+    rect.height = height;
+    gc->ops->PolyFillRect(drawable, gc, 1, &rect);
+    FreeScratchGC(gc);
+}
+
-- 
1.9.0



More information about the xorg-devel mailing list