xf86-video-intel: 4 commits - src/sna/sna_accel.c src/sna/sna_io.c src/uxa/uxa-accel.c test/DrawSegments.c test/.gitignore test/Makefile.am
Chris Wilson
ickle at kemper.freedesktop.org
Tue Sep 16 12:29:25 PDT 2014
src/sna/sna_accel.c | 2
src/sna/sna_io.c | 4
src/uxa/uxa-accel.c | 64 ++++++++-----
test/.gitignore | 1
test/DrawSegments.c | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++++
test/Makefile.am | 1
6 files changed, 296 insertions(+), 25 deletions(-)
New commits:
commit 2a4855a633f42d90e11f5c51342c514c2dc24307
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 16 20:26:28 2014 +0100
sna: Constify argument to box_from_seg()
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e5382a2..ab43831 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -9955,7 +9955,7 @@ out:
RegionUninit(&data.region);
}
-static inline void box_from_seg(BoxPtr b, xSegment *seg, GCPtr gc)
+static inline void box_from_seg(BoxPtr b, const xSegment *seg, GCPtr gc)
{
if (seg->x1 == seg->x2) {
if (seg->y1 > seg->y2) {
commit 1cc9762b08a127a2475a44da71ca07cb294562f2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 16 12:14:31 2014 +0100
uxa: Fix conversion of Segments into Rectangles
The trick is to make sure we consider the CapLast setting in the
direction the line is being drawn and adjust the inked pixels
accordingly.
Testcase: DrawSegments/hv0
Reported-by: Russell King
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/uxa/uxa-accel.c b/src/uxa/uxa-accel.c
index 757b276..9e7879b 100644
--- a/src/uxa/uxa-accel.c
+++ b/src/uxa/uxa-accel.c
@@ -675,6 +675,43 @@ uxa_poly_lines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
free(prect);
}
+static BoxRec box_from_seg(const xSegment *seg, GCPtr gc)
+{
+ BoxRec b;
+
+ if (seg->x1 == seg->x2) {
+ if (seg->y1 > seg->y2) {
+ b.y2 = seg->y1 + 1;
+ b.y1 = seg->y2 + 1;
+ if (gc->capStyle != CapNotLast)
+ b.y1--;
+ } else {
+ b.y1 = seg->y1;
+ b.y2 = seg->y2;
+ if (gc->capStyle != CapNotLast)
+ b.y2++;
+ }
+ b.x1 = seg->x1;
+ b.x2 = seg->x1 + 1;
+ } else {
+ if (seg->x1 > seg->x2) {
+ b.x2 = seg->x1 + 1;
+ b.x1 = seg->x2 + 1;
+ if (gc->capStyle != CapNotLast)
+ b.x1--;
+ } else {
+ b.x1 = seg->x1;
+ b.x2 = seg->x2;
+ if (gc->capStyle != CapNotLast)
+ b.x2++;
+ }
+ b.y1 = seg->y1;
+ b.y2 = seg->y1 + 1;
+ }
+
+ return b;
+}
+
/**
* uxa_poly_segment() checks if it can accelerate the lines as a group of
* horizontal or vertical lines (rectangles), and uses existing rectangle fill
@@ -718,28 +755,11 @@ uxa_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg)
if (!prect)
return;
for (i = 0; i < nseg; i++) {
- if (pSeg[i].x1 < pSeg[i].x2) {
- prect[i].x = pSeg[i].x1;
- prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1;
- } else {
- prect[i].x = pSeg[i].x2;
- prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1;
- }
- if (pSeg[i].y1 < pSeg[i].y2) {
- prect[i].y = pSeg[i].y1;
- prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1;
- } else {
- prect[i].y = pSeg[i].y2;
- prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1;
- }
-
- /* don't paint last pixel */
- if (pGC->capStyle == CapNotLast) {
- if (prect[i].width == 1)
- prect[i].height--;
- else
- prect[i].width--;
- }
+ BoxRec b = box_from_seg(&pSeg[i], pGC);
+ prect[i].x = b.x1;
+ prect[i].y = b.y1;
+ prect[i].width = b.x2 - b.x1;
+ prect[i].height = b.y2 - b.y1;
}
pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect);
free(prect);
commit db157b42aaa7880d98fed3e7493a19471e86e534
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 16 11:56:07 2014 +0100
test: Add DrawSegments
Compare fb/ddx for many DrawSegments operations.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/test/.gitignore b/test/.gitignore
index d036ead..3b18297 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -6,6 +6,7 @@ basic-lines
basic-stress
basic-stippledrect
basic-tiledrect
+DrawSegments
cursor-test
render-fill
render-trapezoid
diff --git a/test/DrawSegments.c b/test/DrawSegments.c
new file mode 100644
index 0000000..d310af9
--- /dev/null
+++ b/test/DrawSegments.c
@@ -0,0 +1,249 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <X11/Xutil.h> /* for XDestroyImage */
+#include <pixman.h> /* for pixman blt functions */
+
+#include "test.h"
+
+static const XPoint points[]= {
+ /* top */
+ { 0, 0},
+ { 1, 0},
+ { 2, 0},
+ { 3, 0},
+ { 4, 0},
+ { 5, 0},
+ { 6, 0},
+ { 7, 0},
+ { 8, 0},
+ /* right */
+ { 8, 1},
+ { 8, 2},
+ { 8, 3},
+ { 8, 4},
+ { 8, 5},
+ { 8, 6},
+ { 8, 7},
+ { 8, 8},
+ /* bottom */
+ { 7, 8},
+ { 6, 8},
+ { 5, 8},
+ { 4, 8},
+ { 3, 8},
+ { 2, 8},
+ { 1, 8},
+ { 0, 8},
+ /* left */
+ { 0, 7},
+ { 0, 6},
+ { 0, 5},
+ { 0, 4},
+ { 0, 3},
+ { 0, 2},
+ { 0, 1},
+ { 0, 0} /* and origin again for luck */
+};
+#define NUM_POINTS (sizeof(points)/sizeof(points[0]))
+
+static void clear(struct test_display *dpy, struct test_target *tt)
+{
+ XRenderColor render_color = {0};
+ XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color,
+ 0, 0, tt->width, tt->height);
+}
+
+static void draw(struct test_display *dpy, struct test_target *tt,
+ int alu, int width, int style, int cap,
+ XSegment *seg, int nseg)
+{
+ XGCValues val;
+ GC gc;
+
+ val.function = alu;
+ val.foreground = WhitePixel(dpy->dpy, 0);
+ val.line_width = width;
+ val.line_style = style;
+ val.cap_style = cap;
+
+ gc = XCreateGC(dpy->dpy, tt->draw,
+ GCForeground |
+ GCFunction |
+ GCLineWidth |
+ GCLineStyle |
+ GCCapStyle,
+ &val);
+ XDrawSegments(dpy->dpy, tt->draw, gc, seg, nseg);
+ XFreeGC(dpy->dpy, gc);
+}
+
+static void hv0(struct test *t, enum target target)
+{
+ char buf[1024];
+ struct test_target out, ref;
+ int a, alu, cap;
+ XSegment seg[(NUM_POINTS+1)*8];
+ int n, x, y, nseg;
+
+ printf("Testing drawing of zero-width line segments (%s): ",
+ test_target_name(target));
+ fflush(stdout);
+
+ test_target_create_render(&t->out, target, &out);
+ test_target_create_render(&t->ref, target, &ref);
+
+ y = x = n = 0;
+ for (a = 0; a <= NUM_POINTS; a++) {
+ seg[n].x1 = a + 64;
+ seg[n].y1 = y + 64;
+ seg[n].x2 = NUM_POINTS + 64;
+ seg[n].y2 = y + 64;
+ n++; y++;
+
+ seg[n].x1 = NUM_POINTS - a + 64;
+ seg[n].y1 = y + 64;
+ seg[n].x2 = 0 + 64;
+ seg[n].y2 = y + 64;
+ n++; y++;
+
+ seg[n].x2 = a + 64;
+ seg[n].y2 = y + 64;
+ seg[n].x1 = NUM_POINTS + 64;
+ seg[n].y1 = y + 64;
+ n++; y++;
+
+ seg[n].x2 = NUM_POINTS - a + 64;
+ seg[n].y2 = y + 64;
+ seg[n].x1 = 0 + 64;
+ seg[n].y1 = y + 64;
+ n++; y++;
+
+
+ seg[n].y1 = a + 64;
+ seg[n].x1 = x + 64;
+ seg[n].y2 = NUM_POINTS + 64;
+ seg[n].x2 = x + 64;
+ n++; x++;
+
+ seg[n].y1 = NUM_POINTS - a + 64;
+ seg[n].x1 = x + 64;
+ seg[n].y2 = 0 + 64;
+ seg[n].x2 = x + 64;
+ n++; x++;
+
+ seg[n].y2 = a + 64;
+ seg[n].x2 = x + 64;
+ seg[n].y1 = NUM_POINTS + 64;
+ seg[n].x1 = x + 64;
+ n++; x++;
+
+ seg[n].y2 = NUM_POINTS - a + 64;
+ seg[n].x2 = x + 64;
+ seg[n].y1 = 0 + 64;
+ seg[n].x1 = x + 64;
+ n++; x++;
+ }
+
+ for (alu = 0; alu < 16; alu++) {
+ for (cap = CapNotLast; cap <= CapProjecting; cap++) {
+ for (nseg = 0; nseg < n; nseg++) {
+ sprintf(buf,
+ "cap=%d, alu=%d, nseg=%d",
+ cap, alu, nseg);
+
+ clear(&t->out, &out);
+ clear(&t->ref, &ref);
+
+ draw(&t->out, &out, alu, 0, LineSolid, cap,
+ seg, nseg);
+ draw(&t->ref, &ref, alu, 0, LineSolid, cap,
+ seg, nseg);
+
+ test_compare(t,
+ out.draw, out.format,
+ ref.draw, ref.format,
+ 0, 0, out.width, out.height,
+ buf);
+ }
+ }
+ }
+
+ test_target_destroy_render(&t->out, &out);
+ test_target_destroy_render(&t->ref, &ref);
+
+ printf("\n");
+}
+
+static void general(struct test *t, enum target target)
+{
+ char buf[1024];
+ struct test_target out, ref;
+ int a, b, alu, lw, style, cap;
+ XSegment seg[NUM_POINTS*NUM_POINTS];
+ int n = 0;
+
+ printf("Testing drawing of general line segments (%s): ",
+ test_target_name(target));
+ fflush(stdout);
+
+ test_target_create_render(&t->out, target, &out);
+ test_target_create_render(&t->ref, target, &ref);
+
+ style = LineSolid;
+
+ for (a = 0; a < NUM_POINTS; a++) {
+ for (b = 0; b < NUM_POINTS; b++) {
+ seg[n].x1 = points[a].x + 64;
+ seg[n].y1 = points[a].y + 64;
+ seg[n].x2 = points[b].x + 64;
+ seg[n].y2 = points[b].y + 64;
+ n++;
+ }
+ }
+
+ for (alu = 0; alu < 16; alu++) {
+ for (cap = CapNotLast; cap <= CapProjecting; cap++) {
+ for (lw = 0; lw <= 4; lw++) {
+ sprintf(buf,
+ "width=%d, cap=%d, alu=%d",
+ lw, cap, alu);
+
+ clear(&t->out, &out);
+ clear(&t->ref, &ref);
+
+ draw(&t->out, &out, alu, lw, style, cap,
+ seg, n);
+ draw(&t->ref, &ref, alu, lw, style, cap,
+ seg, n);
+
+ test_compare(t,
+ out.draw, out.format,
+ ref.draw, ref.format,
+ 0, 0, out.width, out.height,
+ buf);
+ }
+ }
+ }
+
+ test_target_destroy_render(&t->out, &out);
+ test_target_destroy_render(&t->ref, &ref);
+
+ printf("\n");
+}
+
+int main(int argc, char **argv)
+{
+ struct test test;
+ enum target t;
+
+ test_init(&test, argc, argv);
+
+ for (t = TARGET_FIRST; t <= TARGET_LAST; t++) {
+ hv0(&test, t);
+ general(&test, t);
+ }
+
+ return 0;
+}
diff --git a/test/Makefile.am b/test/Makefile.am
index f9906d4..66ed8eb 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -9,6 +9,7 @@ stress_TESTS = \
basic-putimage \
basic-lines \
basic-stress \
+ DrawSegments \
cursor-test \
render-fill \
render-trapezoid \
commit e453f276daa33a66a665e446a071d27e56ff15fe
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Sep 15 12:08:59 2014 +0100
sna/io: Initialise return code to catch early segfaults
In case we are ever given an invalid buffer that we then attempt to read
past the end.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 3ce3ded..0181838 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -1771,6 +1771,7 @@ indirect_replace(struct sna *sna,
if (!src_bo)
return false;
+ ret = false;
if (sigtrap_get() == 0) {
memcpy_blt(src, ptr, pixmap->drawable.bitsPerPixel,
stride, src_bo->pitch,
@@ -1788,8 +1789,7 @@ indirect_replace(struct sna *sna,
&pixmap->drawable, bo, 0, 0,
&box, 1, 0);
sigtrap_put();
- } else
- ret = false;
+ }
kgem_bo_destroy(kgem, src_bo);
More information about the xorg-commit
mailing list