Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(335)

Side by Side Diff: src/gpu/GrMemoryPool.cpp

Issue 2525773002: Make GrMemoryPool play nice with bucketing allocators. (Closed)
Patch Set: Proper naming; kill friend Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrMemoryPool.h" 8 #include "GrMemoryPool.h"
9 9
10 #ifdef SK_DEBUG 10 #ifdef SK_DEBUG
11 #define VALIDATE this->validate() 11 #define VALIDATE this->validate()
12 #else 12 #else
13 #define VALIDATE 13 #define VALIDATE
14 #endif 14 #endif
15 15
16 constexpr size_t GrMemoryPool::kSmallestMinAllocSize;
17
16 GrMemoryPool::GrMemoryPool(size_t preallocSize, size_t minAllocSize) { 18 GrMemoryPool::GrMemoryPool(size_t preallocSize, size_t minAllocSize) {
17 SkDEBUGCODE(fAllocationCnt = 0); 19 SkDEBUGCODE(fAllocationCnt = 0);
18 SkDEBUGCODE(fAllocBlockCnt = 0); 20 SkDEBUGCODE(fAllocBlockCnt = 0);
19 21
20 minAllocSize = SkTMax<size_t>(minAllocSize, 1 << 10); 22 minAllocSize = SkTMax<size_t>(GrSizeAlignUp(minAllocSize, kAlignment), kSmal lestMinAllocSize);
21 fMinAllocSize = GrSizeAlignUp(minAllocSize + kPerAllocPad, kAlignment); 23 preallocSize = SkTMax<size_t>(GrSizeAlignUp(preallocSize, kAlignment), minAl locSize);
22 fPreallocSize = GrSizeAlignUp(preallocSize + kPerAllocPad, kAlignment); 24
23 fPreallocSize = SkTMax(fPreallocSize, fMinAllocSize); 25 fMinAllocSize = minAllocSize;
24 fSize = 0; 26 fSize = 0;
25 27
26 fHead = CreateBlock(fPreallocSize); 28 fHead = CreateBlock(preallocSize);
27 fTail = fHead; 29 fTail = fHead;
28 fHead->fNext = nullptr; 30 fHead->fNext = nullptr;
29 fHead->fPrev = nullptr; 31 fHead->fPrev = nullptr;
30 VALIDATE; 32 VALIDATE;
31 }; 33 };
32 34
33 GrMemoryPool::~GrMemoryPool() { 35 GrMemoryPool::~GrMemoryPool() {
34 VALIDATE; 36 VALIDATE;
35 SkASSERT(0 == fAllocationCnt); 37 SkASSERT(0 == fAllocationCnt);
36 SkASSERT(fHead == fTail); 38 SkASSERT(fHead == fTail);
37 SkASSERT(0 == fHead->fLiveCount); 39 SkASSERT(0 == fHead->fLiveCount);
38 DeleteBlock(fHead); 40 DeleteBlock(fHead);
39 }; 41 };
40 42
41 void* GrMemoryPool::allocate(size_t size) { 43 void* GrMemoryPool::allocate(size_t size) {
42 VALIDATE; 44 VALIDATE;
43 size += kPerAllocPad; 45 size += kPerAllocPad;
44 size = GrSizeAlignUp(size, kAlignment); 46 size = GrSizeAlignUp(size, kAlignment);
45 if (fTail->fFreeSize < size) { 47 if (fTail->fFreeSize < size) {
46 size_t blockSize = size; 48 size_t blockSize = size + kHeaderSize;
47 blockSize = SkTMax<size_t>(blockSize, fMinAllocSize); 49 blockSize = SkTMax<size_t>(blockSize, fMinAllocSize);
48 BlockHeader* block = CreateBlock(blockSize); 50 BlockHeader* block = CreateBlock(blockSize);
49 51
50 block->fPrev = fTail; 52 block->fPrev = fTail;
51 block->fNext = nullptr; 53 block->fNext = nullptr;
52 SkASSERT(nullptr == fTail->fNext); 54 SkASSERT(nullptr == fTail->fNext);
53 fTail->fNext = block; 55 fTail->fNext = block;
54 fTail = block; 56 fTail = block;
55 fSize += block->fSize; 57 fSize += block->fSize;
56 SkDEBUGCODE(++fAllocBlockCnt); 58 SkDEBUGCODE(++fAllocBlockCnt);
(...skipping 23 matching lines...) Expand all
80 AllocHeader* allocData = reinterpret_cast<AllocHeader*>(ptr); 82 AllocHeader* allocData = reinterpret_cast<AllocHeader*>(ptr);
81 SkASSERT(kAssignedMarker == allocData->fSentinal); 83 SkASSERT(kAssignedMarker == allocData->fSentinal);
82 SkDEBUGCODE(allocData->fSentinal = kFreedMarker); 84 SkDEBUGCODE(allocData->fSentinal = kFreedMarker);
83 BlockHeader* block = allocData->fHeader; 85 BlockHeader* block = allocData->fHeader;
84 SkASSERT(kAssignedMarker == block->fBlockSentinal); 86 SkASSERT(kAssignedMarker == block->fBlockSentinal);
85 if (1 == block->fLiveCount) { 87 if (1 == block->fLiveCount) {
86 // the head block is special, it is reset rather than deleted 88 // the head block is special, it is reset rather than deleted
87 if (fHead == block) { 89 if (fHead == block) {
88 fHead->fCurrPtr = reinterpret_cast<intptr_t>(fHead) + kHeaderSize; 90 fHead->fCurrPtr = reinterpret_cast<intptr_t>(fHead) + kHeaderSize;
89 fHead->fLiveCount = 0; 91 fHead->fLiveCount = 0;
90 fHead->fFreeSize = fPreallocSize; 92 fHead->fFreeSize = fHead->fSize - kHeaderSize;
91 } else { 93 } else {
92 BlockHeader* prev = block->fPrev; 94 BlockHeader* prev = block->fPrev;
93 BlockHeader* next = block->fNext; 95 BlockHeader* next = block->fNext;
94 SkASSERT(prev); 96 SkASSERT(prev);
95 prev->fNext = next; 97 prev->fNext = next;
96 if (next) { 98 if (next) {
97 next->fPrev = prev; 99 next->fPrev = prev;
98 } else { 100 } else {
99 SkASSERT(fTail == block); 101 SkASSERT(fTail == block);
100 fTail = prev; 102 fTail = prev;
101 } 103 }
102 fSize -= block->fSize; 104 fSize -= block->fSize;
103 DeleteBlock(block); 105 DeleteBlock(block);
104 SkDEBUGCODE(fAllocBlockCnt--); 106 SkDEBUGCODE(fAllocBlockCnt--);
105 } 107 }
106 } else { 108 } else {
107 --block->fLiveCount; 109 --block->fLiveCount;
108 // Trivial reclaim: if we're releasing the most recent allocation, reuse it 110 // Trivial reclaim: if we're releasing the most recent allocation, reuse it
109 if (block->fPrevPtr == ptr) { 111 if (block->fPrevPtr == ptr) {
110 block->fFreeSize += (block->fCurrPtr - block->fPrevPtr); 112 block->fFreeSize += (block->fCurrPtr - block->fPrevPtr);
111 block->fCurrPtr = block->fPrevPtr; 113 block->fCurrPtr = block->fPrevPtr;
112 } 114 }
113 } 115 }
114 SkDEBUGCODE(--fAllocationCnt); 116 SkDEBUGCODE(--fAllocationCnt);
115 VALIDATE; 117 VALIDATE;
116 } 118 }
117 119
118 GrMemoryPool::BlockHeader* GrMemoryPool::CreateBlock(size_t size) { 120 GrMemoryPool::BlockHeader* GrMemoryPool::CreateBlock(size_t blockSize) {
119 size_t paddedSize = size + kHeaderSize; 121 blockSize = SkTMax<size_t>(blockSize, kHeaderSize);
120 BlockHeader* block = 122 BlockHeader* block =
121 reinterpret_cast<BlockHeader*>(sk_malloc_throw(paddedSize)); 123 reinterpret_cast<BlockHeader*>(sk_malloc_throw(blockSize));
122 // we assume malloc gives us aligned memory 124 // we assume malloc gives us aligned memory
123 SkASSERT(!(reinterpret_cast<intptr_t>(block) % kAlignment)); 125 SkASSERT(!(reinterpret_cast<intptr_t>(block) % kAlignment));
124 SkDEBUGCODE(block->fBlockSentinal = kAssignedMarker); 126 SkDEBUGCODE(block->fBlockSentinal = kAssignedMarker);
125 block->fLiveCount = 0; 127 block->fLiveCount = 0;
126 block->fFreeSize = size; 128 block->fFreeSize = blockSize - kHeaderSize;
127 block->fCurrPtr = reinterpret_cast<intptr_t>(block) + kHeaderSize; 129 block->fCurrPtr = reinterpret_cast<intptr_t>(block) + kHeaderSize;
128 block->fPrevPtr = 0; // gcc warns on assigning nullptr to an intptr_t. 130 block->fPrevPtr = 0; // gcc warns on assigning nullptr to an intptr_t.
129 block->fSize = paddedSize; 131 block->fSize = blockSize;
130 return block; 132 return block;
131 } 133 }
132 134
133 void GrMemoryPool::DeleteBlock(BlockHeader* block) { 135 void GrMemoryPool::DeleteBlock(BlockHeader* block) {
134 SkASSERT(kAssignedMarker == block->fBlockSentinal); 136 SkASSERT(kAssignedMarker == block->fBlockSentinal);
135 SkDEBUGCODE(block->fBlockSentinal = kFreedMarker); // FWIW 137 SkDEBUGCODE(block->fBlockSentinal = kFreedMarker); // FWIW
136 sk_free(block); 138 sk_free(block);
137 } 139 }
138 140
139 void GrMemoryPool::validate() { 141 void GrMemoryPool::validate() {
140 #ifdef SK_DEBUG 142 #ifdef SK_DEBUG
141 BlockHeader* block = fHead; 143 BlockHeader* block = fHead;
142 BlockHeader* prev = nullptr; 144 BlockHeader* prev = nullptr;
143 SkASSERT(block); 145 SkASSERT(block);
144 int allocCount = 0; 146 int allocCount = 0;
145 do { 147 do {
146 SkASSERT(kAssignedMarker == block->fBlockSentinal); 148 SkASSERT(kAssignedMarker == block->fBlockSentinal);
147 allocCount += block->fLiveCount; 149 allocCount += block->fLiveCount;
148 SkASSERT(prev == block->fPrev); 150 SkASSERT(prev == block->fPrev);
149 if (prev) { 151 if (prev) {
150 SkASSERT(prev->fNext == block); 152 SkASSERT(prev->fNext == block);
151 } 153 }
152 154
153 intptr_t b = reinterpret_cast<intptr_t>(block); 155 intptr_t b = reinterpret_cast<intptr_t>(block);
154 size_t ptrOffset = block->fCurrPtr - b; 156 size_t ptrOffset = block->fCurrPtr - b;
155 size_t totalSize = ptrOffset + block->fFreeSize; 157 size_t totalSize = ptrOffset + block->fFreeSize;
156 size_t userSize = totalSize - kHeaderSize;
157 intptr_t userStart = b + kHeaderSize; 158 intptr_t userStart = b + kHeaderSize;
158 159
159 SkASSERT(!(b % kAlignment)); 160 SkASSERT(!(b % kAlignment));
160 SkASSERT(!(totalSize % kAlignment)); 161 SkASSERT(!(totalSize % kAlignment));
161 SkASSERT(!(userSize % kAlignment));
162 SkASSERT(!(block->fCurrPtr % kAlignment)); 162 SkASSERT(!(block->fCurrPtr % kAlignment));
163 if (fHead != block) { 163 if (fHead != block) {
164 SkASSERT(block->fLiveCount); 164 SkASSERT(block->fLiveCount);
165 SkASSERT(userSize >= fMinAllocSize); 165 SkASSERT(totalSize >= fMinAllocSize);
166 } else { 166 } else {
167 SkASSERT(userSize == fPreallocSize); 167 SkASSERT(totalSize == block->fSize);
168 } 168 }
169 if (!block->fLiveCount) { 169 if (!block->fLiveCount) {
170 SkASSERT(ptrOffset == kHeaderSize); 170 SkASSERT(ptrOffset == kHeaderSize);
171 SkASSERT(userStart == block->fCurrPtr); 171 SkASSERT(userStart == block->fCurrPtr);
172 } else { 172 } else {
173 AllocHeader* allocData = reinterpret_cast<AllocHeader*>(userStart); 173 AllocHeader* allocData = reinterpret_cast<AllocHeader*>(userStart);
174 SkASSERT(allocData->fSentinal == kAssignedMarker || 174 SkASSERT(allocData->fSentinal == kAssignedMarker ||
175 allocData->fSentinal == kFreedMarker); 175 allocData->fSentinal == kFreedMarker);
176 SkASSERT(block == allocData->fHeader); 176 SkASSERT(block == allocData->fHeader);
177 } 177 }
178 178
179 prev = block; 179 prev = block;
180 } while ((block = block->fNext)); 180 } while ((block = block->fNext));
181 SkASSERT(allocCount == fAllocationCnt); 181 SkASSERT(allocCount == fAllocationCnt);
182 SkASSERT(prev == fTail); 182 SkASSERT(prev == fTail);
183 SkASSERT(fAllocBlockCnt != 0 || fSize == 0); 183 SkASSERT(fAllocBlockCnt != 0 || fSize == 0);
184 #endif 184 #endif
185 } 185 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698