1 /* 2 * Copyright 2011 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 "GrGLGpu.h" 9 10 #include "builders/GrGLProgramBuilder.h" 11 #include "GrProcessor.h" 12 #include "GrProgramDesc.h" 13 #include "GrGLPathRendering.h" 14 #include "glsl/GrGLSLFragmentProcessor.h" 15 #include "glsl/GrGLSLProgramDataManager.h" 16 #include "SkTSearch.h" 17 18 #ifdef PROGRAM_CACHE_STATS 19 // Display program cache usage 20 static const bool c_DisplayCache{false}; 21 #endif 22 23 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; 24 25 struct GrGLGpu::ProgramCache::Entry { 26 Entry(sk_sp<GrGLProgram> program) 27 : fProgram(std::move(program)) {} 28 29 sk_sp<GrGLProgram> fProgram; 30 }; 31 32 GrGLGpu::ProgramCache::ProgramCache(GrGLGpu* gpu) 33 : fMap(kMaxEntries) 34 , fGpu(gpu) 35 #ifdef PROGRAM_CACHE_STATS 36 , fTotalRequests(0) 37 , fCacheMisses(0) 38 , fHashMisses(0) 39 #endif 40 {} 41 42 GrGLGpu::ProgramCache::~ProgramCache() { 43 // dump stats 44 #ifdef PROGRAM_CACHE_STATS 45 if (c_DisplayCache) { 46 SkDebugf("--- Program Cache ---\n"); 47 SkDebugf("Total requests: %d\n", fTotalRequests); 48 SkDebugf("Cache misses: %d\n", fCacheMisses); 49 SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0) ? 50 100.f * fCacheMisses / fTotalRequests : 51 0.f); 52 int cacheHits = fTotalRequests - fCacheMisses; 53 SkDebugf("Hash miss %%: %f\n", (cacheHits > 0) ? 100.f * fHashMisses / cacheHits : 0.f); 54 SkDebugf("---------------------\n"); 55 } 56 #endif 57 } 58 59 void GrGLGpu::ProgramCache::abandon() { 60 #ifdef PROGRAM_CACHE_STATS 61 fTotalRequests = 0; 62 fCacheMisses = 0; 63 fHashMisses = 0; 64 #endif 65 } 66 67 GrGLProgram* GrGLGpu::ProgramCache::refProgram(const GrGLGpu* gpu, 68 const GrPipeline& pipeline, 69 const GrPrimitiveProcessor& primProc, 70 bool isPoints) { 71 #ifdef PROGRAM_CACHE_STATS 72 ++fTotalRequests; 73 #endif 74 75 // Get GrGLProgramDesc 76 GrProgramDesc desc; 77 if (!GrProgramDesc::Build(&desc, primProc, isPoints, pipeline, *gpu->caps()->shaderCaps())) { 78 GrCapsDebugf(gpu->caps(), "Failed to gl program descriptor!\n"); 79 return nullptr; 80 } 81 desc.finalize(); 82 std::unique_ptr<Entry>* entry = fMap.find(desc); 83 if (!entry) { 84 // Didn't find an origin-independent version, check with the specific origin 85 GrSurfaceOrigin origin = pipeline.proxy()->origin(); 86 desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin)); 87 desc.finalize(); 88 entry = fMap.find(desc); 89 } 90 if (!entry) { 91 // We have a cache miss 92 #ifdef PROGRAM_CACHE_STATS 93 ++fCacheMisses; 94 #endif 95 GrGLProgram* program = GrGLProgramBuilder::CreateProgram(pipeline, primProc, &desc, fGpu); 96 if (nullptr == program) { 97 return nullptr; 98 } 99 entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(sk_sp<GrGLProgram>(program)))); 100 } 101 102 return SkRef((*entry)->fProgram.get()); 103 } 104