/* * Copyright 2017 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrCCPRTriangleShader_DEFINED #define GrCCPRTriangleShader_DEFINED #include "ccpr/GrCCPRCoverageProcessor.h" /** * This class renders the coverage of triangles. Triangles are rendered in three passes, as * described below. */ class GrCCPRTriangleShader : public GrCCPRCoverageProcessor::Shader { public: int getNumInputPoints() const final { return 3; } int getNumSegments() const final { return 3; } // 3 wedges, 3 edges, 3 corners. void appendInputPointFetch(const GrCCPRCoverageProcessor&, GrGLSLShaderBuilder*, const TexelBufferHandle& pointsBuffer, const char* pointId) const final; void emitWind(GrGLSLShaderBuilder* s, const char* pts, const char* rtAdjust, const char* outputWind) const final; }; /** * Pass 1: Draw the triangle's conservative raster hull with a coverage of 1. (Conservative raster * is drawn by considering 3 pixel size boxes, one centered at each vertex, and drawing the * convex hull of those boxes.) */ class GrCCPRTriangleHullShader : public GrCCPRTriangleShader { GeometryType getGeometryType() const override { return GeometryType::kHull; } WindHandling onEmitVaryings(GrGLSLVaryingHandler*, SkString* code, const char* position, const char* coverage, const char* wind) override; void onEmitFragmentCode(GrGLSLPPFragmentBuilder* f, const char* outputCoverage) const override; }; /** * Pass 2: Smooth the edges that were over-rendered during Pass 1. Draw the conservative raster of * each edge (i.e. convex hull of two pixel-size boxes at the endpoints), interpolating from * coverage=-1 on the outside edge to coverage=0 on the inside edge. */ class GrCCPRTriangleEdgeShader : public GrCCPRTriangleShader { GeometryType getGeometryType() const override { return GeometryType::kEdges; } WindHandling onEmitVaryings(GrGLSLVaryingHandler*, SkString* code, const char* position, const char* coverage, const char* wind) override; void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override; GrGLSLGeoToFrag fCoverageTimesWind{kHalf_GrSLType}; }; /** * Pass 3: Touch up the corner pixels. Here we fix the simple distance-to-edge coverage analysis * done previously so that it takes into account the region that is outside both edges at * the same time. */ class GrCCPRTriangleCornerShader : public GrCCPRTriangleShader { GeometryType getGeometryType() const override { return GeometryType::kCorners; } void emitSetupCode(GrGLSLShaderBuilder*, const char* pts, const char* cornerId, const char* bloat, const char* wind, const char* rtAdjust, GeometryVars*) const override; WindHandling onEmitVaryings(GrGLSLVaryingHandler*, SkString* code, const char* position, const char* coverage, const char* wind) override; void onEmitFragmentCode(GrGLSLPPFragmentBuilder* f, const char* outputCoverage) const override; GrShaderVar fAABoxMatrices{"aa_box_matrices", kFloat2x2_GrSLType, 2}; GrShaderVar fAABoxTranslates{"aa_box_translates", kFloat2_GrSLType, 2}; GrShaderVar fGeoShaderBisects{"bisects", kFloat2_GrSLType, 2}; GrGLSLGeoToFrag fCornerLocationInAABoxes{kFloat2x2_GrSLType}; GrGLSLGeoToFrag fBisectInAABoxes{kFloat2x2_GrSLType}; }; #endif