1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2017 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef GrCCCoverageProcessor_DEFINED 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define GrCCCoverageProcessor_DEFINED 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrCaps.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGeometryProcessor.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrShaderCaps.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkNx.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "glsl/GrGLSLGeometryProcessor.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "glsl/GrGLSLVarying.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrGLSLPPFragmentBuilder; 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrGLSLVertexGeoBuilder; 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrMesh; 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * This is the geometry processor for the simple convex primitive shapes (triangles and closed, 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * convex bezier curves) from which ccpr paths are composed. The output is a single-channel alpha 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * value, positive for clockwise shapes and negative for counter-clockwise, that indicates coverage. 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * The caller is responsible to execute all render passes for all applicable primitives into a 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * cleared, floating point, alpha-only render target using SkBlendMode::kPlus (see RenderPass 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * below). Once all of a path's primitives have been drawn, the render target contains a composite 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * coverage count that can then be used to draw the path (see GrCCPathProcessor). 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * To draw a renderer pass, see appendMesh below. 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrCCCoverageProcessor : public GrGeometryProcessor { 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Defines a single triangle or closed quadratic bezier, with transposed x,y point values. 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct TriangleInstance { 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float fX[3]; 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float fY[3]; 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void set(const SkPoint[3], const Sk2f& trans); 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void set(const SkPoint&, const SkPoint&, const SkPoint&, const Sk2f& trans); 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Defines a single closed cubic bezier, with transposed x,y point values. 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct CubicInstance { 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float fX[4]; 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float fY[4]; 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void set(const SkPoint[4], float dx, float dy); 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // All primitive shapes (triangles and closed, convex bezier curves) require more than one 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // render pass. Here we enumerate every render pass needed in order to produce a complete 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // coverage count mask. This is an exhaustive list of all ccpr coverage shaders. 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // During a render pass, the "Impl" (GSImpl or VSimpl) generates conservative geometry for 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // rasterization, and the Shader decides the coverage value at each pixel. 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot enum class RenderPass { 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // For a Hull, the Impl generates a "conservative raster hull" around the input points. This 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // is the geometry that causes a pixel to be rasterized if it is touched anywhere by the 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // input polygon. The input coverage values sent to the Shader at each vertex are either 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // null, or +1 all around if the Impl combines this pass with kTriangleEdges. Logically, 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // the conservative raster hull is equivalent to the convex hull of pixel size boxes 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // centered on each input point. 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kTriangleHulls, 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kQuadraticHulls, 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kCubicHulls, 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // For Edges, the Impl generates conservative rasters around every input edge (i.e. convex 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // hulls of two pixel-size boxes centered on both of the edge's endpoints). The input 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // coverage values sent to the Shader at each vertex are -1 on the outside border of the 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // edge geometry and 0 on the inside. This is the only geometry type that associates 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // coverage values with the output vertices. Interpolated, these coverage values convert 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // jagged conservative raster edges into a smooth antialiased edge. 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // NOTE: The Impl may combine this pass with kTriangleHulls, in which case DoesRenderPass() 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // will be false for kTriangleEdges and it must not be used. 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kTriangleEdges, 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // For Corners, the Impl Generates the conservative rasters of corner points (i.e. 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // pixel-size boxes). It generates 3 corner boxes for triangles and 2 for curves. The Shader 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // specifies which corners. Input coverage values sent to the Shader will be null. 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kTriangleCorners, 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kQuadraticCorners, 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kCubicCorners 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static bool RenderPassIsCubic(RenderPass); 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const char* RenderPassName(RenderPass); 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot constexpr static bool DoesRenderPass(RenderPass renderPass, const GrCaps& caps) { 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return RenderPass::kTriangleEdges != renderPass || 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot caps.shaderCaps()->geometryShaderSupport(); 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrCCCoverageProcessor(GrResourceProvider* rp, RenderPass pass, const GrCaps& caps) 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(kGrCCCoverageProcessor_ClassID) 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fRenderPass(pass) 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fImpl(caps.shaderCaps()->geometryShaderSupport() ? Impl::kGeometryShader 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : Impl::kVertexShader) { 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(DoesRenderPass(pass, caps)); 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (Impl::kGeometryShader == fImpl) { 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->initGS(); 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->initVS(rp, caps); 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Appends a GrMesh that will draw the provided instances. The instanceBuffer must be an array 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // of either TriangleInstance or CubicInstance, depending on this processor's RendererPass, with 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // coordinates in the desired shape's final atlas-space position. 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // NOTE: Quadratics use TriangleInstance since both have 3 points. 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void appendMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance, 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray<GrMesh>* out) { 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (Impl::kGeometryShader == fImpl) { 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->appendGSMesh(instanceBuffer, instanceCount, baseInstance, out); 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->appendVSMesh(instanceBuffer, instanceCount, baseInstance, out); 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // GrPrimitiveProcessor overrides. 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* name() const override { return RenderPassName(fRenderPass); } 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString dumpInfo() const override { 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkStringPrintf("%s\n%s", this->name(), this->INHERITED::dumpInfo().c_str()); 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Increases the 1/2 pixel AA bloat by a factor of debugBloat and outputs color instead of 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // coverage (coverage=+1 -> green, coverage=0 -> black, coverage=-1 -> red). 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void enableDebugVisualizations(float debugBloat) { fDebugBloat = debugBloat; } 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool debugVisualizationsEnabled() const { return fDebugBloat > 0; } 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float debugBloat() const { SkASSERT(this->debugVisualizationsEnabled()); return fDebugBloat; } 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The Shader provides code to calculate each pixel's coverage in a RenderPass. It also 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // provides details about shape-specific geometry. 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot class Shader { 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot public: 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot union GeometryVars { 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct { 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* fAlternatePoints; // floatNx2 (if left null, will use input points). 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } fHullVars; 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct { 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* fPoint; // float2 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } fCornerVars; 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GeometryVars() { memset(this, 0, sizeof(*this)); } 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Called before generating geometry. Subclasses must fill out the applicable fields in 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // GeometryVars (if any), and may also use this opportunity to setup internal member 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // variables that will be needed during onEmitVaryings (e.g. transformation matrices). 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // repetitionID is a 0-based index and indicates which edge or corner is being generated. 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // It will be null when generating a hull. 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual void emitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* repetitionID, const char* wind, 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GeometryVars*) const {} 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void emitVaryings(GrGLSLVaryingHandler* varyingHandler, GrGLSLVarying::Scope scope, 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString* code, const char* position, const char* inputCoverage, 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* wind) { 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(GrGLSLVarying::Scope::kVertToGeo != scope); 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->onEmitVaryings(varyingHandler, scope, code, position, inputCoverage, wind); 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void emitFragmentCode(const GrCCCoverageProcessor& proc, GrGLSLPPFragmentBuilder*, 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* skOutputColor, const char* skOutputCoverage) const; 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Defines an equation ("dot(float3(pt, 1), distance_equation)") that is -1 on the outside 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // border of a conservative raster edge and 0 on the inside. 'leftPt' and 'rightPt' must be 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // ordered clockwise. 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static void EmitEdgeDistanceEquation(GrGLSLVertexGeoBuilder*, const char* leftPt, 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* rightPt, 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* outputDistanceEquation); 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual ~Shader() {} 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot protected: 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Here the subclass adds its internal varyings to the handler and produces code to 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // initialize those varyings from a given position, input coverage value, and wind. 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // NOTE: the coverage input is only relevant for edges (see comments in RenderPass). 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Otherwise it is +1 all around. 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code, 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* position, const char* inputCoverage, 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* wind) = 0; 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Emits the fragment code that calculates a pixel's signed coverage value. 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* outputCoverage) const = 0; 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Returns the name of a Shader's internal varying at the point where where its value is 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // assigned. This is intended to work whether called for a vertex or a geometry shader. 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* OutName(const GrGLSLVarying& varying) const { 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot using Scope = GrGLSLVarying::Scope; 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(Scope::kVertToGeo != varying.scope()); 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return Scope::kGeoToFrag == varying.scope() ? varying.gsOut() : varying.vsOut(); 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Defines a global float2 array that contains MSAA sample locations as offsets from pixel 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // center. Subclasses can use this for software multisampling. 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Returns the number of samples. 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static int DefineSoftSampleLocations(GrGLSLPPFragmentBuilder* f, const char* samplesName); 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot class GSImpl; 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot class VSImpl; 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Slightly undershoot a bloat radius of 0.5 so vertices that fall on integer boundaries don't 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // accidentally bleed into neighbor pixels. 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static constexpr float kAABloatRadius = 0.491111f; 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Number of bezier points for curves, or 3 for triangles. 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int numInputPoints() const { return RenderPassIsCubic(fRenderPass) ? 4 : 3; } 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot enum class Impl : bool { 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kGeometryShader, 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kVertexShader 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void initGS(); 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void initVS(GrResourceProvider*, const GrCaps&); 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void appendGSMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance, 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray<GrMesh>* out) const; 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void appendVSMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance, 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray<GrMesh>* out) const; 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLSLPrimitiveProcessor* createGSImpl(std::unique_ptr<Shader>) const; 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLSLPrimitiveProcessor* createVSImpl(std::unique_ptr<Shader>) const; 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const RenderPass fRenderPass; 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const Impl fImpl; 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGCODE(float fDebugBloat = 0); 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Used by VSImpl. 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<const GrBuffer> fVertexBuffer; 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<const GrBuffer> fIndexBuffer; 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fNumIndicesPerInstance; 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrPrimitiveType fPrimitiveType; 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef GrGeometryProcessor INHERITED; 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotinline void GrCCCoverageProcessor::TriangleInstance::set(const SkPoint p[3], const Sk2f& trans) { 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->set(p[0], p[1], p[2], trans); 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotinline void GrCCCoverageProcessor::TriangleInstance::set(const SkPoint& p0, const SkPoint& p1, 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPoint& p2, const Sk2f& trans) { 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk2f P0 = Sk2f::Load(&p0) + trans; 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk2f P1 = Sk2f::Load(&p1) + trans; 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk2f P2 = Sk2f::Load(&p2) + trans; 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk2f::Store3(this, P0, P1, P2); 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotinline void GrCCCoverageProcessor::CubicInstance::set(const SkPoint p[4], float dx, float dy) { 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk4f X,Y; 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk4f::Load2(p, &X, &Y); 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (X + dx).store(&fX); 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (Y + dy).store(&fY); 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotinline bool GrCCCoverageProcessor::RenderPassIsCubic(RenderPass pass) { 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (pass) { 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kTriangleHulls: 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kTriangleEdges: 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kTriangleCorners: 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kQuadraticHulls: 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kQuadraticCorners: 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kCubicHulls: 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kCubicCorners: 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ABORT("Invalid RenderPass"); 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotinline const char* GrCCCoverageProcessor::RenderPassName(RenderPass pass) { 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (pass) { 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kTriangleHulls: return "kTriangleHulls"; 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kTriangleEdges: return "kTriangleEdges"; 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kTriangleCorners: return "kTriangleCorners"; 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kQuadraticHulls: return "kQuadraticHulls"; 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kQuadraticCorners: return "kQuadraticCorners"; 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kCubicHulls: return "kCubicHulls"; 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case RenderPass::kCubicCorners: return "kCubicCorners"; 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ABORT("Invalid RenderPass"); 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return ""; 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 303