180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc. 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef GrMemoryPool_DEFINED 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GrMemoryPool_DEFINED 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrTypes.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Allocates memory in blocks and parcels out space in the blocks for allocation 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * requests. It is optimized for allocate / release speed over memory 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * effeciency. The interface is designed to be used to implement operator new 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * and delete overrides. All allocations are expected to be released before the 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * pool's destructor is called. Allocations will be 8-byte aligned. 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrMemoryPool { 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Prealloc size is the amount of space to make available at pool creation 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * time and keep around until pool destruction. The min alloc size is the 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * smallest allowed size of additional allocations. 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrMemoryPool(size_t preallocSize, size_t minAllocSize); 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ~GrMemoryPool(); 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Allocates memory. The memory must be freed with release(). 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* allocate(size_t size); 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * p must have been returned by allocate() 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void release(void* p); 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns true if there are no unreleased allocations. 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isEmpty() const { return fTail == fHead && !fHead->fLiveCount; } 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct BlockHeader; 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger static BlockHeader* CreateBlock(size_t size); 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 51e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger static void DeleteBlock(BlockHeader* block); 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void validate(); 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct BlockHeader { 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru BlockHeader* fNext; ///< doubly-linked list of blocks. 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru BlockHeader* fPrev; 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fLiveCount; ///< number of outstanding allocations in the 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ///< block. 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru intptr_t fCurrPtr; ///< ptr to the start of blocks free space. 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru intptr_t fPrevPtr; ///< ptr to the last allocation made 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t fFreeSize; ///< amount of free space left in the block. 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum { 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We assume this alignment is good enough for everybody. 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kAlignment = 8, 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kHeaderSize = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment), 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kPerAllocPad = GR_CT_ALIGN_UP(sizeof(BlockHeader*), kAlignment), 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t fPreallocSize; 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t fMinAllocSize; 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru BlockHeader* fHead; 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru BlockHeader* fTail; 750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#ifdef SK_DEBUG 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fAllocationCnt; 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 81