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