1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
79fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFlattenable.h"
9227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org#include "SkPtrRecorder.h"
109fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#include "SkReadBuffer.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com///////////////////////////////////////////////////////////////////////////////
13f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com
149fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
159fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedbool SkFlattenable::NeedsDeepUnflatten(const SkReadBuffer& buffer) {
169fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    return buffer.isVersionLT(SkReadBuffer::kFlattenCreateProc_Version);
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
189fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
220c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.comSkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {}
230c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
240c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.comuint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) {
250c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    uint32_t index = fFactorySet.find(factory);
260c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    if (index > 0) {
270c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        return index;
280c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    }
290c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    const char* name = SkFlattenable::FactoryToName(factory);
300c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    if (NULL == name) {
310c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        return 0;
320c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    }
330c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    *fNames.append() = name;
340c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    return fFactorySet.add(factory);
350c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com}
360c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
370c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.comconst char* SkNamedFactorySet::getNextAddedFactoryName() {
380c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    if (fNextAddedFactory < fNames.count()) {
390c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        return fNames[fNextAddedFactory++];
400c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    }
410c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    return NULL;
420c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com}
430c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
440c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com///////////////////////////////////////////////////////////////////////////////
450c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
46e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgSkRefCntSet::~SkRefCntSet() {
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // call this now, while our decPtr() is sill in scope
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->reset();
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
51e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgvoid SkRefCntSet::incPtr(void* ptr) {
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    ((SkRefCnt*)ptr)->ref();
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
55e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgvoid SkRefCntSet::decPtr(void* ptr) {
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    ((SkRefCnt*)ptr)->unref();
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
63c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#define MAX_ENTRY_COUNT  1024
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
65c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.orgstruct Entry {
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const char*             fName;
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFlattenable::Factory  fFactory;
68c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    SkFlattenable::Type     fType;
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic int gCount;
72c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.orgstatic Entry gEntries[MAX_ENTRY_COUNT];
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
74c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.orgvoid SkFlattenable::Register(const char name[], Factory factory, SkFlattenable::Type type) {
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(name);
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(factory);
7782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
78c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    static bool gOnce = false;
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (!gOnce) {
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        gCount = 0;
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        gOnce = true;
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
8382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
84c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    SkASSERT(gCount < MAX_ENTRY_COUNT);
8582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
86c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    gEntries[gCount].fName = name;
87c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    gEntries[gCount].fFactory = factory;
88c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    gEntries[gCount].fType = type;
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    gCount += 1;
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
92a0c2bc24381fea063008f9c8823756eb020603b3scroggo@google.com#ifdef SK_DEBUG
93d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comstatic void report_no_entries(const char* functionName) {
94d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    if (!gCount) {
95c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org        SkDebugf("%s has no registered name/factory/type entries."
96c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org                 " Call SkFlattenable::InitializeFlattenablesIfNeeded() before using gEntries",
979245498e40399199ed6d32aa67fe028b634cc582caryclark@google.com                 functionName);
98d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    }
99d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com}
100d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#endif
101d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
103c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    InitializeFlattenablesIfNeeded();
104a0c2bc24381fea063008f9c8823756eb020603b3scroggo@google.com#ifdef SK_DEBUG
105d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    report_no_entries(__FUNCTION__);
106d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#endif
107c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    const Entry* entries = gEntries;
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = gCount - 1; i >= 0; --i) {
109c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org        if (strcmp(entries[i].fName, name) == 0) {
110c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org            return entries[i].fFactory;
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
116c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.orgbool SkFlattenable::NameToType(const char name[], SkFlattenable::Type* type) {
11749f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(type);
118c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    InitializeFlattenablesIfNeeded();
119c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#ifdef SK_DEBUG
120c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    report_no_entries(__FUNCTION__);
121c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#endif
122c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    const Entry* entries = gEntries;
123c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    for (int i = gCount - 1; i >= 0; --i) {
124c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org        if (strcmp(entries[i].fName, name) == 0) {
125c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org            *type = entries[i].fType;
126c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org            return true;
127c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org        }
128c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    }
129c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    return false;
130c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org}
131c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkFlattenable::FactoryToName(Factory fact) {
133c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    InitializeFlattenablesIfNeeded();
134a0c2bc24381fea063008f9c8823756eb020603b3scroggo@google.com#ifdef SK_DEBUG
135d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    report_no_entries(__FUNCTION__);
136d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#endif
137c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    const Entry* entries = gEntries;
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = gCount - 1; i >= 0; --i) {
139c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org        if (entries[i].fFactory == fact) {
140c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org            return entries[i].fName;
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
145