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