1 /*
2 * Copyright (c) 2024 TOKITA Hiroshi
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "utils.h"
8
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/display.h>
11 #include <zephyr/ztest.h>
12 #include <zephyr/logging/log.h>
13
14 LOG_MODULE_REGISTER(cfb_test_draw_text_and_print_utils, CONFIG_CFB_LOG_LEVEL);
15
16 static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
17 static const uint32_t display_width = DT_PROP(DT_CHOSEN(zephyr_display), width);
18 static const uint32_t display_height = DT_PROP(DT_CHOSEN(zephyr_display), height);
19 uint8_t read_buffer[DT_PROP(DT_CHOSEN(zephyr_display), width) *
20 DT_PROP(DT_CHOSEN(zephyr_display), height) * 4];
21
mono_pixel_order(uint32_t order)22 inline uint32_t mono_pixel_order(uint32_t order)
23 {
24 if (IS_ENABLED(CONFIG_SDL_DISPLAY_MONO_MSB_FIRST)) {
25 return BIT(7 - order);
26 } else {
27 return BIT(order);
28 }
29 }
30
display_pixel(int x,int y)31 uint32_t display_pixel(int x, int y)
32 {
33 const uint8_t *ptr = read_buffer + (display_width * (y / 8) + x);
34 struct display_capabilities display_caps;
35
36 display_get_capabilities(dev, &display_caps);
37
38 if (display_caps.current_pixel_format == PIXEL_FORMAT_MONO10) {
39 return !(*ptr & mono_pixel_order(y % 8));
40 }
41
42 return !!(*ptr & mono_pixel_order(y % 8));
43 }
44
image_pixel(const uint32_t * img,size_t width,int x,int y)45 uint32_t image_pixel(const uint32_t *img, size_t width, int x, int y)
46 {
47 const uint32_t *ptr = img + (width * y + x);
48
49 return !!(*ptr & 0xFFFFFF);
50 }
51
verify_pixel(int x,int y,uint32_t color)52 bool verify_pixel(int x, int y, uint32_t color)
53 {
54 struct display_buffer_descriptor desc = {
55 .height = display_height,
56 .pitch = display_width,
57 .width = display_width,
58 .buf_size = display_height * display_width / 8,
59 };
60
61 zassert_ok(display_read(dev, 0, 0, &desc, read_buffer), "display_read failed");
62
63 return ((!!display_pixel(x, y)) == (!!color));
64 }
65
verify_image(int cmp_x,int cmp_y,const uint32_t * img,size_t width,size_t height)66 bool verify_image(int cmp_x, int cmp_y, const uint32_t *img, size_t width, size_t height)
67 {
68 struct display_buffer_descriptor desc = {
69 .height = display_height,
70 .pitch = display_width,
71 .width = display_width,
72 .buf_size = display_height * display_width / 8,
73 };
74
75 zassert_ok(display_read(dev, 0, 0, &desc, read_buffer), "display_read failed");
76
77 for (size_t y = 0; y < height; y++) {
78 for (size_t x = 0; x < width; x++) {
79 uint32_t disp_pix = display_pixel(cmp_x + x, cmp_y + y);
80 uint32_t img_pix = image_pixel(img, width, x, y);
81
82 if (disp_pix != img_pix) {
83 LOG_INF("get_pixel(%d, %d) = %lu", x, y, disp_pix);
84 LOG_INF("pixel_color(%d, %d) = %lu", x, y, img_pix);
85 LOG_INF("disp@(0, %d) %p", y, read_buffer + (y * width / 8));
86 LOG_HEXDUMP_INF(read_buffer + (y * width / 8), 64, "");
87 LOG_INF("img@(0, %d) %p", y, (uint32_t *)img + (y * width));
88 LOG_HEXDUMP_INF((uint32_t *)img + (y * width), 64, "");
89 return false;
90 }
91 }
92 }
93
94 return true;
95 }
96
verify_color_inside_rect(int x,int y,size_t width,size_t height,uint32_t color)97 bool verify_color_inside_rect(int x, int y, size_t width, size_t height, uint32_t color)
98 {
99 struct display_buffer_descriptor desc = {
100 .height = display_height,
101 .pitch = display_width,
102 .width = display_width,
103 .buf_size = display_height * display_width / 8,
104 };
105
106 zassert_ok(display_read(dev, 0, 0, &desc, read_buffer), "display_read failed");
107
108 for (size_t y_ = 0; y_ < height; y_++) {
109 for (size_t x_ = 0; x_ < width; x_++) {
110 uint32_t disp_pix = display_pixel(x + x_, y + y_);
111
112 if (!!disp_pix != !!color) {
113 return false;
114 }
115 }
116 }
117
118 return true;
119 }
120
verify_color_outside_rect(int x,int y,size_t width,size_t height,uint32_t color)121 bool verify_color_outside_rect(int x, int y, size_t width, size_t height, uint32_t color)
122 {
123 bool ret = true;
124
125 if (x > 0) {
126 ret = verify_color_inside_rect(0, 0, x, y + height, color);
127 if (!ret) {
128 return false;
129 }
130 }
131
132 if ((y + height) <= display_height) {
133 ret = verify_color_inside_rect(0, y + height, x + width,
134 display_height - (y + height), color);
135 if (!ret) {
136 return false;
137 }
138 }
139
140 if ((x + width) <= display_width) {
141 ret = verify_color_inside_rect(x + width, y, display_width - (x + width),
142 display_height - y, color);
143 if (!ret) {
144 return false;
145 }
146 }
147
148 if (y > 0) {
149 ret = verify_color_inside_rect(x, 0, display_width - x, y, color);
150 if (!ret) {
151 return false;
152 }
153 }
154
155 return true;
156 }
157
verify_image_and_bg(int x,int y,const uint32_t * img,size_t width,size_t height,uint32_t color)158 bool verify_image_and_bg(int x, int y, const uint32_t *img, size_t width, size_t height,
159 uint32_t color)
160 {
161 bool ret = true;
162
163 ret = verify_image(x, y, img, width, height);
164 if (!ret) {
165 return false;
166 }
167
168 ret = verify_color_outside_rect(x, y, width, height, color);
169
170 return ret;
171 }
172
verify_pixel_and_bg(int x,int y,uint32_t pixcolor,uint32_t bgcolor)173 bool verify_pixel_and_bg(int x, int y, uint32_t pixcolor, uint32_t bgcolor)
174 {
175 bool ret = true;
176
177 ret = verify_pixel(x, y, pixcolor);
178 if (!ret) {
179 return false;
180 }
181
182 ret = verify_color_outside_rect(x, y, 1, 1, bgcolor);
183
184 return ret;
185 }
186