1# -*- coding: utf-8 -*-
2
3#-------------------------------------------------------------------------
4# drawElements Quality Program utilities
5# --------------------------------------
6#
7# Copyright 2015 The Android Open Source Project
8#
9# Licensed under the Apache License, Version 2.0 (the "License");
10# you may not use this file except in compliance with the License.
11# You may obtain a copy of the License at
12#
13#      http://www.apache.org/licenses/LICENSE-2.0
14#
15# Unless required by applicable law or agreed to in writing, software
16# distributed under the License is distributed on an "AS IS" BASIS,
17# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18# See the License for the specific language governing permissions and
19# limitations under the License.
20#
21#-------------------------------------------------------------------------
22
23from itertools import chain
24from khr_util.format import indentLines
25
26def isValueDefined (definitions, value):
27	return value in definitions
28
29def allValuesUndefined (definitions, values):
30	for value in values:
31		if isValueDefined(definitions, value):
32			return False
33	return True
34
35def anyValueDefined (definitions, values):
36	return not allValuesUndefined(definitions, values)
37
38def makeDefSet (iface):
39	return set(enum.name for enum in iface.enums) | \
40		   set(enum.alias for enum in iface.enums if enum.alias != None)
41
42def genStrUtilProtos (iface, enumGroups, bitfieldGroups):
43	definitions = makeDefSet(iface)
44
45	def genNameProtos ():
46		for groupName, values in enumGroups:
47			if anyValueDefined(definitions, values):
48				yield "const char*\tget%sName\t(int value);" % groupName
49			else:
50				print("Warning: Empty value set for %s, skipping" % groupName)
51
52	def genBitfieldProtos ():
53		for groupName, values in bitfieldGroups:
54			if anyValueDefined(definitions, values):
55				yield "tcu::Format::Bitfield<16>\tget%sStr\t(int value);" % groupName
56			else:
57				print("Warning: Empty value set for %s, skipping" % groupName)
58
59	def genStrImpl ():
60		for groupName, values in enumGroups:
61			if anyValueDefined(definitions, values):
62				yield "inline tcu::Format::Enum<int, 2>\tget%(name)sStr\t(int value)\t{ return tcu::Format::Enum<int, 2>(get%(name)sName, value); }" % {"name": groupName}
63
64		# booleans can be stored in enums or in byte-sized arrays. For clarity add special case
65		if anyValueDefined(definitions, ["GL_TRUE", "GL_FALSE"]):
66			yield "inline tcu::Format::Enum<int, 1>\tgetBooleanStr\t(deUint8 value)\t{ return tcu::Format::Enum<int, 1>(getBooleanName, (int)value); }"
67
68	return chain(genNameProtos(), genBitfieldProtos(), genStrImpl())
69
70def genEnumStrImpl (groupName, values, definitions):
71	if allValuesUndefined(definitions, values):
72		return
73
74	yield ""
75	yield "const char* get%sName (int value)" % groupName
76	yield "{"
77	yield "\tswitch (value)"
78	yield "\t{"
79
80	def genCases ():
81		for value in values:
82			if isValueDefined(definitions, value):
83				yield "case %s:\treturn \"%s\";" % (value, value)
84			else:
85				print("Warning: %s not defined, skipping" % value)
86		yield "default:\treturn DE_NULL;"
87
88	for caseLine in indentLines(genCases()):
89		yield "\t\t" + caseLine
90
91	yield "\t}"
92	yield "}"
93
94def genBitfieldStrImpl (groupName, values, definitions):
95	if allValuesUndefined(definitions, values):
96		return
97
98	yield ""
99	yield "tcu::Format::Bitfield<16> get%sStr (int value)" % groupName
100	yield "{"
101	yield "\tstatic const tcu::Format::BitDesc s_desc[] ="
102	yield "\t{"
103
104	def genFields ():
105		for value in values:
106			if isValueDefined(definitions, value):
107				yield "tcu::Format::BitDesc(%s,\t\"%s\")," % (value, value)
108			else:
109				print("Warning: %s not defined, skipping" % value)
110
111	for fieldLine in indentLines(genFields()):
112		yield "\t\t" + fieldLine
113
114	yield "\t};"
115	yield "\treturn tcu::Format::Bitfield<16>(value, &s_desc[0], &s_desc[DE_LENGTH_OF_ARRAY(s_desc)]);"
116	yield "}"
117
118def genStrUtilImpls (iface, enumGroups, bitfieldGroups):
119	definitions = makeDefSet(iface)
120
121	for groupName, values in enumGroups:
122		for line in genEnumStrImpl(groupName, values, definitions):
123			yield line
124	for groupName, values in bitfieldGroups:
125		for line in genBitfieldStrImpl(groupName, values, definitions):
126			yield line
127
128def genQueryEnumUtilImpl (groupName, groupQueries, allEnums):
129	yield ""
130	yield "int get%sQueryNumArgsOut (int pname)" % groupName
131	yield "{"
132	yield "\tswitch(pname)"
133	yield "\t{"
134
135	def genCases ():
136		for enumName, enumQueryNumOutputs in groupQueries:
137			if enumName in allEnums:
138				yield "case %s:\treturn %s;" % (enumName, enumQueryNumOutputs)
139			else:
140				print("Warning: %s not defined, skipping" % enumName)
141		yield "default:\treturn 1;"
142
143	for caseLine in indentLines(genCases()):
144		yield "\t\t" + caseLine
145
146	yield "\t}"
147	yield "}"
148
149def genQueryEnumUtilImpls (iface, queryGroups):
150	allEnums = makeDefSet(iface)
151
152	for groupName, groupQueries in queryGroups:
153		for line in genQueryEnumUtilImpl(groupName, groupQueries, allEnums):
154			yield line
155
156def genSetEnumUtilImpl (groupName, groupQueries, allEnums):
157	yield ""
158	yield "int get%sNumArgs (int pname)" % groupName
159	yield "{"
160	yield "\tswitch(pname)"
161	yield "\t{"
162
163	def genCases ():
164		for enumName, enumQueryNumOutputs in groupQueries:
165			if enumName in allEnums:
166				yield "case %s:\treturn %s;" % (enumName, enumQueryNumOutputs)
167			else:
168				print("Warning: %s not defined, skipping" % enumName)
169		yield "default:\treturn 1;"
170
171	for caseLine in indentLines(genCases()):
172		yield "\t\t" + caseLine
173
174	yield "\t}"
175	yield "}"
176
177def genSetEnumUtilImpls (iface, queryGroups):
178	allEnums = makeDefSet(iface)
179
180	for groupName, groupQueries in queryGroups:
181		for line in genSetEnumUtilImpl(groupName, groupQueries, allEnums):
182			yield line
183
184def addValuePrefix (groups, prefix):
185	return [(groupName, [prefix + value for value in values]) for groupName, values in groups]
186