Home | History | Annotate | Download | only in animator
      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] == NULL);
     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 == NULL)
    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, NULL);
    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 == NULL)
    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 == NULL)
    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 == NULL)
    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 == NULL)
    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