• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* 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 
31 SkTDMemberInfoArray gInfos;
32 SkTDIntArray gInfosCounts;
33 SkTDDisplayTypesArray gInfosTypeIDs;
34 SkTDMemberInfoArray gUnknowns;
35 SkTDIntArray gUnknownsCounts;
36 
AddInfo(SkDisplayTypes type,const SkMemberInfo * info,int infoCount)37 static 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 
WriteInfo(FILE * condensed,const SkMemberInfo * info,int infoCount,const char * typeName,bool draw,bool display)62 static 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 
Get3DName(char * scratch,const char * name)96 static 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 
type_compare(const void * a,const void * b)107 int 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 
BuildCondensedInfo(SkAnimateMaker * maker)113 void 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"
BuildCondensedInfo(SkAnimateMaker *)289 void SkDisplayType::BuildCondensedInfo(SkAnimateMaker* ) {}
290 #endif
291 
292 
293