1 //
2 // Copyright 2019 The ANGLE Project 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 // gl_enum_utils.cpp:
7 // Utility functions for converting GLenums to string.
8
9 #include "common/gl_enum_utils.h"
10
11 #include "common/bitset_utils.h"
12 #include "common/string_utils.h"
13
14 #include <iomanip>
15 #include <sstream>
16
17 namespace gl
18 {
19 namespace
20 {
21
22 template <typename EnumType>
OutputGLenumStringImpl(std::ostream & out,EnumType enumGroup,unsigned int value)23 void OutputGLenumStringImpl(std::ostream &out, EnumType enumGroup, unsigned int value)
24 {
25 const char *enumStr = GLenumToString(enumGroup, value);
26 if (enumStr != kUnknownGLenumString)
27 {
28 out << enumStr;
29 return;
30 }
31
32 if (enumGroup == EnumType::Boolean)
33 {
34 // If an unknown enum was submitted as GLboolean, just write out the value.
35 if (enumStr == kUnknownGLenumString)
36 {
37 out << value;
38 }
39 else
40 {
41 out << enumStr;
42 }
43
44 return;
45 }
46
47 if (enumGroup != EnumType::AllEnums)
48 {
49 // Retry with the "Default" group
50 enumStr = GLenumToString(EnumType::AllEnums, value);
51 if (enumStr != kUnknownGLenumString)
52 {
53 out << enumStr;
54 return;
55 }
56 }
57
58 out << std::hex << "0x" << std::setfill('0') << std::setw(4) << value << std::dec;
59 }
60
61 template <typename EnumType>
GLbitfieldToStringImpl(EnumType enumGroup,unsigned int value)62 std::string GLbitfieldToStringImpl(EnumType enumGroup, unsigned int value)
63 {
64 std::stringstream st;
65
66 if (value == 0)
67 {
68 return "0";
69 }
70
71 const angle::BitSet<32> bitSet(value);
72 bool first = true;
73 for (const auto index : bitSet)
74 {
75 if (!first)
76 {
77 st << " | ";
78 }
79 first = false;
80
81 unsigned int mask = 1u << index;
82 OutputGLenumString(st, enumGroup, mask);
83 }
84
85 return st.str();
86 }
87 } // namespace
88
89 const char kUnknownGLenumString[] = "EnumUnknown";
90
OutputGLenumString(std::ostream & out,GLESEnum enumGroup,unsigned int value)91 void OutputGLenumString(std::ostream &out, GLESEnum enumGroup, unsigned int value)
92 {
93 return OutputGLenumStringImpl(out, enumGroup, value);
94 }
95
OutputGLenumString(std::ostream & out,BigGLEnum enumGroup,unsigned int value)96 void OutputGLenumString(std::ostream &out, BigGLEnum enumGroup, unsigned int value)
97 {
98 return OutputGLenumStringImpl(out, enumGroup, value);
99 }
100
OutputGLbitfieldString(std::ostream & out,GLESEnum enumGroup,unsigned int value)101 void OutputGLbitfieldString(std::ostream &out, GLESEnum enumGroup, unsigned int value)
102 {
103 out << GLbitfieldToString(enumGroup, value);
104 }
105
GLbooleanToString(unsigned int value)106 const char *GLbooleanToString(unsigned int value)
107 {
108 return GLenumToString(GLESEnum::Boolean, value);
109 }
110
GLbitfieldToString(GLESEnum enumGroup,unsigned int value)111 std::string GLbitfieldToString(GLESEnum enumGroup, unsigned int value)
112 {
113 return GLbitfieldToStringImpl(enumGroup, value);
114 }
115
GLbitfieldToString(BigGLEnum enumGroup,unsigned int value)116 std::string GLbitfieldToString(BigGLEnum enumGroup, unsigned int value)
117 {
118 return GLbitfieldToStringImpl(enumGroup, value);
119 }
120
GLinternalFormatToString(unsigned int format)121 const char *GLinternalFormatToString(unsigned int format)
122 {
123 return GLenumToString(gl::GLESEnum::InternalFormat, format);
124 }
125
StringToGLbitfield(const char * str)126 unsigned int StringToGLbitfield(const char *str)
127 {
128 unsigned int value = 0;
129 std::vector<std::string> strings =
130 angle::SplitString(str, " |", angle::WhitespaceHandling::TRIM_WHITESPACE,
131 angle::SplitResult::SPLIT_WANT_NONEMPTY);
132 for (const std::string &enumString : strings)
133 {
134 value |= StringToGLenum(enumString.c_str());
135 }
136 return value;
137 }
138 } // namespace gl
139