blob: 84d8f3d813f646701fc2025f87a3b46d903c52cb [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
Dongseong Hwangd4a34122016-04-25 15:46:32 +030055 struct gbm_bo *fb_bo =
56 gbm_bo_create(gbm, mode->hdisplay, mode->vdisplay, GBM_FORMAT_XRGB8888,
57 GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR);
Zach Reizner842bd992016-03-08 16:00:25 -080058 if (!fb_bo) {
59 bs_debug_error("failed to create buffer object for frame buffer");
60 return 1;
61 }
62
Shirish S99c916e2017-07-07 15:57:57 +053063 struct bs_mapper *mapper = bs_mapper_gem_new();
Dongseong Hwang9093afe2017-03-20 19:16:28 -070064 if (mapper == NULL) {
65 bs_debug_error("failed to create mapper object");
66 return 1;
67 }
68
69 void *map_data;
70 uint8_t *fb_ptr = bs_mapper_map(mapper, fb_bo, 0, &map_data);
71 if (fb_ptr == MAP_FAILED) {
Zach Reizner842bd992016-03-08 16:00:25 -080072 bs_debug_error("failed to mmap frame buffer object");
73 return 1;
74 }
75 uint32_t stride = gbm_bo_get_stride(fb_bo);
76 for (size_t y = 0; y < mode->vdisplay; y++) {
77 for (size_t x = 0; x < mode->hdisplay; x++) {
78 // Solid blue fill
79 fb_ptr[y * stride + x * 4 + 0] = 0xff;
80 fb_ptr[y * stride + x * 4 + 1] = 0;
81 fb_ptr[y * stride + x * 4 + 2] = 0;
82 fb_ptr[y * stride + x * 4 + 3] = 0;
83 }
84 }
Dongseong Hwang9093afe2017-03-20 19:16:28 -070085 bs_mapper_unmap(mapper, fb_bo, map_data);
Zach Reizner842bd992016-03-08 16:00:25 -080086
87 uint32_t fb_id = bs_drm_fb_create_gbm(fb_bo);
88 if (!fb_id) {
89 bs_debug_error("failed to create frame buffer from buffer object");
90 return 1;
91 }
92
93 ret = drmModeSetCrtc(fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &pipe.connector_id,
94 1 /* connector count */, mode);
95 if (ret) {
96 bs_debug_error("failed to set crtc: %d", ret);
97 return 1;
98 }
99
Zach Reizner842bd992016-03-08 16:00:25 -0800100 struct gbm_bo *cursor_bo =
101 gbm_bo_create(gbm, cursor_size, cursor_size, GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR);
102 if (!cursor_bo) {
103 bs_debug_error("failed to create cursor buffer object");
104 return 1;
105 }
106
Dongseong Hwang9093afe2017-03-20 19:16:28 -0700107 uint8_t *cursor_ptr = bs_mapper_map(mapper, cursor_bo, 0, &map_data);
108 if (cursor_ptr == MAP_FAILED) {
Zach Reizner842bd992016-03-08 16:00:25 -0800109 bs_debug_error("failed to mmap cursor buffer object");
110 return 1;
111 }
112 for (size_t y = 0; y < cursor_size; y++) {
113 for (size_t x = 0; x < cursor_size; x++) {
114 // A white triangle pointing right
115 bool color_white = y > x / 2 && y < (cursor_size - x / 2);
116 memset(&cursor_ptr[y * cursor_size * 4 + x * 4], color_white ? 0xFF : 0x00,
117 4);
118 }
119 }
Dongseong Hwang9093afe2017-03-20 19:16:28 -0700120 bs_mapper_unmap(mapper, cursor_bo, map_data);
Zach Reizner842bd992016-03-08 16:00:25 -0800121
122 ret = drmModeSetCursor(fd, crtc_id, gbm_bo_get_handle(cursor_bo).u32, cursor_size,
123 cursor_size);
124 if (ret) {
125 bs_debug_error("failed to set cursor: %d", ret);
126 return 1;
127 }
128
129 // Divisor chosen so that the test would last about 10 seconds @ 60fps.
130 const uint32_t divisor = 25;
131 const uint32_t xinc = mode->hdisplay / divisor;
132 const uint32_t yinc = mode->vdisplay / divisor;
133 for (uint32_t x = 0; x < divisor; x++) {
134 for (uint32_t y = 0; y < divisor; y++) {
135 ret = drmModeMoveCursor(fd, crtc_id, x * xinc + y, y * yinc + x);
136 if (ret) {
137 bs_debug_error("failed to move cursor: %d", ret);
138 return 1;
139 }
140 usleep(16667);
141 }
142 }
143
Dongseong Hwang9093afe2017-03-20 19:16:28 -0700144 bs_mapper_destroy(mapper);
Zach Reizner842bd992016-03-08 16:00:25 -0800145 drmModeRmFB(fd, fb_id);
146 gbm_bo_destroy(fb_bo);
147 gbm_bo_destroy(cursor_bo);
148 gbm_device_destroy(gbm);
149 close(fd);
150
151 return 0;
152}