X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=tests%2Fmodetest%2Fmodetest.c;h=92efb823b9f7c6ceb48ec94c711b11916c3df600;hb=8e93afc9765f1de613c65a76e9a86e17db96e653;hp=9d6e279bc716512ae3f032f27e695a3be8b0fc89;hpb=b50826dbd6a10e89ed03c23a16bf62e7d554a2d6;p=platform%2Fupstream%2Flibdrm.git diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 9d6e279..92efb82 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -37,7 +37,9 @@ * TODO: use cairo to write the mode info on the selected output once * the mode has been programmed, along with possible test patterns. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include #include @@ -58,6 +60,7 @@ #include "libkms.h" #include "buffers.h" +#include "cursor.h" struct crtc { drmModeCrtc *crtc; @@ -693,6 +696,7 @@ struct pipe_arg { uint32_t crtc_id; char mode_str[64]; char format_str[5]; + unsigned int vrefresh; unsigned int fourcc; drmModeModeInfo *mode; struct crtc *crtc; @@ -707,13 +711,15 @@ struct plane_arg { bool has_position; int32_t x, y; uint32_t w, h; + double scale; unsigned int fb_id; char format_str[5]; /* need to leave room for terminating \0 */ unsigned int fourcc; }; static drmModeModeInfo * -connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str) +connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str, + const unsigned int vrefresh) { drmModeConnector *connector; drmModeModeInfo *mode; @@ -725,8 +731,16 @@ connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str) for (i = 0; i < connector->count_modes; i++) { mode = &connector->modes[i]; - if (!strcmp(mode->name, mode_str)) - return mode; + if (!strcmp(mode->name, mode_str)) { + /* If the vertical refresh frequency is not specified then return the + * first mode that match with the name. Else, return the mode that match + * the name and the specified vertical refresh frequency. + */ + if (vrefresh == 0) + return mode; + else if (mode->vrefresh == vrefresh) + return mode; + } } return NULL; @@ -788,7 +802,7 @@ static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe) for (i = 0; i < (int)pipe->num_cons; i++) { mode = connector_find_mode(dev, pipe->con_ids[i], - pipe->mode_str); + pipe->mode_str, pipe->vrefresh); if (mode == NULL) { fprintf(stderr, "failed to find mode \"%s\" for connector %u\n", @@ -988,16 +1002,16 @@ static int set_plane(struct device *dev, struct plane_arg *p) return -1; } + crtc_w = p->w * p->scale; + crtc_h = p->h * p->scale; if (!p->has_position) { /* Default to the middle of the screen */ - crtc_x = (crtc->mode->hdisplay - p->w) / 2; - crtc_y = (crtc->mode->vdisplay - p->h) / 2; + crtc_x = (crtc->mode->hdisplay - crtc_w) / 2; + crtc_y = (crtc->mode->vdisplay - crtc_h) / 2; } else { crtc_x = p->x; crtc_y = p->y; } - crtc_w = p->w; - crtc_h = p->h; /* note src coords (last 4 args) are in Q16 format */ if (drmModeSetPlane(dev->fd, plane_id, crtc->crtc->crtc_id, p->fb_id, @@ -1058,8 +1072,8 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co if (pipe->mode == NULL) continue; - printf("setting mode %s@%s on connectors ", - pipe->mode_str, pipe->format_str); + printf("setting mode %s-%dHz@%s on connectors ", + pipe->mode_str, pipe->mode->vrefresh, pipe->format_str); for (j = 0; j < pipe->num_cons; ++j) printf("%u, ", pipe->con_ids[j]); printf("crtc %d\n", pipe->crtc->crtc->crtc_id); @@ -1093,6 +1107,46 @@ static void set_planes(struct device *dev, struct plane_arg *p, unsigned int cou return; } +static void set_cursors(struct device *dev, struct pipe_arg *pipes, unsigned int count) +{ + uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ + struct kms_bo *bo; + unsigned int i; + int ret; + + /* maybe make cursor width/height configurable some day */ + uint32_t cw = 64; + uint32_t ch = 64; + + /* create cursor bo.. just using PATTERN_PLAIN as it has + * translucent alpha + */ + bo = create_test_buffer(dev->kms, DRM_FORMAT_ARGB8888, + cw, ch, handles, pitches, offsets, PATTERN_PLAIN); + if (bo == NULL) + return; + + for (i = 0; i < count; i++) { + struct pipe_arg *pipe = &pipes[i]; + ret = cursor_init(dev->fd, handles[0], + pipe->crtc->crtc->crtc_id, + pipe->mode->hdisplay, pipe->mode->vdisplay, + cw, ch); + if (ret) { + fprintf(stderr, "failed to init cursor for CRTC[%u]\n", + pipe->crtc_id); + return; + } + } + + cursor_start(); +} + +static void clear_cursors(struct device *dev) +{ + cursor_stop(); +} + static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned int count) { uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ @@ -1191,6 +1245,7 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg) const char *p; char *endp; + pipe->vrefresh = 0; pipe->crtc_id = (uint32_t)-1; strcpy(pipe->format_str, "XR24"); @@ -1225,11 +1280,19 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg) arg = endp + 1; - p = strchrnul(arg, '@'); + /* Search for the vertical refresh or the format. */ + p = strpbrk(arg, "-@"); + if (p == NULL) + p = arg + strlen(arg); len = min(sizeof pipe->mode_str - 1, (unsigned int)(p - arg)); strncpy(pipe->mode_str, arg, len); pipe->mode_str[len] = '\0'; + if (*p == '-') { + pipe->vrefresh = strtoul(p + 1, &endp, 10); + p = endp; + } + if (*p == '@') { strncpy(pipe->format_str, p + 1, 4); pipe->format_str[4] = '\0'; @@ -1271,6 +1334,15 @@ static int parse_plane(struct plane_arg *plane, const char *p) plane->has_position = true; } + if (*end == '*') { + p = end + 1; + plane->scale = strtod(p, &end); + if (plane->scale <= 0.0) + return -EINVAL; + } else { + plane->scale = 1.0; + } + if (*end == '@') { p = end + 1; if (strlen(p) != 4) @@ -1303,7 +1375,7 @@ static int parse_property(struct property_arg *p, const char *arg) static void usage(char *name) { - fprintf(stderr, "usage: %s [-cDdefMPpsvw]\n", name); + fprintf(stderr, "usage: %s [-cDdefMPpsCvw]\n", name); fprintf(stderr, "\n Query options:\n\n"); fprintf(stderr, "\t-c\tlist connectors\n"); @@ -1312,8 +1384,9 @@ static void usage(char *name) fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n"); fprintf(stderr, "\n Test options:\n\n"); - fprintf(stderr, "\t-P :x[++][@]\tset a plane\n"); - fprintf(stderr, "\t-s [,][@]:[@]\tset a mode\n"); + fprintf(stderr, "\t-P :x[++][*][@]\tset a plane\n"); + fprintf(stderr, "\t-s [,][@]:[-][@]\tset a mode\n"); + fprintf(stderr, "\t-C\ttest hw cursor\n"); fprintf(stderr, "\t-v\ttest vsynced page flipping\n"); fprintf(stderr, "\t-w ::\tset property\n"); @@ -1347,7 +1420,13 @@ static int page_flipping_supported(void) #endif } -static char optstr[] = "cdD:efM:P:ps:vw:"; +static int cursor_supported(void) +{ + /*FIXME: generic ioctl needed? */ + return 1; +} + +static char optstr[] = "cdD:efM:P:ps:Cvw:"; int main(int argc, char **argv) { @@ -1357,6 +1436,7 @@ int main(int argc, char **argv) int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0; int drop_master = 0; int test_vsync = 0; + int test_cursor = 0; const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "tilcdc", "msm" }; char *device = NULL; char *module = NULL; @@ -1427,6 +1507,9 @@ int main(int argc, char **argv) count++; break; + case 'C': + test_cursor = 1; + break; case 'v': test_vsync = 1; break; @@ -1486,6 +1569,11 @@ int main(int argc, char **argv) return -1; } + if (test_cursor && !cursor_supported()) { + fprintf(stderr, "hw cursor not supported by drm.\n"); + return -1; + } + dev.resources = get_resources(&dev); if (!dev.resources) { drmClose(dev.fd); @@ -1517,16 +1605,22 @@ int main(int argc, char **argv) if (plane_count) set_planes(&dev, plane_args, plane_count); + if (test_cursor) + set_cursors(&dev, pipe_args, count); + if (test_vsync) test_page_flip(&dev, pipe_args, count); if (drop_master) drmDropMaster(dev.fd); + getchar(); + + if (test_cursor) + clear_cursors(&dev); + kms_bo_destroy(&dev.mode.bo); kms_destroy(&dev.kms); - - getchar(); } free_resources(dev.resources);