1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2021 Google Inc. 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 #ifndef AtlasRenderTask_DEFINED 8*c8dee2aaSAndroid Build Coastguard Worker #define AtlasRenderTask_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkNoncopyable.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkBlockAllocator.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkTBlockList.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDynamicAtlas.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxyView.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTexture.h" 21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/ops/GrOp.h" 22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/ops/OpsTask.h" 23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/tessellate/PathTessellator.h" 24*c8dee2aaSAndroid Build Coastguard Worker 25*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 26*c8dee2aaSAndroid Build Coastguard Worker #include <utility> 27*c8dee2aaSAndroid Build Coastguard Worker 28*c8dee2aaSAndroid Build Coastguard Worker class GrArenas; 29*c8dee2aaSAndroid Build Coastguard Worker class GrOnFlushResourceProvider; 30*c8dee2aaSAndroid Build Coastguard Worker class GrOpFlushState; 31*c8dee2aaSAndroid Build Coastguard Worker class GrRecordingContext; 32*c8dee2aaSAndroid Build Coastguard Worker class GrTextureProxy; 33*c8dee2aaSAndroid Build Coastguard Worker class SkMatrix; 34*c8dee2aaSAndroid Build Coastguard Worker struct GrUserStencilSettings; 35*c8dee2aaSAndroid Build Coastguard Worker struct SkIPoint16; 36*c8dee2aaSAndroid Build Coastguard Worker struct SkIPoint; 37*c8dee2aaSAndroid Build Coastguard Worker struct SkIRect; 38*c8dee2aaSAndroid Build Coastguard Worker struct SkRect; 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::ganesh { 41*c8dee2aaSAndroid Build Coastguard Worker 42*c8dee2aaSAndroid Build Coastguard Worker // Represents a GrRenderTask that draws paths into an atlas. This task gets added the DAG and left 43*c8dee2aaSAndroid Build Coastguard Worker // open, lays out its atlas while future tasks call addPath(), and finally adds its internal draw 44*c8dee2aaSAndroid Build Coastguard Worker // ops during onMakeClosed(). 45*c8dee2aaSAndroid Build Coastguard Worker // 46*c8dee2aaSAndroid Build Coastguard Worker // The atlas texture does not get instantiated automatically. It is the creator's responsibility to 47*c8dee2aaSAndroid Build Coastguard Worker // call instantiate() at flush time. 48*c8dee2aaSAndroid Build Coastguard Worker class AtlasRenderTask final : public OpsTask { 49*c8dee2aaSAndroid Build Coastguard Worker public: 50*c8dee2aaSAndroid Build Coastguard Worker AtlasRenderTask(GrRecordingContext*, 51*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrArenas>, 52*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrDynamicAtlas>); 53*c8dee2aaSAndroid Build Coastguard Worker atlasProxy()54*c8dee2aaSAndroid Build Coastguard Worker const GrTextureProxy* atlasProxy() const { return fDynamicAtlas->textureProxy(); } readView(const GrCaps & caps)55*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceProxyView readView(const GrCaps& caps) const { return fDynamicAtlas->readView(caps); } 56*c8dee2aaSAndroid Build Coastguard Worker 57*c8dee2aaSAndroid Build Coastguard Worker // Allocates a rectangle for, and stages the given path to be rendered into the atlas. Returns 58*c8dee2aaSAndroid Build Coastguard Worker // false if there was not room in the atlas. On success, writes out the location of the path's 59*c8dee2aaSAndroid Build Coastguard Worker // upper-left corner to 'locationInAtlas'. 60*c8dee2aaSAndroid Build Coastguard Worker bool addPath(const SkMatrix&, const SkPath&, SkIPoint pathDevTopLeft, int widthInAtlas, 61*c8dee2aaSAndroid Build Coastguard Worker int heightInAtlas, bool transposedInAtlas, SkIPoint16* locationInAtlas); 62*c8dee2aaSAndroid Build Coastguard Worker 63*c8dee2aaSAndroid Build Coastguard Worker // Must be called at flush time. The texture proxy is instantiated with 'backingTexture', if 64*c8dee2aaSAndroid Build Coastguard Worker // provided. See GrDynamicAtlas. 65*c8dee2aaSAndroid Build Coastguard Worker [[nodiscard]] bool instantiate(GrOnFlushResourceProvider* onFlushRP, 66*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrTexture> backingTexture = nullptr) { 67*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(this->isClosed()); 68*c8dee2aaSAndroid Build Coastguard Worker return fDynamicAtlas->instantiate(onFlushRP, std::move(backingTexture)); 69*c8dee2aaSAndroid Build Coastguard Worker } 70*c8dee2aaSAndroid Build Coastguard Worker 71*c8dee2aaSAndroid Build Coastguard Worker private: 72*c8dee2aaSAndroid Build Coastguard Worker // Adds internal ops to render the atlas before deferring to OpsTask::onMakeClosed. 73*c8dee2aaSAndroid Build Coastguard Worker ExpectedOutcome onMakeClosed(GrRecordingContext*, SkIRect* targetUpdateBounds) override; 74*c8dee2aaSAndroid Build Coastguard Worker 75*c8dee2aaSAndroid Build Coastguard Worker void stencilAtlasRect(GrRecordingContext*, const SkRect&, const SkPMColor4f&, 76*c8dee2aaSAndroid Build Coastguard Worker const GrUserStencilSettings*); 77*c8dee2aaSAndroid Build Coastguard Worker void addAtlasDrawOp(GrOp::Owner, const GrCaps&); 78*c8dee2aaSAndroid Build Coastguard Worker 79*c8dee2aaSAndroid Build Coastguard Worker // Executes the OpsTask and resolves msaa if needed. 80*c8dee2aaSAndroid Build Coastguard Worker bool onExecute(GrOpFlushState* flushState) override; 81*c8dee2aaSAndroid Build Coastguard Worker 82*c8dee2aaSAndroid Build Coastguard Worker const std::unique_ptr<GrDynamicAtlas> fDynamicAtlas; 83*c8dee2aaSAndroid Build Coastguard Worker 84*c8dee2aaSAndroid Build Coastguard Worker // Allocate enough inline entries for 16 atlas path draws, then spill to the heap. 85*c8dee2aaSAndroid Build Coastguard Worker using PathDrawList = PathTessellator::PathDrawList; 86*c8dee2aaSAndroid Build Coastguard Worker using PathDrawAllocator = SkTBlockList<PathDrawList, 16>; 87*c8dee2aaSAndroid Build Coastguard Worker PathDrawAllocator fPathDrawAllocator{64, SkBlockAllocator::GrowthPolicy::kFibonacci}; 88*c8dee2aaSAndroid Build Coastguard Worker 89*c8dee2aaSAndroid Build Coastguard Worker class AtlasPathList : SkNoncopyable { 90*c8dee2aaSAndroid Build Coastguard Worker public: add(PathDrawAllocator * alloc,const SkMatrix & pathMatrix,const SkPath & path)91*c8dee2aaSAndroid Build Coastguard Worker void add(PathDrawAllocator* alloc, const SkMatrix& pathMatrix, const SkPath& path) { 92*c8dee2aaSAndroid Build Coastguard Worker fPathDrawList = &alloc->emplace_back(pathMatrix, path, SK_PMColor4fTRANSPARENT, 93*c8dee2aaSAndroid Build Coastguard Worker fPathDrawList); 94*c8dee2aaSAndroid Build Coastguard Worker if (path.isInverseFillType()) { 95*c8dee2aaSAndroid Build Coastguard Worker // The atlas never has inverse paths. The inversion happens later. 96*c8dee2aaSAndroid Build Coastguard Worker fPathDrawList->fPath.toggleInverseFillType(); 97*c8dee2aaSAndroid Build Coastguard Worker } 98*c8dee2aaSAndroid Build Coastguard Worker fTotalCombinedPathVerbCnt += path.countVerbs(); 99*c8dee2aaSAndroid Build Coastguard Worker ++fPathCount; 100*c8dee2aaSAndroid Build Coastguard Worker } pathDrawList()101*c8dee2aaSAndroid Build Coastguard Worker const PathDrawList* pathDrawList() const { return fPathDrawList; } totalCombinedPathVerbCnt()102*c8dee2aaSAndroid Build Coastguard Worker int totalCombinedPathVerbCnt() const { return fTotalCombinedPathVerbCnt; } pathCount()103*c8dee2aaSAndroid Build Coastguard Worker int pathCount() const { return fPathCount; } 104*c8dee2aaSAndroid Build Coastguard Worker 105*c8dee2aaSAndroid Build Coastguard Worker private: 106*c8dee2aaSAndroid Build Coastguard Worker PathDrawList* fPathDrawList = nullptr; 107*c8dee2aaSAndroid Build Coastguard Worker int fTotalCombinedPathVerbCnt = 0; 108*c8dee2aaSAndroid Build Coastguard Worker int fPathCount = 0; 109*c8dee2aaSAndroid Build Coastguard Worker }; 110*c8dee2aaSAndroid Build Coastguard Worker 111*c8dee2aaSAndroid Build Coastguard Worker AtlasPathList fWindingPathList; 112*c8dee2aaSAndroid Build Coastguard Worker AtlasPathList fEvenOddPathList; 113*c8dee2aaSAndroid Build Coastguard Worker }; 114*c8dee2aaSAndroid Build Coastguard Worker 115*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::ganesh 116*c8dee2aaSAndroid Build Coastguard Worker 117*c8dee2aaSAndroid Build Coastguard Worker #endif // AtlasRenderTask_DEFINED 118