• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
EntryGrGLGpu::ProgramCache::Entry26     Entry(sk_sp<GrGLProgram> program)
27     : fProgram(std::move(program)) {}
28 
29     sk_sp<GrGLProgram> fProgram;
30 };
31 
ProgramCache(GrGLGpu * gpu)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 
~ProgramCache()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 
abandon()59 void GrGLGpu::ProgramCache::abandon() {
60 #ifdef PROGRAM_CACHE_STATS
61     fTotalRequests = 0;
62     fCacheMisses = 0;
63     fHashMisses = 0;
64 #endif
65 }
66 
refProgram(const GrGLGpu * gpu,const GrPipeline & pipeline,const GrPrimitiveProcessor & primProc,bool isPoints)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.getRenderTarget()->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