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
16class GrCCPerFlushResources;
17
18// Renders literal A8 coverage to a CCPR atlas using an intermediate MSAA stencil buffer.
19class GrStencilAtlasOp : public GrDrawOp {
20public:
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.
34 const char* name() const override { return "StencilAtlasOp (CCPR)"; }
35 FixedFunctionFlags fixedFunctionFlags() const override {
36 return FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil;
37 }
38
39 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
40 bool hasMixedSampledCoverage, GrClampType) override {
41 return GrProcessorSet::EmptySetAnalysis();
42 }
43 CombineResult onCombineIfPossible(GrOp* other, GrRecordingContext::Arenas*,
44 const GrCaps&) override {
45 // We will only make multiple copy ops if they have different source proxies.
46 // TODO: make use of texture chaining.
47 return CombineResult::kCannotCombine;
48 }
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
55private:
56 void onPrePrepare(GrRecordingContext*,
57 const GrSurfaceProxyView* writeView,
58 GrAppliedClip*,
59 const GrXferProcessor::DstProxyView&) override {}
60 void onPrepare(GrOpFlushState*) override {}
61 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
62
63 friend class ::GrOpMemoryPool; // for ctor
64
65 GrStencilAtlasOp(sk_sp<const GrCCPerFlushResources> resources, FillBatchID fillBatchID,
66 StrokeBatchID strokeBatchID, int baseStencilResolveInstance,
67 int endStencilResolveInstance, const SkISize& drawBounds)
68 : GrDrawOp(ClassID())
69 , fResources(std::move(resources))
70 , fFillBatchID(fillBatchID)
71 , fStrokeBatchID(strokeBatchID)
72 , fBaseStencilResolveInstance(baseStencilResolveInstance)
73 , fEndStencilResolveInstance(endStencilResolveInstance)
74 , fDrawBounds(drawBounds) {
75 this->setBounds(SkRect::MakeIWH(fDrawBounds.width(), fDrawBounds.height()),
76 GrOp::HasAABloat::kNo, GrOp::IsHairline::kNo);
77 }
78
79 const sk_sp<const GrCCPerFlushResources> fResources;
80 const FillBatchID fFillBatchID;
81 const StrokeBatchID fStrokeBatchID;
82 const int fBaseStencilResolveInstance;
83 const int fEndStencilResolveInstance;
84 const SkISize fDrawBounds;
85 int fResolveBaseVertex;
86};
87
88
89#endif
90