diff options
-rw-r--r-- | src/atlastext/SkAtlasTextTarget.cpp | 10 | ||||
-rw-r--r-- | src/core/SkDraw.cpp | 6 | ||||
-rw-r--r-- | src/core/SkGlyphRun.cpp | 57 | ||||
-rw-r--r-- | src/core/SkGlyphRun.h | 19 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.cpp | 12 | ||||
-rw-r--r-- | src/gpu/text/GrTextContext.cpp | 36 | ||||
-rw-r--r-- | src/gpu/text/GrTextContext.h | 3 | ||||
-rw-r--r-- | src/gpu/text/GrTextUtils.h | 3 |
8 files changed, 107 insertions, 39 deletions
diff --git a/src/atlastext/SkAtlasTextTarget.cpp b/src/atlastext/SkAtlasTextTarget.cpp index 4d7d65d746..8a382c7233 100644 --- a/src/atlastext/SkAtlasTextTarget.cpp +++ b/src/atlastext/SkAtlasTextTarget.cpp @@ -74,6 +74,8 @@ void SkAtlasTextTarget::concat(const SkMatrix& matrix) { this->accessCTM()->preC ////////////////////////////////////////////////////////////////////////////// static const GrColorSpaceInfo kColorSpaceInfo(nullptr, kRGBA_8888_GrPixelConfig); +static const SkSurfaceProps kProps( + SkSurfaceProps::kUseDistanceFieldFonts_Flag, kUnknown_SkPixelGeometry); ////////////////////////////////////////////////////////////////////////////// @@ -83,7 +85,8 @@ public: int width, int height, void* handle) : GrTextUtils::Target(width, height, kColorSpaceInfo) - , SkAtlasTextTarget(std::move(context), width, height, handle) { + , SkAtlasTextTarget(std::move(context), width, height, handle) + , fGlyphDrawer(kProps, kColorSpaceInfo) { fOpMemoryPool = fContext->internal().grContext()->contextPriv().refOpMemoryPool(); } @@ -109,6 +112,10 @@ public: return this->context()->internal().grContext(); } + SkGlyphRunListDrawer* glyphDrawer() override { + return &fGlyphDrawer; + } + /** SkAtlasTextTarget overrides */ void drawText(const SkGlyphID[], const SkPoint[], int glyphCnt, uint32_t color, @@ -123,6 +130,7 @@ private: using SkAtlasTextTarget::fHeight; SkTArray<std::unique_ptr<GrAtlasTextOp>, true> fOps; sk_sp<GrOpMemoryPool> fOpMemoryPool; + SkGlyphRunListDrawer fGlyphDrawer; }; ////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 95942f76a8..b35d7f9f4c 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -1579,7 +1579,7 @@ SkGlyphRunListDrawer::PerMask SkDraw::drawOneMaskCreator( auto useRegion = fRC->isBW() && !fRC->isRect(); if (useRegion) { - return [this, blitter, &paint](const SkMask& mask) { + return [this, blitter, &paint](const SkMask& mask, const SkGlyph&, SkPoint) { SkRegion::Cliperator clipper(fRC->bwRgn(), mask.fBounds); if (!clipper.done()) { @@ -1597,7 +1597,7 @@ SkGlyphRunListDrawer::PerMask SkDraw::drawOneMaskCreator( } else { SkIRect clipBounds = fRC->isBW() ? fRC->bwRgn().getBounds() : fRC->aaRgn().getBounds(); - return [this, blitter, clipBounds, &paint](const SkMask& mask) { + return [this, blitter, clipBounds, &paint](const SkMask& mask, const SkGlyph&, SkPoint) { SkIRect storage; const SkIRect* bounds = &mask.fBounds; @@ -1639,7 +1639,7 @@ void SkDraw::drawGlyphRunList( return this->drawOneMaskCreator(paint, alloc); }; - glyphDraw->drawForBitmap(glyphRunList, *fMatrix, perMaskBuilder, perPathBuilder); + glyphDraw->drawForBitmapDevice(glyphRunList, *fMatrix, perMaskBuilder, perPathBuilder); } #if defined _WIN32 diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp index f53f90986e..1a24c3bdb9 100644 --- a/src/core/SkGlyphRun.cpp +++ b/src/core/SkGlyphRun.cpp @@ -11,6 +11,11 @@ #include <new> #include <tuple> +#if SK_SUPPORT_GPU +#include "GrColorSpaceInfo.h" +#include "GrRenderTargetContext.h" +#endif + #include "SkDevice.h" #include "SkDraw.h" #include "SkFindAndPlaceGlyph.h" @@ -109,6 +114,29 @@ SkGlyphRunListDrawer::SkGlyphRunListDrawer( , fColorType{colorType} , fScalerContextFlags{flags} {} +#if SK_SUPPORT_GPU + +// TODO: unify with code in GrTextContext.cpp +static SkScalerContextFlags compute_scaler_context_flags( + const GrColorSpaceInfo& colorSpaceInfo) { + // If we're doing linear blending, then we can disable the gamma hacks. + // Otherwise, leave them on. In either case, we still want the contrast boost: + // TODO: Can we be even smarter about mask gamma based on the dest transfer function? + if (colorSpaceInfo.isLinearlyBlended()) { + return SkScalerContextFlags::kBoostContrast; + } else { + return SkScalerContextFlags::kFakeGammaAndBoostContrast; + } +} + +SkGlyphRunListDrawer::SkGlyphRunListDrawer( + const SkSurfaceProps& props, const GrColorSpaceInfo& csi) + : SkGlyphRunListDrawer(props, kUnknown_SkColorType, compute_scaler_context_flags(csi)) {} + +SkGlyphRunListDrawer::SkGlyphRunListDrawer(const GrRenderTargetContext& rtc) + : SkGlyphRunListDrawer{rtc.surfaceProps(), rtc.colorSpaceInfo()} {} +#endif + bool SkGlyphRunListDrawer::ShouldDrawAsPath(const SkPaint& paint, const SkMatrix& matrix) { // hairline glyphs are fast enough so we don't need to cache them if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) { @@ -134,7 +162,7 @@ bool SkGlyphRunListDrawer::ensureBitmapBuffers(size_t runSize) { return true; } -void SkGlyphRunListDrawer::drawGlyphRunAsPaths( +void SkGlyphRunListDrawer::drawUsingPaths( const SkGlyphRun& glyphRun, SkPoint origin, const SkSurfaceProps& props, PerPath perPath) const { // setup our std paint, in hopes of getting hits in the cache @@ -243,7 +271,7 @@ void SkGlyphRunListDrawer::drawGlyphRunAsSubpixelMask( const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphID, lookupX, lookupY); SkMask mask; if (prepare_mask(cache, glyph, position, &mask)) { - perMask(mask); + perMask(mask, glyph, position); } } } @@ -270,14 +298,14 @@ void SkGlyphRunListDrawer::drawGlyphRunAsFullpixelMask( const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphID); SkMask mask; if (prepare_mask(cache, glyph, position, &mask)) { - perMask(mask); + perMask(mask, glyph, position); } } } } } -void SkGlyphRunListDrawer::drawForBitmap( +void SkGlyphRunListDrawer::drawForBitmapDevice( const SkGlyphRunList& glyphRunList, const SkMatrix& deviceMatrix, PerMaskCreator perMaskCreator, PerPathCreator perPathCreator) { @@ -292,22 +320,27 @@ void SkGlyphRunListDrawer::drawForBitmap( auto paint = glyphRun.paint(); if (ShouldDrawAsPath(glyphRun.paint(), deviceMatrix)) { auto perPath = perPathCreator(paint, &alloc); - this->drawGlyphRunAsPaths(glyphRun, origin, props, perPath); + this->drawUsingPaths(glyphRun, origin, props, perPath); } else { auto cache = SkStrikeCache::FindOrCreateStrikeExclusive( paint, &props, fScalerContextFlags, &deviceMatrix); auto perMask = perMaskCreator(paint, &alloc); - if (cache->isSubpixel()) { - this->drawGlyphRunAsSubpixelMask( - cache.get(), glyphRun, origin, deviceMatrix, perMask); - } else { - this->drawGlyphRunAsFullpixelMask( - cache.get(), glyphRun, origin, deviceMatrix, perMask); - } + this->drawUsingMasks(cache.get(), glyphRun, origin, deviceMatrix, perMask); } } } +void SkGlyphRunListDrawer::drawUsingMasks( + SkGlyphCache* cache, const SkGlyphRun& glyphRun, + SkPoint origin, const SkMatrix& deviceMatrix, + SkGlyphRunListDrawer::PerMask perMask) { + if (cache->isSubpixel()) { + this->drawGlyphRunAsSubpixelMask(cache, glyphRun, origin, deviceMatrix, perMask); + } else { + this->drawGlyphRunAsFullpixelMask(cache, glyphRun, origin, deviceMatrix, perMask); + } +} + // -- SkGlyphRunList ------------------------------------------------------------------------------- SkGlyphRunList::SkGlyphRunList() = default; SkGlyphRunList::SkGlyphRunList( diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h index 26590c1251..6bdc633091 100644 --- a/src/core/SkGlyphRun.h +++ b/src/core/SkGlyphRun.h @@ -21,7 +21,10 @@ #include "SkTemplates.h" #include "SkTextBlobPriv.h" #include "SkTypes.h" - +#if SK_SUPPORT_GPU +class GrColorSpaceInfo; +class GrRenderTargetContext; +#endif class SkBaseDevice; class SkGlyphRunList; class SkRasterClip; @@ -109,18 +112,26 @@ public: SkGlyphRunListDrawer( const SkSurfaceProps& props, SkColorType colorType, SkScalerContextFlags flags); - using PerMask = std::function<void(const SkMask&)>; + #if SK_SUPPORT_GPU + SkGlyphRunListDrawer(const SkSurfaceProps&, const GrColorSpaceInfo&); + explicit SkGlyphRunListDrawer(const GrRenderTargetContext& renderTargetContext); + #endif + + using PerMask = std::function<void(const SkMask&, const SkGlyph&, SkPoint)>; using PerMaskCreator = std::function<PerMask(const SkPaint&, SkArenaAlloc* alloc)>; using PerPath = std::function<void(const SkPath&, const SkMatrix&)>; using PerPathCreator = std::function<PerPath(const SkPaint&, SkArenaAlloc* alloc)>; - void drawForBitmap( + void drawForBitmapDevice( const SkGlyphRunList& glyphRunList, const SkMatrix& deviceMatrix, PerMaskCreator perMaskCreator, PerPathCreator perPathCreator); + void drawUsingMasks( + SkGlyphCache* cache, const SkGlyphRun& glyphRun, SkPoint origin, + const SkMatrix& deviceMatrix, PerMask perMask); private: static bool ShouldDrawAsPath(const SkPaint& paint, const SkMatrix& matrix); bool ensureBitmapBuffers(size_t runSize); - void drawGlyphRunAsPaths( + void drawUsingPaths( const SkGlyphRun& glyphRun, SkPoint origin, const SkSurfaceProps& props, PerPath perPath) const; void drawGlyphRunAsSubpixelMask( diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index a67e19a9d9..fd515c7ec7 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -27,6 +27,7 @@ #include "GrStyle.h" #include "GrTracing.h" #include "SkDrawShadowInfo.h" +#include "SkGlyphRun.h" #include "SkGr.h" #include "SkLatticeIter.h" #include "SkMatrixPriv.h" @@ -53,12 +54,15 @@ #include "text/GrTextContext.h" #include "text/GrTextUtils.h" + + class GrRenderTargetContext::TextTarget : public GrTextUtils::Target { public: TextTarget(GrRenderTargetContext* renderTargetContext) : Target(renderTargetContext->width(), renderTargetContext->height(), renderTargetContext->colorSpaceInfo()) - , fRenderTargetContext(renderTargetContext) {} + , fRenderTargetContext(renderTargetContext) + , fGlyphDrawer{*renderTargetContext}{} void addDrawOp(const GrClip& clip, std::unique_ptr<GrAtlasTextOp> op) override { fRenderTargetContext->addDrawOp(clip, std::move(op)); @@ -87,8 +91,14 @@ public: return fRenderTargetContext->fContext; } + SkGlyphRunListDrawer* glyphDrawer() override { + return &fGlyphDrawer; + } + private: GrRenderTargetContext* fRenderTargetContext; + SkGlyphRunListDrawer fGlyphDrawer; + }; #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this->drawingManager()->getContext()) diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp index 7b15abc666..6017742707 100644 --- a/src/gpu/text/GrTextContext.cpp +++ b/src/gpu/text/GrTextContext.cpp @@ -92,7 +92,8 @@ void GrTextContext::regenerateGlyphRunList(GrTextBlob* cacheBlob, SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix, const SkSurfaceProps& props, - const SkGlyphRunList& glyphRunList) const { + const SkGlyphRunList& glyphRunList, + SkGlyphRunListDrawer* glyphDrawer) { SkPoint origin = glyphRunList.origin(); cacheBlob->initReusableBlob(paint.luminanceColor(), viewMatrix, origin.x(), origin.y()); @@ -193,19 +194,17 @@ void GrTextContext::regenerateGlyphRunList(GrTextBlob* cacheBlob, sk_sp<GrTextStrike> currStrike; auto cache = cacheBlob->setupCache( runIndex, props, scalerContextFlags, runPaint, &viewMatrix); - SkFindAndPlaceGlyph::ProcessPosText( - SkPaint::kGlyphID_TextEncoding, - (const char*) glyphRun.shuntGlyphsIDs().data(), - glyphRun.shuntGlyphsIDs().size() * sizeof(SkGlyphID), - origin, viewMatrix, (const SkScalar*) glyphRun.positions().data(), 2, cache.get(), - [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { - position += rounding; - BmpAppendGlyph(cacheBlob, runIndex, glyphCache, &currStrike, glyph, - SkScalarFloorToScalar(position.fX), - SkScalarFloorToScalar(position.fY), - runPaint.filteredPremulColor(), cache.get(), SK_Scalar1, false); - } - ); + + auto drawOneGlyph = + [cacheBlob, runIndex, glyphCache, &currStrike, runPaint, cache{cache.get()}] + (const SkMask& mask, const SkGlyph& glyph, SkPoint position) { + BmpAppendGlyph(cacheBlob, runIndex, glyphCache, &currStrike, glyph, + SkScalarFloorToScalar(position.fX), + SkScalarFloorToScalar(position.fY), + runPaint.filteredPremulColor(), cache, SK_Scalar1, false); + }; + + glyphDrawer->drawUsingMasks(cache.get(), glyphRun, origin, viewMatrix, drawOneGlyph); } runIndex += 1; } @@ -270,7 +269,8 @@ void GrTextContext::drawGlyphRunList( cacheBlob = textBlobCache->makeCachedBlob(glyphRunList, key, blurRec, skPaint); this->regenerateGlyphRunList(cacheBlob.get(), glyphCache, *context->contextPriv().caps()->shaderCaps(), paint, - scalerContextFlags, viewMatrix, props, glyphRunList); + scalerContextFlags, viewMatrix, props, glyphRunList, + target->glyphDrawer()); } else { textBlobCache->makeMRU(cacheBlob.get()); @@ -281,7 +281,8 @@ void GrTextContext::drawGlyphRunList( sanityBlob->setupKey(key, blurRec, skPaint); this->regenerateGlyphRunList( sanityBlob.get(), glyphCache, *context->contextPriv().caps()->shaderCaps(), - paint, scalerContextFlags, viewMatrix, props, glyphRunList); + paint, scalerContextFlags, viewMatrix, props, glyphRunList, + target->glyphDrawer()); GrTextBlob::AssertEqual(*sanityBlob, *cacheBlob); } } @@ -293,7 +294,8 @@ void GrTextContext::drawGlyphRunList( } this->regenerateGlyphRunList(cacheBlob.get(), glyphCache, *context->contextPriv().caps()->shaderCaps(), paint, - scalerContextFlags, viewMatrix, props, glyphRunList); + scalerContextFlags, viewMatrix, props, glyphRunList, + target->glyphDrawer()); } cacheBlob->flush(target, props, fDistanceAdjustTable.get(), paint, diff --git a/src/gpu/text/GrTextContext.h b/src/gpu/text/GrTextContext.h index 2794a84b82..908e6419b8 100644 --- a/src/gpu/text/GrTextContext.h +++ b/src/gpu/text/GrTextContext.h @@ -158,7 +158,8 @@ private: SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix, const SkSurfaceProps&, - const SkGlyphRunList& glyphRunList) const; + const SkGlyphRunList& glyphRunList, + SkGlyphRunListDrawer* glyphDrawer); sk_sp<GrTextBlob> makeDrawPosTextBlob(GrTextBlobCache*, GrGlyphCache*, const GrShaderCaps&, diff --git a/src/gpu/text/GrTextUtils.h b/src/gpu/text/GrTextUtils.h index 05fbf6f35e..a02cebf7dd 100644 --- a/src/gpu/text/GrTextUtils.h +++ b/src/gpu/text/GrTextUtils.h @@ -27,6 +27,7 @@ class GrPaint; class GrShaderCaps; class SkColorSpace; class SkGlyph; +class SkGlyphRunListDrawer; class SkMatrix; struct SkIRect; struct SkPoint; @@ -58,6 +59,8 @@ public: virtual GrContext* getContext() = 0; + virtual SkGlyphRunListDrawer* glyphDrawer() = 0; + protected: Target(int width, int height, const GrColorSpaceInfo& colorSpaceInfo) : fWidth(width), fHeight(height), fColorSpaceInfo(colorSpaceInfo) {} |