Line data Source code
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 0 : struct GrGLGpu::ProgramCache::Entry {
26 0 : Entry(sk_sp<GrGLProgram> program)
27 0 : : fProgram(std::move(program)) {}
28 :
29 : sk_sp<GrGLProgram> fProgram;
30 : };
31 :
32 0 : GrGLGpu::ProgramCache::ProgramCache(GrGLGpu* gpu)
33 : : fMap(kMaxEntries)
34 : , fGpu(gpu)
35 : #ifdef PROGRAM_CACHE_STATS
36 : , fTotalRequests(0)
37 : , fCacheMisses(0)
38 0 : , fHashMisses(0)
39 : #endif
40 0 : {}
41 :
42 0 : 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 0 : }
58 :
59 0 : void GrGLGpu::ProgramCache::abandon() {
60 : #ifdef PROGRAM_CACHE_STATS
61 0 : fTotalRequests = 0;
62 0 : fCacheMisses = 0;
63 0 : fHashMisses = 0;
64 : #endif
65 0 : }
66 :
67 0 : GrGLProgram* GrGLGpu::ProgramCache::refProgram(const GrGLGpu* gpu,
68 : const GrPipeline& pipeline,
69 : const GrPrimitiveProcessor& primProc,
70 : bool isPoints) {
71 : #ifdef PROGRAM_CACHE_STATS
72 0 : ++fTotalRequests;
73 : #endif
74 :
75 : // Get GrGLProgramDesc
76 0 : GrProgramDesc desc;
77 0 : if (!GrProgramDesc::Build(&desc, primProc, isPoints, pipeline, *gpu->caps()->shaderCaps())) {
78 0 : GrCapsDebugf(gpu->caps(), "Failed to gl program descriptor!\n");
79 0 : return nullptr;
80 : }
81 0 : desc.finalize();
82 0 : std::unique_ptr<Entry>* entry = fMap.find(desc);
83 0 : if (!entry) {
84 : // Didn't find an origin-independent version, check with the specific origin
85 0 : GrSurfaceOrigin origin = pipeline.getRenderTarget()->origin();
86 0 : desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
87 0 : desc.finalize();
88 0 : entry = fMap.find(desc);
89 : }
90 0 : if (!entry) {
91 : // We have a cache miss
92 : #ifdef PROGRAM_CACHE_STATS
93 0 : ++fCacheMisses;
94 : #endif
95 0 : GrGLProgram* program = GrGLProgramBuilder::CreateProgram(pipeline, primProc, &desc, fGpu);
96 0 : if (nullptr == program) {
97 0 : return nullptr;
98 : }
99 0 : entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(sk_sp<GrGLProgram>(program))));
100 : }
101 :
102 0 : return SkRef((*entry)->fProgram.get());
103 : }
|