1 /*
2 * Copyright (c) 2013, 2018, 2020, The Linux Foundation. All rights reserved.
3
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <unistd.h>
31 #include <gralloc_priv.h>
32 #include "qd_utils.h"
33
34 static const int kFBNodeMax = 4;
35 namespace qdutils {
36
parseLine(char * input,char * tokens[],const uint32_t maxToken,uint32_t * count)37 static int parseLine(char *input, char *tokens[], const uint32_t maxToken, uint32_t *count) {
38 char *tmpToken = NULL;
39 char *tmpPtr;
40 uint32_t index = 0;
41 const char *delim = ", =\n";
42 if (!input) {
43 return -1;
44 }
45 tmpToken = strtok_r(input, delim, &tmpPtr);
46 while (tmpToken && index < maxToken) {
47 tokens[index++] = tmpToken;
48 tmpToken = strtok_r(NULL, delim, &tmpPtr);
49 }
50 *count = index;
51
52 return 0;
53 }
54
getExternalNode(const char * type)55 static int getExternalNode(const char *type) {
56 FILE *displayDeviceFP = NULL;
57 char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
58 char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
59 int j = 0;
60
61 for(j = 0; j < kFBNodeMax; j++) {
62 snprintf (msmFbTypePath, sizeof(msmFbTypePath),
63 "/sys/devices/virtual/graphics/fb%d/msm_fb_type", j);
64 displayDeviceFP = fopen(msmFbTypePath, "r");
65 if(displayDeviceFP) {
66 fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
67 displayDeviceFP);
68 if(strncmp(fbType, type, strlen(type)) == 0) {
69 ALOGD("%s: %s is at fb%d", __func__, type, j);
70 fclose(displayDeviceFP);
71 break;
72 }
73 fclose(displayDeviceFP);
74 } else {
75 ALOGE("%s: Failed to open fb node %s", __func__, msmFbTypePath);
76 }
77 }
78
79 if (j < kFBNodeMax)
80 return j;
81 else
82 ALOGE("%s: Failed to find %s node", __func__, type);
83
84 return -1;
85 }
86
isDPConnected()87 bool isDPConnected() {
88 char connectPath[MAX_FRAME_BUFFER_NAME_SIZE];
89 FILE *connectFile = NULL;
90 size_t len = MAX_STRING_LENGTH;
91 char stringBuffer[MAX_STRING_LENGTH];
92 char *line = stringBuffer;
93
94 int nodeId = getExternalNode("dp panel");
95 if (nodeId < 0) {
96 ALOGE("%s no DP node found", __func__);
97 return false;
98 }
99
100 snprintf(connectPath, sizeof(connectPath),
101 "/sys/devices/virtual/graphics/fb%d/connected", nodeId);
102
103 connectFile = fopen(connectPath, "rb");
104 if (!connectFile) {
105 ALOGW("Failed to open connect node for device node %s", connectPath);
106 return false;
107 }
108
109 if (getline(&line, &len, connectFile) < 0) {
110 fclose(connectFile);
111 return false;
112 }
113
114 fclose(connectFile);
115
116 return atoi(line);
117 }
118
getDPTestConfig(uint32_t * panelBpp,uint32_t * patternType)119 int getDPTestConfig(uint32_t *panelBpp, uint32_t *patternType) {
120 if (!panelBpp || !patternType) {
121 return -1;
122 }
123
124 char configPath[MAX_FRAME_BUFFER_NAME_SIZE];
125 FILE *configFile = NULL;
126 uint32_t tokenCount = 0;
127 const uint32_t maxCount = 10;
128 char *tokens[maxCount] = { NULL };
129 size_t len = MAX_STRING_LENGTH;
130 char stringBuffer[MAX_STRING_LENGTH];
131 char *line = stringBuffer;
132
133 int nodeId = getExternalNode("dp panel");
134 if (nodeId < 0) {
135 ALOGE("%s no DP node found", __func__);
136 return -EINVAL;
137 }
138
139 snprintf(configPath, sizeof(configPath),
140 "/sys/devices/virtual/graphics/fb%d/config", nodeId);
141
142 configFile = fopen(configPath, "rb");
143 if (!configFile) {
144 ALOGW("Failed to open config node for device node %s", configPath);
145 return -EINVAL;
146 }
147
148 while (getline(&line, &len, configFile) != -1) {
149 if (!parseLine(line, tokens, maxCount, &tokenCount)) {
150 if (tokens[0] != NULL) {
151 if (!strncmp(tokens[0], "bpp", strlen("bpp"))) {
152 *panelBpp = static_cast<uint32_t>(atoi(tokens[1]));
153 } else if (!strncmp(tokens[0], "pattern", strlen("pattern"))) {
154 *patternType = static_cast<uint32_t>(atoi(tokens[1]));
155 }
156 }
157 }
158 }
159
160 fclose(configFile);
161
162 return 0;
163 }
164
GetHALPixelFormatString(int format)165 const char *GetHALPixelFormatString(int format) {
166 switch (format) {
167 case HAL_PIXEL_FORMAT_RGBA_8888:
168 return "RGBA_8888";
169 case HAL_PIXEL_FORMAT_RGBX_8888:
170 return "RGBX_8888";
171 case HAL_PIXEL_FORMAT_RGB_888:
172 return "RGB_888";
173 case HAL_PIXEL_FORMAT_RGB_565:
174 return "RGB_565";
175 case HAL_PIXEL_FORMAT_BGR_565:
176 return "BGR_565";
177 case HAL_PIXEL_FORMAT_BGRA_8888:
178 return "BGRA_8888";
179 case HAL_PIXEL_FORMAT_RGBA_5551:
180 return "RGBA_5551";
181 case HAL_PIXEL_FORMAT_RGBA_4444:
182 return "RGBA_4444";
183 case HAL_PIXEL_FORMAT_YV12:
184 return "YV12";
185 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
186 return "YCbCr_422_SP_NV16";
187 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
188 return "YCrCb_420_SP_NV21";
189 case HAL_PIXEL_FORMAT_YCbCr_422_I:
190 return "YCbCr_422_I_YUY2";
191 case HAL_PIXEL_FORMAT_YCrCb_422_I:
192 return "YCrCb_422_I_YVYU";
193 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
194 return "NV12_ENCODEABLE";
195 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
196 return "YCbCr_420_SP_TILED_TILE_4x2";
197 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
198 return "YCbCr_420_SP";
199 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
200 return "YCrCb_420_SP_ADRENO";
201 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
202 return "YCrCb_422_SP";
203 case HAL_PIXEL_FORMAT_R_8:
204 return "R_8";
205 case HAL_PIXEL_FORMAT_RG_88:
206 return "RG_88";
207 case HAL_PIXEL_FORMAT_INTERLACE:
208 return "INTERLACE";
209 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
210 return "YCbCr_420_SP_VENUS";
211 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
212 return "YCrCb_420_SP_VENUS";
213 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
214 return "YCbCr_420_SP_VENUS_UBWC";
215 case HAL_PIXEL_FORMAT_RGBA_1010102:
216 return "RGBA_1010102";
217 case HAL_PIXEL_FORMAT_ARGB_2101010:
218 return "ARGB_2101010";
219 case HAL_PIXEL_FORMAT_RGBX_1010102:
220 return "RGBX_1010102";
221 case HAL_PIXEL_FORMAT_XRGB_2101010:
222 return "XRGB_2101010";
223 case HAL_PIXEL_FORMAT_BGRA_1010102:
224 return "BGRA_1010102";
225 case HAL_PIXEL_FORMAT_ABGR_2101010:
226 return "ABGR_2101010";
227 case HAL_PIXEL_FORMAT_BGRX_1010102:
228 return "BGRX_1010102";
229 case HAL_PIXEL_FORMAT_XBGR_2101010:
230 return "XBGR_2101010";
231 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
232 return "YCbCr_420_P010";
233 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
234 return "YCbCr_420_TP10_UBWC";
235 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
236 return "YCbCr_420_P010_VENUS";
237 case HAL_PIXEL_FORMAT_RGBA_FP16:
238 return "PIXEL_FORMAT_RGBA_FP16";
239 default:
240 return "Unknown_format";
241 }
242 }
243
244 }; //namespace qdutils
245