14da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com/* 24da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * Copyright 2012 Google Inc. 34da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * 44da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 54da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * found in the LICENSE file. 64da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com */ 74da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 84da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com#ifndef GrMemoryPool_DEFINED 94da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com#define GrMemoryPool_DEFINED 104da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 114da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com#include "GrTypes.h" 124da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 134da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com/** 144da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * Allocates memory in blocks and parcels out space in the blocks for allocation 154da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * requests. It is optimized for allocate / release speed over memory 164da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * effeciency. The interface is designed to be used to implement operator new 174da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * and delete overrides. All allocations are expected to be released before the 184da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * pool's destructor is called. Allocations will be 8-byte aligned. 194da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com */ 204da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.comclass GrMemoryPool { 214da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.compublic: 224da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com /** 234da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * Prealloc size is the amount of space to make available at pool creation 244da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * time and keep around until pool destruction. The min alloc size is the 254da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * smallest allowed size of additional allocations. 264da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com */ 274da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com GrMemoryPool(size_t preallocSize, size_t minAllocSize); 284da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 294da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com ~GrMemoryPool(); 304da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 314da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com /** 324da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * Allocates memory. The memory must be freed with release(). 334da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com */ 344da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com void* allocate(size_t size); 354da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 364da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com /** 374da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * p must have been returned by allocate() 384da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com */ 394da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com void release(void* p); 404da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 414da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com /** 424da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com * Returns true if there are no unreleased allocations. 434da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com */ 444da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com bool isEmpty() const { return fTail == fHead && !fHead->fLiveCount; } 454da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 46b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt /** 47b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt * Returns the total allocated size of the GrMemoryPool 48b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt */ 49b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt size_t size() const { return fSize; } 50b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt 514da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.comprivate: 524da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com struct BlockHeader; 534da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 548743b8f2a5e30af66f955519c90cd2cb841af95dcommit-bot@chromium.org static BlockHeader* CreateBlock(size_t size); 554da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 568743b8f2a5e30af66f955519c90cd2cb841af95dcommit-bot@chromium.org static void DeleteBlock(BlockHeader* block); 574da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 584da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com void validate(); 594da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 604da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com struct BlockHeader { 61dcba4c2cc30cc64f08def991376c6dab65cfb51ctomhudson@google.com BlockHeader* fNext; ///< doubly-linked list of blocks. 624da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com BlockHeader* fPrev; 63dcba4c2cc30cc64f08def991376c6dab65cfb51ctomhudson@google.com int fLiveCount; ///< number of outstanding allocations in the 64dcba4c2cc30cc64f08def991376c6dab65cfb51ctomhudson@google.com ///< block. 65dcba4c2cc30cc64f08def991376c6dab65cfb51ctomhudson@google.com intptr_t fCurrPtr; ///< ptr to the start of blocks free space. 66dcba4c2cc30cc64f08def991376c6dab65cfb51ctomhudson@google.com intptr_t fPrevPtr; ///< ptr to the last allocation made 67dcba4c2cc30cc64f08def991376c6dab65cfb51ctomhudson@google.com size_t fFreeSize; ///< amount of free space left in the block. 68b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt size_t fSize; ///< total allocated size of the block 694da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com }; 704da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 714da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com enum { 724da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com // We assume this alignment is good enough for everybody. 734da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com kAlignment = 8, 744da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com kHeaderSize = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment), 754da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com kPerAllocPad = GR_CT_ALIGN_UP(sizeof(BlockHeader*), kAlignment), 764da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com }; 77b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt size_t fSize; 784da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com size_t fPreallocSize; 794da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com size_t fMinAllocSize; 804da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com BlockHeader* fHead; 814da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com BlockHeader* fTail; 82515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 834da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com int fAllocationCnt; 84b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt int fAllocBlockCnt; 854da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com#endif 864da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com}; 874da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com 884da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com#endif 89