void GrMemoryPool::release(void* p) { VALIDATE; intptr_t ptr = reinterpret_cast<intptr_t>(p) - kPerAllocPad; BlockHeader* block = *reinterpret_cast<BlockHeader**>(ptr); if (1 == block->fLiveCount) { // the head block is special, it is reset rather than deleted if (fHead == block) { fHead->fCurrPtr = reinterpret_cast<intptr_t>(fHead) + kHeaderSize; fHead->fLiveCount = 0; fHead->fFreeSize = fPreallocSize; } else { BlockHeader* prev = block->fPrev; BlockHeader* next = block->fNext; GrAssert(prev); prev->fNext = next; if (next) { next->fPrev = prev; } else { GrAssert(fTail == block); fTail = prev; } DeleteBlock(block); } } else { --block->fLiveCount; } GR_DEBUGCODE(--fAllocationCnt); VALIDATE; }
void* GrMemoryPool::allocate(size_t size) { VALIDATE; size = GrSizeAlignUp(size, kAlignment); size += kPerAllocPad; if (fTail->fFreeSize < size) { int blockSize = size; blockSize = GrMax<size_t>(blockSize, fMinAllocSize); BlockHeader* block = CreateBlock(blockSize); block->fPrev = fTail; block->fNext = NULL; GrAssert(NULL == fTail->fNext); fTail->fNext = block; fTail = block; } GrAssert(fTail->fFreeSize >= size); intptr_t ptr = fTail->fCurrPtr; // We stash a pointer to the block header, just before the allocated space, // so that we can decrement the live count on delete in constant time. *reinterpret_cast<BlockHeader**>(ptr) = fTail; ptr += kPerAllocPad; fTail->fCurrPtr += size; fTail->fFreeSize -= size; fTail->fLiveCount += 1; GR_DEBUGCODE(++fAllocationCnt); VALIDATE; return reinterpret_cast<void*>(ptr); }
GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path) : INHERITED(gpu, kIsWrapped) { #ifndef SK_SCALAR_IS_FLOAT GrCrash("Assumes scalar is float."); #endif SkASSERT(!path.isEmpty()); GL_CALL_RET(fPathID, GenPaths(1)); SkSTArray<16, GrGLubyte, true> pathCommands; SkSTArray<16, SkPoint, true> pathPoints; int verbCnt = path.countVerbs(); int pointCnt = path.countPoints(); pathCommands.resize_back(verbCnt); pathPoints.resize_back(pointCnt); // TODO: Direct access to path points since we could pass them on directly. path.getPoints(&pathPoints[0], pointCnt); path.getVerbs(&pathCommands[0], verbCnt); GR_DEBUGCODE(int numPts = 0); for (int i = 0; i < verbCnt; ++i) { SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]); pathCommands[i] = verb_to_gl_path_cmd(v); GR_DEBUGCODE(numPts += num_pts(v)); } GrAssert(pathPoints.count() == numPts); GL_CALL(PathCommands(fPathID, verbCnt, &pathCommands[0], 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0])); fBounds = path.getBounds(); }
GrMemoryPool::GrMemoryPool(size_t preallocSize, size_t minAllocSize) { GR_DEBUGCODE(fAllocationCnt = 0); minAllocSize = GrMax<size_t>(minAllocSize, 1 << 10); fMinAllocSize = GrSizeAlignUp(minAllocSize + kPerAllocPad, kAlignment), fPreallocSize = GrSizeAlignUp(preallocSize + kPerAllocPad, kAlignment); fPreallocSize = GrMax(fPreallocSize, fMinAllocSize); fHead = CreateBlock(fPreallocSize); fTail = fHead; fHead->fNext = NULL; fHead->fPrev = NULL; VALIDATE; };