1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cmath>
17 #include <vector>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include "display_test.h"
21 #include "buffer_handle.h"
22
23 #include "v1_1/display_composer_type.h"
24 #include "v1_0/include/idisplay_buffer.h"
25
26 namespace OHOS {
27 namespace HDI {
28 namespace Display {
29 namespace TEST {
30 using namespace OHOS::HDI::Display::Composer::V1_0;
31 using namespace OHOS::HDI::Display::Buffer::V1_0;
32
33 const uint8_t BITS_PER_BYTE = 8;
34
BGRAToRGBA(uint32_t bgra)35 static uint32_t BGRAToRGBA(uint32_t bgra)
36 {
37 uint32_t rgba = 0;
38 const uint32_t COLOR_RED = 0x0000ff00;
39 const uint32_t COLOR_GREEN = 0x00ff0000;
40 const uint32_t COLOR_BLUE = 0xff000000;
41 const uint32_t ALPHA = 0x000000ff;
42 const int32_t TWO_BYTE_OFFSET = 16;
43
44 rgba |= (bgra & COLOR_RED) << TWO_BYTE_OFFSET; // get red then move to rgba
45 rgba |= (bgra & COLOR_GREEN); // get green
46 rgba |= (bgra & COLOR_BLUE) >> TWO_BYTE_OFFSET; // get blue then move to rgba
47 rgba |= (bgra & ALPHA); // get alpha
48
49 return rgba;
50 }
51
GetPixelFormatBpp(Composer::V1_0::PixelFormat format)52 static int32_t GetPixelFormatBpp(Composer::V1_0::PixelFormat format)
53 {
54 const int32_t BPP_RGBA_8888 = 32;
55 switch (format) {
56 case Composer::V1_0::PIXEL_FMT_RGBA_8888:
57 return BPP_RGBA_8888;
58 case Composer::V1_0::PIXEL_FMT_BGRA_8888:
59 return BPP_RGBA_8888;
60 default:
61 return -1;
62 }
63 }
64
SaveFile(const char * fileName,uint8_t * data,int size)65 void SaveFile(const char *fileName, uint8_t *data, int size)
66 {
67 if (fileName != nullptr && data != nullptr) {
68 int fileFd = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
69 if (fileFd <= 0) {
70 DISPLAY_TEST_LOGE("Open file failed %{public}d", fileFd);
71 return;
72 }
73
74 int hasWriten = write(fileFd, data, size);
75 DISPLAY_TEST_LOGE("SaveFile hasWriten %{public}d", hasWriten);
76 close(fileFd);
77 } else {
78 DISPLAY_TEST_LOGE("SaveFile failed");
79 }
80 }
81
ConverToRGBA(Composer::V1_0::PixelFormat fmt,uint32_t color)82 static uint32_t ConverToRGBA(Composer::V1_0::PixelFormat fmt, uint32_t color)
83 {
84 switch (fmt) {
85 case Composer::V1_0::PIXEL_FMT_BGRA_8888:
86 return BGRAToRGBA(color);
87 case Composer::V1_0::PIXEL_FMT_RGBA_8888:
88 return color;
89 default:
90 DISPLAY_TEST_LOGE("the fmt can not convert %{public}d", fmt);
91 }
92 return color;
93 }
94
GetPixelValue(const BufferHandle & handle,int x,int y)95 uint32_t GetPixelValue(const BufferHandle &handle, int x, int y)
96 {
97 const int32_t PIXEL_BYTES = 4;
98 int32_t bpp = GetPixelFormatBpp((Composer::V1_0::PixelFormat)handle.format);
99 DISPLAY_TEST_CHK_RETURN((bpp <= 0), 0, DISPLAY_TEST_LOGE("CheckPixel do not support format %{public}d",
100 handle.format));
101 DISPLAY_TEST_CHK_RETURN((handle.virAddr == nullptr), 0,
102 DISPLAY_TEST_LOGE("CheckPixel viraddr is null must map it"));
103 DISPLAY_TEST_CHK_RETURN((x < 0 || x >= handle.width), 0,
104 DISPLAY_TEST_LOGE("CheckPixel invalid parameter x:%{public}d width:%{public}d", x, handle.width));
105 DISPLAY_TEST_CHK_RETURN((y < 0 || y >= handle.height), 0,
106 DISPLAY_TEST_LOGE("CheckPixel invalid parameter y:%{public}d height:%{public}d", y, handle.height));
107
108 int32_t position = y * handle.width + x;
109 if ((position * PIXEL_BYTES) > handle.size) {
110 DISPLAY_TEST_LOGE("the pixel position outside\n");
111 }
112 uint32_t *pixel = reinterpret_cast<uint32_t *>(handle.virAddr) + position;
113 DISPLAY_TEST_CHK_RETURN((pixel == nullptr), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("get pixel failed"));
114
115 return *pixel;
116 }
117
GetUint32(uint32_t value)118 uint32_t GetUint32(uint32_t value)
119 {
120 uint32_t dst;
121 uint8_t *data = reinterpret_cast<uint8_t *>(&dst);
122 for (uint8_t i = 0; i < sizeof(uint32_t); i++) {
123 *(data + i) = (value >> ((sizeof(uint32_t) - i - 1) * BITS_PER_BYTE)) & 0xff;
124 }
125 return dst;
126 }
127
CheckPixel(const BufferHandle & handle,int x,int y,uint32_t color)128 uint32_t CheckPixel(const BufferHandle &handle, int x, int y, uint32_t color)
129 {
130 const int32_t PIXEL_BYTES = 4;
131 int32_t bpp = GetPixelFormatBpp(static_cast<Composer::V1_0::PixelFormat>(handle.format));
132 DISPLAY_TEST_CHK_RETURN((bpp <= 0), 0, DISPLAY_TEST_LOGE("CheckPixel do not support format %{public}d",
133 handle.format));
134 DISPLAY_TEST_CHK_RETURN((handle.virAddr == nullptr), 0,
135 DISPLAY_TEST_LOGE("CheckPixel viraddr is null must map it"));
136 DISPLAY_TEST_CHK_RETURN((x < 0 || x >= handle.width), 0,
137 DISPLAY_TEST_LOGE("CheckPixel invalid parameter x:%{public}d width:%{public}d", x, handle.width));
138 DISPLAY_TEST_CHK_RETURN((y < 0 || y >= handle.height), 0,
139 DISPLAY_TEST_LOGE("CheckPixel invalid parameter y:%{public}d height:%{public}d", y, handle.height));
140
141 int32_t position = y * handle.width + x;
142 if ((position * PIXEL_BYTES) > handle.size) {
143 DISPLAY_TEST_LOGE("the pixel position outside\n");
144 }
145 uint32_t *pixel = reinterpret_cast<uint32_t *>(handle.virAddr) + position;
146 DISPLAY_TEST_CHK_RETURN((pixel == nullptr), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("get pixel failed"));
147
148 uint32_t checkColor = ConverToRGBA(static_cast<Composer::V1_0::PixelFormat>(handle.format), GetUint32(*pixel));
149 if (checkColor != color) {
150 DISPLAY_TEST_LOGE("x:%{public}d y:%{public}d width:%{public}d", x, y, handle.width);
151 SaveFile("/data/display_test_bitmap_", static_cast<uint8_t *>(handle.virAddr), handle.size);
152 return DISPLAY_FAILURE;
153 }
154 return DISPLAY_SUCCESS;
155 }
156
SetUint32(uint32_t & dst,uint32_t value)157 void SetUint32(uint32_t &dst, uint32_t value)
158 {
159 uint8_t *data = reinterpret_cast<uint8_t *>(&dst);
160 if (data != nullptr) {
161 for (uint8_t i = 0; i < sizeof(uint32_t); i++) {
162 *(data + i) = (value >> ((sizeof(uint32_t) - i - 1) * BITS_PER_BYTE)) & 0xff;
163 }
164 } else {
165 DISPLAY_TEST_LOGE("SetUint32 failed");
166 }
167 }
168
SetPixel(const BufferHandle & handle,int x,int y,uint32_t color)169 void SetPixel(const BufferHandle &handle, int x, int y, uint32_t color)
170 {
171 const int32_t PIXEL_BYTES = 4;
172 const int32_t BPP = 32;
173 DISPLAY_TEST_CHK_RETURN_NOT_VALUE((BPP <= 0),
174 DISPLAY_TEST_LOGE("CheckPixel do not support format %{public}d", handle.format));
175 DISPLAY_TEST_CHK_RETURN_NOT_VALUE((handle.virAddr == nullptr),
176 DISPLAY_TEST_LOGE("CheckPixel viraddr is null must map it"));
177 DISPLAY_TEST_CHK_RETURN_NOT_VALUE((x < 0 || x >= handle.width),
178 DISPLAY_TEST_LOGE("CheckPixel invalid parameter x:%{public}d width:%{public}d", x, handle.width));
179 DISPLAY_TEST_CHK_RETURN_NOT_VALUE((y < 0 || y >= handle.height),
180 DISPLAY_TEST_LOGE("CheckPixel invalid parameter y:%{public}d height:%{public}d", y, handle.height));
181
182 int32_t position = y * handle.stride / PIXEL_BYTES + x;
183 if ((position * PIXEL_BYTES) > handle.size) {
184 DISPLAY_TEST_LOGE("the pixel position outside\n");
185 }
186 uint32_t *pixel = reinterpret_cast<uint32_t *>(handle.virAddr) + position;
187 DISPLAY_TEST_CHK_RETURN_NOT_VALUE((pixel == nullptr), DISPLAY_TEST_LOGE("get pixel failed"));
188
189 SetUint32(*pixel, color);
190 }
191
ClearColor(const BufferHandle & handle,uint32_t color)192 void ClearColor(const BufferHandle &handle, uint32_t color)
193 {
194 for (int32_t x = 0; x < handle.width; x++) {
195 for (int32_t y = 0; y < handle.height; y++) {
196 SetPixel(handle, x, y, color);
197 }
198 }
199 }
200
ClearColorRect(const BufferHandle & handle,uint32_t color,const IRect & rect)201 void ClearColorRect(const BufferHandle &handle, uint32_t color, const IRect &rect)
202 {
203 DISPLAY_TEST_LOGE("x %{public}d, y %{public}d w %{public}d h %{public}d color %x ", rect.x, rect.y, rect.w, rect.h,
204 color);
205 for (int32_t x = 0; x < rect.w; x++) {
206 for (int32_t y = 0; y < rect.h; y++) {
207 SetPixel(handle, x + rect.x, y + rect.y, color);
208 }
209 }
210 }
211
SplitBuffer(const BufferHandle & handle,std::vector<uint32_t> & colors)212 std::vector<IRect> SplitBuffer(const BufferHandle &handle, std::vector<uint32_t> &colors)
213 {
214 std::vector<IRect> splitRects;
215 if (colors.empty()) {
216 DISPLAY_TEST_LOGE("the colors empty");
217 }
218 const uint32_t ROW_NUM = sqrt(colors.size());
219 const uint32_t COL_NUM = ROW_NUM;
220 if (ROW_NUM == 0) {
221 DISPLAY_TEST_LOGE("ROW_NUM is zero");
222 return splitRects;
223 }
224
225 const uint32_t CELL_WIDTH = handle.width / ROW_NUM;
226 const uint32_t CELL_HEIGHT = handle.height / COL_NUM;
227 IRect rect = { 0, 0, CELL_WIDTH, CELL_HEIGHT };
228 DISPLAY_TEST_LOGE("ROW_NUM %{public}u, COL_NUM %{public}u CELL_WIDTH %{public}u CELL_HEIGHT %{public}u",
229 ROW_NUM, COL_NUM, CELL_WIDTH, CELL_HEIGHT);
230 uint32_t count = 0;
231 for (uint32_t x = 0; x < ROW_NUM; x++) {
232 for (uint32_t y = 0; y < COL_NUM; y++) {
233 rect.x = x * CELL_WIDTH;
234 rect.y = y * CELL_HEIGHT;
235 ClearColorRect(handle, colors[count++], rect);
236 splitRects.push_back(rect);
237 }
238 }
239 SaveFile("/data/splitbuffer_data_", static_cast<uint8_t *>(handle.virAddr), handle.size);
240 return splitRects;
241 }
242 } // OHOS
243 } // HDI
244 } // Display
245 } // TEST
246