diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/modetest/Makefile.am | 6 | ||||
-rw-r--r-- | tests/modetest/modetest.c | 151 |
2 files changed, 130 insertions, 27 deletions
diff --git a/tests/modetest/Makefile.am b/tests/modetest/Makefile.am index b89c489e..860fe064 100644 --- a/tests/modetest/Makefile.am +++ b/tests/modetest/Makefile.am @@ -1,7 +1,8 @@ AM_CFLAGS = \ -I$(top_srcdir)/shared-core \ -I$(top_srcdir)/libdrm/intel/ \ - -I$(top_srcdir)/libdrm + -I$(top_srcdir)/libdrm \ + $(CAIRO_CFLAGS) noinst_PROGRAMS = \ modetest @@ -10,4 +11,5 @@ modetest_SOURCES = \ modetest.c modetest_LDADD = \ $(top_builddir)/libdrm/libdrm.la \ - $(top_builddir)/libdrm/intel/libdrm_intel.la + $(top_builddir)/libdrm/intel/libdrm_intel.la \ + $(CAIRO_LIBS) diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index c38908b0..f1c3bf36 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -37,6 +37,8 @@ * TODO: use cairo to write the mode info on the selected output once * the mode has been programmed, along with possible test patterns. */ +#include "config.h" + #include <assert.h> #include <stdio.h> #include <stdlib.h> @@ -49,6 +51,11 @@ #include "xf86drmMode.h" #include "intel_bufmgr.h" +#ifdef HAVE_CAIRO +#include <math.h> +#include <cairo.h> +#endif + drmModeRes *resources; int fd, modes; @@ -313,50 +320,104 @@ connector_find_mode(struct connector *c) } } -static void -set_mode(struct connector *c, int count) +#ifdef HAVE_CAIRO + +static int +create_test_buffer(drm_intel_bufmgr *bufmgr, + int width, int height, int *stride_out, drm_intel_bo **bo_out) { - drmModeConnector *connector; - drmModeEncoder *encoder = NULL; - struct drm_mode_modeinfo *mode = NULL; - drm_intel_bufmgr *bufmgr; drm_intel_bo *bo; - unsigned int fb_id, *fb_ptr; - int i, j, size, ret, width, height, x; + unsigned int *fb_ptr; + int size, ret, i, stride; div_t d; + cairo_surface_t *surface; + cairo_t *cr; + char buf[64]; + int x, y; - width = 0; - height = 0; - for (i = 0; i < count; i++) { - connector_find_mode(&c[i]); - if (c[i].mode == NULL) - continue; - width += c[i].mode->hdisplay; - if (height < c[i].mode->vdisplay) - height = c[i].mode->vdisplay; + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + stride = cairo_image_surface_get_stride(surface); + size = stride * height; + fb_ptr = (unsigned int *) cairo_image_surface_get_data(surface); + + /* paint the buffer with colored tiles */ + for (i = 0; i < width * height; i++) { + d = div(i, width); + fb_ptr[i] = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6); } - bufmgr = drm_intel_bufmgr_gem_init(fd, 2<<20); - if (!bufmgr) { - fprintf(stderr, "failed to init bufmgr: %s\n", strerror(errno)); - return; + cr = cairo_create(surface); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); + for (x = 0; x < width; x += 250) + for (y = 0; y < height; y += 250) { + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + cairo_move_to(cr, x, y - 20); + cairo_line_to(cr, x, y + 20); + cairo_move_to(cr, x - 20, y); + cairo_line_to(cr, x + 20, y); + cairo_new_sub_path(cr); + cairo_arc(cr, x, y, 10, 0, M_PI * 2); + cairo_set_line_width(cr, 4); + cairo_set_source_rgb(cr, 0, 0, 0); + cairo_stroke_preserve(cr); + cairo_set_source_rgb(cr, 1, 1, 1); + cairo_set_line_width(cr, 2); + cairo_stroke(cr); + snprintf(buf, sizeof buf, "%d, %d", x, y); + cairo_move_to(cr, x + 20, y + 20); + cairo_text_path(cr, buf); + cairo_set_source_rgb(cr, 0, 0, 0); + cairo_stroke_preserve(cr); + cairo_set_source_rgb(cr, 1, 1, 1); + cairo_fill(cr); + } + + cairo_destroy(cr); + + bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096); + if (!bo) { + fprintf(stderr, "failed to alloc buffer: %s\n", + strerror(errno)); + return -1; } + drm_intel_bo_subdata(bo, 0, size, fb_ptr); + + cairo_surface_destroy(surface); + + *bo_out = bo; + *stride_out = stride; + + return 0; +} + +#else + +static int +create_test_buffer(drm_intel_bufmgr *bufmgr, + int width, int height, int *stride_out, drm_intel_bo **bo_out) +{ + drm_intel_bo *bo; + unsigned int *fb_ptr; + int size, ret, i, stride; + div_t d; + /* Mode size at 32 bpp */ - size = width * height * 4; + stride = width * 4; + size = stride * height; bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096); if (!bo) { fprintf(stderr, "failed to alloc buffer: %s\n", strerror(errno)); - return; + return -1; } ret = drm_intel_gem_bo_map_gtt(bo); if (ret) { fprintf(stderr, "failed to GTT map buffer: %s\n", strerror(errno)); - return; + return -1; } fb_ptr = bo->virtual; @@ -366,8 +427,48 @@ set_mode(struct connector *c, int count) d = div(i, width); fb_ptr[i] = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6); } + drm_intel_bo_unmap(bo); + + *bo_out = bo; + *stride_out = stride; + + return 0; +} + +#endif + +static void +set_mode(struct connector *c, int count) +{ + drmModeConnector *connector; + drmModeEncoder *encoder = NULL; + struct drm_mode_modeinfo *mode = NULL; + drm_intel_bufmgr *bufmgr; + drm_intel_bo *bo; + unsigned int fb_id; + int i, j, ret, width, height, x, stride; + + width = 0; + height = 0; + for (i = 0; i < count; i++) { + connector_find_mode(&c[i]); + if (c[i].mode == NULL) + continue; + width += c[i].mode->hdisplay; + if (height < c[i].mode->vdisplay) + height = c[i].mode->vdisplay; + } + + bufmgr = drm_intel_bufmgr_gem_init(fd, 2<<20); + if (!bufmgr) { + fprintf(stderr, "failed to init bufmgr: %s\n", strerror(errno)); + return; + } + + if (create_test_buffer(bufmgr, width, height, &stride, &bo)) + return; - ret = drmModeAddFB(fd, width, height, 32, 32, width * 4, bo->handle, + ret = drmModeAddFB(fd, width, height, 32, 32, stride, bo->handle, &fb_id); if (ret) { fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); |