Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrAllocPool.cpp
1 /*
2  * Copyright 2010 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 "GrAllocPool.h"
9
10 #include "GrTypes.h"
11
12 #define GrAllocPool_MIN_BLOCK_SIZE      ((size_t)128)
13
14 struct GrAllocPool::Block {
15     Block*  fNext;
16     char*   fPtr;
17     size_t  fBytesFree;
18     size_t  fBytesTotal;
19
20     static Block* Create(size_t size, Block* next) {
21         SkASSERT(size >= GrAllocPool_MIN_BLOCK_SIZE);
22
23         Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
24         block->fNext = next;
25         block->fPtr = (char*)block + sizeof(Block);
26         block->fBytesFree = size;
27         block->fBytesTotal = size;
28         return block;
29     }
30
31     bool canAlloc(size_t bytes) const {
32         return bytes <= fBytesFree;
33     }
34
35     void* alloc(size_t bytes) {
36         SkASSERT(bytes <= fBytesFree);
37         fBytesFree -= bytes;
38         void* ptr = fPtr;
39         fPtr += bytes;
40         return ptr;
41     }
42
43     size_t release(size_t bytes) {
44         SkASSERT(bytes > 0);
45         size_t free = SkTMin(bytes, fBytesTotal - fBytesFree);
46         fBytesFree += free;
47         fPtr -= free;
48         return bytes - free;
49     }
50
51     bool empty() const { return fBytesTotal == fBytesFree; }
52 };
53
54 ///////////////////////////////////////////////////////////////////////////////
55
56 GrAllocPool::GrAllocPool(size_t blockSize) {
57     fBlock = NULL;
58     fMinBlockSize = SkTMax(blockSize, GrAllocPool_MIN_BLOCK_SIZE);
59     SkDEBUGCODE(fBlocksAllocated = 0;)
60 }
61
62 GrAllocPool::~GrAllocPool() {
63     this->reset();
64 }
65
66 void GrAllocPool::reset() {
67     this->validate();
68
69     Block* block = fBlock;
70     while (block) {
71         Block* next = block->fNext;
72         sk_free(block);
73         block = next;
74     }
75     fBlock = NULL;
76     SkDEBUGCODE(fBlocksAllocated = 0;)
77 }
78
79 void* GrAllocPool::alloc(size_t size) {
80     this->validate();
81
82     if (!fBlock || !fBlock->canAlloc(size)) {
83         size_t blockSize = SkTMax(fMinBlockSize, size);
84         fBlock = Block::Create(blockSize, fBlock);
85         SkDEBUGCODE(fBlocksAllocated += 1;)
86     }
87     return fBlock->alloc(size);
88 }
89
90 void GrAllocPool::release(size_t bytes) {
91     this->validate();
92
93     while (bytes && fBlock) {
94         bytes = fBlock->release(bytes);
95         if (fBlock->empty()) {
96             Block* next = fBlock->fNext;
97             sk_free(fBlock);
98             fBlock = next;
99             SkDEBUGCODE(fBlocksAllocated -= 1;)
100         }
101     }
102 }
103
104 #ifdef SK_DEBUG
105
106 void GrAllocPool::validate() const {
107     Block* block = fBlock;
108     int count = 0;
109     while (block) {
110         count += 1;
111         block = block->fNext;
112     }
113     SkASSERT(fBlocksAllocated == count);
114 }
115
116 #endif