• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google LLC
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 "experimental/graphite/src/ProgramCache.h"
9 
10 namespace skgpu {
11 
12 ////////////////////////////////////////////////////////////////////////////////////////////////////
ProgramInfo(uint32_t uniqueID,Combination c)13 ProgramCache::ProgramInfo::ProgramInfo(uint32_t uniqueID, Combination c)
14     : fID(uniqueID)
15     , fCombination(c) {
16 }
17 
~ProgramInfo()18 ProgramCache::ProgramInfo::~ProgramInfo() {}
19 
getMSL() const20 std::string ProgramCache::ProgramInfo::getMSL() const {
21     std::string msl = GetMSLUniformStruct(fCombination.fShaderType);
22 
23     switch (fCombination.fShaderType) {
24         case ShaderCombo::ShaderType::kLinearGradient:
25             // TODO: this MSL uses a 'rtSize' uniform that, presumably, we'll be getting from the
26             // vertex shader side of things (still somewhat TBD)
27             msl += std::string(
28             "fragment float4 fragmentShader(VertexOut interpolated [[stage_in]],\n"
29             "                               constant FragmentUniforms &uniforms [[buffer(0)]])\n"
30             "{"
31             "float2 screenPos = float2(2*interpolated.pos.x/uniforms.rtSize[0] - 1,\n"
32             "                          2*interpolated.pos.y/uniforms.rtSize[1] - 1);\n"
33             "float2 delta = uniforms.point1 - uniforms.point0;\n"
34             "float2 pt = screenPos - uniforms.point0;\n"
35             "float t = dot(pt, delta) / dot(delta, delta);\n"
36             "float4 result = uniforms.colors[0];\n"
37             "result = mix(result, uniforms.colors[1],\n"
38             "             clamp((t-uniforms.offsets[0])/(uniforms.offsets[1]-uniforms.offsets[0]),\n"
39             "                   0, 1));\n"
40             "result = mix(result, uniforms.colors[2],\n"
41             "             clamp((t-uniforms.offsets[1])/(uniforms.offsets[2]-uniforms.offsets[1]),\n"
42             "                   0, 1));\n"
43             "result = mix(result, uniforms.colors[3],\n"
44             "             clamp((t-uniforms.offsets[2])/(uniforms.offsets[3]-uniforms.offsets[2]),\n"
45             "             0, 1));\n"
46             "return result;\n"
47             "}\n");
48             break;
49         case ShaderCombo::ShaderType::kRadialGradient:
50         case ShaderCombo::ShaderType::kSweepGradient:
51         case ShaderCombo::ShaderType::kConicalGradient:
52         case ShaderCombo::ShaderType::kNone:
53         default:
54             msl += std::string(
55             "fragment float4 fragmentShader(VertexOut interpolated [[stage_in]],\n"
56             "                               constant FragmentUniforms &uniforms [[buffer(0)]])\n"
57             "{\n"
58             "return float4(uniforms.color);\n"
59             "}\n");
60             break;
61     }
62 
63     return msl;
64 }
65 
66 ////////////////////////////////////////////////////////////////////////////////////////////////////
ProgramCache()67 ProgramCache::ProgramCache() {
68     // kInvalidProgramID (aka 0) is reserved
69     fProgramVector.push_back(nullptr);
70 }
71 
operator ()(Combination c) const72 size_t ProgramCache::Hash::operator()(Combination c) const {
73     return static_cast<int>(c.fShaderType) +
74            static_cast<int>(c.fTileMode) +
75            static_cast<int>(c.fBlendMode);
76 }
77 
findOrCreateProgram(Combination c)78 sk_sp<ProgramCache::ProgramInfo> ProgramCache::findOrCreateProgram(Combination c) {
79     auto iter = fProgramHash.find(c);
80     if (iter != fProgramHash.end()) {
81         SkASSERT(iter->second->id() != kInvalidProgramID);
82         return iter->second;
83     }
84 
85     sk_sp<ProgramInfo> pi(new ProgramInfo(fNextUniqueID++, c));
86     fProgramHash.insert(std::make_pair(c, pi));
87     fProgramVector.push_back(pi);
88     SkASSERT(fProgramVector[pi->id()] == pi);
89     return pi;
90 }
91 
lookup(uint32_t uniqueID)92 sk_sp<ProgramCache::ProgramInfo> ProgramCache::lookup(uint32_t uniqueID) {
93     SkASSERT(uniqueID < fProgramVector.size());
94     return fProgramVector[uniqueID];
95 }
96 
97 } // namespace skgpu
98