GrGLProgram::CachedData* getProgramData(const GrGLProgram& desc, GrCustomStage** stages) { Entry newEntry; newEntry.fKey.setKeyData(desc.keyData()); Entry* entry = fHashCache.find(newEntry.fKey); if (NULL == entry) { if (!desc.genProgram(fGL, stages, &newEntry.fProgramData)) { return NULL; } if (fCount < kMaxEntries) { entry = fEntries + fCount; ++fCount; } else { GrAssert(kMaxEntries == fCount); entry = fEntries; for (int i = 1; i < kMaxEntries; ++i) { if (fEntries[i].fLRUStamp < entry->fLRUStamp) { entry = fEntries + i; } } fHashCache.remove(entry->fKey, entry); GrGpuGLShaders::DeleteProgram(fGL.interface(), &entry->fProgramData); } entry->copyAndTakeOwnership(newEntry); fHashCache.insert(entry->fKey, entry); } entry->fLRUStamp = fCurrLRUStamp; if (GR_UINT32_MAX == fCurrLRUStamp) { // wrap around! just trash our LRU, one time hit. for (int i = 0; i < fCount; ++i) { fEntries[i].fLRUStamp = 0; } } ++fCurrLRUStamp; return &entry->fProgramData; }
GrGLProgram::CachedData* getProgramData(const GrGLProgram& desc, const GrDrawTarget* target) { ProgramHashKey key; while (key.doPass()) { desc.buildKey(key); } Entry* entry = fHashCache.find(key); if (NULL == entry) { if (fCount < kMaxEntries) { entry = fEntries + fCount; ++fCount; } else { GrAssert(kMaxEntries == fCount); entry = fEntries; for (int i = 1; i < kMaxEntries; ++i) { if (fEntries[i].fLRUStamp < entry->fLRUStamp) { entry = fEntries + i; } } fHashCache.remove(entry->fKey, entry); GrGpuGLShaders::DeleteProgram(&entry->fProgramData); } entry->fKey.copyAndTakeOwnership(key); desc.genProgram(&entry->fProgramData, target); fHashCache.insert(entry->fKey, entry); } entry->fLRUStamp = fCurrLRUStamp; if (GR_UINT32_MAX == fCurrLRUStamp) { // wrap around! just trash our LRU, one time hit. for (int i = 0; i < fCount; ++i) { fEntries[i].fLRUStamp = 0; } } ++fCurrLRUStamp; return &entry->fProgramData; }