michael@0: michael@0: /* michael@0: * Copyright 2011 Google Inc. 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: #include "SkFlattenable.h" michael@0: #include "SkPtrRecorder.h" michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: void SkFlattenable::flatten(SkWriteBuffer&) const michael@0: { michael@0: /* we don't write anything at the moment, but this allows our subclasses michael@0: to not know that, since we want them to always call INHERITED::flatten() michael@0: in their code. michael@0: */ michael@0: } michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {} michael@0: michael@0: uint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) { michael@0: uint32_t index = fFactorySet.find(factory); michael@0: if (index > 0) { michael@0: return index; michael@0: } michael@0: const char* name = SkFlattenable::FactoryToName(factory); michael@0: if (NULL == name) { michael@0: return 0; michael@0: } michael@0: *fNames.append() = name; michael@0: return fFactorySet.add(factory); michael@0: } michael@0: michael@0: const char* SkNamedFactorySet::getNextAddedFactoryName() { michael@0: if (fNextAddedFactory < fNames.count()) { michael@0: return fNames[fNextAddedFactory++]; michael@0: } michael@0: return NULL; michael@0: } michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: SkRefCntSet::~SkRefCntSet() { michael@0: // call this now, while our decPtr() is sill in scope michael@0: this->reset(); michael@0: } michael@0: michael@0: void SkRefCntSet::incPtr(void* ptr) { michael@0: ((SkRefCnt*)ptr)->ref(); michael@0: } michael@0: michael@0: void SkRefCntSet::decPtr(void* ptr) { michael@0: ((SkRefCnt*)ptr)->unref(); michael@0: } michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: #define MAX_ENTRY_COUNT 1024 michael@0: michael@0: struct Entry { michael@0: const char* fName; michael@0: SkFlattenable::Factory fFactory; michael@0: SkFlattenable::Type fType; michael@0: }; michael@0: michael@0: static int gCount; michael@0: static Entry gEntries[MAX_ENTRY_COUNT]; michael@0: michael@0: void SkFlattenable::Register(const char name[], Factory factory, SkFlattenable::Type type) { michael@0: SkASSERT(name); michael@0: SkASSERT(factory); michael@0: michael@0: static bool gOnce = false; michael@0: if (!gOnce) { michael@0: gCount = 0; michael@0: gOnce = true; michael@0: } michael@0: michael@0: SkASSERT(gCount < MAX_ENTRY_COUNT); michael@0: michael@0: gEntries[gCount].fName = name; michael@0: gEntries[gCount].fFactory = factory; michael@0: gEntries[gCount].fType = type; michael@0: gCount += 1; michael@0: } michael@0: michael@0: #ifdef SK_DEBUG michael@0: static void report_no_entries(const char* functionName) { michael@0: if (!gCount) { michael@0: SkDebugf("%s has no registered name/factory/type entries." michael@0: " Call SkFlattenable::InitializeFlattenablesIfNeeded() before using gEntries", michael@0: functionName); michael@0: } michael@0: } michael@0: #endif michael@0: michael@0: SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { michael@0: InitializeFlattenablesIfNeeded(); michael@0: #ifdef SK_DEBUG michael@0: report_no_entries(__FUNCTION__); michael@0: #endif michael@0: const Entry* entries = gEntries; michael@0: for (int i = gCount - 1; i >= 0; --i) { michael@0: if (strcmp(entries[i].fName, name) == 0) { michael@0: return entries[i].fFactory; michael@0: } michael@0: } michael@0: return NULL; michael@0: } michael@0: michael@0: bool SkFlattenable::NameToType(const char name[], SkFlattenable::Type* type) { michael@0: SkASSERT(NULL != type); michael@0: InitializeFlattenablesIfNeeded(); michael@0: #ifdef SK_DEBUG michael@0: report_no_entries(__FUNCTION__); michael@0: #endif michael@0: const Entry* entries = gEntries; michael@0: for (int i = gCount - 1; i >= 0; --i) { michael@0: if (strcmp(entries[i].fName, name) == 0) { michael@0: *type = entries[i].fType; michael@0: return true; michael@0: } michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: const char* SkFlattenable::FactoryToName(Factory fact) { michael@0: InitializeFlattenablesIfNeeded(); michael@0: #ifdef SK_DEBUG michael@0: report_no_entries(__FUNCTION__); michael@0: #endif michael@0: const Entry* entries = gEntries; michael@0: for (int i = gCount - 1; i >= 0; --i) { michael@0: if (entries[i].fFactory == fact) { michael@0: return entries[i].fName; michael@0: } michael@0: } michael@0: return NULL; michael@0: }