blob: a031e13909a01a98ad4964b4695c2167ddd92b37 [file] [log] [blame]
Zach Reizner842bd992016-03-08 16:00:25 -08001/*
2 * Copyright 2016 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7#include "bs_drm.h"
8
9int main(int argc, char **argv)
10{
Zach Reizner4f8a8de2016-03-25 17:26:44 -070011 uint32_t cursor_size = 64;
12 if (argc >= 2) {
13 char *end_str;
14 unsigned long new_cursor_size = strtoul(argv[1], &end_str, 0);
15 if (end_str == argv[1] || new_cursor_size == 0 || new_cursor_size > UINT32_MAX) {
16 printf(
17 "usage:\n drm_cursor_test [cursor size]\n\nCursor size defaults to "
18 "%u\n",
19 cursor_size);
20 return 1;
21 }
22 cursor_size = (uint32_t)new_cursor_size;
23 }
24
Zach Reizner842bd992016-03-08 16:00:25 -080025 int fd = bs_drm_open_main_display();
26 if (fd < 0) {
27 bs_debug_error("failed to open card for display");
28 return 1;
29 }
30
31 struct gbm_device *gbm = gbm_create_device(fd);
32 if (!gbm) {
33 bs_debug_error("failed to create gbm");
34 return 1;
35 }
36
37 struct bs_drm_pipe pipe = { 0 };
38 if (!bs_drm_pipe_make(fd, &pipe)) {
39 bs_debug_error("failed to make pipe");
40 return 1;
41 }
42
43 drmModeConnector *connector = drmModeGetConnector(fd, pipe.connector_id);
44 drmModeModeInfo *mode = &connector->modes[0];
45 uint32_t crtc_id = pipe.crtc_id;
46
47 // Restart the cursor position before binding the crtc so that the old cursor position isn't
48 // displayed briefly when the display is turned activated.
49 int ret = drmModeMoveCursor(fd, crtc_id, 0, 0);
50 if (ret) {
51 bs_debug_error("failed to move cursor: %d", ret);
52 return 1;
53 }
54
55 struct gbm_bo *fb_bo = gbm_bo_create(gbm, mode->hdisplay, mode->vdisplay,
56 GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT);
57 if (!fb_bo) {
58 bs_debug_error("failed to create buffer object for frame buffer");
59 return 1;
60 }
61
Dongseong Hwang2193f5c2016-04-22 17:25:58 +030062 uint8_t *fb_ptr = bs_dma_buf_mmap(fb_bo);
Zach Reizner842bd992016-03-08 16:00:25 -080063 if (fb_ptr == NULL) {
64 bs_debug_error("failed to mmap frame buffer object");
65 return 1;
66 }
67 uint32_t stride = gbm_bo_get_stride(fb_bo);
68 for (size_t y = 0; y < mode->vdisplay; y++) {
69 for (size_t x = 0; x < mode->hdisplay; x++) {
70 // Solid blue fill
71 fb_ptr[y * stride + x * 4 + 0] = 0xff;
72 fb_ptr[y * stride + x * 4 + 1] = 0;
73 fb_ptr[y * stride + x * 4 + 2] = 0;
74 fb_ptr[y * stride + x * 4 + 3] = 0;
75 }
76 }
Dongseong Hwang2193f5c2016-04-22 17:25:58 +030077 bs_dma_buf_unmmap(fb_bo, fb_ptr);
Zach Reizner842bd992016-03-08 16:00:25 -080078
79 uint32_t fb_id = bs_drm_fb_create_gbm(fb_bo);
80 if (!fb_id) {
81 bs_debug_error("failed to create frame buffer from buffer object");
82 return 1;
83 }
84
85 ret = drmModeSetCrtc(fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &pipe.connector_id,
86 1 /* connector count */, mode);
87 if (ret) {
88 bs_debug_error("failed to set crtc: %d", ret);
89 return 1;
90 }
91
Zach Reizner842bd992016-03-08 16:00:25 -080092 struct gbm_bo *cursor_bo =
93 gbm_bo_create(gbm, cursor_size, cursor_size, GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR);
94 if (!cursor_bo) {
95 bs_debug_error("failed to create cursor buffer object");
96 return 1;
97 }
98
Dongseong Hwang2193f5c2016-04-22 17:25:58 +030099 uint8_t *cursor_ptr = bs_dma_buf_mmap(cursor_bo);
Zach Reizner842bd992016-03-08 16:00:25 -0800100 if (cursor_ptr == NULL) {
101 bs_debug_error("failed to mmap cursor buffer object");
102 return 1;
103 }
104 for (size_t y = 0; y < cursor_size; y++) {
105 for (size_t x = 0; x < cursor_size; x++) {
106 // A white triangle pointing right
107 bool color_white = y > x / 2 && y < (cursor_size - x / 2);
108 memset(&cursor_ptr[y * cursor_size * 4 + x * 4], color_white ? 0xFF : 0x00,
109 4);
110 }
111 }
Dongseong Hwang2193f5c2016-04-22 17:25:58 +0300112 bs_dma_buf_unmmap(cursor_bo, cursor_ptr);
Zach Reizner842bd992016-03-08 16:00:25 -0800113
114 ret = drmModeSetCursor(fd, crtc_id, gbm_bo_get_handle(cursor_bo).u32, cursor_size,
115 cursor_size);
116 if (ret) {
117 bs_debug_error("failed to set cursor: %d", ret);
118 return 1;
119 }
120
121 // Divisor chosen so that the test would last about 10 seconds @ 60fps.
122 const uint32_t divisor = 25;
123 const uint32_t xinc = mode->hdisplay / divisor;
124 const uint32_t yinc = mode->vdisplay / divisor;
125 for (uint32_t x = 0; x < divisor; x++) {
126 for (uint32_t y = 0; y < divisor; y++) {
127 ret = drmModeMoveCursor(fd, crtc_id, x * xinc + y, y * yinc + x);
128 if (ret) {
129 bs_debug_error("failed to move cursor: %d", ret);
130 return 1;
131 }
132 usleep(16667);
133 }
134 }
135
136 drmModeRmFB(fd, fb_id);
137 gbm_bo_destroy(fb_bo);
138 gbm_bo_destroy(cursor_bo);
139 gbm_device_destroy(gbm);
140 close(fd);
141
142 return 0;
143}