Home | History | Annotate | Download | only in animator
      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