blob: 11fc5c425258f1442c99d0a2b9847021673a0f18 [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
Dongseong Hwang2193f5c2016-04-22 17:25:58 +030063 uint8_t *fb_ptr = bs_dma_buf_mmap(fb_bo);
Zach Reizner842bd992016-03-08 16:00:25 -080064 if (fb_ptr == NULL) {
65 bs_debug_error("failed to mmap frame buffer object");
66 return 1;
67 }
68 uint32_t stride = gbm_bo_get_stride(fb_bo);
69 for (size_t y = 0; y < mode->vdisplay; y++) {
70 for (size_t x = 0; x < mode->hdisplay; x++) {
71 // Solid blue fill
72 fb_ptr[y * stride + x * 4 + 0] = 0xff;
73 fb_ptr[y * stride + x * 4 + 1] = 0;
74 fb_ptr[y * stride + x * 4 + 2] = 0;
75 fb_ptr[y * stride + x * 4 + 3] = 0;
76 }
77 }
Dongseong Hwang2193f5c2016-04-22 17:25:58 +030078 bs_dma_buf_unmmap(fb_bo, fb_ptr);
Zach Reizner842bd992016-03-08 16:00:25 -080079
80 uint32_t fb_id = bs_drm_fb_create_gbm(fb_bo);
81 if (!fb_id) {
82 bs_debug_error("failed to create frame buffer from buffer object");
83 return 1;
84 }
85
86 ret = drmModeSetCrtc(fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &pipe.connector_id,
87 1 /* connector count */, mode);
88 if (ret) {
89 bs_debug_error("failed to set crtc: %d", ret);
90 return 1;
91 }
92
Zach Reizner842bd992016-03-08 16:00:25 -080093 struct gbm_bo *cursor_bo =
94 gbm_bo_create(gbm, cursor_size, cursor_size, GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR);
95 if (!cursor_bo) {
96 bs_debug_error("failed to create cursor buffer object");
97 return 1;
98 }
99
Dongseong Hwang2193f5c2016-04-22 17:25:58 +0300100 uint8_t *cursor_ptr = bs_dma_buf_mmap(cursor_bo);
Zach Reizner842bd992016-03-08 16:00:25 -0800101 if (cursor_ptr == NULL) {
102 bs_debug_error("failed to mmap cursor buffer object");
103 return 1;
104 }
105 for (size_t y = 0; y < cursor_size; y++) {
106 for (size_t x = 0; x < cursor_size; x++) {
107 // A white triangle pointing right
108 bool color_white = y > x / 2 && y < (cursor_size - x / 2);
109 memset(&cursor_ptr[y * cursor_size * 4 + x * 4], color_white ? 0xFF : 0x00,
110 4);
111 }
112 }
Dongseong Hwang2193f5c2016-04-22 17:25:58 +0300113 bs_dma_buf_unmmap(cursor_bo, cursor_ptr);
Zach Reizner842bd992016-03-08 16:00:25 -0800114
115 ret = drmModeSetCursor(fd, crtc_id, gbm_bo_get_handle(cursor_bo).u32, cursor_size,
116 cursor_size);
117 if (ret) {
118 bs_debug_error("failed to set cursor: %d", ret);
119 return 1;
120 }
121
122 // Divisor chosen so that the test would last about 10 seconds @ 60fps.
123 const uint32_t divisor = 25;
124 const uint32_t xinc = mode->hdisplay / divisor;
125 const uint32_t yinc = mode->vdisplay / divisor;
126 for (uint32_t x = 0; x < divisor; x++) {
127 for (uint32_t y = 0; y < divisor; y++) {
128 ret = drmModeMoveCursor(fd, crtc_id, x * xinc + y, y * yinc + x);
129 if (ret) {
130 bs_debug_error("failed to move cursor: %d", ret);
131 return 1;
132 }
133 usleep(16667);
134 }
135 }
136
137 drmModeRmFB(fd, fb_id);
138 gbm_bo_destroy(fb_bo);
139 gbm_bo_destroy(cursor_bo);
140 gbm_device_destroy(gbm);
141 close(fd);
142
143 return 0;
144}