blob: b16ff91ef2e515def014e648e8627fe1429673e1 [file] [log] [blame]
cdalton855d83f2014-09-18 13:51:53 -07001/*
2 * Copyright 2014 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
Robert Phillips646e4292017-06-13 12:44:56 -04008#include "GrGpu.h"
cdalton855d83f2014-09-18 13:51:53 -07009#include "GrPathRendering.h"
10#include "SkDescriptor.h"
Brian Salomon2bbdcc42017-09-07 12:36:34 -040011#include "SkScalerContext.h"
cdalton855d83f2014-09-18 13:51:53 -070012#include "SkGlyph.h"
13#include "SkMatrix.h"
14#include "SkTypeface.h"
15#include "GrPathRange.h"
16
cdalton193d9cf2016-05-12 11:52:02 -070017const GrUserStencilSettings& GrPathRendering::GetStencilPassSettings(FillType fill) {
18 switch (fill) {
19 default:
Ben Wagnerb4aab9a2017-08-16 10:53:04 -040020 SK_ABORT("Unexpected path fill.");
cdalton193d9cf2016-05-12 11:52:02 -070021 case GrPathRendering::kWinding_FillType: {
22 constexpr static GrUserStencilSettings kWindingStencilPass(
23 GrUserStencilSettings::StaticInit<
24 0xffff,
25 GrUserStencilTest::kAlwaysIfInClip,
26 0xffff,
27 GrUserStencilOp::kIncWrap,
28 GrUserStencilOp::kIncWrap,
29 0xffff>()
30 );
31 return kWindingStencilPass;
32 }
33 case GrPathRendering::kEvenOdd_FillType: {
34 constexpr static GrUserStencilSettings kEvenOddStencilPass(
35 GrUserStencilSettings::StaticInit<
36 0xffff,
37 GrUserStencilTest::kAlwaysIfInClip,
38 0xffff,
39 GrUserStencilOp::kInvert,
40 GrUserStencilOp::kInvert,
41 0xffff>()
42 );
43 return kEvenOddStencilPass;
44 }
45 }
46}
47
cdalton855d83f2014-09-18 13:51:53 -070048class GlyphGenerator : public GrPathRange::PathGenerator {
49public:
reeda9322c22016-04-12 06:47:05 -070050 GlyphGenerator(const SkTypeface& typeface, const SkScalerContextEffects& effects,
51 const SkDescriptor& desc)
52 : fScalerContext(typeface.createScalerContext(effects, &desc))
kkinnunen50b58e62015-05-18 23:02:07 -070053#ifdef SK_DEBUG
54 , fDesc(desc.copy())
55#endif
cdalton7d5c9502015-10-03 13:28:35 -070056 {}
cdalton855d83f2014-09-18 13:51:53 -070057
mtklein36352bf2015-03-25 18:17:31 -070058 int getNumPaths() override {
cdalton855d83f2014-09-18 13:51:53 -070059 return fScalerContext->getGlyphCount();
60 }
61
mtklein36352bf2015-03-25 18:17:31 -070062 void generatePath(int glyphID, SkPath* out) override {
Ben Wagner6e9ac122016-11-11 14:31:06 -050063 fScalerContext->getPath(glyphID, out);
cdalton855d83f2014-09-18 13:51:53 -070064 }
kkinnunen50b58e62015-05-18 23:02:07 -070065#ifdef SK_DEBUG
bsalomonc5d07fa2016-05-17 10:17:45 -070066 bool isEqualTo(const SkDescriptor& desc) const override { return *fDesc == desc; }
kkinnunen50b58e62015-05-18 23:02:07 -070067#endif
cdalton855d83f2014-09-18 13:51:53 -070068private:
bungeman7cfd46a2016-10-20 16:06:52 -040069 const std::unique_ptr<SkScalerContext> fScalerContext;
kkinnunen50b58e62015-05-18 23:02:07 -070070#ifdef SK_DEBUG
bungeman520ced62016-10-18 08:03:42 -040071 const std::unique_ptr<SkDescriptor> fDesc;
kkinnunen50b58e62015-05-18 23:02:07 -070072#endif
cdalton855d83f2014-09-18 13:51:53 -070073};
74
Robert Phillips646e4292017-06-13 12:44:56 -040075void GrPathRendering::stencilPath(const StencilPathArgs& args, const GrPath* path) {
76 fGpu->handleDirtyContext();
77 this->onStencilPath(args, path);
78}
79
80void GrPathRendering::drawPath(const GrPipeline& pipeline,
81 const GrPrimitiveProcessor& primProc,
82 // Cover pass settings in pipeline.
83 const GrStencilSettings& stencilPassSettings,
84 const GrPath* path) {
85 fGpu->handleDirtyContext();
86 if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
Robert Phillips2890fbf2017-07-26 15:48:41 -040087 fGpu->xferBarrier(pipeline.renderTarget(), barrierType);
Robert Phillips646e4292017-06-13 12:44:56 -040088 }
89 this->onDrawPath(pipeline, primProc, stencilPassSettings, path);
90}
91
92void GrPathRendering::drawPaths(const GrPipeline& pipeline,
93 const GrPrimitiveProcessor& primProc,
94 // Cover pass settings in pipeline.
95 const GrStencilSettings& stencilPassSettings,
96 const GrPathRange* pathRange,
97 const void* indices,
98 PathIndexType indexType,
99 const float transformValues[],
100 PathTransformType transformType,
101 int count) {
102 fGpu->handleDirtyContext();
103 if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
Robert Phillips2890fbf2017-07-26 15:48:41 -0400104 fGpu->xferBarrier(pipeline.renderTarget(), barrierType);
Robert Phillips646e4292017-06-13 12:44:56 -0400105 }
106#ifdef SK_DEBUG
107 pathRange->assertPathsLoaded(indices, indexType, count);
108#endif
109 this->onDrawPaths(pipeline, primProc, stencilPassSettings, pathRange, indices, indexType,
110 transformValues, transformType, count);
111}