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#ifndef AtlasInstancedHelper_DEFINED 9cb93a386Sopenharmony_ci#define AtlasInstancedHelper_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "src/core/SkIPoint16.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrGeometryProcessor.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrSurfaceProxyView.h" 14cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLUniformHandler.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_cinamespace skgpu::v1 { 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ci// This class encapsulates all the necessary steps for an instanced GrGeometryProcessor to clip 19cb93a386Sopenharmony_ci// against a path mask from an atlas. 20cb93a386Sopenharmony_ciclass AtlasInstancedHelper { 21cb93a386Sopenharmony_cipublic: 22cb93a386Sopenharmony_ci enum class ShaderFlags { 23cb93a386Sopenharmony_ci kNone = 0, 24cb93a386Sopenharmony_ci kInvertCoverage = 1 << 0, 25cb93a386Sopenharmony_ci kCheckBounds = 1 << 1 26cb93a386Sopenharmony_ci }; 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ci GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(ShaderFlags); 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci constexpr static int kNumShaderFlags = 2; 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci AtlasInstancedHelper(GrSurfaceProxyView atlasView, ShaderFlags shaderFlags) 33cb93a386Sopenharmony_ci : fAtlasProxy(atlasView.detachProxy()) 34cb93a386Sopenharmony_ci , fAtlasSwizzle(atlasView.swizzle()) 35cb93a386Sopenharmony_ci , fShaderFlags(shaderFlags) { 36cb93a386Sopenharmony_ci // Bottom left origin is not supported. 37cb93a386Sopenharmony_ci SkASSERT(atlasView.origin() == kTopLeft_GrSurfaceOrigin); 38cb93a386Sopenharmony_ci } 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci GrSurfaceProxy* proxy() const { return fAtlasProxy.get(); } 41cb93a386Sopenharmony_ci const GrSwizzle& atlasSwizzle() const { return fAtlasSwizzle; } 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ci // Returns whether the two helpers can be batched together in a single draw. 44cb93a386Sopenharmony_ci bool isCompatible(const AtlasInstancedHelper& helper) { 45cb93a386Sopenharmony_ci // TODO: We may want to consider two helpers compatible if they only differ in the 46cb93a386Sopenharmony_ci // kCheckBounds flag -- we can always promote one to checking its bounds. 47cb93a386Sopenharmony_ci SkASSERT(fAtlasProxy != helper.fAtlasProxy || fAtlasSwizzle == helper.fAtlasSwizzle); 48cb93a386Sopenharmony_ci return fAtlasProxy == helper.fAtlasProxy && fShaderFlags == helper.fShaderFlags; 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci // Adds bits to the shader key that uniquely identify this specific helper's shader code. 52cb93a386Sopenharmony_ci void getKeyBits(GrProcessorKeyBuilder* b) const { 53cb93a386Sopenharmony_ci b->addBits(kNumShaderFlags, (int)fShaderFlags, "atlasFlags"); 54cb93a386Sopenharmony_ci } 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci // Appends the instanced input attribs to the back of the array that we will need in order to 57cb93a386Sopenharmony_ci // locate our path in the atlas. 58cb93a386Sopenharmony_ci void appendInstanceAttribs(SkTArray<GrGeometryProcessor::Attribute>* instanceAttribs) const; 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci struct Instance { 61cb93a386Sopenharmony_ci Instance(SkIPoint16 locationInAtlas, const SkIRect& pathDevIBounds, bool transposedInAtlas) 62cb93a386Sopenharmony_ci : fLocationInAtlas(locationInAtlas) 63cb93a386Sopenharmony_ci , fPathDevIBounds(pathDevIBounds) 64cb93a386Sopenharmony_ci , fTransposedInAtlas(transposedInAtlas) { 65cb93a386Sopenharmony_ci SkASSERT(fLocationInAtlas.x() >= 0); 66cb93a386Sopenharmony_ci SkASSERT(fLocationInAtlas.y() >= 0); 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci SkIPoint16 fLocationInAtlas; 69cb93a386Sopenharmony_ci SkIRect fPathDevIBounds; 70cb93a386Sopenharmony_ci bool fTransposedInAtlas; 71cb93a386Sopenharmony_ci }; 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci // Writes out the given instance data, formatted for the specific attribs that we added during 74cb93a386Sopenharmony_ci // appendInstanceAttribs(). 75cb93a386Sopenharmony_ci void writeInstanceData(VertexWriter* instanceWriter, const Instance*) const; 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_ci // Injects vertex code, fragment code, varyings, and uniforms to ultimately multiply 78cb93a386Sopenharmony_ci // "args.fOutputCoverage" in the fragment shader by the atlas coverage. 79cb93a386Sopenharmony_ci // 80cb93a386Sopenharmony_ci // The caller is responsible to store "atlasAdjustUniformHandle" and pass it to 81cb93a386Sopenharmony_ci // setUniformData(). 82cb93a386Sopenharmony_ci void injectShaderCode(const GrGeometryProcessor::ProgramImpl::EmitArgs&, 83cb93a386Sopenharmony_ci const GrShaderVar& devCoord, 84cb93a386Sopenharmony_ci GrGLSLUniformHandler::UniformHandle* atlasAdjustUniformHandle) const; 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci // The atlas clip requires one uniform value -- "atlasAdjustUniform". The caller should have 87cb93a386Sopenharmony_ci // stored this handle after its call to injectShaderCode(). This method sets its value prior to 88cb93a386Sopenharmony_ci // drawing. 89cb93a386Sopenharmony_ci void setUniformData(const GrGLSLProgramDataManager&, 90cb93a386Sopenharmony_ci const GrGLSLUniformHandler::UniformHandle& atlasAdjustUniformHandle) const; 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ciprivate: 93cb93a386Sopenharmony_ci const sk_sp<GrSurfaceProxy> fAtlasProxy; 94cb93a386Sopenharmony_ci const GrSwizzle fAtlasSwizzle; 95cb93a386Sopenharmony_ci const ShaderFlags fShaderFlags; 96cb93a386Sopenharmony_ci}; 97cb93a386Sopenharmony_ci 98cb93a386Sopenharmony_ciGR_MAKE_BITFIELD_CLASS_OPS(AtlasInstancedHelper::ShaderFlags); 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci} // namespace skgpu::v1 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_ci#endif // AtlasInstancedHelper_DEFINED 103