1 /*
2 * Copyright 2015 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 #include "include/private/GrRecordingContext.h"
9 #include "include/private/SkTemplates.h"
10 #include "src/gpu/GrAppliedClip.h"
11 #include "src/gpu/GrMemoryPool.h"
12 #include "src/gpu/GrProgramInfo.h"
13 #include "src/gpu/GrRecordingContextPriv.h"
14 #include "src/gpu/GrRenderTargetContext.h"
15 #include "src/gpu/GrRenderTargetPriv.h"
16 #include "src/gpu/ops/GrDrawPathOp.h"
17 #include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
18
19 static constexpr GrUserStencilSettings kCoverPass{
20 GrUserStencilSettings::StaticInit<
21 0x0000,
22 GrUserStencilTest::kNotEqual,
23 0xffff,
24 GrUserStencilOp::kZero,
25 GrUserStencilOp::kKeep,
26 0xffff>()
27 };
28
GrDrawPathOpBase(uint32_t classID,const SkMatrix & viewMatrix,GrPaint && paint,GrPathRendering::FillType fill,GrAA aa)29 GrDrawPathOpBase::GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&& paint,
30 GrPathRendering::FillType fill, GrAA aa)
31 : INHERITED(classID)
32 , fViewMatrix(viewMatrix)
33 , fInputColor(paint.getColor4f())
34 , fFillType(fill)
35 , fDoAA(GrAA::kYes == aa)
36 , fProcessorSet(std::move(paint)) {}
37
38 #ifdef SK_DEBUG
dumpInfo() const39 SkString GrDrawPathOp::dumpInfo() const {
40 SkString string;
41 string.printf("PATH: 0x%p", fPath.get());
42 string.append(INHERITED::dumpInfo());
43 return string;
44 }
45 #endif
46
doProcessorAnalysis(const GrCaps & caps,const GrAppliedClip * clip,bool hasMixedSampledCoverage,GrClampType clampType)47 const GrProcessorSet::Analysis& GrDrawPathOpBase::doProcessorAnalysis(
48 const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
49 GrClampType clampType) {
50 fAnalysis = fProcessorSet.finalize(
51 fInputColor, GrProcessorAnalysisCoverage::kNone, clip, &kCoverPass,
52 hasMixedSampledCoverage, caps, clampType, &fInputColor);
53 return fAnalysis;
54 }
55
56 //////////////////////////////////////////////////////////////////////////////
57
init_stencil_pass_settings(const GrOpFlushState & flushState,GrPathRendering::FillType fillType,GrStencilSettings * stencil)58 void init_stencil_pass_settings(const GrOpFlushState& flushState,
59 GrPathRendering::FillType fillType, GrStencilSettings* stencil) {
60 const GrAppliedClip* appliedClip = flushState.drawOpArgs().appliedClip();
61 bool stencilClip = appliedClip && appliedClip->hasStencilClip();
62 GrRenderTarget* rt = flushState.drawOpArgs().proxy()->peekRenderTarget();
63 stencil->reset(GrPathRendering::GetStencilPassSettings(fillType), stencilClip,
64 rt->renderTargetPriv().numStencilBits());
65 }
66
67 //////////////////////////////////////////////////////////////////////////////
68
Make(GrRecordingContext * context,const SkMatrix & viewMatrix,GrPaint && paint,GrAA aa,sk_sp<const GrPath> path)69 std::unique_ptr<GrDrawOp> GrDrawPathOp::Make(GrRecordingContext* context,
70 const SkMatrix& viewMatrix,
71 GrPaint&& paint,
72 GrAA aa,
73 sk_sp<const GrPath> path) {
74 GrOpMemoryPool* pool = context->priv().opMemoryPool();
75
76 return pool->allocate<GrDrawPathOp>(viewMatrix, std::move(paint), aa, std::move(path));
77 }
78
onExecute(GrOpFlushState * flushState,const SkRect & chainBounds)79 void GrDrawPathOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
80 GrPipeline::FixedDynamicState* fixedDynamicState = nullptr, storage;
81
82 const GrAppliedClip* appliedClip = flushState->appliedClip();
83 if (appliedClip && appliedClip->scissorState().enabled()) {
84 storage.fScissorRect = appliedClip->scissorState().rect();
85 fixedDynamicState = &storage;
86 }
87
88 GrPipeline::InputFlags pipelineFlags = GrPipeline::InputFlags::kNone;
89 if (this->doAA()) {
90 pipelineFlags |= GrPipeline::InputFlags::kHWAntialias;
91 }
92
93 auto pipeline = GrSimpleMeshDrawOpHelper::CreatePipeline(flushState,
94 this->detachProcessorSet(),
95 pipelineFlags,
96 &kCoverPass);
97
98 sk_sp<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(), this->viewMatrix()));
99
100 GrRenderTargetProxy* proxy = flushState->proxy();
101 GrProgramInfo programInfo(proxy->numSamples(),
102 proxy->numStencilSamples(),
103 proxy->backendFormat(),
104 flushState->view()->origin(),
105 pipeline,
106 pathProc.get(),
107 fixedDynamicState,
108 nullptr, 0,
109 GrPrimitiveType::kPath);
110
111 GrStencilSettings stencil;
112 init_stencil_pass_settings(*flushState, this->fillType(), &stencil);
113 flushState->gpu()->pathRendering()->drawPath(proxy->peekRenderTarget(),
114 programInfo, stencil, fPath.get());
115 }
116
117 //////////////////////////////////////////////////////////////////////////////
118
pre_translate_transform_values(const float * xforms,GrPathRendering::PathTransformType type,int count,SkScalar x,SkScalar y,float * dst)119 inline void pre_translate_transform_values(const float* xforms,
120 GrPathRendering::PathTransformType type, int count,
121 SkScalar x, SkScalar y, float* dst) {
122 if (0 == x && 0 == y) {
123 memcpy(dst, xforms, count * GrPathRendering::PathTransformSize(type) * sizeof(float));
124 return;
125 }
126 switch (type) {
127 case GrPathRendering::kNone_PathTransformType:
128 SK_ABORT("Cannot pre-translate kNone_PathTransformType.");
129 break;
130 case GrPathRendering::kTranslateX_PathTransformType:
131 SkASSERT(0 == y);
132 for (int i = 0; i < count; i++) {
133 dst[i] = xforms[i] + x;
134 }
135 break;
136 case GrPathRendering::kTranslateY_PathTransformType:
137 SkASSERT(0 == x);
138 for (int i = 0; i < count; i++) {
139 dst[i] = xforms[i] + y;
140 }
141 break;
142 case GrPathRendering::kTranslate_PathTransformType:
143 for (int i = 0; i < 2 * count; i += 2) {
144 dst[i] = xforms[i] + x;
145 dst[i + 1] = xforms[i + 1] + y;
146 }
147 break;
148 case GrPathRendering::kAffine_PathTransformType:
149 for (int i = 0; i < 6 * count; i += 6) {
150 dst[i] = xforms[i];
151 dst[i + 1] = xforms[i + 1];
152 dst[i + 2] = xforms[i] * x + xforms[i + 1] * y + xforms[i + 2];
153 dst[i + 3] = xforms[i + 3];
154 dst[i + 4] = xforms[i + 4];
155 dst[i + 5] = xforms[i + 3] * x + xforms[i + 4] * y + xforms[i + 5];
156 }
157 break;
158 default:
159 SK_ABORT("Unknown transform type.");
160 break;
161 }
162 }
163