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