|
1 |
|
2 /* |
|
3 * Copyright 2006 The Android Open Source Project |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 |
|
9 |
|
10 #include "SkTypes.h" |
|
11 #if defined SK_BUILD_CONDENSED |
|
12 #include "SkMemberInfo.h" |
|
13 #if SK_USE_CONDENSED_INFO == 1 |
|
14 #error "SK_USE_CONDENSED_INFO must be zero to build condensed info" |
|
15 #endif |
|
16 #if !defined SK_BUILD_FOR_WIN32 |
|
17 #error "SK_BUILD_FOR_WIN32 must be defined to build condensed info" |
|
18 #endif |
|
19 #include "SkDisplayType.h" |
|
20 #include "SkIntArray.h" |
|
21 #include <stdio.h> |
|
22 |
|
23 SkTDMemberInfoArray gInfos; |
|
24 SkTDIntArray gInfosCounts; |
|
25 SkTDDisplayTypesArray gInfosTypeIDs; |
|
26 SkTDMemberInfoArray gUnknowns; |
|
27 SkTDIntArray gUnknownsCounts; |
|
28 |
|
29 static void AddInfo(SkDisplayTypes type, const SkMemberInfo* info, int infoCount) { |
|
30 SkASSERT(gInfos[type] == NULL); |
|
31 gInfos[type] = info; |
|
32 gInfosCounts[type] = infoCount; |
|
33 *gInfosTypeIDs.append() = type; |
|
34 size_t allStrs = 0; |
|
35 for (int inner = 0; inner < infoCount; inner++) { |
|
36 SkASSERT(info[inner].fCount < 256); |
|
37 int offset = (int) info[inner].fOffset; |
|
38 SkASSERT(offset < 128 && offset > -129); |
|
39 SkASSERT(allStrs < 256); |
|
40 if (info[inner].fType == SkType_BaseClassInfo) { |
|
41 const SkMemberInfo* innerInfo = (const SkMemberInfo*) info[inner].fName; |
|
42 if (gUnknowns.find(innerInfo) == -1) { |
|
43 *gUnknowns.append() = innerInfo; |
|
44 *gUnknownsCounts.append() = info[inner].fCount; |
|
45 } |
|
46 } |
|
47 if (info[inner].fType != SkType_BaseClassInfo && info[inner].fName) |
|
48 allStrs += strlen(info[inner].fName); |
|
49 allStrs += 1; |
|
50 SkASSERT(info[inner].fType < 256); |
|
51 } |
|
52 } |
|
53 |
|
54 static void WriteInfo(FILE* condensed, const SkMemberInfo* info, int infoCount, |
|
55 const char* typeName, bool draw, bool display) { |
|
56 fprintf(condensed, "static const char g%sStrings[] = \n", typeName); |
|
57 int inner; |
|
58 // write strings |
|
59 for (inner = 0; inner < infoCount; inner++) { |
|
60 const char* name = (info[inner].fType != SkType_BaseClassInfo && info[inner].fName) ? |
|
61 info[inner].fName : ""; |
|
62 const char* zero = inner < infoCount - 1 ? "\\0" : ""; |
|
63 fprintf(condensed, "\t\"%s%s\"\n", name, zero); |
|
64 } |
|
65 fprintf(condensed, ";\n\nstatic const SkMemberInfo g%s", draw ? "Draw" : display ? "Display" : ""); |
|
66 fprintf(condensed, "%sInfo[] = {", typeName); |
|
67 size_t nameOffset = 0; |
|
68 // write info tables |
|
69 for (inner = 0; inner < infoCount; inner++) { |
|
70 size_t offset = info[inner].fOffset; |
|
71 if (info[inner].fType == SkType_BaseClassInfo) { |
|
72 offset = (size_t) gInfos.find((const SkMemberInfo* ) info[inner].fName); |
|
73 SkASSERT((int) offset >= 0); |
|
74 offset = gInfosTypeIDs.find((SkDisplayTypes) offset); |
|
75 SkASSERT((int) offset >= 0); |
|
76 } |
|
77 fprintf(condensed, "\n\t{%d, %d, %d, %d}", nameOffset, offset, |
|
78 info[inner].fType, info[inner].fCount); |
|
79 if (inner < infoCount - 1) |
|
80 putc(',', condensed); |
|
81 if (info[inner].fType != SkType_BaseClassInfo && info[inner].fName) |
|
82 nameOffset += strlen(info[inner].fName); |
|
83 nameOffset += 1; |
|
84 } |
|
85 fprintf(condensed, "\n};\n\n"); |
|
86 } |
|
87 |
|
88 static void Get3DName(char* scratch, const char* name) { |
|
89 if (strncmp("skia3d:", name, sizeof("skia3d:") - 1) == 0) { |
|
90 strcpy(scratch, "3D_"); |
|
91 scratch[3]= name[7] & ~0x20; |
|
92 strcpy(&scratch[4], &name[8]); |
|
93 } else { |
|
94 scratch[0] = name[0] & ~0x20; |
|
95 strcpy(&scratch[1], &name[1]); |
|
96 } |
|
97 } |
|
98 |
|
99 int type_compare(const void* a, const void* b) { |
|
100 SkDisplayTypes first = *(SkDisplayTypes*) a; |
|
101 SkDisplayTypes second = *(SkDisplayTypes*) b; |
|
102 return first < second ? -1 : first == second ? 0 : 1; |
|
103 } |
|
104 |
|
105 void SkDisplayType::BuildCondensedInfo(SkAnimateMaker* maker) { |
|
106 gInfos.setCount(kNumberOfTypes); |
|
107 memset(gInfos.begin(), 0, sizeof(gInfos[0]) * kNumberOfTypes); |
|
108 gInfosCounts.setCount(kNumberOfTypes); |
|
109 memset(gInfosCounts.begin(), -1, sizeof(gInfosCounts[0]) * kNumberOfTypes); |
|
110 // check to see if it is condensable |
|
111 int index, infoCount; |
|
112 for (index = 0; index < kTypeNamesSize; index++) { |
|
113 const SkMemberInfo* info = GetMembers(maker, gTypeNames[index].fType, &infoCount); |
|
114 if (info == NULL) |
|
115 continue; |
|
116 AddInfo(gTypeNames[index].fType, info, infoCount); |
|
117 } |
|
118 const SkMemberInfo* extraInfo = |
|
119 SkDisplayType::GetMembers(maker, SkType_3D_Point, &infoCount); |
|
120 AddInfo(SkType_Point, extraInfo, infoCount); |
|
121 AddInfo(SkType_3D_Point, extraInfo, infoCount); |
|
122 // int baseInfos = gInfos.count(); |
|
123 do { |
|
124 SkTDMemberInfoArray oldRefs = gUnknowns; |
|
125 SkTDIntArray oldRefCounts = gUnknownsCounts; |
|
126 gUnknowns.reset(); |
|
127 gUnknownsCounts.reset(); |
|
128 for (index = 0; index < oldRefs.count(); index++) { |
|
129 const SkMemberInfo* info = oldRefs[index]; |
|
130 if (gInfos.find(info) == -1) { |
|
131 int typeIndex = 0; |
|
132 for (; typeIndex < kNumberOfTypes; typeIndex++) { |
|
133 const SkMemberInfo* temp = SkDisplayType::GetMembers( |
|
134 maker, (SkDisplayTypes) typeIndex, NULL); |
|
135 if (temp == info) |
|
136 break; |
|
137 } |
|
138 SkASSERT(typeIndex < kNumberOfTypes); |
|
139 AddInfo((SkDisplayTypes) typeIndex, info, oldRefCounts[index]); |
|
140 } |
|
141 } |
|
142 } while (gUnknowns.count() > 0); |
|
143 qsort(gInfosTypeIDs.begin(), gInfosTypeIDs.count(), sizeof(gInfosTypeIDs[0]), &type_compare); |
|
144 #ifdef SK_DEBUG |
|
145 FILE* condensed = fopen("../../src/animator/SkCondensedDebug.cpp", "w+"); |
|
146 fprintf(condensed, "#include \"SkTypes.h\"\n"); |
|
147 fprintf(condensed, "#ifdef SK_DEBUG\n"); |
|
148 #else |
|
149 FILE* condensed = fopen("../../src/animator/SkCondensedRelease.cpp", "w+"); |
|
150 fprintf(condensed, "#include \"SkTypes.h\"\n"); |
|
151 fprintf(condensed, "#ifdef SK_RELEASE\n"); |
|
152 #endif |
|
153 // write header |
|
154 fprintf(condensed, "// This file was automatically generated.\n"); |
|
155 fprintf(condensed, "// To change it, edit the file with the matching debug info.\n"); |
|
156 fprintf(condensed, "// Then execute SkDisplayType::BuildCondensedInfo() to " |
|
157 "regenerate this file.\n\n"); |
|
158 // write name of memberInfo |
|
159 int typeNameIndex = 0; |
|
160 int unknown = 1; |
|
161 for (index = 0; index < gInfos.count(); index++) { |
|
162 const SkMemberInfo* info = gInfos[index]; |
|
163 if (info == NULL) |
|
164 continue; |
|
165 char scratch[64]; |
|
166 bool drawPrefix, displayPrefix; |
|
167 while (gTypeNames[typeNameIndex].fType < index) |
|
168 typeNameIndex++; |
|
169 if (gTypeNames[typeNameIndex].fType == index) { |
|
170 Get3DName(scratch, gTypeNames[typeNameIndex].fName); |
|
171 drawPrefix = gTypeNames[typeNameIndex].fDrawPrefix; |
|
172 displayPrefix = gTypeNames[typeNameIndex].fDisplayPrefix; |
|
173 } else { |
|
174 sprintf(scratch, "Unknown%d", unknown++); |
|
175 drawPrefix = displayPrefix = false; |
|
176 } |
|
177 WriteInfo(condensed, info, gInfosCounts[index], scratch, drawPrefix, displayPrefix); |
|
178 } |
|
179 // write array of table pointers |
|
180 // start here; |
|
181 fprintf(condensed, "static const SkMemberInfo* const gInfoTables[] = {"); |
|
182 typeNameIndex = 0; |
|
183 unknown = 1; |
|
184 for (index = 0; index < gInfos.count(); index++) { |
|
185 const SkMemberInfo* info = gInfos[index]; |
|
186 if (info == NULL) |
|
187 continue; |
|
188 char scratch[64]; |
|
189 bool drawPrefix, displayPrefix; |
|
190 while (gTypeNames[typeNameIndex].fType < index) |
|
191 typeNameIndex++; |
|
192 if (gTypeNames[typeNameIndex].fType == index) { |
|
193 Get3DName(scratch, gTypeNames[typeNameIndex].fName); |
|
194 drawPrefix = gTypeNames[typeNameIndex].fDrawPrefix; |
|
195 displayPrefix = gTypeNames[typeNameIndex].fDisplayPrefix; |
|
196 } else { |
|
197 sprintf(scratch, "Unknown%d", unknown++); |
|
198 drawPrefix = displayPrefix = false; |
|
199 } |
|
200 fprintf(condensed, "\n\tg"); |
|
201 if (drawPrefix) |
|
202 fprintf(condensed, "Draw"); |
|
203 if (displayPrefix) |
|
204 fprintf(condensed, "Display"); |
|
205 fprintf(condensed, "%sInfo", scratch); |
|
206 if (index < gInfos.count() - 1) |
|
207 putc(',', condensed); |
|
208 } |
|
209 fprintf(condensed, "\n};\n\n"); |
|
210 // write the array of number of entries in the info table |
|
211 fprintf(condensed, "static const unsigned char gInfoCounts[] = {\n\t"); |
|
212 int written = 0; |
|
213 for (index = 0; index < gInfosCounts.count(); index++) { |
|
214 int count = gInfosCounts[index]; |
|
215 if (count < 0) |
|
216 continue; |
|
217 if (written > 0) |
|
218 putc(',', condensed); |
|
219 if (written % 20 == 19) |
|
220 fprintf(condensed, "\n\t"); |
|
221 fprintf(condensed, "%d",count); |
|
222 written++; |
|
223 } |
|
224 fprintf(condensed, "\n};\n\n"); |
|
225 // write array of type ids table entries correspond to |
|
226 fprintf(condensed, "static const unsigned char gTypeIDs[] = {\n\t"); |
|
227 int typeIDCount = 0; |
|
228 typeNameIndex = 0; |
|
229 unknown = 1; |
|
230 for (index = 0; index < gInfosCounts.count(); index++) { |
|
231 const SkMemberInfo* info = gInfos[index]; |
|
232 if (info == NULL) |
|
233 continue; |
|
234 typeIDCount++; |
|
235 char scratch[64]; |
|
236 while (gTypeNames[typeNameIndex].fType < index) |
|
237 typeNameIndex++; |
|
238 if (gTypeNames[typeNameIndex].fType == index) { |
|
239 Get3DName(scratch, gTypeNames[typeNameIndex].fName); |
|
240 } else |
|
241 sprintf(scratch, "Unknown%d", unknown++); |
|
242 fprintf(condensed, "%d%c // %s\n\t", index, |
|
243 index < gInfosCounts.count() ? ',' : ' ', scratch); |
|
244 } |
|
245 fprintf(condensed, "\n};\n\n"); |
|
246 fprintf(condensed, "static const int kTypeIDs = %d;\n\n", typeIDCount); |
|
247 // write the array of string pointers |
|
248 fprintf(condensed, "static const char* const gInfoNames[] = {"); |
|
249 typeNameIndex = 0; |
|
250 unknown = 1; |
|
251 written = 0; |
|
252 for (index = 0; index < gInfosCounts.count(); index++) { |
|
253 const SkMemberInfo* info = gInfos[index]; |
|
254 if (info == NULL) |
|
255 continue; |
|
256 if (written > 0) |
|
257 putc(',', condensed); |
|
258 written++; |
|
259 fprintf(condensed, "\n\tg"); |
|
260 char scratch[64]; |
|
261 while (gTypeNames[typeNameIndex].fType < index) |
|
262 typeNameIndex++; |
|
263 if (gTypeNames[typeNameIndex].fType == index) { |
|
264 Get3DName(scratch, gTypeNames[typeNameIndex].fName); |
|
265 } else |
|
266 sprintf(scratch, "Unknown%d", unknown++); |
|
267 fprintf(condensed, "%sStrings", scratch); |
|
268 } |
|
269 fprintf(condensed, "\n};\n\n"); |
|
270 fprintf(condensed, "#endif\n"); |
|
271 fclose(condensed); |
|
272 gInfos.reset(); |
|
273 gInfosCounts.reset(); |
|
274 gInfosTypeIDs.reset(); |
|
275 gUnknowns.reset(); |
|
276 gUnknownsCounts.reset(); |
|
277 } |
|
278 |
|
279 #elif defined SK_DEBUG |
|
280 #include "SkDisplayType.h" |
|
281 void SkDisplayType::BuildCondensedInfo(SkAnimateMaker* ) {} |
|
282 #endif |