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