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