1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com */ 7f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 85739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com#include "GrGpuGL.h" 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 10a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.com#include "GrEffect.h" 11d698f77c13d97c61109b861eac4d25b14a5de935bsalomon@google.com#include "GrGLEffect.h" 125c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com#include "SkRTConf.h" 13511923443facc611b3735b4688342c12071feaa0cdalton#include "GrGLNameAllocator.h" 142db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com#include "SkTSearch.h" 15f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 16a2f4b15d4e861b8b29e20ec37743fd3fd4b05b03jvanverth@google.com#ifdef PROGRAM_CACHE_STATS 175c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.comSK_CONF_DECLARE(bool, c_DisplayCache, "gpu.displayCache", false, 185c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com "Display program cache usage."); 19a2f4b15d4e861b8b29e20ec37743fd3fd4b05b03jvanverth@google.com#endif 205c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com 21dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.comtypedef GrGLUniformManager::UniformHandle UniformHandle; 22dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com 232db3ded335fdb6697623bece61cabc307a414770bsalomon@google.comstruct GrGpuGL::ProgramCache::Entry { 242db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com SK_DECLARE_INST_COUNT_ROOT(Entry); 252db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com Entry() : fProgram(NULL), fLRUStamp(0) {} 262db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 272db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com SkAutoTUnref<GrGLProgram> fProgram; 282db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com unsigned int fLRUStamp; 292db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com}; 302db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 312db3ded335fdb6697623bece61cabc307a414770bsalomon@google.comstruct GrGpuGL::ProgramCache::ProgDescLess { 322db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com bool operator() (const GrGLProgramDesc& desc, const Entry* entry) { 33f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != entry->fProgram.get()); 342db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com return GrGLProgramDesc::Less(desc, entry->fProgram->getDesc()); 352db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 362db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 372db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com bool operator() (const Entry* entry, const GrGLProgramDesc& desc) { 38f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != entry->fProgram.get()); 392db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com return GrGLProgramDesc::Less(entry->fProgram->getDesc(), desc); 402db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 412db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com}; 42f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 439188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.orgGrGpuGL::ProgramCache::ProgramCache(GrGpuGL* gpu) 44c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com : fCount(0) 45c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com , fCurrLRUStamp(0) 469188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.org , fGpu(gpu) 47948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com#ifdef PROGRAM_CACHE_STATS 48948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com , fTotalRequests(0) 49948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com , fCacheMisses(0) 502db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com , fHashMisses(0) 51948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com#endif 52948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com{ 532db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com for (int i = 0; i < 1 << kHashBits; ++i) { 542db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com fHashTable[i] = NULL; 552db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 56948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com} 57948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com 58948787737b77555318fa2433e7ff941516fe950ejvanverth@google.comGrGpuGL::ProgramCache::~ProgramCache() { 592db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com for (int i = 0; i < fCount; ++i){ 602db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com SkDELETE(fEntries[i]); 612db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 62948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com // dump stats 63948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com#ifdef PROGRAM_CACHE_STATS 645c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com if (c_DisplayCache) { 655c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com SkDebugf("--- Program Cache ---\n"); 665c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com SkDebugf("Total requests: %d\n", fTotalRequests); 675c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com SkDebugf("Cache misses: %d\n", fCacheMisses); 685c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0) ? 695c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com 100.f * fCacheMisses / fTotalRequests : 705c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com 0.f); 715c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com int cacheHits = fTotalRequests - fCacheMisses; 725c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com SkDebugf("Hash miss %%: %f\n", (cacheHits > 0) ? 100.f * fHashMisses / cacheHits : 0.f); 735c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com SkDebugf("---------------------\n"); 745c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com } 75948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com#endif 76c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com} 77f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 78ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.comvoid GrGpuGL::ProgramCache::abandon() { 79c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com for (int i = 0; i < fCount; ++i) { 80f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != fEntries[i]->fProgram.get()); 812db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com fEntries[i]->fProgram->abandon(); 822db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com fEntries[i]->fProgram.reset(NULL); 83f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com } 84c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com fCount = 0; 85c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com} 86f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 872db3ded335fdb6697623bece61cabc307a414770bsalomon@google.comint GrGpuGL::ProgramCache::search(const GrGLProgramDesc& desc) const { 882db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com ProgDescLess less; 892db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com return SkTSearch(fEntries, fCount, desc, sizeof(Entry*), less); 902db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com} 912db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 9231ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.comGrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc, 932c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com const GrEffectStage* colorStages[], 942c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com const GrEffectStage* coverageStages[]) { 95948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com#ifdef PROGRAM_CACHE_STATS 96948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com ++fTotalRequests; 97948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com#endif 989ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com 992db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com Entry* entry = NULL; 1002db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 1012db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com uint32_t hashIdx = desc.getChecksum(); 1022db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com hashIdx ^= hashIdx >> 16; 1032db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com if (kHashBits <= 8) { 1042db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com hashIdx ^= hashIdx >> 8; 1052db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 1062db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com hashIdx &=((1 << kHashBits) - 1); 1072db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com Entry* hashedEntry = fHashTable[hashIdx]; 1082db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com if (NULL != hashedEntry && hashedEntry->fProgram->getDesc() == desc) { 109f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != hashedEntry->fProgram); 1102db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com entry = hashedEntry; 1112db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 1122db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 1132db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com int entryIdx; 1142db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com if (NULL == entry) { 1152db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com entryIdx = this->search(desc); 1162db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com if (entryIdx >= 0) { 1172db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com entry = fEntries[entryIdx]; 1182db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com#ifdef PROGRAM_CACHE_STATS 1192db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com ++fHashMisses; 1202db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com#endif 1212db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 1222db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 1232db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 124c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com if (NULL == entry) { 1252db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com // We have a cache miss 126948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com#ifdef PROGRAM_CACHE_STATS 127948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com ++fCacheMisses; 128948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com#endif 1299188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.org GrGLProgram* program = GrGLProgram::Create(fGpu, desc, colorStages, coverageStages); 1302db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com if (NULL == program) { 131c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com return NULL; 132c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com } 1332db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com int purgeIdx = 0; 134c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com if (fCount < kMaxEntries) { 1352db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com entry = SkNEW(Entry); 1362db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com purgeIdx = fCount++; 1372db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com fEntries[purgeIdx] = entry; 138c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com } else { 139f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fCount == kMaxEntries); 1402db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com purgeIdx = 0; 141c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com for (int i = 1; i < kMaxEntries; ++i) { 1422db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com if (fEntries[i]->fLRUStamp < fEntries[purgeIdx]->fLRUStamp) { 1432db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com purgeIdx = i; 144f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com } 145f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com } 1462db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com entry = fEntries[purgeIdx]; 1472db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com int purgedHashIdx = entry->fProgram->getDesc().getChecksum() & ((1 << kHashBits) - 1); 1482db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com if (fHashTable[purgedHashIdx] == entry) { 1492db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com fHashTable[purgedHashIdx] = NULL; 1502db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 151f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com } 152f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fEntries[purgeIdx] == entry); 1532db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com entry->fProgram.reset(program); 1542d816ad36e806e5b1cf3c447e547829bbbe74fd1skia.committer@gmail.com // We need to shift fEntries around so that the entry currently at purgeIdx is placed 1552db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com // just before the entry at ~entryIdx (in order to keep fEntries sorted by descriptor). 1562db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com entryIdx = ~entryIdx; 1572db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com if (entryIdx < purgeIdx) { 1582db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com // Let E and P be the entries at index entryIdx and purgeIdx, respectively. 1592db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com // If the entries array looks like this: 1602db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com // aaaaEbbbbbPccccc 1612db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com // we rearrange it to look like this: 1622db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com // aaaaPEbbbbbccccc 1632db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com size_t copySize = (purgeIdx - entryIdx) * sizeof(Entry*); 1642db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com memmove(fEntries + entryIdx + 1, fEntries + entryIdx, copySize); 1652db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com fEntries[entryIdx] = entry; 1662db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } else if (purgeIdx < entryIdx) { 1672db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com // If the entries array looks like this: 1682db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com // aaaaPbbbbbEccccc 1692db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com // we rearrange it to look like this: 1702db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com // aaaabbbbbPEccccc 1712db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com size_t copySize = (entryIdx - purgeIdx - 1) * sizeof(Entry*); 1722db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com memmove(fEntries + purgeIdx, fEntries + purgeIdx + 1, copySize); 1732db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com fEntries[entryIdx - 1] = entry; 1742db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 175515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 176f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != fEntries[0]->fProgram.get()); 1772db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com for (int i = 0; i < fCount - 1; ++i) { 178f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != fEntries[i + 1]->fProgram.get()); 1792db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com const GrGLProgramDesc& a = fEntries[i]->fProgram->getDesc(); 1802db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com const GrGLProgramDesc& b = fEntries[i + 1]->fProgram->getDesc(); 181f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(GrGLProgramDesc::Less(a, b)); 182f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(!GrGLProgramDesc::Less(b, a)); 1832db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 1842db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com#endif 185c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com } 186f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 1872db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com fHashTable[hashIdx] = entry; 188c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com entry->fLRUStamp = fCurrLRUStamp; 1892db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 1902db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com if (SK_MaxU32 == fCurrLRUStamp) { 191c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com // wrap around! just trash our LRU, one time hit. 192c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com for (int i = 0; i < fCount; ++i) { 1932db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com fEntries[i]->fLRUStamp = 0; 194f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com } 195f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com } 196c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com ++fCurrLRUStamp; 1979ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com return entry->fProgram; 198c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com} 199f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 2001e257a5db32e1c9e3b0dba80f43470816ef948afbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 2011e257a5db32e1c9e3b0dba80f43470816ef948afbsalomon@google.com 2025739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.comvoid GrGpuGL::abandonResources(){ 2035739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com INHERITED::abandonResources(); 2045739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com fProgramCache->abandon(); 2055739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com fHWProgramID = 0; 206511923443facc611b3735b4688342c12071feaa0cdalton fPathNameAllocator.reset(NULL); 2075739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com} 2085739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com 2095739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 2105739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com 2110b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) 2120b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com 21326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.combool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) { 2148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com const GrDrawState& drawState = this->getDrawState(); 2158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 2166a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com // GrGpu::setupClipAndFlushState should have already checked this and bailed if not true. 217f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != drawState.getRenderTarget()); 218c96cb3a929f954cd2e7b6319efdfa6b758b20bd3bsalomon@google.com 2196a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com if (kStencilPath_DrawType == type) { 2206b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org const GrRenderTarget* rt = this->getDrawState().getRenderTarget(); 2216b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org SkISize size; 2226b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org size.set(rt->width(), rt->height()); 2236b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org this->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin()); 2246a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com } else { 225ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com this->flushMiscFixedFunctionState(); 2264be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com 227ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com GrBlendCoeff srcCoeff; 228ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com GrBlendCoeff dstCoeff; 2292b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com GrDrawState::BlendOptFlags blendOpts = drawState.getBlendOpts(false, &srcCoeff, &dstCoeff); 2302b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com if (GrDrawState::kSkipDraw_BlendOptFlag & blendOpts) { 231ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com return false; 232ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com } 233f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 2342c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com SkSTArray<8, const GrEffectStage*, true> colorStages; 2352c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com SkSTArray<8, const GrEffectStage*, true> coverageStages; 23631ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com GrGLProgramDesc desc; 23731ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com GrGLProgramDesc::Build(this->getDrawState(), 2380a6fe71f1bc0e601b41b7ae6d28b8c96a2c41116commit-bot@chromium.org type, 23991207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com blendOpts, 24091207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com srcCoeff, 24191207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com dstCoeff, 24291207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com this, 24326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com dstCopy, 2442c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com &colorStages, 2452c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com &coverageStages, 24691207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com &desc); 2479ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com 2482c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com fCurrentProgram.reset(fProgramCache->getProgram(desc, 2492c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com colorStages.begin(), 2502c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com coverageStages.begin())); 2519ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com if (NULL == fCurrentProgram.get()) { 252330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com SkDEBUGFAIL("Failed to create program!"); 253ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com return false; 254ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com } 255c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org 2569b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org SkASSERT((kDrawPath_DrawType != type && kDrawPaths_DrawType != type) 2579b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org || !fCurrentProgram->hasVertexShader()); 258c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org 2599ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com fCurrentProgram.get()->ref(); 2604c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com 2616a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com GrGLuint programID = fCurrentProgram->programID(); 2626a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com if (fHWProgramID != programID) { 2636a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com GL_CALL(UseProgram(programID)); 2646a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com fHWProgramID = programID; 265ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com } 2666a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com 2679ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff); 268ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff); 269ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 2709188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.org fCurrentProgram->setData(blendOpts, 2712c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com colorStages.begin(), 2722c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com coverageStages.begin(), 2732c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com dstCopy, 2742c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com &fSharedGLProgramState); 275f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com } 276ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com this->flushStencil(type); 277a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com this->flushScissor(); 278ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com this->flushAAState(type); 2794c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com 280fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect* devRect = NULL; 281fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect devClipBounds; 2823e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com if (drawState.isClipState()) { 28302ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com this->getClip()->getConservativeBounds(drawState.getRenderTarget(), &devClipBounds); 2847b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devRect = &devClipBounds; 2854c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com } 2864c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com // This must come after textures are flushed because a texture may need 2874c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com // to be msaa-resolved (which will modify bound FBO state). 2887b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com this->flushRenderTarget(devRect); 2894c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com 290f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com return true; 291f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com} 292f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 293880b8fcf255e67a15687e8b7cc47397372db683cbsalomon@google.comvoid GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) { 294f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 295a4662865e37a2ca95b5e3379072f6a274acc8ac8robertphillips@google.com GrGLsizei stride = static_cast<GrGLsizei>(this->getDrawState().getVertexSize()); 296880b8fcf255e67a15687e8b7cc47397372db683cbsalomon@google.com 2976918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com size_t vertexOffsetInBytes = stride * info.startVertex(); 2986918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 2996918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com const GeometryPoolState& geoPoolState = this->getGeomPoolState(); 3006918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 3016918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com GrGLVertexBuffer* vbuf; 3026918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com switch (this->getGeomSrc().fVertexSrc) { 3036918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com case kBuffer_GeometrySrcType: 3046918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com vbuf = (GrGLVertexBuffer*) this->getGeomSrc().fVertexBuffer; 3056918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com break; 3066918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com case kArray_GeometrySrcType: 3076918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com case kReserved_GeometrySrcType: 3086918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com this->finalizeReservedVertices(); 3096918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com vertexOffsetInBytes += geoPoolState.fPoolStartVertex * this->getGeomSrc().fVertexSize; 3106918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer; 3116918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com break; 3126918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com default: 3136918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com vbuf = NULL; // suppress warning 31488cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unknown geometry src type!"); 3156918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } 3166918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 317f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != vbuf); 3188341eb76fbc54593e873f5589961e02793e7f15fcommit-bot@chromium.org SkASSERT(!vbuf->isMapped()); 3196918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com vertexOffsetInBytes += vbuf->baseOffset(); 3206918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 3216918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com GrGLIndexBuffer* ibuf = NULL; 3226918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com if (info.isIndexed()) { 323f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != indexOffsetInBytes); 3246918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 3256918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com switch (this->getGeomSrc().fIndexSrc) { 3266918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com case kBuffer_GeometrySrcType: 3276918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com *indexOffsetInBytes = 0; 3286918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer; 3296918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com break; 3306918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com case kArray_GeometrySrcType: 3316918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com case kReserved_GeometrySrcType: 3326918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com this->finalizeReservedIndices(); 3336918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com *indexOffsetInBytes = geoPoolState.fPoolStartIndex * sizeof(GrGLushort); 3346918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer; 3356918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com break; 3366918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com default: 3376918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com ibuf = NULL; // suppress warning 33888cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unknown geometry src type!"); 3396918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } 3406918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 341f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != ibuf); 3428341eb76fbc54593e873f5589961e02793e7f15fcommit-bot@chromium.org SkASSERT(!ibuf->isMapped()); 3436918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com *indexOffsetInBytes += ibuf->baseOffset(); 3446918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } 3456918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com GrGLAttribArrayState* attribState = 3466918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf); 347880b8fcf255e67a15687e8b7cc47397372db683cbsalomon@google.com 3480a6fe71f1bc0e601b41b7ae6d28b8c96a2c41116commit-bot@chromium.org if (fCurrentProgram->hasVertexShader()) { 3496ebfbf9968c76b0238f1b48296ff1b507e110ba1commit-bot@chromium.org int vertexAttribCount = this->getDrawState().getVertexAttribCount(); 3506b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org uint32_t usedAttribArraysMask = 0; 3516b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs(); 3526ebfbf9968c76b0238f1b48296ff1b507e110ba1commit-bot@chromium.org 3536b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount; 3546b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org ++vertexAttribIndex, ++vertexAttrib) { 3556b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org 3566b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org usedAttribArraysMask |= (1 << vertexAttribIndex); 3576b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org GrVertexAttribType attribType = vertexAttrib->fType; 3586b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org attribState->set(this, 3596b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org vertexAttribIndex, 3606b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org vbuf, 3616b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org GrGLAttribTypeToLayout(attribType).fCount, 3626b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org GrGLAttribTypeToLayout(attribType).fType, 3636b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org GrGLAttribTypeToLayout(attribType).fNormalized, 3646b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org stride, 3656b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org reinterpret_cast<GrGLvoid*>( 3666ebfbf9968c76b0238f1b48296ff1b507e110ba1commit-bot@chromium.org vertexOffsetInBytes + vertexAttrib->fOffset)); 3676b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org } 3686ebfbf9968c76b0238f1b48296ff1b507e110ba1commit-bot@chromium.org attribState->disableUnusedArrays(this, usedAttribArraysMask); 3696b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org } 370f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com} 371