180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2010 Google Inc.
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef GrAllocator_DEFINED
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GrAllocator_DEFINED
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrConfig.h"
120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "GrTypes.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTArray.h"
140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkTypes.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass GrAllocator : public SkNoncopyable {
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    ~GrAllocator() {
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        reset();
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Create an allocator
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @param   itemSize        the size of each item to allocate
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @param   itemsPerBlock   the number of items to allocate at once
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @param   initialBlock    optional memory to use for the first block.
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *                          Must be at least itemSize*itemsPerBlock sized.
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *                          Caller is responsible for freeing this memory.
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrAllocator(size_t itemSize, int itemsPerBlock, void* initialBlock) :
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fItemSize(itemSize),
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fItemsPerBlock(itemsPerBlock),
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fOwnFirstBlock(NULL == initialBlock),
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fCount(0) {
360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkASSERT(itemsPerBlock > 0);
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fBlockSize = fItemSize * fItemsPerBlock;
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fBlocks.push_back() = initialBlock;
390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDEBUGCODE(if (!fOwnFirstBlock) {*((char*)initialBlock+fBlockSize-1)='a';} );
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
42910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    /*
43910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     * Set first block of memory to write into.  Must be called before any other methods.
44910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     * This requires that you have passed NULL in the constructor.
45910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     *
46910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     * @param   initialBlock    optional memory to use for the first block.
47910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     *                          Must be at least itemSize*itemsPerBlock sized.
48910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     *                          Caller is responsible for freeing this memory.
49910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     */
50910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    void setInitialBlock(void* initialBlock) {
51910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        SkASSERT(0 == fCount);
52910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        SkASSERT(1 == fBlocks.count());
53910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        SkASSERT(NULL == fBlocks.back());
54910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        fOwnFirstBlock = false;
55910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        fBlocks.back() = initialBlock;
56910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    }
57910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Adds an item and returns pointer to it.
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @return pointer to the added item.
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void* push_back() {
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int indexInBlock = fCount % fItemsPerBlock;
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // we always have at least one block
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (0 == indexInBlock) {
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (0 != fCount) {
680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                fBlocks.push_back() = sk_malloc_throw(fBlockSize);
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else if (fOwnFirstBlock) {
700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                fBlocks[0] = sk_malloc_throw(fBlockSize);
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        void* ret = (char*)fBlocks[fCount/fItemsPerBlock] +
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    fItemSize * indexInBlock;
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        ++fCount;
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return ret;
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * removes all added items
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void reset() {
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int blockCount = GrMax((unsigned)1,
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                               GrUIDivRoundUp(fCount, fItemsPerBlock));
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int i = 1; i < blockCount; ++i) {
860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            sk_free(fBlocks[i]);
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fOwnFirstBlock) {
890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            sk_free(fBlocks[0]);
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fBlocks[0] = NULL;
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fBlocks.pop_back_n(blockCount-1);
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fCount = 0;
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * count of items
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count() const {
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return fCount;
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * is the count 0
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool empty() const { return fCount == 0; }
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * access last item, only call if count() != 0
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void* back() {
1120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkASSERT(fCount);
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return (*this)[fCount-1];
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * access last item, only call if count() != 0
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const void* back() const {
1200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkASSERT(fCount);
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return (*this)[fCount-1];
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * access item by index.
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void* operator[] (int i) {
1280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkASSERT(i >= 0 && i < fCount);
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return (char*)fBlocks[i / fItemsPerBlock] +
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru               fItemSize * (i % fItemsPerBlock);
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * access item by index.
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const void* operator[] (int i) const {
1370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkASSERT(i >= 0 && i < fCount);
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return (const char*)fBlocks[i / fItemsPerBlock] +
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru               fItemSize * (i % fItemsPerBlock);
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const int NUM_INIT_BLOCK_PTRS = 8;
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSTArray<NUM_INIT_BLOCK_PTRS, void*>   fBlocks;
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t                                  fBlockSize;
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t                                  fItemSize;
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int                                     fItemsPerBlock;
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool                                    fOwnFirstBlock;
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int                                     fCount;
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef SkNoncopyable INHERITED;
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <typename T>
1560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass GrTAllocator : public SkNoncopyable {
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual ~GrTAllocator() { this->reset(); };
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Create an allocator
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @param   itemsPerBlock   the number of items to allocate at once
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    explicit GrTAllocator(int itemsPerBlock)
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        : fAllocator(sizeof(T), itemsPerBlock, NULL) {}
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Adds an item and returns it.
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @return the added item.
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    T& push_back() {
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        void* item = fAllocator.push_back();
1750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkASSERT(NULL != item);
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkNEW_PLACEMENT(item, T);
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return *(T*)item;
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    T& push_back(const T& t) {
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        void* item = fAllocator.push_back();
1820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkASSERT(NULL != item);
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkNEW_PLACEMENT_ARGS(item, T, (t));
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return *(T*)item;
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * removes all added items
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void reset() {
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int c = fAllocator.count();
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int i = 0; i < c; ++i) {
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            ((T*)fAllocator[i])->~T();
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fAllocator.reset();
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * count of items
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count() const {
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return fAllocator.count();
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * is the count 0
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool empty() const { return fAllocator.empty(); }
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * access last item, only call if count() != 0
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    T& back() {
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return *(T*)fAllocator.back();
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * access last item, only call if count() != 0
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const T& back() const {
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return *(const T*)fAllocator.back();
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * access item by index.
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    T& operator[] (int i) {
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return *(T*)(fAllocator[i]);
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * access item by index.
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const T& operator[] (int i) const {
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return *(const T*)(fAllocator[i]);
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected:
239910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    /*
240910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     * Set first block of memory to write into.  Must be called before any other methods.
241910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     *
242910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     * @param   initialBlock    optional memory to use for the first block.
243910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     *                          Must be at least size(T)*itemsPerBlock sized.
244910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     *                          Caller is responsible for freeing this memory.
245910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     */
246910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    void setInitialBlock(void* initialBlock) {
247910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        fAllocator.setInitialBlock(initialBlock);
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrAllocator fAllocator;
2520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef SkNoncopyable INHERITED;
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <int N, typename T> class GrSTAllocator : public GrTAllocator<T> {
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef GrTAllocator<T> INHERITED;
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
260910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    GrSTAllocator() : INHERITED(N) {
261910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        this->setInitialBlock(fStorage.get());
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAlignedSTStorage<N, T> fStorage;
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
269