1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2022 Google LLC 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef skgpu_graphite_RendererProvider_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define skgpu_graphite_RendererProvider_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathTypes.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkVertices.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/AtlasTypes.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Renderer.h" 15*c8dee2aaSAndroid Build Coastguard Worker 16*c8dee2aaSAndroid Build Coastguard Worker #include <vector> 17*c8dee2aaSAndroid Build Coastguard Worker 18*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite { 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker class Caps; 21*c8dee2aaSAndroid Build Coastguard Worker class StaticBufferManager; 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_ENABLE_VELLO_SHADERS 24*c8dee2aaSAndroid Build Coastguard Worker class VelloRenderer; 25*c8dee2aaSAndroid Build Coastguard Worker #endif 26*c8dee2aaSAndroid Build Coastguard Worker 27*c8dee2aaSAndroid Build Coastguard Worker /** 28*c8dee2aaSAndroid Build Coastguard Worker * Graphite defines a limited set of renderers in order to increase the likelihood of batching 29*c8dee2aaSAndroid Build Coastguard Worker * across draw calls, and reducing the number of shader permutations required. These Renderers are 30*c8dee2aaSAndroid Build Coastguard Worker * stateless singletons and remain alive for the life of the Context and its Recorders. 31*c8dee2aaSAndroid Build Coastguard Worker * 32*c8dee2aaSAndroid Build Coastguard Worker * Because Renderers are immutable and the defined Renderers are created at context initialization, 33*c8dee2aaSAndroid Build Coastguard Worker * RendererProvider is trivially thread-safe. 34*c8dee2aaSAndroid Build Coastguard Worker */ 35*c8dee2aaSAndroid Build Coastguard Worker class RendererProvider { 36*c8dee2aaSAndroid Build Coastguard Worker public: 37*c8dee2aaSAndroid Build Coastguard Worker static bool IsVelloRendererSupported(const Caps*); 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker ~RendererProvider(); 40*c8dee2aaSAndroid Build Coastguard Worker 41*c8dee2aaSAndroid Build Coastguard Worker // TODO: Add configuration options to disable "optimization" renderers in favor of the more 42*c8dee2aaSAndroid Build Coastguard Worker // general case, or renderers that won't be used by the application. When that's added, these 43*c8dee2aaSAndroid Build Coastguard Worker // functions could return null. 44*c8dee2aaSAndroid Build Coastguard Worker 45*c8dee2aaSAndroid Build Coastguard Worker // Path rendering for fills and strokes stencilTessellatedCurvesAndTris(SkPathFillType type)46*c8dee2aaSAndroid Build Coastguard Worker const Renderer* stencilTessellatedCurvesAndTris(SkPathFillType type) const { 47*c8dee2aaSAndroid Build Coastguard Worker return &fStencilTessellatedCurves[(int) type]; 48*c8dee2aaSAndroid Build Coastguard Worker } stencilTessellatedWedges(SkPathFillType type)49*c8dee2aaSAndroid Build Coastguard Worker const Renderer* stencilTessellatedWedges(SkPathFillType type) const { 50*c8dee2aaSAndroid Build Coastguard Worker return &fStencilTessellatedWedges[(int) type]; 51*c8dee2aaSAndroid Build Coastguard Worker } convexTessellatedWedges()52*c8dee2aaSAndroid Build Coastguard Worker const Renderer* convexTessellatedWedges() const { return &fConvexTessellatedWedges; } tessellatedStrokes()53*c8dee2aaSAndroid Build Coastguard Worker const Renderer* tessellatedStrokes() const { return &fTessellatedStrokes; } 54*c8dee2aaSAndroid Build Coastguard Worker 55*c8dee2aaSAndroid Build Coastguard Worker // Coverage mask rendering coverageMask()56*c8dee2aaSAndroid Build Coastguard Worker const Renderer* coverageMask() const { return &fCoverageMask; } 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Worker // Atlased text rendering bitmapText(bool useLCDText,skgpu::MaskFormat format)59*c8dee2aaSAndroid Build Coastguard Worker const Renderer* bitmapText(bool useLCDText, skgpu::MaskFormat format) const { 60*c8dee2aaSAndroid Build Coastguard Worker // We use 565 here to represent all LCD rendering, regardless of texture format 61*c8dee2aaSAndroid Build Coastguard Worker if (useLCDText) { 62*c8dee2aaSAndroid Build Coastguard Worker return &fBitmapText[(int)skgpu::MaskFormat::kA565]; 63*c8dee2aaSAndroid Build Coastguard Worker } 64*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(format != skgpu::MaskFormat::kA565); 65*c8dee2aaSAndroid Build Coastguard Worker return &fBitmapText[(int)format]; 66*c8dee2aaSAndroid Build Coastguard Worker } sdfText(bool useLCDText)67*c8dee2aaSAndroid Build Coastguard Worker const Renderer* sdfText(bool useLCDText) const { return &fSDFText[useLCDText]; } 68*c8dee2aaSAndroid Build Coastguard Worker 69*c8dee2aaSAndroid Build Coastguard Worker // Mesh rendering vertices(SkVertices::VertexMode mode,bool hasColors,bool hasTexCoords)70*c8dee2aaSAndroid Build Coastguard Worker const Renderer* vertices(SkVertices::VertexMode mode, bool hasColors, bool hasTexCoords) const { 71*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(mode != SkVertices::kTriangleFan_VertexMode); // Should be converted to kTriangles 72*c8dee2aaSAndroid Build Coastguard Worker bool triStrip = mode == SkVertices::kTriangleStrip_VertexMode; 73*c8dee2aaSAndroid Build Coastguard Worker return &fVertices[4*triStrip + 2*hasColors + hasTexCoords]; 74*c8dee2aaSAndroid Build Coastguard Worker } 75*c8dee2aaSAndroid Build Coastguard Worker 76*c8dee2aaSAndroid Build Coastguard Worker // Filled and stroked [r]rects analyticRRect()77*c8dee2aaSAndroid Build Coastguard Worker const Renderer* analyticRRect() const { return &fAnalyticRRect; } 78*c8dee2aaSAndroid Build Coastguard Worker 79*c8dee2aaSAndroid Build Coastguard Worker // Per-edge AA quadrilaterals perEdgeAAQuad()80*c8dee2aaSAndroid Build Coastguard Worker const Renderer* perEdgeAAQuad() const { return &fPerEdgeAAQuad; } 81*c8dee2aaSAndroid Build Coastguard Worker 82*c8dee2aaSAndroid Build Coastguard Worker // Non-AA bounds filling (can handle inverse "fills" but will touch every pixel within the clip) nonAABounds()83*c8dee2aaSAndroid Build Coastguard Worker const Renderer* nonAABounds() const { return &fNonAABoundsFill; } 84*c8dee2aaSAndroid Build Coastguard Worker 85*c8dee2aaSAndroid Build Coastguard Worker // Circular arcs circularArc()86*c8dee2aaSAndroid Build Coastguard Worker const Renderer* circularArc() const { return &fCircularArc; } 87*c8dee2aaSAndroid Build Coastguard Worker analyticBlur()88*c8dee2aaSAndroid Build Coastguard Worker const Renderer* analyticBlur() const { return &fAnalyticBlur; } 89*c8dee2aaSAndroid Build Coastguard Worker 90*c8dee2aaSAndroid Build Coastguard Worker // TODO: May need to add support for inverse filled strokes (need to check SVG spec if this is a 91*c8dee2aaSAndroid Build Coastguard Worker // real thing). 92*c8dee2aaSAndroid Build Coastguard Worker 93*c8dee2aaSAndroid Build Coastguard Worker // Iterate over all available Renderers to combine with specified paint combinations when 94*c8dee2aaSAndroid Build Coastguard Worker // pre-compiling pipelines. renderers()95*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const Renderer* const> renderers() const { 96*c8dee2aaSAndroid Build Coastguard Worker return {fRenderers.data(), fRenderers.size()}; 97*c8dee2aaSAndroid Build Coastguard Worker } 98*c8dee2aaSAndroid Build Coastguard Worker 99*c8dee2aaSAndroid Build Coastguard Worker const RenderStep* lookup(uint32_t uniqueID) const; 100*c8dee2aaSAndroid Build Coastguard Worker 101*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_ENABLE_VELLO_SHADERS 102*c8dee2aaSAndroid Build Coastguard Worker // Compute shader-based path renderer and compositor. velloRenderer()103*c8dee2aaSAndroid Build Coastguard Worker const VelloRenderer* velloRenderer() const { return fVelloRenderer.get(); } 104*c8dee2aaSAndroid Build Coastguard Worker #endif 105*c8dee2aaSAndroid Build Coastguard Worker 106*c8dee2aaSAndroid Build Coastguard Worker private: 107*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kPathTypeCount = 4; 108*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kVerticesCount = 8; // 2 modes * 2 color configs * 2 tex coord configs 109*c8dee2aaSAndroid Build Coastguard Worker 110*c8dee2aaSAndroid Build Coastguard Worker friend class Context; // for ctor 111*c8dee2aaSAndroid Build Coastguard Worker 112*c8dee2aaSAndroid Build Coastguard Worker // TODO: Take in caps that determines which Renderers to use for each category 113*c8dee2aaSAndroid Build Coastguard Worker RendererProvider(const Caps*, StaticBufferManager* bufferManager); 114*c8dee2aaSAndroid Build Coastguard Worker 115*c8dee2aaSAndroid Build Coastguard Worker // Cannot be moved or copied 116*c8dee2aaSAndroid Build Coastguard Worker RendererProvider(const RendererProvider&) = delete; 117*c8dee2aaSAndroid Build Coastguard Worker RendererProvider(RendererProvider&&) = delete; 118*c8dee2aaSAndroid Build Coastguard Worker 119*c8dee2aaSAndroid Build Coastguard Worker // Renderers are composed of 1+ steps, and some steps can be shared by multiple Renderers. 120*c8dee2aaSAndroid Build Coastguard Worker // Renderers don't keep their RenderSteps alive so RendererProvider holds them here. 121*c8dee2aaSAndroid Build Coastguard Worker std::vector<std::unique_ptr<RenderStep>> fRenderSteps; 122*c8dee2aaSAndroid Build Coastguard Worker 123*c8dee2aaSAndroid Build Coastguard Worker // NOTE: Keep all Renderers dense to support automatically completing 'fRenderers'. 124*c8dee2aaSAndroid Build Coastguard Worker Renderer fStencilTessellatedCurves[kPathTypeCount]; 125*c8dee2aaSAndroid Build Coastguard Worker Renderer fStencilTessellatedWedges[kPathTypeCount]; 126*c8dee2aaSAndroid Build Coastguard Worker Renderer fConvexTessellatedWedges; 127*c8dee2aaSAndroid Build Coastguard Worker Renderer fTessellatedStrokes; 128*c8dee2aaSAndroid Build Coastguard Worker 129*c8dee2aaSAndroid Build Coastguard Worker Renderer fCoverageMask; 130*c8dee2aaSAndroid Build Coastguard Worker 131*c8dee2aaSAndroid Build Coastguard Worker Renderer fBitmapText[3]; // int variant 132*c8dee2aaSAndroid Build Coastguard Worker Renderer fSDFText[2]; // bool isLCD 133*c8dee2aaSAndroid Build Coastguard Worker 134*c8dee2aaSAndroid Build Coastguard Worker Renderer fAnalyticRRect; 135*c8dee2aaSAndroid Build Coastguard Worker Renderer fPerEdgeAAQuad; 136*c8dee2aaSAndroid Build Coastguard Worker Renderer fNonAABoundsFill; 137*c8dee2aaSAndroid Build Coastguard Worker Renderer fCircularArc; 138*c8dee2aaSAndroid Build Coastguard Worker 139*c8dee2aaSAndroid Build Coastguard Worker Renderer fAnalyticBlur; 140*c8dee2aaSAndroid Build Coastguard Worker 141*c8dee2aaSAndroid Build Coastguard Worker Renderer fVertices[kVerticesCount]; 142*c8dee2aaSAndroid Build Coastguard Worker 143*c8dee2aaSAndroid Build Coastguard Worker // Aggregate of all enabled Renderers for convenient iteration when pre-compiling 144*c8dee2aaSAndroid Build Coastguard Worker std::vector<const Renderer*> fRenderers; 145*c8dee2aaSAndroid Build Coastguard Worker 146*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_ENABLE_VELLO_SHADERS 147*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<VelloRenderer> fVelloRenderer; 148*c8dee2aaSAndroid Build Coastguard Worker #endif 149*c8dee2aaSAndroid Build Coastguard Worker }; 150*c8dee2aaSAndroid Build Coastguard Worker 151*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite 152*c8dee2aaSAndroid Build Coastguard Worker 153*c8dee2aaSAndroid Build Coastguard Worker #endif // skgpu_graphite_RendererProvider_DEFINED 154