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