[PATCH 05/13] glamor: Add glamor_program based 0-width dashed lines
Keith Packard
keithp at keithp.com
Mon May 5 15:02:12 PDT 2014
This makes sure the pixelization for dashed lines matches non-dashed
lines, while also speeding them up.
v2: Switch to glamor_make_current
v3: Create dash pattern pixmap without GLAMOR_CREATE_FBO_NO_FBO
Signed-off-by: Keith Packard <keithp at keithp.com>
fixup for dash
---
glamor/Makefile.am | 1 +
glamor/glamor.c | 11 +-
glamor/glamor_core.c | 26 +++-
glamor/glamor_dash.c | 368 ++++++++++++++++++++++++++++++++++++++++++++++++
glamor/glamor_lines.c | 32 +++--
glamor/glamor_priv.h | 29 +++-
glamor/glamor_program.c | 7 +
glamor/glamor_program.h | 3 +
glamor/glamor_segs.c | 33 +++--
9 files changed, 490 insertions(+), 20 deletions(-)
create mode 100644 glamor/glamor_dash.c
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 8fd6ec1..9dd06eb 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -9,6 +9,7 @@ libglamor_la_SOURCES = \
glamor_context.h \
glamor_copy.c \
glamor_core.c \
+ glamor_dash.c \
glamor_debug.h \
glamor_fill.c \
glamor_font.c \
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 3468b51..1ae0382 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -37,6 +37,7 @@
DevPrivateKeyRec glamor_screen_private_key;
DevPrivateKeyRec glamor_pixmap_private_key;
+DevPrivateKeyRec glamor_gc_private_key;
/**
* glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
@@ -346,7 +347,15 @@ glamor_init(ScreenPtr screen, unsigned int flags)
LogMessage(X_WARNING,
"glamor%d: Failed to allocate pixmap private\n",
screen->myNum);
- goto fail;;
+ goto fail;
+ }
+
+ if (!dixRegisterPrivateKey(&glamor_gc_private_key, PRIVATE_GC,
+ sizeof (glamor_gc_private))) {
+ LogMessage(X_WARNING,
+ "glamor%d: Failed to allocate gc private\n",
+ screen->myNum);
+ goto fail;
}
if (epoxy_is_desktop_gl())
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index ffb6eba..9d941d7 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -409,14 +409,35 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
fbValidateGC(gc, changes, drawable);
}
+ if (changes & GCDashList) {
+ glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
+
+ if (gc_priv->dash) {
+ glamor_destroy_pixmap(gc_priv->dash);
+ gc_priv->dash = NULL;
+ }
+ }
+
gc->ops = &glamor_gc_ops;
}
+static void
+glamor_destroy_gc(GCPtr gc)
+{
+ glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
+
+ if (gc_priv->dash) {
+ glamor_destroy_pixmap(gc_priv->dash);
+ gc_priv->dash = NULL;
+ }
+ miDestroyGC(gc);
+}
+
static GCFuncs glamor_gc_funcs = {
glamor_validate_gc,
miChangeGC,
miCopyGC,
- miDestroyGC,
+ glamor_destroy_gc,
miChangeClip,
miDestroyClip,
miCopyClip
@@ -429,6 +450,9 @@ static GCFuncs glamor_gc_funcs = {
int
glamor_create_gc(GCPtr gc)
{
+ glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
+
+ gc_priv->dash = NULL;
if (!fbCreateGC(gc))
return FALSE;
diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c
new file mode 100644
index 0000000..59565be
--- /dev/null
+++ b/glamor/glamor_dash.c
@@ -0,0 +1,368 @@
+/*
+ * 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"
+#include "glamor_program.h"
+#include "glamor_transform.h"
+#include "glamor_transfer.h"
+#include "glamor_prepare.h"
+
+static const char dash_vs_vars[] =
+ "attribute vec3 primitive;\n"
+ "varying float dash_offset;\n";
+
+static const char dash_vs_exec[] =
+ " dash_offset = primitive.z / dash_length;\n"
+ GLAMOR_POS(gl_Position, primitive.xy);
+
+static const char dash_fs_vars[] =
+ "varying float dash_offset;\n";
+
+static const char on_off_fs_exec[] =
+ " float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n"
+ " if (pattern == 0.0)\n"
+ " discard;\n";
+
+/* XXX deal with stippled double dashed lines once we have stippling support */
+static const char double_fs_exec[] =
+ " float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n"
+ " if (pattern == 0.0)\n"
+ " gl_FragColor = bg;\n"
+ " else\n"
+ " gl_FragColor = fg;\n";
+
+
+static const glamor_facet glamor_facet_on_off_dash_lines = {
+ .version = 130,
+ .name = "poly_lines_on_off_dash",
+ .vs_vars = dash_vs_vars,
+ .vs_exec = dash_vs_exec,
+ .fs_vars = dash_fs_vars,
+ .fs_exec = on_off_fs_exec,
+ .locations = glamor_program_location_dash,
+};
+
+static const glamor_facet glamor_facet_double_dash_lines = {
+ .version = 130,
+ .name = "poly_lines_double_dash",
+ .vs_vars = dash_vs_vars,
+ .vs_exec = dash_vs_exec,
+ .fs_vars = dash_fs_vars,
+ .fs_exec = double_fs_exec,
+ .locations = glamor_program_location_dash|glamor_program_location_fg|glamor_program_location_bg,
+};
+
+static PixmapPtr
+glamor_get_dash_pixmap(GCPtr gc)
+{
+ glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
+ ScreenPtr screen = gc->pScreen;
+ PixmapPtr pixmap;
+ int offset;
+ int d;
+ uint32_t pixel;
+ GCPtr scratch_gc;
+
+ if (gc_priv->dash)
+ return gc_priv->dash;
+
+ offset = 0;
+ for (d = 0; d < gc->numInDashList; d++)
+ offset += gc->dash[d];
+
+ pixmap = glamor_create_pixmap(screen, offset, 1, 8, 0);
+ if (!pixmap)
+ goto bail;
+
+ scratch_gc = GetScratchGC(8, screen);
+ if (!scratch_gc)
+ goto bail_pixmap;
+
+ pixel = 0xffffffff;
+ offset = 0;
+ for (d = 0; d < gc->numInDashList; d++) {
+ xRectangle rect;
+ ChangeGCVal changes;
+
+ changes.val = pixel;
+ (void) ChangeGC(NullClient, scratch_gc,
+ GCForeground, &changes);
+ ValidateGC(&pixmap->drawable, scratch_gc);
+ rect.x = offset;
+ rect.y = 0;
+ rect.width = gc->dash[d];
+ rect.height = 1;
+ scratch_gc->ops->PolyFillRect (&pixmap->drawable, scratch_gc, 1, &rect);
+ offset += gc->dash[d];
+ pixel = ~pixel;
+ }
+ FreeScratchGC(scratch_gc);
+
+ gc_priv->dash = pixmap;
+ return pixmap;
+
+bail_pixmap:
+ glamor_destroy_pixmap(pixmap);
+bail:
+ return NULL;
+}
+
+static glamor_program *
+glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
+{
+ 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 = glamor_get_pixmap_private(pixmap);
+ PixmapPtr dash_pixmap;
+ glamor_pixmap_private *dash_priv;
+ glamor_program *prog;
+
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ goto bail;
+
+ if (gc->lineWidth != 0)
+ goto bail;
+
+ dash_pixmap = glamor_get_dash_pixmap(gc);
+ dash_priv = glamor_get_pixmap_private(pixmap);
+
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dash_priv))
+ goto bail;
+
+ glamor_make_current(glamor_priv);
+
+ switch (gc->lineStyle) {
+ case LineOnOffDash:
+ prog = glamor_use_program_fill(pixmap, gc,
+ &glamor_priv->on_off_dash_line_progs,
+ &glamor_facet_on_off_dash_lines);
+ if (!prog)
+ goto bail_ctx;
+ break;
+ case LineDoubleDash:
+ if (gc->fillStyle != FillSolid)
+ goto bail_ctx;
+
+ prog = &glamor_priv->double_dash_line_prog;
+
+ if (!prog->prog) {
+ if (!glamor_build_program(screen, prog,
+ &glamor_facet_double_dash_lines,
+ NULL))
+ goto bail_ctx;
+ }
+
+ if (!glamor_use_program(pixmap, gc, prog, NULL))
+ goto bail_ctx;
+
+ glamor_set_color(pixmap, gc->fgPixel, prog->fg_uniform);
+ glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform);
+ break;
+
+ default:
+ goto bail_ctx;
+ }
+
+
+ /* Set the dash pattern as texture 1 */
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, dash_priv->base.fbo->tex);
+ glUniform1i(prog->dash_uniform, 1);
+ glUniform1f(prog->dash_length_uniform, dash_pixmap->drawable.width);
+
+ return prog;
+
+bail_ctx:
+ glDisable(GL_COLOR_LOGIC_OP);
+bail:
+ return NULL;
+}
+
+static void
+glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog, int n, GLenum mode)
+{
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+ int box_x, box_y;
+ int off_x, off_y;
+
+ glEnable(GL_SCISSOR_TEST);
+
+ glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ int nbox = RegionNumRects(gc->pCompositeClip);
+ BoxPtr box = RegionRects(gc->pCompositeClip);
+
+ glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y);
+
+ while (nbox--) {
+ glScissor(box->x1 + off_x,
+ box->y1 + off_y,
+ box->x2 - box->x1,
+ box->y2 - box->y1);
+ box++;
+ glDrawArrays(mode, 0, n);
+ }
+ }
+
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_COLOR_LOGIC_OP);
+ glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+}
+
+static int
+glamor_line_length(short x1, short y1, short x2, short y2)
+{
+ int dx = abs(x2 - x1);
+ int dy = abs(y2 - y1);
+ if (dx > dy)
+ return dx;
+ return dy;
+}
+
+Bool
+glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc,
+ int mode, int n, DDXPointPtr points)
+{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_program *prog;
+ short *v;
+ char *vbo_offset;
+ int add_last;
+ int dash_pos;
+ int prev_x, prev_y;
+ int i;
+
+ if (n < 2)
+ return TRUE;
+
+ if (!(prog = glamor_dash_setup(drawable, gc)))
+ return FALSE;
+
+ add_last = 0;
+ if (gc->capStyle != CapNotLast)
+ add_last = 1;
+
+ /* Set up the vertex buffers for the points */
+
+ v = glamor_get_vbo_space(drawable->pScreen, (n + add_last) * 4 * sizeof (short), &vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE,
+ 4 * sizeof (short), vbo_offset);
+
+ if (mode == CoordModePrevious) {
+ DDXPointRec here = { 0, 0 };
+
+ for (i = 0; i < n; i++) {
+ here.x += points[i].x;
+ points[i].x = here.x;
+ here.y += points[i].y;
+ points[i].y = here.y;
+ }
+ }
+
+ dash_pos = gc->dashOffset;
+ prev_x = prev_y = 0;
+ for (i = 0; i < n; i++) {
+ if (i)
+ dash_pos += glamor_line_length(prev_x, prev_y,
+ points[i].x, points[i].y);
+ v[0] = prev_x = points[i].x;
+ v[1] = prev_y = points[i].y;
+ v[2] = dash_pos;
+ v += 4;
+ }
+
+ if (add_last) {
+ v[0] = v[-4] + 1;
+ v[1] = v[-3];
+ v[2] = dash_pos + 1;
+ }
+
+ glamor_put_vbo_space(screen);
+
+ glamor_dash_loop(drawable, gc, prog, n + add_last, GL_LINE_STRIP);
+
+ return TRUE;
+}
+
+static short *
+glamor_add_segment(short *v, short x1, short y1, short x2, short y2, int dash_start)
+{
+ v[0] = x1;
+ v[1] = y1;
+ v[2] = dash_start;
+
+ v[4] = x2;
+ v[5] = y2;
+ v[6] = dash_start + glamor_line_length(x1, y1,
+ x2, y2);
+ return v + 8;
+}
+
+Bool
+glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc,
+ int nseg, xSegment *segs)
+{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_program *prog;
+ short *v;
+ char *vbo_offset;
+ int dash_start = gc->dashOffset;
+ int add_last;
+ int i;
+
+ if (!(prog = glamor_dash_setup(drawable, gc)))
+ return FALSE;
+
+ add_last = 0;
+ if (gc->capStyle != CapNotLast)
+ add_last = 1;
+
+ /* Set up the vertex buffers for the points */
+
+ v = glamor_get_vbo_space(drawable->pScreen, (nseg<<add_last) * 8 * sizeof (short), &vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE,
+ 4 * sizeof (short), vbo_offset);
+
+ for (i = 0; i < nseg; i++) {
+ v = glamor_add_segment(v,
+ segs[i].x1, segs[i].y1,
+ segs[i].x2, segs[i].y2,
+ dash_start);
+ if (add_last)
+ v = glamor_add_segment(v,
+ segs[i].x2, segs[i].y2,
+ segs[i].x2 + 1, segs[i].y2,
+ v[-8 + 6]);
+ }
+
+ glamor_put_vbo_space(screen);
+
+ glamor_dash_loop(drawable, gc, prog, nseg << (1 + add_last), GL_LINES);
+
+ return TRUE;
+}
diff --git a/glamor/glamor_lines.c b/glamor/glamor_lines.c
index 3f021a6..f577936 100644
--- a/glamor/glamor_lines.c
+++ b/glamor/glamor_lines.c
@@ -33,8 +33,8 @@ static const glamor_facet glamor_facet_poly_lines = {
};
static Bool
-glamor_poly_lines_gl(DrawablePtr drawable, GCPtr gc,
- int mode, int n, DDXPointPtr points)
+glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
+ int mode, int n, DDXPointPtr points)
{
ScreenPtr screen = drawable->pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
@@ -51,12 +51,6 @@ glamor_poly_lines_gl(DrawablePtr drawable, GCPtr gc,
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
goto bail;
- if (gc->lineWidth != 0)
- goto bail;
-
- if (gc->lineStyle != LineSolid)
- goto bail;
-
add_last = 0;
if (gc->capStyle != CapNotLast)
add_last = 1;
@@ -130,6 +124,28 @@ bail:
return FALSE;
}
+static Bool
+glamor_poly_lines_gl(DrawablePtr drawable, GCPtr gc,
+ int mode, int n, DDXPointPtr points)
+{
+ if (gc->lineWidth != 0)
+ return FALSE;
+
+ switch (gc->lineStyle) {
+ case LineSolid:
+ return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points);
+ case LineOnOffDash:
+ return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points);
+ case LineDoubleDash:
+ if (gc->fillStyle == FillTiled)
+ return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points);
+ else
+ return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points);
+ default:
+ return FALSE;
+ }
+}
+
static void
glamor_poly_lines_bail(DrawablePtr drawable, GCPtr gc,
int mode, int n, DDXPointPtr points)
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 59fb32d..e438f7f 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -250,6 +250,10 @@ typedef struct glamor_screen_private {
/* glamor segment shaders */
glamor_program_fill poly_segment_program;
+ /* glamor dash line shader */
+ glamor_program_fill on_off_dash_line_progs;
+ glamor_program double_dash_line_prog;
+
/* vertext/elment_index buffer object for render */
GLuint vbo, ebo;
/** Next offset within the VBO that glamor_get_vbo_space() will use. */
@@ -562,6 +566,13 @@ typedef enum glamor_pixmap_status {
GLAMOR_UPLOAD_FAILED
} glamor_pixmap_status_t;
+/* GC private structure. Currently holds only any computed dash pixmap */
+
+typedef struct {
+ PixmapPtr dash;
+} glamor_gc_private;
+
+extern DevPrivateKeyRec glamor_gc_private_key;
extern DevPrivateKeyRec glamor_screen_private_key;
extern DevPrivateKeyRec glamor_pixmap_private_key;
@@ -594,6 +605,12 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
+static inline glamor_gc_private *
+glamor_get_gc_private(GCPtr gc)
+{
+ return dixLookupPrivate(&gc->devPrivates, &glamor_gc_private_key);
+}
+
/**
* Returns TRUE if the given planemask covers all the significant bits in the
* pixel values for pDrawable.
@@ -979,7 +996,17 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
void
glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d);
-/* glamor_lines.c */
+
+/* glamor_dash.c */
+Bool
+glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc,
+ int mode, int n, DDXPointPtr points);
+
+Bool
+glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc,
+ int nseg, xSegment *segs);
+
+/* glamor_lines.c */
void
glamor_poly_lines(DrawablePtr drawable, GCPtr gc,
int mode, int n, DDXPointPtr points);
diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index a9371f3..0e3e94d 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -122,6 +122,11 @@ static glamor_location_var location_vars[] = {
.fs_vars = ("uniform uvec4 bitplane;\n"
"uniform uvec4 bitmul;\n"),
},
+ {
+ .location = glamor_program_location_dash,
+ .vs_vars = "uniform float dash_length;\n",
+ .fs_vars = "uniform sampler2D dash;\n",
+ },
};
#define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0])
@@ -326,6 +331,8 @@ glamor_build_program(ScreenPtr screen,
prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font");
prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane");
prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul");
+ prog->dash_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash");
+ prog->dash_length_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash_length");
if (glGetError() != GL_NO_ERROR)
goto fail;
diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h
index 118f978..56ba03a 100644
--- a/glamor/glamor_program.h
+++ b/glamor/glamor_program.h
@@ -30,6 +30,7 @@ typedef enum {
glamor_program_location_fill = 4,
glamor_program_location_font = 8,
glamor_program_location_bitplane = 16,
+ glamor_program_location_dash = 32,
} glamor_program_location;
typedef enum {
@@ -64,6 +65,8 @@ struct _glamor_program {
GLint font_uniform;
GLint bitplane_uniform;
GLint bitmul_uniform;
+ GLint dash_uniform;
+ GLint dash_length_uniform;
glamor_program_location locations;
glamor_program_flag flags;
glamor_use prim_use;
diff --git a/glamor/glamor_segs.c b/glamor/glamor_segs.c
index 98ef9a0..01129a2 100644
--- a/glamor/glamor_segs.c
+++ b/glamor/glamor_segs.c
@@ -33,8 +33,8 @@ static const glamor_facet glamor_facet_poly_segment = {
};
static Bool
-glamor_poly_segment_gl(DrawablePtr drawable, GCPtr gc,
- int nseg, xSegment *segs)
+glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc,
+ int nseg, xSegment *segs)
{
ScreenPtr screen = drawable->pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
@@ -51,12 +51,6 @@ glamor_poly_segment_gl(DrawablePtr drawable, GCPtr gc,
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
goto bail;
- if (gc->lineWidth != 0)
- goto bail;
-
- if (gc->lineStyle != LineSolid)
- goto bail;
-
add_last = 0;
if (gc->capStyle != CapNotLast)
add_last = 1;
@@ -122,6 +116,28 @@ bail:
return FALSE;
}
+static Bool
+glamor_poly_segment_gl(DrawablePtr drawable, GCPtr gc,
+ int nseg, xSegment *segs)
+{
+ if (gc->lineWidth != 0)
+ return FALSE;
+
+ switch (gc->lineStyle) {
+ case LineSolid:
+ return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs);
+ case LineOnOffDash:
+ return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs);
+ case LineDoubleDash:
+ if (gc->fillStyle == FillTiled)
+ return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs);
+ else
+ return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs);
+ default:
+ return FALSE;
+ }
+}
+
static void
glamor_poly_segment_bail(DrawablePtr drawable, GCPtr gc,
int nseg, xSegment *segs)
@@ -140,7 +156,6 @@ glamor_poly_segment_bail(DrawablePtr drawable, GCPtr gc,
miPolySegment(drawable, gc, nseg, segs);
}
-
void
glamor_poly_segment(DrawablePtr drawable, GCPtr gc,
int nseg, xSegment *segs)
--
2.0.0.rc0
More information about the xorg-devel
mailing list