1 /*
2 * Copyright (c) 2019, 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 <drm/drm_fourcc.h>
31 #include <drm_utils.h>
32 #include <regex>
33 #include <sstream>
34 #include <sstream>
35 #include <string>
36 #include <string>
37 #include <utility>
38 #include <vector>
39
40 using std::string;
41 using std::stringstream;
42 using std::regex;
43 using std::pair;
44 using std::vector;
45
46 namespace sde_drm {
47
ParseFormats(const string & line,vector<pair<uint32_t,uint64_t>> * formats)48 void ParseFormats(const string &line, vector<pair<uint32_t, uint64_t>> *formats) {
49 // Match fourcc strings like RA24 or those with modifier like RA24/5/1. The
50 // digit after first / is vendor code, the digit after second / is modifier
51 // code.
52 regex exp_base("[[:alnum:]]{4}(/[[:digit:]]/([[:digit:]]){1,3})?");
53 regex exp_modifier("[[:alnum:]]{4}(/[[:digit:]]/([[:digit:]]){1,3})");
54 string tmp_line = line;
55 std::smatch str_match; // Resultant match
56 while (std::regex_search(tmp_line, str_match, exp_base)) { //clang_sa_ignore[core.CallAndMessage]
57 string matched_sub_str = str_match.str();
58 string final_format_str = {};
59 uint64_t modifier = 0;
60
61 if (std::regex_match(matched_sub_str, exp_modifier)) { //clang_sa_ignore[core.CallAndMessage]
62 // Here we try to parse formats with vendor code and modifier like
63 // RA24/5/1
64
65 // Extract base format string
66 final_format_str = matched_sub_str.substr(0, matched_sub_str.find("/"));
67
68 // Match vendor code
69 string vendor_sub_str = matched_sub_str.substr(matched_sub_str.find("/") + 1);
70 uint64_t vendor_code = std::stoi(vendor_sub_str);
71
72 // Match modifier
73 uint64_t fmt_modifier = std::stoi(vendor_sub_str.substr(vendor_sub_str.find("/") + 1));
74 if (vendor_code == DRM_FORMAT_MOD_VENDOR_QCOM) {
75 // Macro from drm_fourcc.h to form modifier
76 modifier = fourcc_mod_code(QCOM, fmt_modifier);
77 }
78
79 } else {
80 final_format_str = matched_sub_str.c_str();
81 }
82
83 // fourcc_code is a macro from drm_fourcc.h to form the format from 4 characters (thus fourcc)
84 formats->push_back(std::make_pair(fourcc_code(final_format_str.at(0), final_format_str.at(1),
85 final_format_str.at(2), final_format_str.at(3)),
86 modifier));
87 tmp_line = str_match.suffix();
88 }
89 }
90
Tokenize(const std::string & str,std::vector<std::string> * tokens,char delim)91 void Tokenize(const std::string &str, std::vector<std::string> *tokens, char delim) {
92 size_t pos = 0;
93 std::string str_temp(str);
94
95 while ((pos = str_temp.find(delim)) != std::string::npos && delim != ' ') {
96 str_temp.replace(pos, 1, 1, ' ');
97 }
98
99 std::stringstream ss(str_temp);
100 while (ss >> str_temp) {
101 tokens->push_back(str_temp);
102 }
103 }
104
105 } // namespace sde_drm
106