1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPathHeap.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h"
118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h"
128c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org#include "SkTSearch.h"
138b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <new>
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kPathCount  64
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkPathHeap::SkPathHeap() : fHeap(kPathCount * sizeof(SkPath)) {
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
218b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkPathHeap::SkPathHeap(SkReadBuffer& buffer)
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            : fHeap(kPathCount * sizeof(SkPath)) {
23c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com    const int count = buffer.readInt();
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fPaths.setCount(count);
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath** ptr = fPaths.begin();
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath* p = (SkPath*)fHeap.allocThrow(count * sizeof(SkPath));
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < count; i++) {
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        new (p) SkPath;
312b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        buffer.readPath(p);
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *ptr++ = p; // record the pointer
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        p++;        // move to the next storage location
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkPathHeap::~SkPathHeap() {
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath** iter = fPaths.begin();
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath** stop = fPaths.end();
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (iter < stop) {
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        (*iter)->~SkPath();
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        iter++;
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkPathHeap::append(const SkPath& path) {
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath* p = (SkPath*)fHeap.allocThrow(sizeof(SkPath));
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    new (p) SkPath(path);
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *fPaths.append() = p;
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return fPaths.count();
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
53e62513fb9274b65bcd9fecf61acc418dd3949df5skia.committer@gmail.comSkPathHeap::LookupEntry::LookupEntry(const SkPath& path)
548c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    : fGenerationID(path.getGenerationID()), fStorageSlot(0) {
558c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org}
568c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org
578c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.orgSkPathHeap::LookupEntry* SkPathHeap::addIfNotPresent(const SkPath& path) {
588c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    LookupEntry searchKey(path);
598c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    int index = SkTSearch<const LookupEntry, LookupEntry::Less>(
608c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org                                    fLookupTable.begin(),
618c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org                                    fLookupTable.count(),
62e62513fb9274b65bcd9fecf61acc418dd3949df5skia.committer@gmail.com                                    searchKey,
638c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org                                    sizeof(LookupEntry));
648c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    if (index < 0) {
658c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org        index = ~index;
668c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org        *fLookupTable.insert(index) = LookupEntry(path);
678c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    }
688c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org
698c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    return &fLookupTable[index];;
708c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org}
718c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org
728c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.orgint SkPathHeap::insert(const SkPath& path) {
738c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    SkPathHeap::LookupEntry* entry = this->addIfNotPresent(path);
748c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org
758c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    if (entry->storageSlot() > 0) {
768c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org        return entry->storageSlot();
778c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    }
788c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org
798c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    int newSlot = this->append(path);
808c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    SkASSERT(newSlot > 0);
818c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    entry->setStorageSlot(newSlot);
828c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org    return newSlot;
838c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org}
848c2ee5963505cdbe128f68d67f064a3901d22a3ccommit-bot@chromium.org
858b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkPathHeap::flatten(SkWriteBuffer& buffer) const {
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int count = fPaths.count();
87fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
88c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com    buffer.writeInt(count);
89aa537d4bdb2384cdcd0644a02a2ab7fb0ecdd3b3commit-bot@chromium.org    SkPath* const* iter = fPaths.begin();
90aa537d4bdb2384cdcd0644a02a2ab7fb0ecdd3b3commit-bot@chromium.org    SkPath* const* stop = fPaths.end();
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (iter < stop) {
922b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        buffer.writePath(**iter);
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        iter++;
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
96