1/* 2 * Copyright 2014 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 "GrPathRange.h" 9#include "SkPath.h" 10 11enum { 12 kPathsPerGroup = 16 // Paths get tracked in groups of 16 for lazy loading. 13}; 14 15GrPathRange::GrPathRange(GrGpu* gpu, 16 PathGenerator* pathGenerator, 17 const SkStrokeRec& stroke) 18 : INHERITED(gpu, kCached_LifeCycle), 19 fPathGenerator(SkRef(pathGenerator)), 20 fNumPaths(fPathGenerator->getNumPaths()), 21 fStroke(stroke) { 22 const int numGroups = (fNumPaths + kPathsPerGroup - 1) / kPathsPerGroup; 23 fGeneratedPaths.reset((numGroups + 7) / 8); // 1 bit per path group. 24 memset(&fGeneratedPaths.front(), 0, fGeneratedPaths.count()); 25} 26 27GrPathRange::GrPathRange(GrGpu* gpu, 28 int numPaths, 29 const SkStrokeRec& stroke) 30 : INHERITED(gpu, kCached_LifeCycle), 31 fNumPaths(numPaths), 32 fStroke(stroke) { 33} 34 35void GrPathRange::willDrawPaths(const void* indices, PathIndexType indexType, int count) const { 36 if (!fPathGenerator) { 37 return; 38 } 39 40 switch (indexType) { 41 case kU8_PathIndexType: return this->willDrawPaths<uint8_t>(indices, count); 42 case kU16_PathIndexType: return this->willDrawPaths<uint16_t>(indices, count); 43 case kU32_PathIndexType: return this->willDrawPaths<uint32_t>(indices, count); 44 default: SkFAIL("Unknown path index type"); 45 } 46} 47 48template<typename IndexType> void GrPathRange::willDrawPaths(const void* indices, int count) const { 49 SkASSERT(fPathGenerator); 50 51 const IndexType* indexArray = reinterpret_cast<const IndexType*>(indices); 52 bool didLoadPaths = false; 53 54 for (int i = 0; i < count; ++i) { 55 SkASSERT(indexArray[i] < static_cast<uint32_t>(fNumPaths)); 56 57 const int groupIndex = indexArray[i] / kPathsPerGroup; 58 const int groupByte = groupIndex / 8; 59 const uint8_t groupBit = 1 << (groupIndex % 8); 60 61 const bool hasPath = SkToBool(fGeneratedPaths[groupByte] & groupBit); 62 if (!hasPath) { 63 // We track which paths are loaded in groups of kPathsPerGroup. To 64 // mark a path as loaded we need to load the entire group. 65 const int groupFirstPath = groupIndex * kPathsPerGroup; 66 const int groupLastPath = SkTMin(groupFirstPath + kPathsPerGroup, fNumPaths) - 1; 67 68 SkPath path; 69 for (int pathIdx = groupFirstPath; pathIdx <= groupLastPath; ++pathIdx) { 70 fPathGenerator->generatePath(pathIdx, &path); 71 this->onInitPath(pathIdx, path); 72 } 73 74 fGeneratedPaths[groupByte] |= groupBit; 75 didLoadPaths = true; 76 } 77 } 78 79 if (didLoadPaths) { 80 this->didChangeGpuMemorySize(); 81 } 82} 83