| OLD | NEW |
| (Empty) |
| 1 /* libs/corecg/SkChunkAlloc.cpp | |
| 2 ** | |
| 3 ** Copyright 2006, The Android Open Source Project | |
| 4 ** | |
| 5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
| 6 ** you may not use this file except in compliance with the License. | |
| 7 ** You may obtain a copy of the License at | |
| 8 ** | |
| 9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 ** | |
| 11 ** Unless required by applicable law or agreed to in writing, software | |
| 12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 ** See the License for the specific language governing permissions and | |
| 15 ** limitations under the License. | |
| 16 */ | |
| 17 | |
| 18 #include "SkChunkAlloc.h" | |
| 19 | |
| 20 struct SkChunkAlloc::Block { | |
| 21 Block* fNext; | |
| 22 size_t fFreeSize; | |
| 23 char* fFreePtr; | |
| 24 // data[] follows | |
| 25 | |
| 26 void freeChain() { // this can be null | |
| 27 Block* block = this; | |
| 28 while (block) { | |
| 29 Block* next = block->fNext; | |
| 30 sk_free(block); | |
| 31 block = next; | |
| 32 } | |
| 33 }; | |
| 34 | |
| 35 Block* tail() { | |
| 36 Block* block = this; | |
| 37 if (block) { | |
| 38 for (;;) { | |
| 39 Block* next = block->fNext; | |
| 40 if (NULL == next) { | |
| 41 break; | |
| 42 } | |
| 43 block = next; | |
| 44 } | |
| 45 } | |
| 46 return block; | |
| 47 } | |
| 48 }; | |
| 49 | |
| 50 SkChunkAlloc::SkChunkAlloc(size_t minSize) | |
| 51 : fBlock(NULL), fMinSize(SkAlign4(minSize)), fPool(NULL), fTotalCapacity(0) | |
| 52 { | |
| 53 } | |
| 54 | |
| 55 SkChunkAlloc::~SkChunkAlloc() { | |
| 56 this->reset(); | |
| 57 } | |
| 58 | |
| 59 void SkChunkAlloc::reset() { | |
| 60 fBlock->freeChain(); | |
| 61 fBlock = NULL; | |
| 62 fPool->freeChain(); | |
| 63 fPool = NULL; | |
| 64 fTotalCapacity = 0; | |
| 65 } | |
| 66 | |
| 67 void SkChunkAlloc::reuse() { | |
| 68 if (fPool && fBlock) { | |
| 69 fPool->tail()->fNext = fBlock; | |
| 70 } | |
| 71 fPool = fBlock; | |
| 72 fBlock = NULL; | |
| 73 fTotalCapacity = 0; | |
| 74 } | |
| 75 | |
| 76 SkChunkAlloc::Block* SkChunkAlloc::newBlock(size_t bytes, AllocFailType ftype) { | |
| 77 Block* block = fPool; | |
| 78 | |
| 79 if (block && bytes <= block->fFreeSize) { | |
| 80 fPool = block->fNext; | |
| 81 return block; | |
| 82 } | |
| 83 | |
| 84 size_t size = SkMax32((int32_t)bytes, (int32_t)fMinSize); | |
| 85 | |
| 86 block = (Block*)sk_malloc_flags(sizeof(Block) + size, | |
| 87 ftype == kThrow_AllocFailType ? SK_MALLOC_THROW : 0); | |
| 88 | |
| 89 if (block) { | |
| 90 // block->fNext = fBlock; | |
| 91 block->fFreeSize = size; | |
| 92 block->fFreePtr = (char*)block + sizeof(Block); | |
| 93 | |
| 94 fTotalCapacity += size; | |
| 95 } | |
| 96 return block; | |
| 97 } | |
| 98 | |
| 99 void* SkChunkAlloc::alloc(size_t bytes, AllocFailType ftype) { | |
| 100 bytes = SkAlign4(bytes); | |
| 101 | |
| 102 Block* block = fBlock; | |
| 103 | |
| 104 if (block == NULL || bytes > block->fFreeSize) { | |
| 105 block = this->newBlock(bytes, ftype); | |
| 106 if (NULL == block) { | |
| 107 return NULL; | |
| 108 } | |
| 109 block->fNext = fBlock; | |
| 110 fBlock = block; | |
| 111 } | |
| 112 | |
| 113 SkASSERT(block && bytes <= block->fFreeSize); | |
| 114 void* ptr = block->fFreePtr; | |
| 115 | |
| 116 block->fFreeSize -= bytes; | |
| 117 block->fFreePtr += bytes; | |
| 118 return ptr; | |
| 119 } | |
| 120 | |
| OLD | NEW |