blob: 9916aaa0ca097303bb2122cc33ecde4e1333d4f9 [file] [log] [blame]
junov@google.comf93e7172011-03-31 21:26:24 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * 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.
junov@google.comf93e7172011-03-31 21:26:24 +00006 */
7
John Stilesfbd050b2020-08-03 13:21:46 -04008#include <memory>
9
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "src/gpu/gl/GrGLGpu.h"
epoger@google.comec3ed6a2011-07-28 14:26:00 +000011
Brian Osman172bb442019-09-06 10:16:02 -040012#include "include/gpu/GrContextOptions.h"
Adlai Holler3d0359a2020-07-09 15:35:55 -040013#include "include/gpu/GrDirectContext.h"
Adlai Hollera0693042020-10-14 11:23:11 -040014#include "src/gpu/GrDirectContextPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/gpu/GrProcessor.h"
16#include "src/gpu/GrProgramDesc.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "src/gpu/gl/builders/GrGLProgramBuilder.h"
18#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000019
bsalomon861e1032014-12-16 07:33:49 -080020struct GrGLGpu::ProgramCache::Entry {
Brian Osmaned58e002019-09-06 14:42:43 -040021 Entry(sk_sp<GrGLProgram> program)
22 : fProgram(std::move(program)) {}
23
24 Entry(const GrGLPrecompiledProgram& precompiledProgram)
25 : fPrecompiledProgram(precompiledProgram) {}
halcanary9d524f22016-03-29 09:03:52 -070026
Ethan Nicholas1b9924f2016-12-15 15:28:42 -050027 sk_sp<GrGLProgram> fProgram;
Brian Osmaned58e002019-09-06 14:42:43 -040028 GrGLPrecompiledProgram fPrecompiledProgram;
bsalomon@google.com2db3ded2013-05-22 14:34:04 +000029};
junov@google.comf93e7172011-03-31 21:26:24 +000030
bsalomon861e1032014-12-16 07:33:49 -080031GrGLGpu::ProgramCache::ProgramCache(GrGLGpu* gpu)
Brian Osman172bb442019-09-06 10:16:02 -040032 : fMap(gpu->getContext()->priv().options().fRuntimeProgramCacheSize)
Brian Osmane9d9a322019-09-03 13:59:36 -040033 , fGpu(gpu) {}
jvanverth@google.com94878772013-03-12 16:00:54 +000034
Brian Osmane9d9a322019-09-03 13:59:36 -040035GrGLGpu::ProgramCache::~ProgramCache() {}
junov@google.comf93e7172011-03-31 21:26:24 +000036
egdaniel22281c12016-03-23 13:49:40 -070037void GrGLGpu::ProgramCache::abandon() {
Robert Phillipsf6a0b452020-02-18 14:26:46 -050038 fMap.foreach([](GrProgramDesc*, std::unique_ptr<Entry>* e) {
Brian Osmaned58e002019-09-06 14:42:43 -040039 if ((*e)->fProgram) {
40 (*e)->fProgram->abandon();
41 }
Brian Osman0b8bb882019-04-12 11:47:19 -040042 });
43
44 this->reset();
45}
46
47void GrGLGpu::ProgramCache::reset() {
Robert Phillips752e08b2018-06-22 09:48:38 -040048 fMap.reset();
joshualitt8fd844f2015-12-02 13:36:47 -080049}
50
Stephen Whiteb1857852020-02-07 15:33:23 +000051sk_sp<GrGLProgram> GrGLGpu::ProgramCache::findOrCreateProgram(GrRenderTarget* renderTarget,
52 const GrProgramInfo& programInfo) {
53 const GrCaps& caps = *fGpu->caps();
Robert Phillipsf272bea2019-10-17 08:56:16 -040054
Robert Phillips03e4c952019-11-26 16:20:22 -050055 GrProgramDesc desc = caps.makeDesc(renderTarget, programInfo);
56 if (!desc.isValid()) {
Robert Phillipsf6a0b452020-02-18 14:26:46 -050057 GrCapsDebugf(&caps, "Failed to gl program descriptor!\n");
egdaniel0e1853c2016-03-17 11:35:45 -070058 return nullptr;
59 }
Brian Osmane11dfd32019-07-23 10:29:41 -040060
Robert Phillips19f466d2020-02-26 10:27:07 -050061 Stats::ProgramCacheResult stat;
62 sk_sp<GrGLProgram> tmp = this->findOrCreateProgram(renderTarget, desc, programInfo, &stat);
63 if (!tmp) {
64 fGpu->fStats.incNumInlineCompilationFailures();
65 } else {
66 fGpu->fStats.incNumInlineProgramCacheResult(stat);
67 }
68
69 return tmp;
Robert Phillips979b2232020-02-20 10:47:29 -050070}
71
72sk_sp<GrGLProgram> GrGLGpu::ProgramCache::findOrCreateProgram(GrRenderTarget* renderTarget,
73 const GrProgramDesc& desc,
Robert Phillips19f466d2020-02-26 10:27:07 -050074 const GrProgramInfo& programInfo,
75 Stats::ProgramCacheResult* stat) {
76 *stat = Stats::ProgramCacheResult::kHit;
Ethan Nicholas1b9924f2016-12-15 15:28:42 -050077 std::unique_ptr<Entry>* entry = fMap.find(desc);
Brian Osmaned58e002019-09-06 14:42:43 -040078 if (entry && !(*entry)->fProgram) {
79 // We've pre-compiled the GL program, but don't have the GrGLProgram scaffolding
80 const GrGLPrecompiledProgram* precompiledProgram = &((*entry)->fPrecompiledProgram);
81 SkASSERT(precompiledProgram->fProgramID != 0);
Stephen Whiteb1857852020-02-07 15:33:23 +000082 (*entry)->fProgram = GrGLProgramBuilder::CreateProgram(fGpu, renderTarget, desc,
83 programInfo, precompiledProgram);
84 if (!(*entry)->fProgram) {
Brian Osmaned58e002019-09-06 14:42:43 -040085 // Should we purge the program ID from the cache at this point?
86 SkDEBUGFAIL("Couldn't create program from precompiled program");
Robert Phillips19f466d2020-02-26 10:27:07 -050087 fGpu->fStats.incNumCompilationFailures();
Brian Osmaned58e002019-09-06 14:42:43 -040088 return nullptr;
89 }
Robert Phillips19f466d2020-02-26 10:27:07 -050090 fGpu->fStats.incNumPartialCompilationSuccesses();
91 *stat = Stats::ProgramCacheResult::kPartial;
Brian Osmaned58e002019-09-06 14:42:43 -040092 } else if (!entry) {
bsalomon@google.com2db3ded2013-05-22 14:34:04 +000093 // We have a cache miss
Stephen Whiteb1857852020-02-07 15:33:23 +000094 sk_sp<GrGLProgram> program = GrGLProgramBuilder::CreateProgram(fGpu, renderTarget,
95 desc, programInfo);
96 if (!program) {
Robert Phillips19f466d2020-02-26 10:27:07 -050097 fGpu->fStats.incNumCompilationFailures();
halcanary96fcdcc2015-08-27 07:41:13 -070098 return nullptr;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +000099 }
Robert Phillips19f466d2020-02-26 10:27:07 -0500100 fGpu->fStats.incNumCompilationSuccesses();
John Stilesfbd050b2020-08-03 13:21:46 -0400101 entry = fMap.insert(desc, std::make_unique<Entry>(std::move(program)));
Robert Phillips19f466d2020-02-26 10:27:07 -0500102 *stat = Stats::ProgramCacheResult::kMiss;
junov@google.comf93e7172011-03-31 21:26:24 +0000103 }
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000104
Stephen Whiteb1857852020-02-07 15:33:23 +0000105 return (*entry)->fProgram;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000106}
Brian Osmaned58e002019-09-06 14:42:43 -0400107
108bool GrGLGpu::ProgramCache::precompileShader(const SkData& key, const SkData& data) {
109 GrProgramDesc desc;
110 if (!GrProgramDesc::BuildFromData(&desc, key.data(), key.size())) {
111 return false;
112 }
113
114 std::unique_ptr<Entry>* entry = fMap.find(desc);
115 if (entry) {
116 // We've already seen/compiled this shader
117 return true;
118 }
119
120 GrGLPrecompiledProgram precompiledProgram;
121 if (!GrGLProgramBuilder::PrecompileProgram(&precompiledProgram, fGpu, data)) {
122 return false;
123 }
124
John Stilesfbd050b2020-08-03 13:21:46 -0400125 fMap.insert(desc, std::make_unique<Entry>(precompiledProgram));
Brian Osmaned58e002019-09-06 14:42:43 -0400126 return true;
127}