Reorganize TrackLayerDevice and move processGlyphRunForMask

The routine processGlyphRunForMask needs to move to SkGlyphRun
to use all the new positioning routines. This requires the
definition for TrackLayerDevice to be visible in SkGlyphRun.

Change-Id: I0fd20870940471cfbae29e411597e115d150893a
Reviewed-on: https://skia-review.googlesource.com/149046
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2018-08-23 18:19:03 -04:00 committed by Skia Commit-Bot
parent 3217808ed9
commit 447b1980a3
4 changed files with 181 additions and 156 deletions

View File

@ -32,6 +32,7 @@
#include "SkPaintPriv.h"
#include "SkPathEffect.h"
#include "SkRasterClip.h"
#include "SkRemoteGlyphCache.h"
#include "SkStrikeCache.h"
#include "SkTextBlob.h"
#include "SkTextBlobPriv.h"
@ -878,6 +879,43 @@ void SkGlyphRunListPainter::drawGlyphRunAsSDFWithFallback(
}
}
// -- SkRemoteGlyphCache ---------------------------------------------------------------------------
void SkTextBlobCacheDiffCanvas::TrackLayerDevice::processGlyphRunForMask(
const SkGlyphRun& glyphRun, const SkMatrix& runMatrix, SkPoint origin) {
TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::processGlyphRunForMask");
const SkPaint& runPaint = glyphRun.paint();
SkSTArenaAlloc<120> arena;
SkFindAndPlaceGlyph::MapperInterface* mapper =
SkFindAndPlaceGlyph::CreateMapper(runMatrix, origin, 2, &arena);
SkScalerContextEffects effects;
auto* glyphCacheState = fStrikeServer->getOrCreateCache(
runPaint, &this->surfaceProps(), &runMatrix,
SkScalerContextFlags::kFakeGammaAndBoostContrast, &effects);
SkASSERT(glyphCacheState);
const bool asPath = false;
bool isSubpixel = glyphCacheState->isSubpixel();
SkAxisAlignment axisAlignment = glyphCacheState->axisAlignmentForHText();
auto glyphs = glyphRun.shuntGlyphsIDs();
auto positions = glyphRun.positions();
for (uint32_t index = 0; index < glyphRun.runSize(); index++) {
SkIPoint subPixelPos{0, 0};
if (isSubpixel) {
SkPoint glyphPos = mapper->map(positions[index]);
subPixelPos = SkFindAndPlaceGlyph::SubpixelAlignment(axisAlignment, glyphPos);
}
glyphCacheState->addGlyph(
SkPackedGlyphID(glyphs[index], subPixelPos.x(), subPixelPos.y()),
asPath);
}
}
// -- GrTextContext --------------------------------------------------------------------------------
GrColor generate_filtered_color(const SkPaint& paint, const GrColorSpaceInfo& colorSpaceInfo) {
GrColor4f filteredColor = SkColorToUnpremulGrColor4f(paint.getColor(), colorSpaceInfo);
if (paint.getColorFilter() != nullptr) {

View File

@ -12,7 +12,6 @@
#include <memory>
#include <vector>
#include "SkArenaAlloc.h"
#include "SkDescriptor.h"
#include "SkMask.h"
#include "SkPath.h"
@ -26,6 +25,7 @@
class GrColorSpaceInfo;
class GrRenderTargetContext;
#endif
class SkArenaAlloc;
class SkBaseDevice;
class SkGlyphRunList;
class SkRasterClip;
@ -142,7 +142,7 @@ public:
using PerMaskCreator = std::function<PerMask(const SkPaint&, SkArenaAlloc* alloc)>;
using PerPath = std::function<void(const SkPath*, const SkGlyph&, SkPoint)>;
using PerPathCreator = std::function<PerPath(
const SkPaint&, SkScalar matrixScale,SkArenaAlloc* alloc)>;
const SkPaint&, SkScalar matrixScale, SkArenaAlloc* alloc)>;
void drawForBitmapDevice(
const SkGlyphRunList& glyphRunList, const SkMatrix& deviceMatrix,
PerMaskCreator perMaskCreator, PerPathCreator perPathCreator);

View File

@ -214,182 +214,142 @@ bool SkDescriptorMapOperators::operator()(const SkDescriptor* lhs, const SkDescr
}
// -- TrackLayerDevice -----------------------------------------------------------------------------
#define FAIL_AND_RETURN \
SkDEBUGFAIL("Failed to process glyph run"); \
return;
SkTextBlobCacheDiffCanvas::TrackLayerDevice::TrackLayerDevice(
const SkIRect& bounds, const SkSurfaceProps& props, SkStrikeServer* server,
const SkTextBlobCacheDiffCanvas::Settings& settings)
: SkNoPixelsDevice(bounds, props), fStrikeServer(server), fSettings(settings) {
SkASSERT(fStrikeServer);
}
class SkTextBlobCacheDiffCanvas::TrackLayerDevice : public SkNoPixelsDevice {
public:
TrackLayerDevice(const SkIRect& bounds, const SkSurfaceProps& props, SkStrikeServer* server,
const SkTextBlobCacheDiffCanvas::Settings& settings)
: SkNoPixelsDevice(bounds, props), fStrikeServer(server), fSettings(settings) {
SkASSERT(fStrikeServer);
SkBaseDevice* SkTextBlobCacheDiffCanvas::TrackLayerDevice::onCreateDevice(
const CreateInfo& cinfo, const SkPaint*) {
const SkSurfaceProps surfaceProps(this->surfaceProps().flags(), cinfo.fPixelGeometry);
return new TrackLayerDevice(this->getGlobalBounds(), surfaceProps, fStrikeServer, fSettings);
}
void SkTextBlobCacheDiffCanvas::TrackLayerDevice::drawGlyphRunList(
const SkGlyphRunList& glyphRunList) {
for (auto& glyphRun : glyphRunList) {
this->processGlyphRun(glyphRunList.origin(), glyphRun);
}
SkBaseDevice* onCreateDevice(const CreateInfo& cinfo, const SkPaint*) override {
const SkSurfaceProps surfaceProps(this->surfaceProps().flags(), cinfo.fPixelGeometry);
return new TrackLayerDevice(this->getGlobalBounds(), surfaceProps, fStrikeServer,
fSettings);
}
void SkTextBlobCacheDiffCanvas::TrackLayerDevice::processGlyphRun(
const SkPoint& origin, const SkGlyphRun& glyphRun) {
TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::processGlyphRun");
const SkPaint& runPaint = glyphRun.paint();
const SkMatrix& runMatrix = this->ctm();
// If the matrix has perspective, we fall back to using distance field text or paths.
#if SK_SUPPORT_GPU
if (this->maybeProcessGlyphRunForDFT(glyphRun, runMatrix)) {
return;
} else
#endif
if (SkDraw::ShouldDrawTextAsPaths(runPaint, runMatrix)) {
this->processGlyphRunForPaths(glyphRun, runMatrix);
} else {
this->processGlyphRunForMask(glyphRun, runMatrix, origin);
}
}
protected:
void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override {
for (auto& glyphRun : glyphRunList) {
this->processGlyphRun(glyphRunList.origin(), glyphRun);
}
}
void SkTextBlobCacheDiffCanvas::TrackLayerDevice::processGlyphRunForPaths(
const SkGlyphRun& glyphRun, const SkMatrix& runMatrix) {
TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::processGlyphRunForPaths");
const SkPaint& runPaint = glyphRun.paint();
private:
void processGlyphRun(const SkPoint& origin,
const SkGlyphRun& glyphRun) {
TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::processGlyphRun");
const SkPaint& runPaint = glyphRun.paint();
const SkMatrix& runMatrix = this->ctm();
// If the matrix has perspective, we fall back to using distance field text or paths.
#if SK_SUPPORT_GPU
if (this->maybeProcessGlyphRunForDFT(glyphRun, runMatrix)) {
return;
} else
#endif
if (SkDraw::ShouldDrawTextAsPaths(runPaint, runMatrix)) {
this->processGlyphRunForPaths(glyphRun, runMatrix);
} else {
processGlyphRunForMask(glyphRun, runMatrix, origin);
}
}
void processGlyphRunForMask(
const SkGlyphRun& glyphRun, const SkMatrix& runMatrix, SkPoint origin) {
TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::processGlyphRunForMask");
const SkPaint& runPaint = glyphRun.paint();
SkSTArenaAlloc<120> arena;
SkFindAndPlaceGlyph::MapperInterface* mapper =
SkFindAndPlaceGlyph::CreateMapper(runMatrix, origin, 2, &arena);
SkScalerContextEffects effects;
auto* glyphCacheState = fStrikeServer->getOrCreateCache(
runPaint, &this->surfaceProps(), &runMatrix,
SkScalerContextFlags::kFakeGammaAndBoostContrast, &effects);
SkASSERT(glyphCacheState);
const bool asPath = false;
bool isSubpixel = glyphCacheState->isSubpixel();
SkAxisAlignment axisAlignment = glyphCacheState->axisAlignmentForHText();
auto glyphs = glyphRun.shuntGlyphsIDs();
auto positions = glyphRun.positions();
for (uint32_t index = 0; index < glyphRun.runSize(); index++) {
SkIPoint subPixelPos{0, 0};
if (isSubpixel) {
SkPoint glyphPos = mapper->map(positions[index]);
subPixelPos = SkFindAndPlaceGlyph::SubpixelAlignment(axisAlignment, glyphPos);
}
glyphCacheState->addGlyph(
SkPackedGlyphID(glyphs[index], subPixelPos.x(), subPixelPos.y()),
asPath);
}
}
void processGlyphRunForPaths(const SkGlyphRun& glyphRun, const SkMatrix& runMatrix) {
TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::processGlyphRunForPaths");
const SkPaint& runPaint = glyphRun.paint();
// The code below borrowed from GrTextContext::DrawBmpPosTextAsPaths.
SkPaint pathPaint(runPaint);
// The code below borrowed from GrTextContext::DrawBmpPosTextAsPaths.
SkPaint pathPaint(runPaint);
#if SK_SUPPORT_GPU
SkScalar matrixScale = pathPaint.setupForAsPaths();
GrTextContext::FallbackGlyphRunHelper fallbackTextHelper(
runMatrix, runPaint, glyph_size_limit(fSettings), matrixScale);
const SkPoint emptyPosition{0, 0};
SkScalar matrixScale = pathPaint.setupForAsPaths();
GrTextContext::FallbackGlyphRunHelper fallbackTextHelper(
runMatrix, runPaint, glyph_size_limit(fSettings), matrixScale);
const SkPoint emptyPosition{0, 0};
#else
pathPaint.setupForAsPaths();
pathPaint.setupForAsPaths();
#endif
pathPaint.setStyle(SkPaint::kFill_Style);
pathPaint.setPathEffect(nullptr);
pathPaint.setStyle(SkPaint::kFill_Style);
pathPaint.setPathEffect(nullptr);
SkScalerContextEffects effects;
auto* glyphCacheState = fStrikeServer->getOrCreateCache(
pathPaint, &this->surfaceProps(), nullptr,
SkScalerContextFlags::kFakeGammaAndBoostContrast, &effects);
SkScalerContextEffects effects;
auto* glyphCacheState = fStrikeServer->getOrCreateCache(
pathPaint, &this->surfaceProps(), nullptr,
SkScalerContextFlags::kFakeGammaAndBoostContrast, &effects);
const bool asPath = true;
auto glyphs = glyphRun.shuntGlyphsIDs();
for (uint32_t index = 0; index < glyphRun.runSize(); index++) {
auto glyphID = glyphs[index];
const bool asPath = true;
auto glyphs = glyphRun.shuntGlyphsIDs();
for (uint32_t index = 0; index < glyphRun.runSize(); index++) {
auto glyphID = glyphs[index];
#if SK_SUPPORT_GPU
const auto& glyph =
glyphCacheState->findGlyph(glyphID);
if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
// Note that we send data for the original glyph even in the case of fallback
// since its glyph metrics will still be used on the client.
fallbackTextHelper.appendGlyph(glyph, glyphID, emptyPosition);
}
#endif
glyphCacheState->addGlyph(glyphID, asPath);
const auto& glyph =
glyphCacheState->findGlyph(glyphID);
if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
// Note that we send data for the original glyph even in the case of fallback
// since its glyph metrics will still be used on the client.
fallbackTextHelper.appendGlyph(glyph, glyphID, emptyPosition);
}
#if SK_SUPPORT_GPU
add_fallback_text_to_cache(fallbackTextHelper, this->surfaceProps(), runMatrix, runPaint,
fStrikeServer);
#endif
glyphCacheState->addGlyph(glyphID, asPath);
}
#if SK_SUPPORT_GPU
bool maybeProcessGlyphRunForDFT(const SkGlyphRun& glyphRun, const SkMatrix& runMatrix) {
TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::maybeProcessGlyphRunForDFT");
add_fallback_text_to_cache(fallbackTextHelper, this->surfaceProps(), runMatrix, runPaint,
fStrikeServer);
#endif
}
const SkPaint& runPaint = glyphRun.paint();
#if SK_SUPPORT_GPU
bool SkTextBlobCacheDiffCanvas::TrackLayerDevice::maybeProcessGlyphRunForDFT(
const SkGlyphRun& glyphRun, const SkMatrix& runMatrix) {
TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::maybeProcessGlyphRunForDFT");
GrTextContext::Options options;
options.fMinDistanceFieldFontSize = fSettings.fMinDistanceFieldFontSize;
options.fMaxDistanceFieldFontSize = fSettings.fMaxDistanceFieldFontSize;
GrTextContext::SanitizeOptions(&options);
if (!GrTextContext::CanDrawAsDistanceFields(runPaint, runMatrix, this->surfaceProps(),
fSettings.fContextSupportsDistanceFieldText,
options)) {
return false;
}
const SkPaint& runPaint = glyphRun.paint();
SkScalar textRatio;
SkPaint dfPaint(runPaint);
SkScalerContextFlags flags;
GrTextContext::InitDistanceFieldPaint(nullptr, &dfPaint, runMatrix, options, &textRatio,
&flags);
SkScalerContextEffects effects;
auto* glyphCacheState = fStrikeServer->getOrCreateCache(dfPaint, &this->surfaceProps(),
nullptr, flags, &effects);
GrTextContext::FallbackGlyphRunHelper fallbackTextHelper(
runMatrix, runPaint, glyph_size_limit(fSettings), textRatio);
const bool asPath = false;
const SkPoint emptyPosition{0, 0};
auto glyphs = glyphRun.shuntGlyphsIDs();
for (uint32_t index = 0; index < glyphRun.runSize(); index++) {
auto glyphID = glyphs[index];
const auto& glyph =
glyphCacheState->findGlyph(glyphID);
if (glyph.fMaskFormat != SkMask::kSDF_Format) {
// Note that we send data for the original glyph even in the case of fallback
// since its glyph metrics will still be used on the client.
fallbackTextHelper.appendGlyph(glyph, glyphID, emptyPosition);
}
glyphCacheState->addGlyph(SkPackedGlyphID(glyphs[index]), asPath);
}
add_fallback_text_to_cache(fallbackTextHelper, this->surfaceProps(), runMatrix, runPaint,
fStrikeServer);
return true;
GrTextContext::Options options;
options.fMinDistanceFieldFontSize = fSettings.fMinDistanceFieldFontSize;
options.fMaxDistanceFieldFontSize = fSettings.fMaxDistanceFieldFontSize;
GrTextContext::SanitizeOptions(&options);
if (!GrTextContext::CanDrawAsDistanceFields(runPaint, runMatrix, this->surfaceProps(),
fSettings.fContextSupportsDistanceFieldText,
options)) {
return false;
}
SkScalar textRatio;
SkPaint dfPaint(runPaint);
SkScalerContextFlags flags;
GrTextContext::InitDistanceFieldPaint(nullptr, &dfPaint, runMatrix, options, &textRatio,
&flags);
SkScalerContextEffects effects;
auto* glyphCacheState = fStrikeServer->getOrCreateCache(dfPaint, &this->surfaceProps(),
nullptr, flags, &effects);
GrTextContext::FallbackGlyphRunHelper fallbackTextHelper(
runMatrix, runPaint, glyph_size_limit(fSettings), textRatio);
const bool asPath = false;
const SkPoint emptyPosition{0, 0};
auto glyphs = glyphRun.shuntGlyphsIDs();
for (uint32_t index = 0; index < glyphRun.runSize(); index++) {
auto glyphID = glyphs[index];
const auto& glyph =
glyphCacheState->findGlyph(glyphID);
if (glyph.fMaskFormat != SkMask::kSDF_Format) {
// Note that we send data for the original glyph even in the case of fallback
// since its glyph metrics will still be used on the client.
fallbackTextHelper.appendGlyph(glyph, glyphID, emptyPosition);
}
glyphCacheState->addGlyph(SkPackedGlyphID(glyphs[index]), asPath);
}
add_fallback_text_to_cache(fallbackTextHelper, this->surfaceProps(), runMatrix, runPaint,
fStrikeServer);
return true;
}
#endif
SkStrikeServer* const fStrikeServer;
const SkTextBlobCacheDiffCanvas::Settings fSettings;
};
// -- SkTextBlobCacheDiffCanvas -------------------------------------------------------------------
SkTextBlobCacheDiffCanvas::Settings::Settings() = default;

View File

@ -16,6 +16,7 @@
#include "../private/SkTHash.h"
#include "SkData.h"
#include "SkDevice.h"
#include "SkDrawLooper.h"
#include "SkMakeUnique.h"
#include "SkNoDrawCanvas.h"
@ -27,6 +28,8 @@ class Serializer;
enum SkAxisAlignment : uint32_t;
class SkDescriptor;
class SkGlyphCache;
class SkGlyphRun;
class SkGlyphRunList;
struct SkPackedGlyphID;
enum SkScalerContextFlags : uint32_t;
class SkScalerContextRecDescriptor;
@ -77,7 +80,31 @@ protected:
const SkPaint& paint) override;
private:
class TrackLayerDevice;
class TrackLayerDevice : public SkNoPixelsDevice {
public:
TrackLayerDevice(const SkIRect& bounds, const SkSurfaceProps& props, SkStrikeServer* server,
const SkTextBlobCacheDiffCanvas::Settings& settings);
SkBaseDevice* onCreateDevice(const CreateInfo& cinfo, const SkPaint*) override;
protected:
void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override;
private:
void processGlyphRun(const SkPoint& origin, const SkGlyphRun& glyphRun);
void processGlyphRunForMask(
const SkGlyphRun& glyphRun, const SkMatrix& runMatrix, SkPoint origin);
void processGlyphRunForPaths(const SkGlyphRun& glyphRun, const SkMatrix& runMatrix);
#if SK_SUPPORT_GPU
bool maybeProcessGlyphRunForDFT(const SkGlyphRun& glyphRun, const SkMatrix& runMatrix);
#endif
SkStrikeServer* const fStrikeServer;
const SkTextBlobCacheDiffCanvas::Settings fSettings;
};
};
using SkDiscardableHandleId = uint32_t;