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