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] == nullptr); 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 == nullptr) 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, nullptr); 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 == nullptr) 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 == nullptr) 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 == nullptr) 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 == nullptr) 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 283