1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2010 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrAllocPool.h" 9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 10a0b40280a49a8a43af7929ead3b3489951c58501commit-bot@chromium.org#include "GrTypes.h" 11a0b40280a49a8a43af7929ead3b3489951c58501commit-bot@chromium.org 12ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#define GrAllocPool_MIN_BLOCK_SIZE ((size_t)128) 13ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 14ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comstruct GrAllocPool::Block { 15ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Block* fNext; 16ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com char* fPtr; 17ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com size_t fBytesFree; 18ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com size_t fBytesTotal; 19ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 20ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com static Block* Create(size_t size, Block* next) { 21f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(size >= GrAllocPool_MIN_BLOCK_SIZE); 22ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 23939ca7ce860c5e80a4fdccc0dba5f7bfa29fef22reed@google.com Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size); 24ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com block->fNext = next; 25ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com block->fPtr = (char*)block + sizeof(Block); 26ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com block->fBytesFree = size; 27ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com block->fBytesTotal = size; 28ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return block; 29ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 30ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 31ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com bool canAlloc(size_t bytes) const { 32ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return bytes <= fBytesFree; 33ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 35ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com void* alloc(size_t bytes) { 36f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(bytes <= fBytesFree); 37ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fBytesFree -= bytes; 38ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com void* ptr = fPtr; 39ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fPtr += bytes; 40ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return ptr; 41ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 42fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 43ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com size_t release(size_t bytes) { 44f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(bytes > 0); 45972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org size_t free = SkTMin(bytes, fBytesTotal - fBytesFree); 46ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fBytesFree += free; 47ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fPtr -= free; 48ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return bytes - free; 49ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 50fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 51ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com bool empty() const { return fBytesTotal == fBytesFree; } 52ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}; 53ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 54ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/////////////////////////////////////////////////////////////////////////////// 55ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 56ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrAllocPool::GrAllocPool(size_t blockSize) { 57ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fBlock = NULL; 58972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org fMinBlockSize = SkTMax(blockSize, GrAllocPool_MIN_BLOCK_SIZE); 591acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org SkDEBUGCODE(fBlocksAllocated = 0;) 60ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 61ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 62ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrAllocPool::~GrAllocPool() { 63ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com this->reset(); 64ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 65ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 66ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrAllocPool::reset() { 67ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com this->validate(); 68ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 69ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Block* block = fBlock; 70ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com while (block) { 71ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Block* next = block->fNext; 72939ca7ce860c5e80a4fdccc0dba5f7bfa29fef22reed@google.com sk_free(block); 73ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com block = next; 74ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 75ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fBlock = NULL; 761acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org SkDEBUGCODE(fBlocksAllocated = 0;) 77ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 78ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 79ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid* GrAllocPool::alloc(size_t size) { 80ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com this->validate(); 81fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 82ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (!fBlock || !fBlock->canAlloc(size)) { 83972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org size_t blockSize = SkTMax(fMinBlockSize, size); 84ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fBlock = Block::Create(blockSize, fBlock); 851acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org SkDEBUGCODE(fBlocksAllocated += 1;) 86ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 87ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return fBlock->alloc(size); 88ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 89ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 90ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrAllocPool::release(size_t bytes) { 91ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com this->validate(); 92fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 93ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com while (bytes && NULL != fBlock) { 94ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com bytes = fBlock->release(bytes); 95ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (fBlock->empty()) { 96ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Block* next = fBlock->fNext; 97939ca7ce860c5e80a4fdccc0dba5f7bfa29fef22reed@google.com sk_free(fBlock); 98ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fBlock = next; 991acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org SkDEBUGCODE(fBlocksAllocated -= 1;) 100ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 101ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 102ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 103ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 104515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 105ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 106ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrAllocPool::validate() const { 107ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Block* block = fBlock; 108ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com int count = 0; 109ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com while (block) { 110ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com count += 1; 111ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com block = block->fNext; 112ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 113f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fBlocksAllocated == count); 114ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 115ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 116ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 117