1/*
2 * Copyright 2020 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 GrDrawAtlasPathOp_DEFINED
9#define GrDrawAtlasPathOp_DEFINED
10
11#include "src/core/SkIPoint16.h"
12#include "src/gpu/ops/GrDrawOp.h"
13
14class GrDrawAtlasPathOp : public GrDrawOp {
15public:
16 DEFINE_OP_CLASS_ID
17
18 GrDrawAtlasPathOp(int numRenderTargetSamples, sk_sp<GrTextureProxy> atlasProxy,
19 const SkIRect& devIBounds, const SkIPoint16& locationInAtlas,
20 bool transposedInAtlas, const SkMatrix& viewMatrix, GrPaint&& paint)
21 : GrDrawOp(ClassID())
22 , fEnableHWAA(numRenderTargetSamples > 1)
23 , fAtlasProxy(std::move(atlasProxy))
24 , fInstanceList(devIBounds, locationInAtlas, transposedInAtlas, paint.getColor4f(),
25 viewMatrix)
26 , fProcessors(std::move(paint)) {
27 this->setBounds(SkRect::Make(devIBounds), HasAABloat::kYes, IsHairline::kNo);
28 }
29
30 const char* name() const override { return "GrDrawAtlasPathOp"; }
31 FixedFunctionFlags fixedFunctionFlags() const override {
32 return (fEnableHWAA) ? FixedFunctionFlags::kUsesHWAA : FixedFunctionFlags::kNone;
33 }
34 void visitProxies(const VisitProxyFunc& fn) const override {
35 fn(fAtlasProxy.get(), GrMipmapped::kNo);
36 fProcessors.visitProxies(fn);
37 }
38 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
39 bool hasMixedSampledCoverage, GrClampType) override;
40 CombineResult onCombineIfPossible(GrOp*, GrRecordingContext::Arenas*, const GrCaps&) override;
41 void onPrepare(GrOpFlushState*) override;
42 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
43
44private:
45 void onPrePrepare(GrRecordingContext*,
46 const GrSurfaceProxyView* writeView,
47 GrAppliedClip*,
48 const GrXferProcessor::DstProxyView&) override;
49
50 struct Instance {
51 constexpr static size_t Stride(bool usesLocalCoords) {
52 size_t stride = sizeof(Instance);
53 if (!usesLocalCoords) {
54 stride -= sizeof(Instance::fViewMatrixIfUsingLocalCoords);
55 }
56 return stride;
57 }
58 Instance(const SkIRect& devIBounds, const SkIPoint16& locationInAtlas,
59 bool transposedInAtlas, const SkPMColor4f& color, const SkMatrix& m)
60 : fDevXYWH{devIBounds.left(), devIBounds.top(), devIBounds.width(),
61 // We use negative height to indicate that the path is transposed.
62 (transposedInAtlas) ? -devIBounds.height() : devIBounds.height()}
63 , fAtlasXY{locationInAtlas.x(), locationInAtlas.y()}
64 , fColor(color)
65 , fViewMatrixIfUsingLocalCoords{m.getScaleX(), m.getSkewY(),
66 m.getSkewX(), m.getScaleY(),
67 m.getTranslateX(), m.getTranslateY()} {
68 }
69 std::array<int, 4> fDevXYWH;
70 std::array<int, 2> fAtlasXY;
71 SkPMColor4f fColor;
72 float fViewMatrixIfUsingLocalCoords[6];
73 };
74
75 struct InstanceList {
76 InstanceList(const SkIRect& devIBounds, const SkIPoint16& locationInAtlas,
77 bool transposedInAtlas, const SkPMColor4f& color, const SkMatrix& viewMatrix)
78 : fInstance(devIBounds, locationInAtlas, transposedInAtlas, color, viewMatrix) {
79 }
80 InstanceList* fNext = nullptr;
81 Instance fInstance;
82 };
83
84 const bool fEnableHWAA;
85 const sk_sp<GrTextureProxy> fAtlasProxy;
86 bool fUsesLocalCoords = false;
87
88 InstanceList fInstanceList;
89 InstanceList** fInstanceTail = &fInstanceList.fNext;
90 int fInstanceCount = 1;
91
92 sk_sp<const GrBuffer> fInstanceBuffer;
93 int fBaseInstance;
94
95 GrProcessorSet fProcessors;
96};
97
98#endif
99