/* * Copyright 2006 The Android Open Source Project * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkTypes.h" #if defined SK_BUILD_CONDENSED #include "SkMemberInfo.h" #if SK_USE_CONDENSED_INFO == 1 #error "SK_USE_CONDENSED_INFO must be zero to build condensed info" #endif #if !defined SK_BUILD_FOR_WIN32 #error "SK_BUILD_FOR_WIN32 must be defined to build condensed info" #endif #include "SkDisplayType.h" #include "SkIntArray.h" #include SkTDMemberInfoArray gInfos; SkTDIntArray gInfosCounts; SkTDDisplayTypesArray gInfosTypeIDs; SkTDMemberInfoArray gUnknowns; SkTDIntArray gUnknownsCounts; static void AddInfo(SkDisplayTypes type, const SkMemberInfo* info, int infoCount) { SkASSERT(gInfos[type] == nullptr); gInfos[type] = info; gInfosCounts[type] = infoCount; *gInfosTypeIDs.append() = type; size_t allStrs = 0; for (int inner = 0; inner < infoCount; inner++) { SkASSERT(info[inner].fCount < 256); int offset = (int) info[inner].fOffset; SkASSERT(offset < 128 && offset > -129); SkASSERT(allStrs < 256); if (info[inner].fType == SkType_BaseClassInfo) { const SkMemberInfo* innerInfo = (const SkMemberInfo*) info[inner].fName; if (gUnknowns.find(innerInfo) == -1) { *gUnknowns.append() = innerInfo; *gUnknownsCounts.append() = info[inner].fCount; } } if (info[inner].fType != SkType_BaseClassInfo && info[inner].fName) allStrs += strlen(info[inner].fName); allStrs += 1; SkASSERT(info[inner].fType < 256); } } static void WriteInfo(FILE* condensed, const SkMemberInfo* info, int infoCount, const char* typeName, bool draw, bool display) { fprintf(condensed, "static const char g%sStrings[] = \n", typeName); int inner; // write strings for (inner = 0; inner < infoCount; inner++) { const char* name = (info[inner].fType != SkType_BaseClassInfo && info[inner].fName) ? info[inner].fName : ""; const char* zero = inner < infoCount - 1 ? "\\0" : ""; fprintf(condensed, "\t\"%s%s\"\n", name, zero); } fprintf(condensed, ";\n\nstatic const SkMemberInfo g%s", draw ? "Draw" : display ? "Display" : ""); fprintf(condensed, "%sInfo[] = {", typeName); size_t nameOffset = 0; // write info tables for (inner = 0; inner < infoCount; inner++) { size_t offset = info[inner].fOffset; if (info[inner].fType == SkType_BaseClassInfo) { offset = (size_t) gInfos.find((const SkMemberInfo* ) info[inner].fName); SkASSERT((int) offset >= 0); offset = gInfosTypeIDs.find((SkDisplayTypes) offset); SkASSERT((int) offset >= 0); } fprintf(condensed, "\n\t{%d, %d, %d, %d}", nameOffset, offset, info[inner].fType, info[inner].fCount); if (inner < infoCount - 1) putc(',', condensed); if (info[inner].fType != SkType_BaseClassInfo && info[inner].fName) nameOffset += strlen(info[inner].fName); nameOffset += 1; } fprintf(condensed, "\n};\n\n"); } static void Get3DName(char* scratch, const char* name) { if (strncmp("skia3d:", name, sizeof("skia3d:") - 1) == 0) { strcpy(scratch, "3D_"); scratch[3]= name[7] & ~0x20; strcpy(&scratch[4], &name[8]); } else { scratch[0] = name[0] & ~0x20; strcpy(&scratch[1], &name[1]); } } int type_compare(const void* a, const void* b) { SkDisplayTypes first = *(SkDisplayTypes*) a; SkDisplayTypes second = *(SkDisplayTypes*) b; return first < second ? -1 : first == second ? 0 : 1; } void SkDisplayType::BuildCondensedInfo(SkAnimateMaker* maker) { gInfos.setCount(kNumberOfTypes); memset(gInfos.begin(), 0, sizeof(gInfos[0]) * kNumberOfTypes); gInfosCounts.setCount(kNumberOfTypes); memset(gInfosCounts.begin(), -1, sizeof(gInfosCounts[0]) * kNumberOfTypes); // check to see if it is condensable int index, infoCount; for (index = 0; index < kTypeNamesSize; index++) { const SkMemberInfo* info = GetMembers(maker, gTypeNames[index].fType, &infoCount); if (info == nullptr) continue; AddInfo(gTypeNames[index].fType, info, infoCount); } const SkMemberInfo* extraInfo = SkDisplayType::GetMembers(maker, SkType_3D_Point, &infoCount); AddInfo(SkType_Point, extraInfo, infoCount); AddInfo(SkType_3D_Point, extraInfo, infoCount); // int baseInfos = gInfos.count(); do { SkTDMemberInfoArray oldRefs = gUnknowns; SkTDIntArray oldRefCounts = gUnknownsCounts; gUnknowns.reset(); gUnknownsCounts.reset(); for (index = 0; index < oldRefs.count(); index++) { const SkMemberInfo* info = oldRefs[index]; if (gInfos.find(info) == -1) { int typeIndex = 0; for (; typeIndex < kNumberOfTypes; typeIndex++) { const SkMemberInfo* temp = SkDisplayType::GetMembers( maker, (SkDisplayTypes) typeIndex, nullptr); if (temp == info) break; } SkASSERT(typeIndex < kNumberOfTypes); AddInfo((SkDisplayTypes) typeIndex, info, oldRefCounts[index]); } } } while (gUnknowns.count() > 0); qsort(gInfosTypeIDs.begin(), gInfosTypeIDs.count(), sizeof(gInfosTypeIDs[0]), &type_compare); #ifdef SK_DEBUG FILE* condensed = fopen("../../src/animator/SkCondensedDebug.inc", "w+"); fprintf(condensed, "#include \"SkTypes.h\"\n"); fprintf(condensed, "#ifdef SK_DEBUG\n"); #else FILE* condensed = fopen("../../src/animator/SkCondensedRelease.inc", "w+"); fprintf(condensed, "#include \"SkTypes.h\"\n"); fprintf(condensed, "#ifdef SK_RELEASE\n"); #endif // write header fprintf(condensed, "// This file was automatically generated.\n"); fprintf(condensed, "// To change it, edit the file with the matching debug info.\n"); fprintf(condensed, "// Then execute SkDisplayType::BuildCondensedInfo() to " "regenerate this file.\n\n"); // write name of memberInfo int typeNameIndex = 0; int unknown = 1; for (index = 0; index < gInfos.count(); index++) { const SkMemberInfo* info = gInfos[index]; if (info == nullptr) continue; char scratch[64]; bool drawPrefix, displayPrefix; while (gTypeNames[typeNameIndex].fType < index) typeNameIndex++; if (gTypeNames[typeNameIndex].fType == index) { Get3DName(scratch, gTypeNames[typeNameIndex].fName); drawPrefix = gTypeNames[typeNameIndex].fDrawPrefix; displayPrefix = gTypeNames[typeNameIndex].fDisplayPrefix; } else { sprintf(scratch, "Unknown%d", unknown++); drawPrefix = displayPrefix = false; } WriteInfo(condensed, info, gInfosCounts[index], scratch, drawPrefix, displayPrefix); } // write array of table pointers // start here; fprintf(condensed, "static const SkMemberInfo* const gInfoTables[] = {"); typeNameIndex = 0; unknown = 1; for (index = 0; index < gInfos.count(); index++) { const SkMemberInfo* info = gInfos[index]; if (info == nullptr) continue; char scratch[64]; bool drawPrefix, displayPrefix; while (gTypeNames[typeNameIndex].fType < index) typeNameIndex++; if (gTypeNames[typeNameIndex].fType == index) { Get3DName(scratch, gTypeNames[typeNameIndex].fName); drawPrefix = gTypeNames[typeNameIndex].fDrawPrefix; displayPrefix = gTypeNames[typeNameIndex].fDisplayPrefix; } else { sprintf(scratch, "Unknown%d", unknown++); drawPrefix = displayPrefix = false; } fprintf(condensed, "\n\tg"); if (drawPrefix) fprintf(condensed, "Draw"); if (displayPrefix) fprintf(condensed, "Display"); fprintf(condensed, "%sInfo", scratch); if (index < gInfos.count() - 1) putc(',', condensed); } fprintf(condensed, "\n};\n\n"); // write the array of number of entries in the info table fprintf(condensed, "static const unsigned char gInfoCounts[] = {\n\t"); int written = 0; for (index = 0; index < gInfosCounts.count(); index++) { int count = gInfosCounts[index]; if (count < 0) continue; if (written > 0) putc(',', condensed); if (written % 20 == 19) fprintf(condensed, "\n\t"); fprintf(condensed, "%d",count); written++; } fprintf(condensed, "\n};\n\n"); // write array of type ids table entries correspond to fprintf(condensed, "static const unsigned char gTypeIDs[] = {\n\t"); int typeIDCount = 0; typeNameIndex = 0; unknown = 1; for (index = 0; index < gInfosCounts.count(); index++) { const SkMemberInfo* info = gInfos[index]; if (info == nullptr) continue; typeIDCount++; char scratch[64]; while (gTypeNames[typeNameIndex].fType < index) typeNameIndex++; if (gTypeNames[typeNameIndex].fType == index) { Get3DName(scratch, gTypeNames[typeNameIndex].fName); } else sprintf(scratch, "Unknown%d", unknown++); fprintf(condensed, "%d%c // %s\n\t", index, index < gInfosCounts.count() ? ',' : ' ', scratch); } fprintf(condensed, "\n};\n\n"); fprintf(condensed, "static const int kTypeIDs = %d;\n\n", typeIDCount); // write the array of string pointers fprintf(condensed, "static const char* const gInfoNames[] = {"); typeNameIndex = 0; unknown = 1; written = 0; for (index = 0; index < gInfosCounts.count(); index++) { const SkMemberInfo* info = gInfos[index]; if (info == nullptr) continue; if (written > 0) putc(',', condensed); written++; fprintf(condensed, "\n\tg"); char scratch[64]; while (gTypeNames[typeNameIndex].fType < index) typeNameIndex++; if (gTypeNames[typeNameIndex].fType == index) { Get3DName(scratch, gTypeNames[typeNameIndex].fName); } else sprintf(scratch, "Unknown%d", unknown++); fprintf(condensed, "%sStrings", scratch); } fprintf(condensed, "\n};\n\n"); fprintf(condensed, "#endif\n"); fclose(condensed); gInfos.reset(); gInfosCounts.reset(); gInfosTypeIDs.reset(); gUnknowns.reset(); gUnknownsCounts.reset(); } #elif defined SK_DEBUG #include "SkDisplayType.h" void SkDisplayType::BuildCondensedInfo(SkAnimateMaker* ) {} #endif