• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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