1855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton/*
2855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton * Copyright 2014 Google Inc.
3855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton *
4855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton * Use of this source code is governed by a BSD-style license that can be
5855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton * found in the LICENSE file.
6855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton */
7855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
8646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips#include "GrGpu.h"
9855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "GrPathRendering.h"
10855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkDescriptor.h"
11855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkGlyph.h"
12855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkMatrix.h"
13855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkTypeface.h"
14855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "GrPathRange.h"
15855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
16193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdaltonconst GrUserStencilSettings& GrPathRendering::GetStencilPassSettings(FillType fill) {
17193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton    switch (fill) {
18193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton        default:
19193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton            SkFAIL("Unexpected path fill.");
20193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton        case GrPathRendering::kWinding_FillType: {
21193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton            constexpr static GrUserStencilSettings kWindingStencilPass(
22193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                GrUserStencilSettings::StaticInit<
23193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    0xffff,
24193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    GrUserStencilTest::kAlwaysIfInClip,
25193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    0xffff,
26193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    GrUserStencilOp::kIncWrap,
27193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    GrUserStencilOp::kIncWrap,
28193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    0xffff>()
29193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton            );
30193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton            return kWindingStencilPass;
31193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton        }
32193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton        case GrPathRendering::kEvenOdd_FillType: {
33193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton            constexpr static GrUserStencilSettings kEvenOddStencilPass(
34193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                GrUserStencilSettings::StaticInit<
35193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    0xffff,
36193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    GrUserStencilTest::kAlwaysIfInClip,
37193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    0xffff,
38193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    GrUserStencilOp::kInvert,
39193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    GrUserStencilOp::kInvert,
40193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton                    0xffff>()
41193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton            );
42193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton            return kEvenOddStencilPass;
43193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton        }
44193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton    }
45193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton}
46193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton
47855d83ff79c6c822b2ad653f2f890178ad0f637bcdaltonclass GlyphGenerator : public GrPathRange::PathGenerator {
48855d83ff79c6c822b2ad653f2f890178ad0f637bcdaltonpublic:
49a9322c2d86aaef1085c267dfc43cf0747f170a86reed    GlyphGenerator(const SkTypeface& typeface, const SkScalerContextEffects& effects,
50a9322c2d86aaef1085c267dfc43cf0747f170a86reed                   const SkDescriptor& desc)
51a9322c2d86aaef1085c267dfc43cf0747f170a86reed        : fScalerContext(typeface.createScalerContext(effects, &desc))
5250b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen#ifdef SK_DEBUG
5350b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        , fDesc(desc.copy())
5450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen#endif
557d5c950e85b4766a05ed834c594033c9dd6913cbcdalton    {}
56855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
5736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    int getNumPaths() override {
58855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        return fScalerContext->getGlyphCount();
59855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    }
60855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
6136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void generatePath(int glyphID, SkPath* out) override {
626e9ac12495f3b64b6ea8860bb9f99c43cd33aa08Ben Wagner        fScalerContext->getPath(glyphID, out);
63855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    }
6450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen#ifdef SK_DEBUG
65c5d07faced11ab20218aef04cbc3388d7a85eb28bsalomon    bool isEqualTo(const SkDescriptor& desc) const override { return *fDesc == desc; }
6650b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen#endif
67855d83ff79c6c822b2ad653f2f890178ad0f637bcdaltonprivate:
687cfd46aebda7b7d2b88e73621ed0d1be7244c2cabungeman    const std::unique_ptr<SkScalerContext> fScalerContext;
6950b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen#ifdef SK_DEBUG
70520ced63cf0750e207223169a31edb2a16e5ca96bungeman    const std::unique_ptr<SkDescriptor> fDesc;
7150b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen#endif
72855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton};
73855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
7467d52cf0d8baff02fd4337a62f1f9cd975edc18fRobert Phillipssk_sp<GrPathRange> GrPathRendering::createGlyphs(const SkTypeface* typeface,
7567d52cf0d8baff02fd4337a62f1f9cd975edc18fRobert Phillips                                                 const SkScalerContextEffects& effects,
7667d52cf0d8baff02fd4337a62f1f9cd975edc18fRobert Phillips                                                 const SkDescriptor* desc,
7767d52cf0d8baff02fd4337a62f1f9cd975edc18fRobert Phillips                                                 const GrStyle& style) {
7896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == typeface) {
79855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        typeface = SkTypeface::GetDefaultTypeface();
8096fcdcc219d2a0d3579719b84b28bede76efba64halcanary        SkASSERT(nullptr != typeface);
81855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    }
82855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
83855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    if (desc) {
84144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary        sk_sp<GlyphGenerator> generator(new GlyphGenerator(*typeface, effects, *desc));
85144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary        return this->createPathRange(generator.get(), style);
86855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    }
87855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
88855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    SkScalerContextRec rec;
89855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    memset(&rec, 0, sizeof(rec));
90855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    rec.fFontID = typeface->uniqueID();
91855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    rec.fTextSize = SkPaint::kCanonicalTextSizeForPaths;
92855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    rec.fPreScaleX = rec.fPost2x2[0][0] = rec.fPost2x2[1][1] = SK_Scalar1;
93855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    // Don't bake stroke information into the glyphs, we'll let the GPU do the stroking.
94855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
95855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1));
96855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    SkDescriptor*    genericDesc = ad.getDesc();
97855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
98855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    genericDesc->init();
99855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    genericDesc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
100855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    genericDesc->computeChecksum();
101646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips
102a9322c2d86aaef1085c267dfc43cf0747f170a86reed    // No effects, so we make a dummy struct
103a9322c2d86aaef1085c267dfc43cf0747f170a86reed    SkScalerContextEffects noEffects;
104855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
105144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary    sk_sp<GlyphGenerator> generator(new GlyphGenerator(*typeface, noEffects, *genericDesc));
106144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary    return this->createPathRange(generator.get(), style);
107855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton}
108646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips
109646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillipsvoid GrPathRendering::stencilPath(const StencilPathArgs& args, const GrPath* path) {
110646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips    fGpu->handleDirtyContext();
111646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips    this->onStencilPath(args, path);
112646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips}
113646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips
114646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillipsvoid GrPathRendering::drawPath(const GrPipeline& pipeline,
115646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                               const GrPrimitiveProcessor& primProc,
116646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                               // Cover pass settings in pipeline.
117646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                               const GrStencilSettings& stencilPassSettings,
118646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                               const GrPath* path) {
119646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips    fGpu->handleDirtyContext();
120646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips    if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
121646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips        fGpu->xferBarrier(pipeline.getRenderTarget(), barrierType);
122646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips    }
123646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips    this->onDrawPath(pipeline, primProc, stencilPassSettings, path);
124646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips}
125646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips
126646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillipsvoid GrPathRendering::drawPaths(const GrPipeline& pipeline,
127646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                                const GrPrimitiveProcessor& primProc,
128646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                                // Cover pass settings in pipeline.
129646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                                const GrStencilSettings& stencilPassSettings,
130646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                                const GrPathRange* pathRange,
131646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                                const void* indices,
132646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                                PathIndexType indexType,
133646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                                const float transformValues[],
134646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                                PathTransformType transformType,
135646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                                int count) {
136646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips    fGpu->handleDirtyContext();
137646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips    if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
138646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips        fGpu->xferBarrier(pipeline.getRenderTarget(), barrierType);
139646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips    }
140646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips#ifdef SK_DEBUG
141646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips    pathRange->assertPathsLoaded(indices, indexType, count);
142646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips#endif
143646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips    this->onDrawPaths(pipeline, primProc, stencilPassSettings, pathRange, indices, indexType,
144646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips                      transformValues, transformType, count);
145646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips}
146