Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkFlattenable.h"
      9 #include "SkPtrRecorder.h"
     10 #include "SkReadBuffer.h"
     11 
     12 SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {}
     13 
     14 uint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) {
     15     uint32_t index = fFactorySet.find(factory);
     16     if (index > 0) {
     17         return index;
     18     }
     19     const char* name = SkFlattenable::FactoryToName(factory);
     20     if (nullptr == name) {
     21         return 0;
     22     }
     23     *fNames.append() = name;
     24     return fFactorySet.add(factory);
     25 }
     26 
     27 const char* SkNamedFactorySet::getNextAddedFactoryName() {
     28     if (fNextAddedFactory < fNames.count()) {
     29         return fNames[fNextAddedFactory++];
     30     }
     31     return nullptr;
     32 }
     33 
     34 ///////////////////////////////////////////////////////////////////////////////
     35 
     36 SkRefCntSet::~SkRefCntSet() {
     37     // call this now, while our decPtr() is sill in scope
     38     this->reset();
     39 }
     40 
     41 void SkRefCntSet::incPtr(void* ptr) {
     42     ((SkRefCnt*)ptr)->ref();
     43 }
     44 
     45 void SkRefCntSet::decPtr(void* ptr) {
     46     ((SkRefCnt*)ptr)->unref();
     47 }
     48 
     49 ///////////////////////////////////////////////////////////////////////////////
     50 
     51 struct Entry {
     52     const char*             fName;
     53     SkFlattenable::Factory  fFactory;
     54     SkFlattenable::Type     fType;
     55 };
     56 
     57 static int gCount = 0;
     58 static Entry gEntries[128];
     59 
     60 void SkFlattenable::Register(const char name[], Factory factory, SkFlattenable::Type type) {
     61     SkASSERT(name);
     62     SkASSERT(factory);
     63     SkASSERT(gCount < (int)SK_ARRAY_COUNT(gEntries));
     64 
     65     gEntries[gCount].fName = name;
     66     gEntries[gCount].fFactory = factory;
     67     gEntries[gCount].fType = type;
     68     gCount += 1;
     69 }
     70 
     71 #ifdef SK_DEBUG
     72 static void report_no_entries(const char* functionName) {
     73     if (!gCount) {
     74         SkDebugf("%s has no registered name/factory/type entries."
     75                  " Call SkFlattenable::InitializeFlattenablesIfNeeded() before using gEntries",
     76                  functionName);
     77     }
     78 }
     79 #endif
     80 
     81 SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
     82     InitializeFlattenablesIfNeeded();
     83 #ifdef SK_DEBUG
     84     report_no_entries(__FUNCTION__);
     85 #endif
     86     const Entry* entries = gEntries;
     87     for (int i = gCount - 1; i >= 0; --i) {
     88         if (strcmp(entries[i].fName, name) == 0) {
     89             return entries[i].fFactory;
     90         }
     91     }
     92     return nullptr;
     93 }
     94 
     95 bool SkFlattenable::NameToType(const char name[], SkFlattenable::Type* type) {
     96     SkASSERT(type);
     97     InitializeFlattenablesIfNeeded();
     98 #ifdef SK_DEBUG
     99     report_no_entries(__FUNCTION__);
    100 #endif
    101     const Entry* entries = gEntries;
    102     for (int i = gCount - 1; i >= 0; --i) {
    103         if (strcmp(entries[i].fName, name) == 0) {
    104             *type = entries[i].fType;
    105             return true;
    106         }
    107     }
    108     return false;
    109 }
    110 
    111 const char* SkFlattenable::FactoryToName(Factory fact) {
    112     InitializeFlattenablesIfNeeded();
    113 #ifdef SK_DEBUG
    114     report_no_entries(__FUNCTION__);
    115 #endif
    116     const Entry* entries = gEntries;
    117     for (int i = gCount - 1; i >= 0; --i) {
    118         if (entries[i].fFactory == fact) {
    119             return entries[i].fName;
    120         }
    121     }
    122     return nullptr;
    123 }
    124