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