1 /*
2  * Copyright 2019 Google LLC.
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 GrStencilAtlasOp_DEFINED
9 #define GrStencilAtlasOp_DEFINED
10 
11 #include "src/gpu/GrMemoryPool.h"
12 #include "src/gpu/ccpr/GrCCFiller.h"
13 #include "src/gpu/ccpr/GrCCStroker.h"
14 #include "src/gpu/ops/GrDrawOp.h"
15 
16 class GrCCPerFlushResources;
17 
18 // Renders literal A8 coverage to a CCPR atlas using an intermediate MSAA stencil buffer.
19 class GrStencilAtlasOp : public GrDrawOp {
20 public:
21     DEFINE_OP_CLASS_ID
22 
23     using FillBatchID = GrCCFiller::BatchID;
24     using StrokeBatchID = GrCCStroker::BatchID;
25 
26     // Once all the paths in an atlas have been drawn to the stencil buffer, we make a final pass
27     // where we draw "resolve" rects over each path whose purpose is to convert winding counts to A8
28     // coverage.
29     struct ResolveRectInstance {
30         int16_t l, t, r, b;
31     };
32 
33     // GrDrawOp interface.
name()34     const char* name() const override { return "StencilAtlasOp (CCPR)"; }
fixedFunctionFlags()35     FixedFunctionFlags fixedFunctionFlags() const override {
36         return FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil;
37     }
38 
finalize(const GrCaps &,const GrAppliedClip *,bool hasMixedSampledCoverage,GrClampType)39     GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
40                                       bool hasMixedSampledCoverage, GrClampType) override {
41         return GrProcessorSet::EmptySetAnalysis();
42     }
onCombineIfPossible(GrOp * other,const GrCaps &)43     CombineResult onCombineIfPossible(GrOp* other, const GrCaps&) override {
44         // We will only make multiple copy ops if they have different source proxies.
45         // TODO: make use of texture chaining.
46         return CombineResult::kCannotCombine;
47     }
onPrepare(GrOpFlushState *)48     void onPrepare(GrOpFlushState*) override {}
49 
50     static std::unique_ptr<GrDrawOp> Make(
51             GrRecordingContext*, sk_sp<const GrCCPerFlushResources>, FillBatchID, StrokeBatchID,
52             int baseStencilResolveInstance, int endStencilResolveInstance,
53             const SkISize& drawBounds);
54 
55     void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override;
56 
57 private:
58     friend class ::GrOpMemoryPool; // for ctor
59 
GrStencilAtlasOp(sk_sp<const GrCCPerFlushResources> resources,FillBatchID fillBatchID,StrokeBatchID strokeBatchID,int baseStencilResolveInstance,int endStencilResolveInstance,const SkISize & drawBounds)60     GrStencilAtlasOp(sk_sp<const GrCCPerFlushResources> resources, FillBatchID fillBatchID,
61                      StrokeBatchID strokeBatchID, int baseStencilResolveInstance,
62                      int endStencilResolveInstance, const SkISize& drawBounds)
63             : GrDrawOp(ClassID())
64             , fResources(std::move(resources))
65             , fFillBatchID(fillBatchID)
66             , fStrokeBatchID(strokeBatchID)
67             , fBaseStencilResolveInstance(baseStencilResolveInstance)
68             , fEndStencilResolveInstance(endStencilResolveInstance)
69             , fDrawBounds(drawBounds) {
70         this->setBounds(SkRect::MakeIWH(fDrawBounds.width(), fDrawBounds.height()),
71                         GrOp::HasAABloat::kNo, GrOp::IsHairline::kNo);
72     }
73 
74     const sk_sp<const GrCCPerFlushResources> fResources;
75     const FillBatchID fFillBatchID;
76     const StrokeBatchID fStrokeBatchID;
77     const int fBaseStencilResolveInstance;
78     const int fEndStencilResolveInstance;
79     const SkISize fDrawBounds;
80     int fResolveBaseVertex;
81 };
82 
83 
84 #endif
85