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 #define MAX_ENTRY_COUNT  1024
     52 
     53 struct Entry {
     54     const char*             fName;
     55     SkFlattenable::Factory  fFactory;
     56     SkFlattenable::Type     fType;
     57 };
     58 
     59 static int gCount = 0;
     60 static Entry gEntries[MAX_ENTRY_COUNT];
     61 
     62 void SkFlattenable::Register(const char name[], Factory factory, SkFlattenable::Type type) {
     63     SkASSERT(name);
     64     SkASSERT(factory);
     65     SkASSERT(gCount < MAX_ENTRY_COUNT);
     66 
     67     gEntries[gCount].fName = name;
     68     gEntries[gCount].fFactory = factory;
     69     gEntries[gCount].fType = type;
     70     gCount += 1;
     71 }
     72 
     73 #ifdef SK_DEBUG
     74 static void report_no_entries(const char* functionName) {
     75     if (!gCount) {
     76         SkDebugf("%s has no registered name/factory/type entries."
     77                  " Call SkFlattenable::InitializeFlattenablesIfNeeded() before using gEntries",
     78                  functionName);
     79     }
     80 }
     81 #endif
     82 
     83 SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
     84     InitializeFlattenablesIfNeeded();
     85 #ifdef SK_DEBUG
     86     report_no_entries(__FUNCTION__);
     87 #endif
     88     const Entry* entries = gEntries;
     89     for (int i = gCount - 1; i >= 0; --i) {
     90         if (strcmp(entries[i].fName, name) == 0) {
     91             return entries[i].fFactory;
     92         }
     93     }
     94     return nullptr;
     95 }
     96 
     97 bool SkFlattenable::NameToType(const char name[], SkFlattenable::Type* type) {
     98     SkASSERT(type);
     99     InitializeFlattenablesIfNeeded();
    100 #ifdef SK_DEBUG
    101     report_no_entries(__FUNCTION__);
    102 #endif
    103     const Entry* entries = gEntries;
    104     for (int i = gCount - 1; i >= 0; --i) {
    105         if (strcmp(entries[i].fName, name) == 0) {
    106             *type = entries[i].fType;
    107             return true;
    108         }
    109     }
    110     return false;
    111 }
    112 
    113 const char* SkFlattenable::FactoryToName(Factory fact) {
    114     InitializeFlattenablesIfNeeded();
    115 #ifdef SK_DEBUG
    116     report_no_entries(__FUNCTION__);
    117 #endif
    118     const Entry* entries = gEntries;
    119     for (int i = gCount - 1; i >= 0; --i) {
    120         if (entries[i].fFactory == fact) {
    121             return entries[i].fName;
    122         }
    123     }
    124     return nullptr;
    125 }
    126