1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "src/gpu/GrAppliedClip.h"
11cb93a386Sopenharmony_ci#include "src/gpu/GrProcessorSet.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrProgramInfo.h"
13cb93a386Sopenharmony_ci#include "src/gpu/GrUserStencilSettings.h"
14cb93a386Sopenharmony_ci#include "src/gpu/SkGr.h"
15cb93a386Sopenharmony_ci#include "src/gpu/geometry/GrRect.h"
16cb93a386Sopenharmony_ci
17cb93a386Sopenharmony_ciGrSimpleMeshDrawOpHelper::GrSimpleMeshDrawOpHelper(GrProcessorSet* processorSet,
18cb93a386Sopenharmony_ci                                                   GrAAType aaType,
19cb93a386Sopenharmony_ci                                                   InputFlags inputFlags)
20cb93a386Sopenharmony_ci        : fProcessors(processorSet)
21cb93a386Sopenharmony_ci        , fPipelineFlags((GrPipeline::InputFlags)inputFlags)
22cb93a386Sopenharmony_ci        , fAAType((int)aaType)
23cb93a386Sopenharmony_ci        , fUsesLocalCoords(false)
24cb93a386Sopenharmony_ci        , fCompatibleWithCoverageAsAlpha(false) {
25cb93a386Sopenharmony_ci    SkDEBUGCODE(fDidAnalysis = false);
26cb93a386Sopenharmony_ci    SkDEBUGCODE(fMadePipeline = false);
27cb93a386Sopenharmony_ci}
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ciGrSimpleMeshDrawOpHelper::~GrSimpleMeshDrawOpHelper() {
30cb93a386Sopenharmony_ci    if (fProcessors) {
31cb93a386Sopenharmony_ci        fProcessors->~GrProcessorSet();
32cb93a386Sopenharmony_ci    }
33cb93a386Sopenharmony_ci}
34cb93a386Sopenharmony_ci
35cb93a386Sopenharmony_ciGrDrawOp::FixedFunctionFlags GrSimpleMeshDrawOpHelper::fixedFunctionFlags() const {
36cb93a386Sopenharmony_ci    return GrAATypeIsHW(this->aaType()) ? GrDrawOp::FixedFunctionFlags::kUsesHWAA
37cb93a386Sopenharmony_ci                                        : GrDrawOp::FixedFunctionFlags::kNone;
38cb93a386Sopenharmony_ci}
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_cibool GrSimpleMeshDrawOpHelper::isCompatible(const GrSimpleMeshDrawOpHelper& that,
41cb93a386Sopenharmony_ci                                            const GrCaps& caps, const SkRect& thisBounds,
42cb93a386Sopenharmony_ci                                            const SkRect& thatBounds, bool ignoreAAType) const {
43cb93a386Sopenharmony_ci    if (SkToBool(fProcessors) != SkToBool(that.fProcessors)) {
44cb93a386Sopenharmony_ci        return false;
45cb93a386Sopenharmony_ci    }
46cb93a386Sopenharmony_ci    if (fProcessors) {
47cb93a386Sopenharmony_ci        if (*fProcessors != *that.fProcessors) {
48cb93a386Sopenharmony_ci            return false;
49cb93a386Sopenharmony_ci        }
50cb93a386Sopenharmony_ci    }
51cb93a386Sopenharmony_ci
52cb93a386Sopenharmony_ci#ifdef SK_DEBUG
53cb93a386Sopenharmony_ci    if (ignoreAAType) {
54cb93a386Sopenharmony_ci        // If we're ignoring AA it should be bc we already know they are the same or that
55cb93a386Sopenharmony_ci        // the are different but are compatible (i.e., one is AA and the other is None)
56cb93a386Sopenharmony_ci        SkASSERT(fAAType == that.fAAType ||
57cb93a386Sopenharmony_ci                 GrMeshDrawOp::CanUpgradeAAOnMerge(this->aaType(), that.aaType()));
58cb93a386Sopenharmony_ci    }
59cb93a386Sopenharmony_ci#endif
60cb93a386Sopenharmony_ci
61cb93a386Sopenharmony_ci    bool result = fPipelineFlags == that.fPipelineFlags &&
62cb93a386Sopenharmony_ci                  (ignoreAAType || fAAType == that.fAAType);
63cb93a386Sopenharmony_ci    SkASSERT(!result || fCompatibleWithCoverageAsAlpha == that.fCompatibleWithCoverageAsAlpha);
64cb93a386Sopenharmony_ci    SkASSERT(!result || fUsesLocalCoords == that.fUsesLocalCoords);
65cb93a386Sopenharmony_ci    return result;
66cb93a386Sopenharmony_ci}
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ciGrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors(
69cb93a386Sopenharmony_ci        const GrCaps& caps, const GrAppliedClip* clip, GrClampType clampType,
70cb93a386Sopenharmony_ci        GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor, bool* wideColor) {
71cb93a386Sopenharmony_ci    GrProcessorAnalysisColor color = *geometryColor;
72cb93a386Sopenharmony_ci    auto result = this->finalizeProcessors(caps, clip, clampType, geometryCoverage, &color);
73cb93a386Sopenharmony_ci    color.isConstant(geometryColor);
74cb93a386Sopenharmony_ci    if (wideColor) {
75cb93a386Sopenharmony_ci        *wideColor = !geometryColor->fitsInBytes();
76cb93a386Sopenharmony_ci    }
77cb93a386Sopenharmony_ci    return result;
78cb93a386Sopenharmony_ci}
79cb93a386Sopenharmony_ci
80cb93a386Sopenharmony_ciGrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors(
81cb93a386Sopenharmony_ci        const GrCaps& caps, const GrAppliedClip* clip, const GrUserStencilSettings* userStencil,
82cb93a386Sopenharmony_ci        GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
83cb93a386Sopenharmony_ci        GrProcessorAnalysisColor* geometryColor) {
84cb93a386Sopenharmony_ci    SkDEBUGCODE(fDidAnalysis = true);
85cb93a386Sopenharmony_ci    GrProcessorSet::Analysis analysis;
86cb93a386Sopenharmony_ci    if (fProcessors) {
87cb93a386Sopenharmony_ci        GrProcessorAnalysisCoverage coverage = geometryCoverage;
88cb93a386Sopenharmony_ci        if (GrProcessorAnalysisCoverage::kNone == coverage) {
89cb93a386Sopenharmony_ci            coverage = (clip && clip->hasCoverageFragmentProcessor())
90cb93a386Sopenharmony_ci                               ? GrProcessorAnalysisCoverage::kSingleChannel
91cb93a386Sopenharmony_ci                               : GrProcessorAnalysisCoverage::kNone;
92cb93a386Sopenharmony_ci        }
93cb93a386Sopenharmony_ci        SkPMColor4f overrideColor;
94cb93a386Sopenharmony_ci        analysis = fProcessors->finalize(*geometryColor, coverage, clip, userStencil, caps,
95cb93a386Sopenharmony_ci                                         clampType, &overrideColor);
96cb93a386Sopenharmony_ci        if (analysis.inputColorIsOverridden()) {
97cb93a386Sopenharmony_ci            *geometryColor = overrideColor;
98cb93a386Sopenharmony_ci        }
99cb93a386Sopenharmony_ci    } else {
100cb93a386Sopenharmony_ci        analysis = GrProcessorSet::EmptySetAnalysis();
101cb93a386Sopenharmony_ci    }
102cb93a386Sopenharmony_ci    fUsesLocalCoords = analysis.usesLocalCoords();
103cb93a386Sopenharmony_ci    fCompatibleWithCoverageAsAlpha = analysis.isCompatibleWithCoverageAsAlpha();
104cb93a386Sopenharmony_ci    return analysis;
105cb93a386Sopenharmony_ci}
106cb93a386Sopenharmony_ci
107cb93a386Sopenharmony_ciconst GrPipeline* GrSimpleMeshDrawOpHelper::CreatePipeline(
108cb93a386Sopenharmony_ci                                                const GrCaps* caps,
109cb93a386Sopenharmony_ci                                                SkArenaAlloc* arena,
110cb93a386Sopenharmony_ci                                                GrSwizzle writeViewSwizzle,
111cb93a386Sopenharmony_ci                                                GrAppliedClip&& appliedClip,
112cb93a386Sopenharmony_ci                                                const GrDstProxyView& dstProxyView,
113cb93a386Sopenharmony_ci                                                GrProcessorSet&& processorSet,
114cb93a386Sopenharmony_ci                                                GrPipeline::InputFlags pipelineFlags) {
115cb93a386Sopenharmony_ci    GrPipeline::InitArgs pipelineArgs;
116cb93a386Sopenharmony_ci
117cb93a386Sopenharmony_ci    pipelineArgs.fInputFlags = pipelineFlags;
118cb93a386Sopenharmony_ci    pipelineArgs.fCaps = caps;
119cb93a386Sopenharmony_ci    pipelineArgs.fDstProxyView = dstProxyView;
120cb93a386Sopenharmony_ci    pipelineArgs.fWriteSwizzle = writeViewSwizzle;
121cb93a386Sopenharmony_ci
122cb93a386Sopenharmony_ci    return arena->make<GrPipeline>(pipelineArgs,
123cb93a386Sopenharmony_ci                                   std::move(processorSet),
124cb93a386Sopenharmony_ci                                   std::move(appliedClip));
125cb93a386Sopenharmony_ci}
126cb93a386Sopenharmony_ci
127cb93a386Sopenharmony_ciconst GrPipeline* GrSimpleMeshDrawOpHelper::CreatePipeline(
128cb93a386Sopenharmony_ci                                                GrOpFlushState* flushState,
129cb93a386Sopenharmony_ci                                                GrProcessorSet&& processorSet,
130cb93a386Sopenharmony_ci                                                GrPipeline::InputFlags pipelineFlags) {
131cb93a386Sopenharmony_ci    return CreatePipeline(&flushState->caps(),
132cb93a386Sopenharmony_ci                          flushState->allocator(),
133cb93a386Sopenharmony_ci                          flushState->writeView().swizzle(),
134cb93a386Sopenharmony_ci                          flushState->detachAppliedClip(),
135cb93a386Sopenharmony_ci                          flushState->dstProxyView(),
136cb93a386Sopenharmony_ci                          std::move(processorSet),
137cb93a386Sopenharmony_ci                          pipelineFlags);
138cb93a386Sopenharmony_ci}
139cb93a386Sopenharmony_ci
140cb93a386Sopenharmony_ciconst GrPipeline* GrSimpleMeshDrawOpHelper::createPipeline(GrOpFlushState* flushState) {
141cb93a386Sopenharmony_ci    return CreatePipeline(&flushState->caps(),
142cb93a386Sopenharmony_ci                          flushState->allocator(),
143cb93a386Sopenharmony_ci                          flushState->writeView().swizzle(),
144cb93a386Sopenharmony_ci                          flushState->detachAppliedClip(),
145cb93a386Sopenharmony_ci                          flushState->dstProxyView(),
146cb93a386Sopenharmony_ci                          this->detachProcessorSet(),
147cb93a386Sopenharmony_ci                          this->pipelineFlags());
148cb93a386Sopenharmony_ci}
149cb93a386Sopenharmony_ci
150cb93a386Sopenharmony_ciconst GrPipeline* GrSimpleMeshDrawOpHelper::createPipeline(
151cb93a386Sopenharmony_ci        const GrCaps* caps,
152cb93a386Sopenharmony_ci        SkArenaAlloc* arena,
153cb93a386Sopenharmony_ci        GrSwizzle writeViewSwizzle,
154cb93a386Sopenharmony_ci        GrAppliedClip&& appliedClip,
155cb93a386Sopenharmony_ci        const GrDstProxyView& dstProxyView) {
156cb93a386Sopenharmony_ci    return GrSimpleMeshDrawOpHelper::CreatePipeline(caps,
157cb93a386Sopenharmony_ci                                                    arena,
158cb93a386Sopenharmony_ci                                                    writeViewSwizzle,
159cb93a386Sopenharmony_ci                                                    std::move(appliedClip),
160cb93a386Sopenharmony_ci                                                    dstProxyView,
161cb93a386Sopenharmony_ci                                                    this->detachProcessorSet(),
162cb93a386Sopenharmony_ci                                                    this->pipelineFlags());
163cb93a386Sopenharmony_ci}
164cb93a386Sopenharmony_ci
165cb93a386Sopenharmony_ciGrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(
166cb93a386Sopenharmony_ci            const GrCaps* caps,
167cb93a386Sopenharmony_ci            SkArenaAlloc* arena,
168cb93a386Sopenharmony_ci            const GrSurfaceProxyView& writeView,
169cb93a386Sopenharmony_ci            bool usesMSAASurface,
170cb93a386Sopenharmony_ci            GrAppliedClip&& appliedClip,
171cb93a386Sopenharmony_ci            const GrDstProxyView& dstProxyView,
172cb93a386Sopenharmony_ci            GrGeometryProcessor* geometryProcessor,
173cb93a386Sopenharmony_ci            GrProcessorSet&& processorSet,
174cb93a386Sopenharmony_ci            GrPrimitiveType primitiveType,
175cb93a386Sopenharmony_ci            GrXferBarrierFlags renderPassXferBarriers,
176cb93a386Sopenharmony_ci            GrLoadOp colorLoadOp,
177cb93a386Sopenharmony_ci            GrPipeline::InputFlags pipelineFlags,
178cb93a386Sopenharmony_ci            const GrUserStencilSettings* stencilSettings) {
179cb93a386Sopenharmony_ci    auto pipeline = CreatePipeline(caps,
180cb93a386Sopenharmony_ci                                   arena,
181cb93a386Sopenharmony_ci                                   writeView.swizzle(),
182cb93a386Sopenharmony_ci                                   std::move(appliedClip),
183cb93a386Sopenharmony_ci                                   dstProxyView,
184cb93a386Sopenharmony_ci                                   std::move(processorSet),
185cb93a386Sopenharmony_ci                                   pipelineFlags);
186cb93a386Sopenharmony_ci
187cb93a386Sopenharmony_ci    return CreateProgramInfo(caps, arena, pipeline, writeView, usesMSAASurface, geometryProcessor,
188cb93a386Sopenharmony_ci                             primitiveType, renderPassXferBarriers, colorLoadOp, stencilSettings);
189cb93a386Sopenharmony_ci}
190cb93a386Sopenharmony_ci
191cb93a386Sopenharmony_ciGrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(const GrCaps* caps,
192cb93a386Sopenharmony_ci                                                           SkArenaAlloc* arena,
193cb93a386Sopenharmony_ci                                                           const GrPipeline* pipeline,
194cb93a386Sopenharmony_ci                                                           const GrSurfaceProxyView& writeView,
195cb93a386Sopenharmony_ci                                                           bool usesMSAASurface,
196cb93a386Sopenharmony_ci                                                           GrGeometryProcessor* geometryProcessor,
197cb93a386Sopenharmony_ci                                                           GrPrimitiveType primitiveType,
198cb93a386Sopenharmony_ci                                                           GrXferBarrierFlags xferBarrierFlags,
199cb93a386Sopenharmony_ci                                                           GrLoadOp colorLoadOp,
200cb93a386Sopenharmony_ci                                                           const GrUserStencilSettings* stencilSettings) {
201cb93a386Sopenharmony_ci    auto tmp = arena->make<GrProgramInfo>(*caps,
202cb93a386Sopenharmony_ci                                          writeView,
203cb93a386Sopenharmony_ci                                          usesMSAASurface,
204cb93a386Sopenharmony_ci                                          pipeline,
205cb93a386Sopenharmony_ci                                          stencilSettings,
206cb93a386Sopenharmony_ci                                          geometryProcessor,
207cb93a386Sopenharmony_ci                                          primitiveType,
208cb93a386Sopenharmony_ci                                          0,
209cb93a386Sopenharmony_ci                                          xferBarrierFlags,
210cb93a386Sopenharmony_ci                                          colorLoadOp);
211cb93a386Sopenharmony_ci    return tmp;
212cb93a386Sopenharmony_ci}
213cb93a386Sopenharmony_ci
214cb93a386Sopenharmony_ciGrProgramInfo* GrSimpleMeshDrawOpHelper::createProgramInfo(
215cb93a386Sopenharmony_ci                                            const GrCaps* caps,
216cb93a386Sopenharmony_ci                                            SkArenaAlloc* arena,
217cb93a386Sopenharmony_ci                                            const GrSurfaceProxyView& writeView,
218cb93a386Sopenharmony_ci                                            bool usesMSAASurface,
219cb93a386Sopenharmony_ci                                            GrAppliedClip&& appliedClip,
220cb93a386Sopenharmony_ci                                            const GrDstProxyView& dstProxyView,
221cb93a386Sopenharmony_ci                                            GrGeometryProcessor* gp,
222cb93a386Sopenharmony_ci                                            GrPrimitiveType primType,
223cb93a386Sopenharmony_ci                                            GrXferBarrierFlags renderPassXferBarriers,
224cb93a386Sopenharmony_ci                                            GrLoadOp colorLoadOp) {
225cb93a386Sopenharmony_ci    return CreateProgramInfo(caps,
226cb93a386Sopenharmony_ci                             arena,
227cb93a386Sopenharmony_ci                             writeView,
228cb93a386Sopenharmony_ci                             usesMSAASurface,
229cb93a386Sopenharmony_ci                             std::move(appliedClip),
230cb93a386Sopenharmony_ci                             dstProxyView,
231cb93a386Sopenharmony_ci                             gp,
232cb93a386Sopenharmony_ci                             this->detachProcessorSet(),
233cb93a386Sopenharmony_ci                             primType,
234cb93a386Sopenharmony_ci                             renderPassXferBarriers,
235cb93a386Sopenharmony_ci                             colorLoadOp,
236cb93a386Sopenharmony_ci                             this->pipelineFlags());
237cb93a386Sopenharmony_ci}
238cb93a386Sopenharmony_ci
239cb93a386Sopenharmony_ci#if GR_TEST_UTILS
240cb93a386Sopenharmony_cistatic void dump_pipeline_flags(GrPipeline::InputFlags flags, SkString* result) {
241cb93a386Sopenharmony_ci    if (GrPipeline::InputFlags::kNone != flags) {
242cb93a386Sopenharmony_ci        if (flags & GrPipeline::InputFlags::kSnapVerticesToPixelCenters) {
243cb93a386Sopenharmony_ci            result->append("Snap vertices to pixel center.\n");
244cb93a386Sopenharmony_ci        }
245cb93a386Sopenharmony_ci        if (flags & GrPipeline::InputFlags::kWireframe) {
246cb93a386Sopenharmony_ci            result->append("Wireframe enabled.\n");
247cb93a386Sopenharmony_ci        }
248cb93a386Sopenharmony_ci        if (flags & GrPipeline::InputFlags::kConservativeRaster) {
249cb93a386Sopenharmony_ci            result->append("Conservative raster enabled.\n");
250cb93a386Sopenharmony_ci        }
251cb93a386Sopenharmony_ci        return;
252cb93a386Sopenharmony_ci    }
253cb93a386Sopenharmony_ci    result->append("No pipeline flags\n");
254cb93a386Sopenharmony_ci}
255cb93a386Sopenharmony_ci
256cb93a386Sopenharmony_ciSkString GrSimpleMeshDrawOpHelper::dumpInfo() const {
257cb93a386Sopenharmony_ci    const GrProcessorSet& processors = fProcessors ? *fProcessors : GrProcessorSet::EmptySet();
258cb93a386Sopenharmony_ci    SkString result = processors.dumpProcessors();
259cb93a386Sopenharmony_ci    result.append("AA Type: ");
260cb93a386Sopenharmony_ci    switch (this->aaType()) {
261cb93a386Sopenharmony_ci        case GrAAType::kNone:
262cb93a386Sopenharmony_ci            result.append(" none\n");
263cb93a386Sopenharmony_ci            break;
264cb93a386Sopenharmony_ci        case GrAAType::kCoverage:
265cb93a386Sopenharmony_ci            result.append(" coverage\n");
266cb93a386Sopenharmony_ci            break;
267cb93a386Sopenharmony_ci        case GrAAType::kMSAA:
268cb93a386Sopenharmony_ci            result.append(" msaa\n");
269cb93a386Sopenharmony_ci            break;
270cb93a386Sopenharmony_ci    }
271cb93a386Sopenharmony_ci    dump_pipeline_flags(fPipelineFlags, &result);
272cb93a386Sopenharmony_ci    return result;
273cb93a386Sopenharmony_ci}
274cb93a386Sopenharmony_ci#endif
275