Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / gpu / ganesh / gl / GrGLGpuProgramCache.cpp
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 <memory>
9
10 #include "src/gpu/ganesh/gl/GrGLGpu.h"
11
12 #include "include/gpu/GrContextOptions.h"
13 #include "include/gpu/GrDirectContext.h"
14 #include "src/gpu/ganesh/GrDirectContextPriv.h"
15 #include "src/gpu/ganesh/GrFragmentProcessor.h"
16 #include "src/gpu/ganesh/GrProcessor.h"
17 #include "src/gpu/ganesh/GrProgramDesc.h"
18 #include "src/gpu/ganesh/gl/builders/GrGLProgramBuilder.h"
19
20 struct GrGLGpu::ProgramCache::Entry {
21     Entry(sk_sp<GrGLProgram> program)
22         : fProgram(std::move(program)) {}
23
24     Entry(const GrGLPrecompiledProgram& precompiledProgram)
25         : fPrecompiledProgram(precompiledProgram) {}
26
27     sk_sp<GrGLProgram> fProgram;
28     GrGLPrecompiledProgram fPrecompiledProgram;
29 };
30
31 GrGLGpu::ProgramCache::ProgramCache(int runtimeProgramCacheSize)
32     : fMap(runtimeProgramCacheSize) {
33 }
34
35 GrGLGpu::ProgramCache::~ProgramCache() {}
36
37 void GrGLGpu::ProgramCache::abandon() {
38     fMap.foreach([](GrProgramDesc*, std::unique_ptr<Entry>* e) {
39         if ((*e)->fProgram) {
40             (*e)->fProgram->abandon();
41         }
42     });
43
44     this->reset();
45 }
46
47 void GrGLGpu::ProgramCache::reset() {
48     fMap.reset();
49 }
50
51 sk_sp<GrGLProgram> GrGLGpu::ProgramCache::findOrCreateProgram(GrDirectContext* dContext,
52                                                               const GrProgramInfo& programInfo) {
53     const GrCaps* caps = dContext->priv().caps();
54
55     GrProgramDesc desc = caps->makeDesc(/*renderTarget*/nullptr, programInfo);
56     if (!desc.isValid()) {
57         GrCapsDebugf(caps, "Failed to gl program descriptor!\n");
58         return nullptr;
59     }
60
61     Stats::ProgramCacheResult stat;
62     sk_sp<GrGLProgram> tmp = this->findOrCreateProgramImpl(dContext, desc, programInfo, &stat);
63     if (!tmp) {
64         fStats.incNumInlineCompilationFailures();
65     } else {
66         fStats.incNumInlineProgramCacheResult(stat);
67     }
68
69     return tmp;
70 }
71
72 sk_sp<GrGLProgram> GrGLGpu::ProgramCache::findOrCreateProgram(GrDirectContext* dContext,
73                                                               const GrProgramDesc& desc,
74                                                               const GrProgramInfo& programInfo,
75                                                               Stats::ProgramCacheResult* stat) {
76     sk_sp<GrGLProgram> tmp = this->findOrCreateProgramImpl(dContext, desc, programInfo, stat);
77     if (!tmp) {
78         fStats.incNumPreCompilationFailures();
79     } else {
80         fStats.incNumPreProgramCacheResult(*stat);
81     }
82
83     return tmp;
84 }
85
86 sk_sp<GrGLProgram> GrGLGpu::ProgramCache::findOrCreateProgramImpl(GrDirectContext* dContext,
87                                                                   const GrProgramDesc& desc,
88                                                                   const GrProgramInfo& programInfo,
89                                                                   Stats::ProgramCacheResult* stat) {
90     *stat = Stats::ProgramCacheResult::kHit;
91     std::unique_ptr<Entry>* entry = fMap.find(desc);
92     if (entry && !(*entry)->fProgram) {
93         // We've pre-compiled the GL program, but don't have the GrGLProgram scaffolding
94         const GrGLPrecompiledProgram* precompiledProgram = &((*entry)->fPrecompiledProgram);
95         SkASSERT(precompiledProgram->fProgramID != 0);
96         (*entry)->fProgram = GrGLProgramBuilder::CreateProgram(dContext, desc, programInfo,
97                                                                precompiledProgram);
98         if (!(*entry)->fProgram) {
99             // Should we purge the program ID from the cache at this point?
100             SkDEBUGFAIL("Couldn't create program from precompiled program");
101             fStats.incNumCompilationFailures();
102             return nullptr;
103         }
104         fStats.incNumPartialCompilationSuccesses();
105         *stat = Stats::ProgramCacheResult::kPartial;
106     } else if (!entry) {
107         // We have a cache miss
108         sk_sp<GrGLProgram> program = GrGLProgramBuilder::CreateProgram(dContext, desc, programInfo);
109         if (!program) {
110             fStats.incNumCompilationFailures();
111             return nullptr;
112         }
113         fStats.incNumCompilationSuccesses();
114         entry = fMap.insert(desc, std::make_unique<Entry>(std::move(program)));
115         *stat = Stats::ProgramCacheResult::kMiss;
116     }
117
118     return (*entry)->fProgram;
119 }
120
121 bool GrGLGpu::ProgramCache::precompileShader(GrDirectContext* dContext,
122                                              const SkData& key,
123                                              const SkData& data) {
124     GrProgramDesc desc;
125     if (!GrProgramDesc::BuildFromData(&desc, key.data(), key.size())) {
126         return false;
127     }
128
129     std::unique_ptr<Entry>* entry = fMap.find(desc);
130     if (entry) {
131         // We've already seen/compiled this shader
132         return true;
133     }
134
135     GrGLPrecompiledProgram precompiledProgram;
136     if (!GrGLProgramBuilder::PrecompileProgram(dContext, &precompiledProgram, data)) {
137         return false;
138     }
139
140     fMap.insert(desc, std::make_unique<Entry>(precompiledProgram));
141     return true;
142 }