1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2019 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 "tools/gpu/TestOps.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "src/core/SkPointPriv.h" 11cb93a386Sopenharmony_ci#include "src/gpu/BufferWriter.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrGeometryProcessor.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrMemoryPool.h" 15cb93a386Sopenharmony_ci#include "src/gpu/GrOpFlushState.h" 16cb93a386Sopenharmony_ci#include "src/gpu/GrProgramInfo.h" 17cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" 18cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVarying.h" 19cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h" 20cb93a386Sopenharmony_ci#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h" 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_cinamespace { 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ciclass GP : public GrGeometryProcessor { 25cb93a386Sopenharmony_cipublic: 26cb93a386Sopenharmony_ci GP(const SkMatrix& localMatrix, bool wideColor) 27cb93a386Sopenharmony_ci : GrGeometryProcessor(kTestRectOp_ClassID), fLocalMatrix(localMatrix) { 28cb93a386Sopenharmony_ci fInColor = MakeColorAttribute("color", wideColor); 29cb93a386Sopenharmony_ci this->setVertexAttributes(&fInPosition, 3); 30cb93a386Sopenharmony_ci } 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci const char* name() const override { return "TestRectOp::GP"; } 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override { 35cb93a386Sopenharmony_ci class Impl : public ProgramImpl { 36cb93a386Sopenharmony_ci public: 37cb93a386Sopenharmony_ci void setData(const GrGLSLProgramDataManager& pdman, 38cb93a386Sopenharmony_ci const GrShaderCaps& shaderCaps, 39cb93a386Sopenharmony_ci const GrGeometryProcessor& geomProc) override { 40cb93a386Sopenharmony_ci const auto& gp = geomProc.cast<GP>(); 41cb93a386Sopenharmony_ci SetTransform(pdman, shaderCaps, fLocalMatrixUni, gp.fLocalMatrix); 42cb93a386Sopenharmony_ci } 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ci private: 45cb93a386Sopenharmony_ci void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { 46cb93a386Sopenharmony_ci const auto& gp = args.fGeomProc.cast<GP>(); 47cb93a386Sopenharmony_ci args.fVaryingHandler->emitAttributes(gp); 48cb93a386Sopenharmony_ci GrGLSLVarying colorVarying(kHalf4_GrSLType); 49cb93a386Sopenharmony_ci args.fVaryingHandler->addVarying("color", &colorVarying, 50cb93a386Sopenharmony_ci GrGLSLVaryingHandler::Interpolation::kCanBeFlat); 51cb93a386Sopenharmony_ci args.fVertBuilder->codeAppendf("%s = %s;", colorVarying.vsOut(), gp.fInColor.name()); 52cb93a386Sopenharmony_ci args.fFragBuilder->codeAppendf("half4 %s = %s;", 53cb93a386Sopenharmony_ci args.fOutputColor, colorVarying.fsIn()); 54cb93a386Sopenharmony_ci args.fFragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage); 55cb93a386Sopenharmony_ci WriteOutputPosition(args.fVertBuilder, gpArgs, gp.fInPosition.name()); 56cb93a386Sopenharmony_ci WriteLocalCoord(args.fVertBuilder, 57cb93a386Sopenharmony_ci args.fUniformHandler, 58cb93a386Sopenharmony_ci *args.fShaderCaps, 59cb93a386Sopenharmony_ci gpArgs, 60cb93a386Sopenharmony_ci gp.fInLocalCoords.asShaderVar(), 61cb93a386Sopenharmony_ci gp.fLocalMatrix, 62cb93a386Sopenharmony_ci &fLocalMatrixUni); 63cb93a386Sopenharmony_ci } 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci UniformHandle fLocalMatrixUni; 66cb93a386Sopenharmony_ci }; 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci return std::make_unique<Impl>(); 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci void addToKey(const GrShaderCaps& shaderCaps, GrProcessorKeyBuilder* b) const override { 72cb93a386Sopenharmony_ci b->add32(ProgramImpl::ComputeMatrixKey(shaderCaps, fLocalMatrix)); 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci bool wideColor() const { return fInColor.cpuType() != kUByte4_norm_GrVertexAttribType; } 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_ciprivate: 78cb93a386Sopenharmony_ci Attribute fInPosition = { "inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType}; 79cb93a386Sopenharmony_ci Attribute fInLocalCoords = {"inLocalCoords", kFloat2_GrVertexAttribType, kFloat2_GrSLType}; 80cb93a386Sopenharmony_ci Attribute fInColor; 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci SkMatrix fLocalMatrix; 83cb93a386Sopenharmony_ci}; 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ciclass TestRectOp final : public GrMeshDrawOp { 86cb93a386Sopenharmony_cipublic: 87cb93a386Sopenharmony_ci static GrOp::Owner Make(GrRecordingContext*, 88cb93a386Sopenharmony_ci GrPaint&&, 89cb93a386Sopenharmony_ci const SkRect& drawRect, 90cb93a386Sopenharmony_ci const SkRect& localRect, 91cb93a386Sopenharmony_ci const SkMatrix& localM); 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci const char* name() const override { return "TestRectOp"; } 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; } 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci GrProcessorSet::Analysis finalize(const GrCaps&, 98cb93a386Sopenharmony_ci const GrAppliedClip*, 99cb93a386Sopenharmony_ci GrClampType) override; 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci void visitProxies(const GrVisitProxyFunc& func) const override { 102cb93a386Sopenharmony_ci if (fProgramInfo) { 103cb93a386Sopenharmony_ci fProgramInfo->visitFPProxies(func); 104cb93a386Sopenharmony_ci } else { 105cb93a386Sopenharmony_ci fProcessorSet.visitProxies(func); 106cb93a386Sopenharmony_ci } 107cb93a386Sopenharmony_ci } 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ciprivate: 110cb93a386Sopenharmony_ci DEFINE_OP_CLASS_ID 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci TestRectOp(const GrCaps*, 113cb93a386Sopenharmony_ci GrPaint&&, 114cb93a386Sopenharmony_ci const SkRect& drawRect, 115cb93a386Sopenharmony_ci const SkRect& localRect, 116cb93a386Sopenharmony_ci const SkMatrix& localMatrix); 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci GrProgramInfo* programInfo() override { return fProgramInfo; } 119cb93a386Sopenharmony_ci void onCreateProgramInfo(const GrCaps*, 120cb93a386Sopenharmony_ci SkArenaAlloc*, 121cb93a386Sopenharmony_ci const GrSurfaceProxyView& writeView, 122cb93a386Sopenharmony_ci bool usesMSAASurface, 123cb93a386Sopenharmony_ci GrAppliedClip&&, 124cb93a386Sopenharmony_ci const GrDstProxyView&, 125cb93a386Sopenharmony_ci GrXferBarrierFlags renderPassXferBarriers, 126cb93a386Sopenharmony_ci GrLoadOp colorLoadOp) override; 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_ci void onPrepareDraws(GrMeshDrawTarget*) override; 129cb93a386Sopenharmony_ci void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_ci SkRect fDrawRect; 132cb93a386Sopenharmony_ci SkRect fLocalRect; 133cb93a386Sopenharmony_ci SkPMColor4f fColor; 134cb93a386Sopenharmony_ci GP fGP; 135cb93a386Sopenharmony_ci GrProcessorSet fProcessorSet; 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci // If this op is prePrepared the created programInfo will be stored here for use in 138cb93a386Sopenharmony_ci // onExecute. In the prePrepared case it will have been stored in the record-time arena. 139cb93a386Sopenharmony_ci GrProgramInfo* fProgramInfo = nullptr; 140cb93a386Sopenharmony_ci GrSimpleMesh* fMesh = nullptr; 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci friend class ::GrOp; 143cb93a386Sopenharmony_ci}; 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_ciGrOp::Owner TestRectOp::Make(GrRecordingContext* context, 146cb93a386Sopenharmony_ci GrPaint&& paint, 147cb93a386Sopenharmony_ci const SkRect& drawRect, 148cb93a386Sopenharmony_ci const SkRect& localRect, 149cb93a386Sopenharmony_ci const SkMatrix& localM) { 150cb93a386Sopenharmony_ci const auto* caps = context->priv().caps(); 151cb93a386Sopenharmony_ci return GrOp::Make<TestRectOp>(context, caps, std::move(paint), drawRect, localRect, localM); 152cb93a386Sopenharmony_ci} 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_ciGrProcessorSet::Analysis TestRectOp::finalize(const GrCaps& caps, 155cb93a386Sopenharmony_ci const GrAppliedClip* clip, 156cb93a386Sopenharmony_ci GrClampType clampType) { 157cb93a386Sopenharmony_ci return fProcessorSet.finalize(GrProcessorAnalysisColor::Opaque::kYes, 158cb93a386Sopenharmony_ci GrProcessorAnalysisCoverage::kSingleChannel, clip, 159cb93a386Sopenharmony_ci &GrUserStencilSettings::kUnused, caps, clampType, &fColor); 160cb93a386Sopenharmony_ci} 161cb93a386Sopenharmony_ci 162cb93a386Sopenharmony_cistatic bool use_wide_color(const GrPaint& paint, const GrCaps* caps) { 163cb93a386Sopenharmony_ci return !paint.getColor4f().fitsInBytes() && caps->halfFloatVertexAttributeSupport(); 164cb93a386Sopenharmony_ci} 165cb93a386Sopenharmony_ciTestRectOp::TestRectOp(const GrCaps* caps, 166cb93a386Sopenharmony_ci GrPaint&& paint, 167cb93a386Sopenharmony_ci const SkRect& drawRect, 168cb93a386Sopenharmony_ci const SkRect& localRect, 169cb93a386Sopenharmony_ci const SkMatrix& localMatrix) 170cb93a386Sopenharmony_ci : GrMeshDrawOp(ClassID()) 171cb93a386Sopenharmony_ci , fDrawRect(drawRect) 172cb93a386Sopenharmony_ci , fLocalRect(localRect) 173cb93a386Sopenharmony_ci , fColor(paint.getColor4f()) 174cb93a386Sopenharmony_ci , fGP(localMatrix, use_wide_color(paint, caps)) 175cb93a386Sopenharmony_ci , fProcessorSet(std::move(paint)) { 176cb93a386Sopenharmony_ci this->setBounds(drawRect.makeSorted(), HasAABloat::kNo, IsHairline::kNo); 177cb93a386Sopenharmony_ci} 178cb93a386Sopenharmony_ci 179cb93a386Sopenharmony_civoid TestRectOp::onCreateProgramInfo(const GrCaps* caps, 180cb93a386Sopenharmony_ci SkArenaAlloc* arena, 181cb93a386Sopenharmony_ci const GrSurfaceProxyView& writeView, 182cb93a386Sopenharmony_ci bool usesMSAASurface, 183cb93a386Sopenharmony_ci GrAppliedClip&& appliedClip, 184cb93a386Sopenharmony_ci const GrDstProxyView& dstProxyView, 185cb93a386Sopenharmony_ci GrXferBarrierFlags renderPassXferBarriers, 186cb93a386Sopenharmony_ci GrLoadOp colorLoadOp) { 187cb93a386Sopenharmony_ci fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps, 188cb93a386Sopenharmony_ci arena, 189cb93a386Sopenharmony_ci writeView, 190cb93a386Sopenharmony_ci usesMSAASurface, 191cb93a386Sopenharmony_ci std::move(appliedClip), 192cb93a386Sopenharmony_ci dstProxyView, 193cb93a386Sopenharmony_ci &fGP, 194cb93a386Sopenharmony_ci std::move(fProcessorSet), 195cb93a386Sopenharmony_ci GrPrimitiveType::kTriangles, 196cb93a386Sopenharmony_ci renderPassXferBarriers, 197cb93a386Sopenharmony_ci colorLoadOp, 198cb93a386Sopenharmony_ci GrPipeline::InputFlags::kNone); 199cb93a386Sopenharmony_ci} 200cb93a386Sopenharmony_ci 201cb93a386Sopenharmony_civoid TestRectOp::onPrepareDraws(GrMeshDrawTarget* target) { 202cb93a386Sopenharmony_ci QuadHelper helper(target, fGP.vertexStride(), 1); 203cb93a386Sopenharmony_ci skgpu::VertexWriter writer{helper.vertices()}; 204cb93a386Sopenharmony_ci auto pos = skgpu::VertexWriter::TriStripFromRect(fDrawRect); 205cb93a386Sopenharmony_ci auto local = skgpu::VertexWriter::TriStripFromRect(fLocalRect); 206cb93a386Sopenharmony_ci GrVertexColor color(fColor, fGP.wideColor()); 207cb93a386Sopenharmony_ci writer.writeQuad(pos, local, color); 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_ci fMesh = helper.mesh(); 210cb93a386Sopenharmony_ci} 211cb93a386Sopenharmony_ci 212cb93a386Sopenharmony_civoid TestRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { 213cb93a386Sopenharmony_ci if (!fProgramInfo) { 214cb93a386Sopenharmony_ci this->createProgramInfo(flushState); 215cb93a386Sopenharmony_ci } 216cb93a386Sopenharmony_ci 217cb93a386Sopenharmony_ci flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds); 218cb93a386Sopenharmony_ci flushState->bindTextures(fProgramInfo->geomProc(), nullptr, fProgramInfo->pipeline()); 219cb93a386Sopenharmony_ci flushState->drawMesh(*fMesh); 220cb93a386Sopenharmony_ci} 221cb93a386Sopenharmony_ci 222cb93a386Sopenharmony_ci} // anonymous namespace 223cb93a386Sopenharmony_ci 224cb93a386Sopenharmony_cinamespace sk_gpu_test::test_ops { 225cb93a386Sopenharmony_ci 226cb93a386Sopenharmony_ciGrOp::Owner MakeRect(GrRecordingContext* context, 227cb93a386Sopenharmony_ci GrPaint&& paint, 228cb93a386Sopenharmony_ci const SkRect& drawRect, 229cb93a386Sopenharmony_ci const SkRect& localRect, 230cb93a386Sopenharmony_ci const SkMatrix& localM) { 231cb93a386Sopenharmony_ci return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM); 232cb93a386Sopenharmony_ci} 233cb93a386Sopenharmony_ci 234cb93a386Sopenharmony_ciGrOp::Owner MakeRect(GrRecordingContext* context, 235cb93a386Sopenharmony_ci std::unique_ptr<GrFragmentProcessor> fp, 236cb93a386Sopenharmony_ci const SkRect& drawRect, 237cb93a386Sopenharmony_ci const SkRect& localRect, 238cb93a386Sopenharmony_ci const SkMatrix& localM) { 239cb93a386Sopenharmony_ci GrPaint paint; 240cb93a386Sopenharmony_ci paint.setColorFragmentProcessor(std::move(fp)); 241cb93a386Sopenharmony_ci return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM); 242cb93a386Sopenharmony_ci} 243cb93a386Sopenharmony_ci 244cb93a386Sopenharmony_ciGrOp::Owner MakeRect(GrRecordingContext* context, 245cb93a386Sopenharmony_ci GrPaint&& paint, 246cb93a386Sopenharmony_ci const SkRect& rect) { 247cb93a386Sopenharmony_ci return TestRectOp::Make(context, std::move(paint), rect, rect, SkMatrix::I()); 248cb93a386Sopenharmony_ci} 249cb93a386Sopenharmony_ci 250cb93a386Sopenharmony_ci} // namespace sk_gpu_test::test_ops 251