/* * 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 GrCCPathProcessor_DEFINED #define GrCCPathProcessor_DEFINED #include #include "include/core/SkPath.h" #include "src/gpu/GrCaps.h" #include "src/gpu/GrGeometryProcessor.h" #include "src/gpu/GrPipeline.h" #include "src/gpu/ccpr/GrCCAtlas.h" #include "src/gpu/ccpr/GrOctoBounds.h" class GrCCPathCacheEntry; class GrCCPerFlushResources; class GrOnFlushResourceProvider; class GrOpFlushState; /** * This class draws AA paths using the coverage count masks produced by GrCCCoverageProcessor. * * Paths are drawn as bloated octagons, and coverage is derived from the coverage count mask and * fill rule. * * To draw paths, the caller must set up an instance buffer as detailed below, then call drawPaths() * providing its own instance buffer alongside the buffers found by calling FindIndexBuffer/ * FindVertexBuffer. */ class GrCCPathProcessor : public GrGeometryProcessor { public: struct Instance { SkRect fDevBounds; // "right < left" indicates even-odd fill type. SkRect fDevBounds45; // Bounding box in "| 1 -1 | * devCoords" space. See GrOctoBounds. // | 1 1 | SkIVector fDevToAtlasOffset; // Translation from device space to location in atlas. uint64_t fColor; // Color always stored as 4 x fp16 void set(const GrOctoBounds&, const SkIVector& devToAtlasOffset, uint64_t, GrFillRule); void set(const GrCCPathCacheEntry&, const SkIVector& shift, uint64_t, GrFillRule); }; GR_STATIC_ASSERT(4 * 12 == sizeof(Instance)); static sk_sp FindVertexBuffer(GrOnFlushResourceProvider*); static sk_sp FindIndexBuffer(GrOnFlushResourceProvider*); enum class CoverageMode : bool { kCoverageCount, kLiteral }; static CoverageMode GetCoverageMode(GrCCAtlas::CoverageType coverageType) { return (GrCCAtlas::CoverageType::kFP16_CoverageCount == coverageType) ? CoverageMode::kCoverageCount : CoverageMode::kLiteral; } GrCCPathProcessor( CoverageMode, const GrTexture* atlasTexture, const GrSwizzle&, GrSurfaceOrigin atlasOrigin, const SkMatrix& viewMatrixIfUsingLocalCoords = SkMatrix::I()); const char* name() const override { return "GrCCPathProcessor"; } void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override { b->add32((uint32_t)fCoverageMode); } GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; void drawPaths(GrOpFlushState*, const GrPipeline&, const GrPipeline::FixedDynamicState*, const GrCCPerFlushResources&, int baseInstance, int endInstance, const SkRect& bounds) const; private: const TextureSampler& onTextureSampler(int) const override { return fAtlasAccess; } const CoverageMode fCoverageMode; const TextureSampler fAtlasAccess; SkISize fAtlasSize; GrSurfaceOrigin fAtlasOrigin; SkMatrix fLocalMatrix; static constexpr Attribute kInstanceAttribs[] = { {"devbounds", kFloat4_GrVertexAttribType, kFloat4_GrSLType}, {"devbounds45", kFloat4_GrVertexAttribType, kFloat4_GrSLType}, {"dev_to_atlas_offset", kInt2_GrVertexAttribType, kInt2_GrSLType}, {"color", kHalf4_GrVertexAttribType, kHalf4_GrSLType} }; static constexpr int kColorAttribIdx = 3; static constexpr Attribute kCornersAttrib = {"corners", kFloat4_GrVertexAttribType, kFloat4_GrSLType}; class Impl; typedef GrGeometryProcessor INHERITED; }; inline void GrCCPathProcessor::Instance::set( const GrOctoBounds& octoBounds, const SkIVector& devToAtlasOffset, uint64_t color, GrFillRule fillRule) { if (GrFillRule::kNonzero == fillRule) { // We cover "nonzero" paths with clockwise triangles, which is the default result from // normal octo bounds. fDevBounds = octoBounds.bounds(); fDevBounds45 = octoBounds.bounds45(); } else { // We cover "even/odd" paths with counterclockwise triangles. Here we reorder the bounding // box vertices so the output is flipped horizontally. fDevBounds.setLTRB( octoBounds.right(), octoBounds.top(), octoBounds.left(), octoBounds.bottom()); fDevBounds45.setLTRB( octoBounds.bottom45(), octoBounds.right45(), octoBounds.top45(), octoBounds.left45()); } fDevToAtlasOffset = devToAtlasOffset; fColor = color; } #endif