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 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 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 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 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 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" 289 void SkDisplayType::BuildCondensedInfo(SkAnimateMaker* ) {} 290 #endif 291 292 293