blob: 57fb26c538db7216f7e4457199049189c91e26ae [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"
Michael Ludwigc1ed11d2021-08-24 11:49:55 -040012#include "src/core/SkTBlockList.h"
Chris Dalton83420eb2021-06-23 18:47:09 -060013#include "src/gpu/GrDynamicAtlas.h"
Robert Phillips3e87a8e2021-08-25 13:22:24 -040014#include "src/gpu/ops/OpsTask.h"
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060015#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.
Robert Phillips3e87a8e2021-08-25 13:22:24 -040025class GrAtlasRenderTask : public skgpu::v1::OpsTask {
Chris Dalton83420eb2021-06-23 18:47:09 -060026public:
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:
Robert Phillips3e87a8e2021-08-25 13:22:24 -040049 // Adds internal ops to render the atlas before deferring to OpsTask::onMakeClosed.
Chris Dalton83420eb2021-06-23 18:47:09 -060050 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
Robert Phillips3e87a8e2021-08-25 13:22:24 -040056 // Executes the OpsTask and resolves msaa if needed.
Chris Dalton83420eb2021-06-23 18:47:09 -060057 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.
Michael Ludwigc1ed11d2021-08-24 11:49:55 -040062 using PathDrawAllocator = SkTBlockList<GrPathTessellator::PathDrawList, 16>;
63 PathDrawAllocator fPathDrawAllocator{64, SkBlockAllocator::GrowthPolicy::kFibonacci};
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060064
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