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

Side by Side Diff: src/core/SkChunkAlloc.cpp

Issue 940533003: Decrease GrInOrderDrawBuffer::Cmd's reliance on GrInOrderDrawBuffer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix bug and add unit test Created 5 years, 10 months 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 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
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 "SkChunkAlloc.h" 8 #include "SkChunkAlloc.h"
9 9
10 // Don't malloc any chunks smaller than this 10 // Don't malloc any chunks smaller than this
11 #define MIN_CHUNKALLOC_BLOCK_SIZE 1024 11 #define MIN_CHUNKALLOC_BLOCK_SIZE 1024
12 12
13 // Return the new min blocksize given the current value 13 // Return the new min blocksize given the current value
14 static size_t increase_next_size(size_t size) { 14 static size_t increase_next_size(size_t size) {
15 return size + (size >> 1); 15 return size + (size >> 1);
16 } 16 }
17 17
18 /////////////////////////////////////////////////////////////////////////////// 18 ///////////////////////////////////////////////////////////////////////////////
19 19
20 struct SkChunkAlloc::Block { 20 struct SkChunkAlloc::Block {
21 Block* fNext; 21 Block* fNext;
22 size_t fFreeSize; 22 size_t fFreeSize;
23 char* fFreePtr; 23 char* fFreePtr;
24 // data[] follows 24 // data[] follows
25 25
26 size_t blockSize() {
27 char* start = this->startOfData();
28 size_t bytes = fFreePtr - start;
29 return fFreeSize + bytes;
30 }
31
32 void reset() {
33 fNext = NULL;
34 fFreeSize = this->blockSize();
35 fFreePtr = this->startOfData();
36 }
37
26 char* startOfData() { 38 char* startOfData() {
27 return reinterpret_cast<char*>(this + 1); 39 return reinterpret_cast<char*>(this + 1);
28 } 40 }
29 41
30 static void FreeChain(Block* block) { 42 static void FreeChain(Block* block) {
31 while (block) { 43 while (block) {
32 Block* next = block->fNext; 44 Block* next = block->fNext;
33 sk_free(block); 45 sk_free(block);
34 block = next; 46 block = next;
35 } 47 }
(...skipping 26 matching lines...) Expand all
62 74
63 void SkChunkAlloc::reset() { 75 void SkChunkAlloc::reset() {
64 Block::FreeChain(fBlock); 76 Block::FreeChain(fBlock);
65 fBlock = NULL; 77 fBlock = NULL;
66 fChunkSize = fMinSize; // reset to our initial minSize 78 fChunkSize = fMinSize; // reset to our initial minSize
67 fTotalCapacity = 0; 79 fTotalCapacity = 0;
68 fTotalUsed = 0; 80 fTotalUsed = 0;
69 fBlockCount = 0; 81 fBlockCount = 0;
70 } 82 }
71 83
84 void SkChunkAlloc::rewind() {
85 Block* largest = fBlock;
86
87 if (largest) {
88 Block* next;
89 for (Block* cur = largest->fNext; cur; cur = next) {
90 next = cur->fNext;
91 if (cur->blockSize() > largest->blockSize()) {
92 sk_free(largest);
93 largest = cur;
94 } else {
95 sk_free(cur);
96 }
97 }
98
99 largest->reset();
100 fTotalCapacity = largest->blockSize();
101 fBlockCount = 1;
102 } else {
103 fTotalCapacity = 0;
104 fBlockCount = 0;
105 }
106
107 fBlock = largest;
108 fChunkSize = fMinSize; // reset to our initial minSize
109 fTotalUsed = 0;
110 }
111
72 SkChunkAlloc::Block* SkChunkAlloc::newBlock(size_t bytes, AllocFailType ftype) { 112 SkChunkAlloc::Block* SkChunkAlloc::newBlock(size_t bytes, AllocFailType ftype) {
73 size_t size = bytes; 113 size_t size = bytes;
74 if (size < fChunkSize) { 114 if (size < fChunkSize) {
75 size = fChunkSize; 115 size = fChunkSize;
76 } 116 }
77 117
78 Block* block = (Block*)sk_malloc_flags(sizeof(Block) + size, 118 Block* block = (Block*)sk_malloc_flags(sizeof(Block) + size,
79 ftype == kThrow_AllocFailType ? SK_MALLOC_THROW : 0); 119 ftype == kThrow_AllocFailType ? SK_MALLOC_THROW : 0);
80 120
81 if (block) { 121 if (block) {
82 // block->fNext = fBlock;
83 block->fFreeSize = size; 122 block->fFreeSize = size;
84 block->fFreePtr = block->startOfData(); 123 block->fFreePtr = block->startOfData();
85 124
86 fTotalCapacity += size; 125 fTotalCapacity += size;
87 fBlockCount += 1; 126 fBlockCount += 1;
88 127
89 fChunkSize = increase_next_size(fChunkSize); 128 fChunkSize = increase_next_size(fChunkSize);
90 } 129 }
91 return block; 130 return block;
92 } 131 }
93 132
133 SkChunkAlloc::Block* SkChunkAlloc::addBlockIfNecessary(size_t bytes, AllocFailTy pe ftype) {
134 SkASSERT(SkIsAlign4(bytes));
135
136 if (!fBlock || bytes > fBlock->fFreeSize) {
137 Block* block = this->newBlock(bytes, ftype);
138 if (!block) {
139 return NULL;
140 }
141 block->fNext = fBlock;
142 fBlock = block;
143 }
144
145 SkASSERT(fBlock && bytes <= fBlock->fFreeSize);
146 return fBlock;
147 }
148
149 void SkChunkAlloc::preAlloc(size_t bytes) {
150 bytes = SkAlign4(bytes);
151
152 this->addBlockIfNecessary(bytes, kReturnNil_AllocFailType);
153 }
154
94 void* SkChunkAlloc::alloc(size_t bytes, AllocFailType ftype) { 155 void* SkChunkAlloc::alloc(size_t bytes, AllocFailType ftype) {
95 fTotalUsed += bytes; 156 fTotalUsed += bytes;
96 157
97 bytes = SkAlign4(bytes); 158 bytes = SkAlign4(bytes);
98 159
99 Block* block = fBlock; 160 Block* block = this->addBlockIfNecessary(bytes, ftype);
100 161 if (!block) {
101 if (block == NULL || bytes > block->fFreeSize) { 162 return NULL;
102 block = this->newBlock(bytes, ftype);
103 if (NULL == block) {
104 return NULL;
105 }
106 block->fNext = fBlock;
107 fBlock = block;
108 } 163 }
109 164
110 SkASSERT(block && bytes <= block->fFreeSize);
111 char* ptr = block->fFreePtr; 165 char* ptr = block->fFreePtr;
112 166
113 block->fFreeSize -= bytes; 167 block->fFreeSize -= bytes;
114 block->fFreePtr = ptr + bytes; 168 block->fFreePtr = ptr + bytes;
115 return ptr; 169 return ptr;
116 } 170 }
117 171
118 size_t SkChunkAlloc::unalloc(void* ptr) { 172 size_t SkChunkAlloc::unalloc(void* ptr) {
119 size_t bytes = 0; 173 size_t bytes = 0;
120 Block* block = fBlock; 174 Block* block = fBlock;
121 if (block) { 175 if (block) {
122 char* cPtr = reinterpret_cast<char*>(ptr); 176 char* cPtr = reinterpret_cast<char*>(ptr);
123 char* start = block->startOfData(); 177 char* start = block->startOfData();
124 if (start <= cPtr && cPtr < block->fFreePtr) { 178 if (start <= cPtr && cPtr < block->fFreePtr) {
125 bytes = block->fFreePtr - cPtr; 179 bytes = block->fFreePtr - cPtr;
180 fTotalUsed -= bytes;
126 block->fFreeSize += bytes; 181 block->fFreeSize += bytes;
127 block->fFreePtr = cPtr; 182 block->fFreePtr = cPtr;
128 } 183 }
129 } 184 }
130 return bytes; 185 return bytes;
131 } 186 }
132 187
133 bool SkChunkAlloc::contains(const void* addr) const { 188 bool SkChunkAlloc::contains(const void* addr) const {
134 const Block* block = fBlock; 189 const Block* block = fBlock;
135 while (block) { 190 while (block) {
136 if (block->contains(addr)) { 191 if (block->contains(addr)) {
137 return true; 192 return true;
138 } 193 }
139 block = block->fNext; 194 block = block->fNext;
140 } 195 }
141 return false; 196 return false;
142 } 197 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698