Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2010 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 
     11 #include "GrAllocPool.h"
     12 
     13 #define GrAllocPool_MIN_BLOCK_SIZE      ((size_t)128)
     14 
     15 struct GrAllocPool::Block {
     16     Block*  fNext;
     17     char*   fPtr;
     18     size_t  fBytesFree;
     19     size_t  fBytesTotal;
     20 
     21     static Block* Create(size_t size, Block* next) {
     22         GrAssert(size >= GrAllocPool_MIN_BLOCK_SIZE);
     23 
     24         Block* block = (Block*)GrMalloc(sizeof(Block) + size);
     25         block->fNext = next;
     26         block->fPtr = (char*)block + sizeof(Block);
     27         block->fBytesFree = size;
     28         block->fBytesTotal = size;
     29         return block;
     30     }
     31 
     32     bool canAlloc(size_t bytes) const {
     33         return bytes <= fBytesFree;
     34     }
     35 
     36     void* alloc(size_t bytes) {
     37         GrAssert(bytes <= fBytesFree);
     38         fBytesFree -= bytes;
     39         void* ptr = fPtr;
     40         fPtr += bytes;
     41         return ptr;
     42     }
     43 
     44     size_t release(size_t bytes) {
     45         GrAssert(bytes > 0);
     46         size_t free = GrMin(bytes, fBytesTotal - fBytesFree);
     47         fBytesFree += free;
     48         fPtr -= free;
     49         return bytes - free;
     50     }
     51 
     52     bool empty() const { return fBytesTotal == fBytesFree; }
     53 };
     54 
     55 ///////////////////////////////////////////////////////////////////////////////
     56 
     57 GrAllocPool::GrAllocPool(size_t blockSize) {
     58     fBlock = NULL;
     59     fMinBlockSize = GrMax(blockSize, GrAllocPool_MIN_BLOCK_SIZE);
     60     GR_DEBUGCODE(fBlocksAllocated = 0;)
     61 }
     62 
     63 GrAllocPool::~GrAllocPool() {
     64     this->reset();
     65 }
     66 
     67 void GrAllocPool::reset() {
     68     this->validate();
     69 
     70     Block* block = fBlock;
     71     while (block) {
     72         Block* next = block->fNext;
     73         GrFree(block);
     74         block = next;
     75     }
     76     fBlock = NULL;
     77     GR_DEBUGCODE(fBlocksAllocated = 0;)
     78 }
     79 
     80 void* GrAllocPool::alloc(size_t size) {
     81     this->validate();
     82 
     83     if (!fBlock || !fBlock->canAlloc(size)) {
     84         size_t blockSize = GrMax(fMinBlockSize, size);
     85         fBlock = Block::Create(blockSize, fBlock);
     86         GR_DEBUGCODE(fBlocksAllocated += 1;)
     87     }
     88     return fBlock->alloc(size);
     89 }
     90 
     91 void GrAllocPool::release(size_t bytes) {
     92     this->validate();
     93 
     94     while (bytes && NULL != fBlock) {
     95         bytes = fBlock->release(bytes);
     96         if (fBlock->empty()) {
     97             Block* next = fBlock->fNext;
     98             GrFree(fBlock);
     99             fBlock = next;
    100             GR_DEBUGCODE(fBlocksAllocated -= 1;)
    101         }
    102     }
    103 }
    104 
    105 
    106 #if GR_DEBUG
    107 
    108 void GrAllocPool::validate() const {
    109     Block* block = fBlock;
    110     int count = 0;
    111     while (block) {
    112         count += 1;
    113         block = block->fNext;
    114     }
    115     GrAssert(fBlocksAllocated == count);
    116 }
    117 
    118 #endif
    119