blob: abd3c18ad3b7d555509af3d856df2ad275d64057 [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{
11 int fd = bs_drm_open_main_display();
12 if (fd < 0) {
13 bs_debug_error("failed to open card for display");
14 return 1;
15 }
16
17 struct gbm_device *gbm = gbm_create_device(fd);
18 if (!gbm) {
19 bs_debug_error("failed to create gbm");
20 return 1;
21 }
22
23 struct bs_drm_pipe pipe = { 0 };
24 if (!bs_drm_pipe_make(fd, &pipe)) {
25 bs_debug_error("failed to make pipe");
26 return 1;
27 }
28
29 drmModeConnector *connector = drmModeGetConnector(fd, pipe.connector_id);
30 drmModeModeInfo *mode = &connector->modes[0];
31 uint32_t crtc_id = pipe.crtc_id;
32
33 // Restart the cursor position before binding the crtc so that the old cursor position isn't
34 // displayed briefly when the display is turned activated.
35 int ret = drmModeMoveCursor(fd, crtc_id, 0, 0);
36 if (ret) {
37 bs_debug_error("failed to move cursor: %d", ret);
38 return 1;
39 }
40
41 struct gbm_bo *fb_bo = gbm_bo_create(gbm, mode->hdisplay, mode->vdisplay,
42 GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT);
43 if (!fb_bo) {
44 bs_debug_error("failed to create buffer object for frame buffer");
45 return 1;
46 }
47
48 uint8_t *fb_ptr = bs_dumb_mmap_gbm(fb_bo);
49 if (fb_ptr == NULL) {
50 bs_debug_error("failed to mmap frame buffer object");
51 return 1;
52 }
53 uint32_t stride = gbm_bo_get_stride(fb_bo);
54 for (size_t y = 0; y < mode->vdisplay; y++) {
55 for (size_t x = 0; x < mode->hdisplay; x++) {
56 // Solid blue fill
57 fb_ptr[y * stride + x * 4 + 0] = 0xff;
58 fb_ptr[y * stride + x * 4 + 1] = 0;
59 fb_ptr[y * stride + x * 4 + 2] = 0;
60 fb_ptr[y * stride + x * 4 + 3] = 0;
61 }
62 }
63 bs_dumb_unmmap_gbm(fb_bo, fb_ptr);
64
65 uint32_t fb_id = bs_drm_fb_create_gbm(fb_bo);
66 if (!fb_id) {
67 bs_debug_error("failed to create frame buffer from buffer object");
68 return 1;
69 }
70
71 ret = drmModeSetCrtc(fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &pipe.connector_id,
72 1 /* connector count */, mode);
73 if (ret) {
74 bs_debug_error("failed to set crtc: %d", ret);
75 return 1;
76 }
77
78 const uint32_t cursor_size = 64;
79 struct gbm_bo *cursor_bo =
80 gbm_bo_create(gbm, cursor_size, cursor_size, GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR);
81 if (!cursor_bo) {
82 bs_debug_error("failed to create cursor buffer object");
83 return 1;
84 }
85
86 uint8_t *cursor_ptr = bs_dumb_mmap_gbm(cursor_bo);
87 if (cursor_ptr == NULL) {
88 bs_debug_error("failed to mmap cursor buffer object");
89 return 1;
90 }
91 for (size_t y = 0; y < cursor_size; y++) {
92 for (size_t x = 0; x < cursor_size; x++) {
93 // A white triangle pointing right
94 bool color_white = y > x / 2 && y < (cursor_size - x / 2);
95 memset(&cursor_ptr[y * cursor_size * 4 + x * 4], color_white ? 0xFF : 0x00,
96 4);
97 }
98 }
99 bs_dumb_unmmap_gbm(cursor_bo, cursor_ptr);
100
101 ret = drmModeSetCursor(fd, crtc_id, gbm_bo_get_handle(cursor_bo).u32, cursor_size,
102 cursor_size);
103 if (ret) {
104 bs_debug_error("failed to set cursor: %d", ret);
105 return 1;
106 }
107
108 // Divisor chosen so that the test would last about 10 seconds @ 60fps.
109 const uint32_t divisor = 25;
110 const uint32_t xinc = mode->hdisplay / divisor;
111 const uint32_t yinc = mode->vdisplay / divisor;
112 for (uint32_t x = 0; x < divisor; x++) {
113 for (uint32_t y = 0; y < divisor; y++) {
114 ret = drmModeMoveCursor(fd, crtc_id, x * xinc + y, y * yinc + x);
115 if (ret) {
116 bs_debug_error("failed to move cursor: %d", ret);
117 return 1;
118 }
119 usleep(16667);
120 }
121 }
122
123 drmModeRmFB(fd, fb_id);
124 gbm_bo_destroy(fb_bo);
125 gbm_bo_destroy(cursor_bo);
126 gbm_device_destroy(gbm);
127 close(fd);
128
129 return 0;
130}