Flutter Engine
The Flutter Engine
AtlasRenderTask.cpp
Go to the documentation of this file.
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
9
11#include "src/core/SkIPoint16.h"
21
22namespace skgpu::ganesh {
23
25 sk_sp<GrArenas> arenas,
26 std::unique_ptr<GrDynamicAtlas> dynamicAtlas)
27 : OpsTask(rContext->priv().drawingManager(),
28 dynamicAtlas->writeView(*rContext->priv().caps()),
29 rContext->priv().auditTrail(),
30 std::move(arenas))
31 , fDynamicAtlas(std::move(dynamicAtlas)) {
32}
33
34bool AtlasRenderTask::addPath(const SkMatrix& viewMatrix, const SkPath& path,
35 SkIPoint pathDevTopLeft, int widthInAtlas, int heightInAtlas,
36 bool transposedInAtlas, SkIPoint16* locationInAtlas) {
37 SkASSERT(!this->isClosed());
38 SkASSERT(this->isEmpty());
39 SkASSERT(!fDynamicAtlas->isInstantiated()); // Paths can't be added after instantiate().
40
41 if (!fDynamicAtlas->addRect(widthInAtlas, heightInAtlas, locationInAtlas)) {
42 return false;
43 }
44
45 SkMatrix pathToAtlasMatrix = viewMatrix;
46 if (transposedInAtlas) {
47 std::swap(pathToAtlasMatrix[0], pathToAtlasMatrix[3]);
48 std::swap(pathToAtlasMatrix[1], pathToAtlasMatrix[4]);
49 float tx=pathToAtlasMatrix.getTranslateX(), ty=pathToAtlasMatrix.getTranslateY();
50 pathToAtlasMatrix.setTranslateX(ty - pathDevTopLeft.y() + locationInAtlas->x());
51 pathToAtlasMatrix.setTranslateY(tx - pathDevTopLeft.x() + locationInAtlas->y());
52 } else {
53 pathToAtlasMatrix.postTranslate(locationInAtlas->x() - pathDevTopLeft.x(),
54 locationInAtlas->y() - pathDevTopLeft.y());
55 }
56
58 fWindingPathList.add(&fPathDrawAllocator, pathToAtlasMatrix, path);
59 } else {
60 fEvenOddPathList.add(&fPathDrawAllocator, pathToAtlasMatrix, path);
61 }
62 return true;
63}
64
65GrRenderTask::ExpectedOutcome AtlasRenderTask::onMakeClosed(GrRecordingContext* rContext,
66 SkIRect* targetUpdateBounds) {
67 // We don't add our ops until now, at which point we know the atlas is done being built.
68 SkASSERT(this->isEmpty());
69 SkASSERT(!fDynamicAtlas->isInstantiated()); // Instantiation happens after makeClosed().
70
71 const GrCaps& caps = *rContext->priv().caps();
72
73 // Set our dimensions now. OpsTask will need them when we add our ops.
74 this->target(0)->priv().setLazyDimensions(fDynamicAtlas->drawBounds());
76 SkRect drawRect = target(0)->getBoundsRect();
77
78 // Clear the atlas.
82
83 constexpr static GrUserStencilSettings kClearStencil(
85 0x0000,
87 0xffff,
90 0xffff>());
91
92 this->stencilAtlasRect(rContext, drawRect, SK_PMColor4fTRANSPARENT, &kClearStencil);
93 } else {
96 }
97
98 // Add ops to stencil the atlas paths.
99 for (const auto* pathList : {&fWindingPathList, &fEvenOddPathList}) {
100 if (pathList->pathCount() > 0) {
101 auto op = GrOp::Make<PathStencilCoverOp>(
102 rContext,
103 pathList->pathDrawList(),
104 pathList->totalCombinedPathVerbCnt(),
105 pathList->pathCount(),
106 GrPaint(),
109 drawRect);
110 this->addAtlasDrawOp(std::move(op), caps);
111 }
112 }
113
114 // Finally, draw a fullscreen rect to cover our stencilled paths.
115 const GrUserStencilSettings* stencil;
117 constexpr static GrUserStencilSettings kTestStencil(
119 0x0000,
121 0xffff,
124 0xffff>());
125
126 // This is the final op in the task. Since Ganesh is planning to discard the stencil values
127 // anyway, there is no need to reset the stencil values back to 0.
128 stencil = &kTestStencil;
129 } else {
132 0x0000,
134 0xffff,
137 0xffff>());
138
139 // Outset the cover rect to make extra sure we clear every stencil value touched by the
140 // atlas.
141 drawRect.outset(1, 1);
142 stencil = &kTestAndResetStencil;
143 }
144 this->stencilAtlasRect(rContext, drawRect, SK_PMColor4fWHITE, stencil);
145
146 this->OpsTask::onMakeClosed(rContext, targetUpdateBounds);
147
148 // Don't mark msaa dirty. Since this op defers being closed, the drawing manager's dirty
149 // tracking doesn't work anyway. We will just resolve msaa manually during onExecute.
151}
152
153void AtlasRenderTask::stencilAtlasRect(GrRecordingContext* rContext, const SkRect& rect,
154 const SkPMColor4f& color,
155 const GrUserStencilSettings* stencil) {
157 paint.setColor4f(color);
159 GrQuad quad(rect);
160 DrawQuad drawQuad{quad, quad, GrQuadAAFlags::kAll};
161 auto op = FillRectOp::Make(rContext, std::move(paint), GrAAType::kMSAA, &drawQuad, stencil);
162 this->addAtlasDrawOp(std::move(op), *rContext->priv().caps());
163}
164
165void AtlasRenderTask::addAtlasDrawOp(GrOp::Owner op, const GrCaps& caps) {
166 SkASSERT(!this->isClosed());
167
168 auto drawOp = static_cast<GrDrawOp*>(op.get());
169 SkDEBUGCODE(drawOp->fAddDrawOpCalled = true;)
170
171 auto processorAnalysis = drawOp->finalize(caps, nullptr,
172 GrColorTypeClampType(fDynamicAtlas->colorType()));
173 SkASSERT(!processorAnalysis.requiresDstTexture());
174 SkASSERT(!processorAnalysis.usesNonCoherentHWBlending());
175
176 drawOp->setClippedBounds(drawOp->bounds());
177 this->recordOp(std::move(op), true/*usesMSAA*/, processorAnalysis, nullptr, nullptr, caps);
178}
179
180bool AtlasRenderTask::onExecute(GrOpFlushState* flushState) {
181 if (!this->OpsTask::onExecute(flushState)) {
182 return false;
183 }
184 if (this->target(0)->requiresManualMSAAResolve()) {
185 // Since atlases don't get closed until they are done being built, the drawingManager
186 // doesn't detect that they need an MSAA resolve. Do it here manually.
187 auto nativeRect = GrNativeRect::MakeIRectRelativeTo(
189 this->target(0)->backingStoreDimensions().height(),
190 SkIRect::MakeSize(fDynamicAtlas->drawBounds()));
191 flushState->gpu()->resolveRenderTarget(this->target(0)->peekRenderTarget(), nativeRect);
192 }
193 return true;
194}
195
196} // namespace skgpu::ganesh
GrFillRule GrFillRuleForSkPath(const SkPath &path)
Definition: GrTypesPriv.h:195
static constexpr GrClampType GrColorTypeClampType(GrColorType colorType)
Definition: GrTypesPriv.h:868
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr SkPMColor4f SK_PMColor4fWHITE
Definition: SkColorData.h:380
constexpr SkPMColor4f SK_PMColor4fTRANSPARENT
Definition: SkColorData.h:378
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
const GrCaps * caps() const
Definition: GrCaps.h:57
bool discardStencilValuesAfterRenderPass() const
Definition: GrCaps.h:122
bool performColorClearsAsDraws() const
Definition: GrCaps.h:431
bool performStencilClearsAsDraws() const
Definition: GrCaps.h:438
static constexpr GrSurfaceOrigin kTextureOrigin
std::unique_ptr< GrOp > Owner
Definition: GrOp.h:72
Definition: GrQuad.h:30
GrRecordingContextPriv priv()
GrSurfaceProxy * target(int i) const
Definition: GrRenderTask.h:104
bool isClosed() const
Definition: GrRenderTask.h:56
SkDEBUGCODE(~GrRenderTask() override;) void makeClosed(GrRecordingContext *)
void setLazyDimensions(SkISize dimensions)
virtual GrRenderTargetProxy * asRenderTargetProxy()
GrSurfaceProxyPriv priv()
SkRect getBoundsRect() const
static const GrXPFactory * FromBlendMode(SkBlendMode)
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:281
SkMatrix & setTranslateY(SkScalar v)
Definition: SkMatrix.h:530
SkScalar getTranslateY() const
Definition: SkMatrix.h:452
SkMatrix & setTranslateX(SkScalar v)
Definition: SkMatrix.h:524
SkScalar getTranslateX() const
Definition: SkMatrix.h:445
Definition: SkPath.h:59
AtlasRenderTask(GrRecordingContext *, sk_sp< GrArenas >, std::unique_ptr< GrDynamicAtlas >)
bool addPath(const SkMatrix &, const SkPath &, SkIPoint pathDevTopLeft, int widthInAtlas, int heightInAtlas, bool transposedInAtlas, SkIPoint16 *locationInAtlas)
static GrOp::Owner Make(GrRecordingContext *, GrPaint &&, GrAAType, DrawQuad *, const GrUserStencilSettings *=nullptr, InputFlags=InputFlags::kNone)
Definition: FillRectOp.cpp:470
void recordOp(GrOp::Owner, bool usesMSAA, GrProcessorSet::Analysis, GrAppliedClip *, const GrDstProxyView *, const GrCaps &)
Definition: OpsTask.cpp:955
void setColorLoadOp(GrLoadOp op, std::array< float, 4 > color={0, 0, 0, 0})
Definition: OpsTask.cpp:659
bool isEmpty() const
Definition: OpsTask.h:50
bool onExecute(GrOpFlushState *flushState) override
Definition: OpsTask.cpp:540
void setInitialStencilContent(StencilContent initialContent)
Definition: OpsTask.h:136
ExpectedOutcome onMakeClosed(GrRecordingContext *, SkIRect *targetUpdateBounds) override
Definition: OpsTask.cpp:1057
const Paint & paint
Definition: color_source.cc:38
DlColor color
FlPixelBufferTexturePrivate * priv
Optional< SkRect > bounds
Definition: SkRecords.h:189
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
static constexpr GrUserStencilSettings kTestAndResetStencil(GrUserStencilSettings::StaticInit< 0x0000, GrUserStencilTest::kLessIfInClip, 0x0001, GrUserStencilOp::kZero, GrUserStencilOp::kReplace, 0xffff >())
Definition: ref_ptr.h:256
int32_t height
static SkIRect MakeIRectRelativeTo(GrSurfaceOrigin origin, int rtHeight, SkIRect devRect)
Definition: GrNativeRect.h:31
static constexpr Init< Ref, Test, TestMask, PassOp, FailOp, WriteMask > StaticInit()
int16_t y() const
Definition: SkIPoint16.h:43
int16_t x() const
Definition: SkIPoint16.h:37
constexpr int32_t y() const
Definition: SkPoint_impl.h:52
constexpr int32_t x() const
Definition: SkPoint_impl.h:46
Definition: SkRect.h:32
static constexpr SkIRect MakeSize(const SkISize &size)
Definition: SkRect.h:66
void outset(float dx, float dy)
Definition: SkRect.h:1077