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