blob: 1074a9f111affd8db9f01f25cbee5f1bfdcfbd1d [file] [log] [blame]
Chris Dalton83420eb2021-06-23 18:47:09 -06001/*
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
Robert Phillips832f3fb2021-08-18 13:05:15 -04008#ifndef GrAtlasRenderTask_DEFINED
9#define GrAtlasRenderTask_DEFINED
Chris Dalton83420eb2021-06-23 18:47:09 -060010
11#include "include/core/SkPath.h"
12#include "src/gpu/GrDynamicAtlas.h"
13#include "src/gpu/GrOpsTask.h"
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060014#include "src/gpu/GrTBlockList.h"
15#include "src/gpu/tessellate/GrPathTessellator.h"
Chris Dalton83420eb2021-06-23 18:47:09 -060016
17struct SkIPoint16;
18
19// Represents a GrRenderTask that draws paths into an atlas. This task gets added the DAG and left
20// open, lays out its atlas while future tasks call addPath(), and finally adds its internal draw
21// ops during onMakeClosed().
22//
23// The atlas texture does not get instantiated automatically. It is the creator's responsibility to
24// call instantiate() at flush time.
25class GrAtlasRenderTask : public GrOpsTask {
26public:
Robert Phillipsa92913e2021-07-12 16:31:52 -040027 GrAtlasRenderTask(GrRecordingContext*,
28 sk_sp<GrArenas>,
Chris Dalton83420eb2021-06-23 18:47:09 -060029 std::unique_ptr<GrDynamicAtlas>);
30
31 const GrTextureProxy* atlasProxy() const { return fDynamicAtlas->textureProxy(); }
32 GrSurfaceProxyView readView(const GrCaps& caps) const { return fDynamicAtlas->readView(caps); }
33
34 // Allocates a rectangle for, and stages the given path to be rendered into the atlas. Returns
35 // false if there was not room in the atlas. On success, writes out the location of the path's
36 // upper-left corner to 'locationInAtlas'.
Chris Dalton5e332c82021-07-21 16:04:47 -060037 bool addPath(const SkMatrix&, const SkPath&, SkIPoint pathDevTopLeft, int widthInAtlas,
38 int heightInAtlas, bool transposedInAtlas, SkIPoint16* locationInAtlas);
Chris Dalton83420eb2021-06-23 18:47:09 -060039
40 // Must be called at flush time. The texture proxy is instantiated with 'backingTexture', if
41 // provided. See GrDynamicAtlas.
42 void instantiate(GrOnFlushResourceProvider* onFlushRP,
43 sk_sp<GrTexture> backingTexture = nullptr) {
44 SkASSERT(this->isClosed());
45 fDynamicAtlas->instantiate(onFlushRP, std::move(backingTexture));
46 }
47
48private:
49 // Adds internal ops to render the atlas before deferring to GrOpsTask::onMakeClosed.
50 ExpectedOutcome onMakeClosed(GrRecordingContext*, SkIRect* targetUpdateBounds) override;
51
52 void stencilAtlasRect(GrRecordingContext*, const SkRect&, const SkPMColor4f&,
53 const GrUserStencilSettings*);
Chris Dalton5e332c82021-07-21 16:04:47 -060054 void addAtlasDrawOp(GrOp::Owner, const GrCaps&);
Chris Dalton83420eb2021-06-23 18:47:09 -060055
56 // Executes the GrOpsTask and resolves msaa if needed.
57 bool onExecute(GrOpFlushState* flushState) override;
58
Chris Dalton83420eb2021-06-23 18:47:09 -060059 const std::unique_ptr<GrDynamicAtlas> fDynamicAtlas;
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060060
61 // Allocate enough inline entries for 16 atlas path draws, then spill to the heap.
62 using PathDrawAllocator = GrTBlockList<GrPathTessellator::PathDrawList, 16>;
63 PathDrawAllocator fPathDrawAllocator{64, GrBlockAllocator::GrowthPolicy::kFibonacci};
64
65 class AtlasPathList : SkNoncopyable {
66 public:
67 void add(PathDrawAllocator* alloc, const SkMatrix& pathMatrix, const SkPath& path) {
68 fPathDrawList = &alloc->emplace_back(pathMatrix, path, fPathDrawList);
69 if (path.isInverseFillType()) {
70 // The atlas never has inverse paths. The inversion happens later.
71 fPathDrawList->fPath.toggleInverseFillType();
72 }
73 fTotalCombinedPathVerbCnt += path.countVerbs();
74 ++fPathCount;
75 }
76 const GrPathTessellator::PathDrawList* pathDrawList() const { return fPathDrawList; }
77 int totalCombinedPathVerbCnt() const { return fTotalCombinedPathVerbCnt; }
78 int pathCount() const { return fPathCount; }
79
80 private:
81 GrPathTessellator::PathDrawList* fPathDrawList = nullptr;
82 int fTotalCombinedPathVerbCnt = 0;
83 int fPathCount = 0;
84 };
85
86 AtlasPathList fWindingPathList;
87 AtlasPathList fEvenOddPathList;
Chris Dalton83420eb2021-06-23 18:47:09 -060088};
89
90#endif