xref: /aosp_15_r20/external/skia/src/gpu/ganesh/ops/AtlasRenderTask.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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