Add bilerp support to scaled emojis
Bug: skia:7562 Change-Id: Ibdf8e71050e909de87ca2beb3fb2b57327011364 Reviewed-on: https://skia-review.googlesource.com/111820 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
974aa8eaba
commit
cf838c7450
@ -258,8 +258,10 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
|
|||||||
flushInfo.fGeometryProcessor = this->setupDfProcessor(fullAtlasManager);
|
flushInfo.fGeometryProcessor = this->setupDfProcessor(fullAtlasManager);
|
||||||
SkDEBUGCODE(dfPerspective = fGeoData[0].fViewMatrix.hasPerspective());
|
SkDEBUGCODE(dfPerspective = fGeoData[0].fViewMatrix.hasPerspective());
|
||||||
} else {
|
} else {
|
||||||
|
GrSamplerState samplerState = fHasScaledGlyphs ? GrSamplerState::ClampBilerp()
|
||||||
|
: GrSamplerState::ClampNearest();
|
||||||
flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
|
flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
|
||||||
this->color(), proxies, atlasPageCount, GrSamplerState::ClampNearest(), maskFormat,
|
this->color(), proxies, atlasPageCount, samplerState, maskFormat,
|
||||||
localMatrix, this->usesLocalCoords());
|
localMatrix, this->usesLocalCoords());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,8 +351,10 @@ void GrAtlasTextOp::flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) co
|
|||||||
proxies, numProxies, GrSamplerState::ClampBilerp());
|
proxies, numProxies, GrSamplerState::ClampBilerp());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reinterpret_cast<GrBitmapTextGeoProc*>(gp)->addNewProxies(
|
GrSamplerState samplerState = fHasScaledGlyphs ? GrSamplerState::ClampBilerp()
|
||||||
proxies, numProxies, GrSamplerState::ClampNearest());
|
: GrSamplerState::ClampNearest();
|
||||||
|
reinterpret_cast<GrBitmapTextGeoProc*>(gp)->addNewProxies(proxies, numProxies,
|
||||||
|
samplerState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,6 +402,10 @@ bool GrAtlasTextOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
|
|||||||
if (kColorBitmapMask_MaskType == fMaskType && this->color() != that->color()) {
|
if (kColorBitmapMask_MaskType == fMaskType && this->color() != that->color()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fHasScaledGlyphs != that->fHasScaledGlyphs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep the batch vertex buffer size below 32K so we don't have to create a special one
|
// Keep the batch vertex buffer size below 32K so we don't have to create a special one
|
||||||
|
@ -41,8 +41,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static std::unique_ptr<GrAtlasTextOp> MakeBitmap(
|
static std::unique_ptr<GrAtlasTextOp> MakeBitmap(
|
||||||
GrPaint&& paint, GrMaskFormat maskFormat,
|
GrPaint&& paint, GrMaskFormat maskFormat, int glyphCount,
|
||||||
int glyphCount, GrRestrictedAtlasManager* restrictedAtlasManager) {
|
bool hasScaledGlyphs,
|
||||||
|
GrRestrictedAtlasManager* restrictedAtlasManager) {
|
||||||
std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(restrictedAtlasManager,
|
std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(restrictedAtlasManager,
|
||||||
std::move(paint)));
|
std::move(paint)));
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ public:
|
|||||||
op->fNumGlyphs = glyphCount;
|
op->fNumGlyphs = glyphCount;
|
||||||
op->fGeoCount = 1;
|
op->fGeoCount = 1;
|
||||||
op->fLuminanceColor = 0;
|
op->fLuminanceColor = 0;
|
||||||
|
op->fHasScaledGlyphs = hasScaledGlyphs;
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,15 +185,18 @@ private:
|
|||||||
int fGeoDataAllocSize;
|
int fGeoDataAllocSize;
|
||||||
uint32_t fSRGBFlags;
|
uint32_t fSRGBFlags;
|
||||||
GrProcessorSet fProcessors;
|
GrProcessorSet fProcessors;
|
||||||
bool fUsesLocalCoords;
|
struct {
|
||||||
bool fCanCombineOnTouchOrOverlap;
|
uint32_t fUsesLocalCoords : 1;
|
||||||
|
uint32_t fCanCombineOnTouchOrOverlap : 1;
|
||||||
|
uint32_t fUseGammaCorrectDistanceTable : 1;
|
||||||
|
uint32_t fHasScaledGlyphs : 1;
|
||||||
|
};
|
||||||
int fGeoCount;
|
int fGeoCount;
|
||||||
int fNumGlyphs;
|
int fNumGlyphs;
|
||||||
MaskType fMaskType;
|
MaskType fMaskType;
|
||||||
// Distance field properties
|
// Distance field properties
|
||||||
sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
|
sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
|
||||||
SkColor fLuminanceColor;
|
SkColor fLuminanceColor;
|
||||||
bool fUseGammaCorrectDistanceTable;
|
|
||||||
uint32_t fDFGPFlags = 0;
|
uint32_t fDFGPFlags = 0;
|
||||||
|
|
||||||
typedef GrMeshDrawOp INHERITED;
|
typedef GrMeshDrawOp INHERITED;
|
||||||
|
@ -152,6 +152,7 @@ void GrAtlasTextBlob::appendGlyph(int runIndex,
|
|||||||
subRun->appendVertices(vertexStride);
|
subRun->appendVertices(vertexStride);
|
||||||
fGlyphs[subRun->glyphEndIndex()] = glyph;
|
fGlyphs[subRun->glyphEndIndex()] = glyph;
|
||||||
subRun->glyphAppended();
|
subRun->glyphAppended();
|
||||||
|
subRun->setHasScaledGlyphs(SK_Scalar1 != scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrAtlasTextBlob::appendPathGlyph(int runIndex, const SkPath& path, SkScalar x, SkScalar y,
|
void GrAtlasTextBlob::appendPathGlyph(int runIndex, const SkPath& path, SkScalar x, SkScalar y,
|
||||||
@ -264,8 +265,8 @@ inline std::unique_ptr<GrAtlasTextOp> GrAtlasTextBlob::makeOp(
|
|||||||
target->colorSpaceInfo().isGammaCorrect(), paint.luminanceColor(),
|
target->colorSpaceInfo().isGammaCorrect(), paint.luminanceColor(),
|
||||||
info.hasUseLCDText(), useBGR, info.isAntiAliased());
|
info.hasUseLCDText(), useBGR, info.isAntiAliased());
|
||||||
} else {
|
} else {
|
||||||
op = GrAtlasTextOp::MakeBitmap(std::move(grPaint), format,
|
op = GrAtlasTextOp::MakeBitmap(std::move(grPaint), format, glyphCount,
|
||||||
glyphCount, restrictedAtlasManager);
|
info.hasScaledGlyphs(), restrictedAtlasManager);
|
||||||
}
|
}
|
||||||
GrAtlasTextOp::Geometry& geometry = op->geometry();
|
GrAtlasTextOp::Geometry& geometry = op->geometry();
|
||||||
geometry.fViewMatrix = viewMatrix;
|
geometry.fViewMatrix = viewMatrix;
|
||||||
@ -355,9 +356,10 @@ void GrAtlasTextBlob::flush(GrRestrictedAtlasManager* restrictedAtlasManager,
|
|||||||
SkRect rtBounds = SkRect::MakeWH(target->width(), target->height());
|
SkRect rtBounds = SkRect::MakeWH(target->width(), target->height());
|
||||||
SkRRect clipRRect;
|
SkRRect clipRRect;
|
||||||
GrAA aa;
|
GrAA aa;
|
||||||
// We can clip geometrically if we're not using SDFs,
|
// We can clip geometrically if we're not using SDFs or scaled glyphs,
|
||||||
// and we have an axis-aligned rectangular non-AA clip
|
// and we have an axis-aligned rectangular non-AA clip
|
||||||
if (!info.drawAsDistanceFields() && clip.isRRect(rtBounds, &clipRRect, &aa) &&
|
if (!info.drawAsDistanceFields() && !info.hasScaledGlyphs() &&
|
||||||
|
clip.isRRect(rtBounds, &clipRRect, &aa) &&
|
||||||
clipRRect.isRect() && GrAA::kNo == aa) {
|
clipRRect.isRect() && GrAA::kNo == aa) {
|
||||||
skipClip = true;
|
skipClip = true;
|
||||||
// We only need to do clipping work if the subrun isn't contained by the clip
|
// We only need to do clipping work if the subrun isn't contained by the clip
|
||||||
|
@ -435,13 +435,19 @@ private:
|
|||||||
fFlags = hasW ? (fFlags | kHasWCoord_Flag) : fFlags & ~kHasWCoord_Flag;
|
fFlags = hasW ? (fFlags | kHasWCoord_Flag) : fFlags & ~kHasWCoord_Flag;
|
||||||
}
|
}
|
||||||
bool hasWCoord() const { return SkToBool(fFlags & kHasWCoord_Flag); }
|
bool hasWCoord() const { return SkToBool(fFlags & kHasWCoord_Flag); }
|
||||||
|
void setHasScaledGlyphs(bool hasScaledGlyphs) {
|
||||||
|
fFlags = hasScaledGlyphs ? (fFlags | kHasScaledGlyphs_Flag)
|
||||||
|
: fFlags & ~kHasScaledGlyphs_Flag;
|
||||||
|
}
|
||||||
|
bool hasScaledGlyphs() const { return SkToBool(fFlags & kHasScaledGlyphs_Flag); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Flag {
|
enum Flag {
|
||||||
kDrawAsSDF_Flag = 0x1,
|
kDrawAsSDF_Flag = 0x01,
|
||||||
kUseLCDText_Flag = 0x2,
|
kUseLCDText_Flag = 0x02,
|
||||||
kAntiAliased_Flag = 0x4,
|
kAntiAliased_Flag = 0x04,
|
||||||
kHasWCoord_Flag = 0x8
|
kHasWCoord_Flag = 0x08,
|
||||||
|
kHasScaledGlyphs_Flag = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
GrDrawOpAtlas::BulkUseTokenUpdater fBulkUseToken;
|
GrDrawOpAtlas::BulkUseTokenUpdater fBulkUseToken;
|
||||||
|
@ -280,7 +280,8 @@ Regenerator::Result Regenerator::doRegen() {
|
|||||||
if (!fFullAtlasManager->hasGlyph(glyph) &&
|
if (!fFullAtlasManager->hasGlyph(glyph) &&
|
||||||
!strike->addGlyphToAtlas(fResourceProvider, fUploadTarget, fGlyphCache,
|
!strike->addGlyphToAtlas(fResourceProvider, fUploadTarget, fGlyphCache,
|
||||||
fFullAtlasManager, glyph,
|
fFullAtlasManager, glyph,
|
||||||
fLazyCache->get(), fSubRun->maskFormat())) {
|
fLazyCache->get(), fSubRun->maskFormat(),
|
||||||
|
fSubRun->hasScaledGlyphs())) {
|
||||||
fBrokenRun = glyphIdx > 0;
|
fBrokenRun = glyphIdx > 0;
|
||||||
result.fFinished = false;
|
result.fFinished = false;
|
||||||
return result;
|
return result;
|
||||||
|
@ -856,6 +856,7 @@ void GrAtlasTextContext::FallbackTextHelper::appendText(const SkGlyph& glyph, in
|
|||||||
SkScalar scaledGlyphSize = maxDim * fMaxScale;
|
SkScalar scaledGlyphSize = maxDim * fMaxScale;
|
||||||
if (!fViewMatrix.hasPerspective() && scaledGlyphSize > fMaxTextSize) {
|
if (!fViewMatrix.hasPerspective() && scaledGlyphSize > fMaxTextSize) {
|
||||||
fUseScaledFallback = true;
|
fUseScaledFallback = true;
|
||||||
|
fMaxTextSize -= 2; // Subtract 2 to account for the bilerp pad around the glyph
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,35 +298,57 @@ bool GrTextStrike::addGlyphToAtlas(GrResourceProvider* resourceProvider,
|
|||||||
GrAtlasManager* fullAtlasManager,
|
GrAtlasManager* fullAtlasManager,
|
||||||
GrGlyph* glyph,
|
GrGlyph* glyph,
|
||||||
SkGlyphCache* cache,
|
SkGlyphCache* cache,
|
||||||
GrMaskFormat expectedMaskFormat) {
|
GrMaskFormat expectedMaskFormat,
|
||||||
|
bool isScaledGlyph) {
|
||||||
SkASSERT(glyph);
|
SkASSERT(glyph);
|
||||||
SkASSERT(cache);
|
SkASSERT(cache);
|
||||||
SkASSERT(fCache.find(glyph->fPackedID));
|
SkASSERT(fCache.find(glyph->fPackedID));
|
||||||
|
|
||||||
int bytesPerPixel = GrMaskFormatBytesPerPixel(expectedMaskFormat);
|
int bytesPerPixel = GrMaskFormatBytesPerPixel(expectedMaskFormat);
|
||||||
|
int width = glyph->width();
|
||||||
|
int height = glyph->height();
|
||||||
|
int rowBytes = width * bytesPerPixel;
|
||||||
|
|
||||||
size_t size = glyph->fBounds.area() * bytesPerPixel;
|
size_t size = glyph->fBounds.area() * bytesPerPixel;
|
||||||
|
bool isSDFGlyph = GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(glyph->fPackedID);
|
||||||
|
bool addPad = isScaledGlyph && !isSDFGlyph;
|
||||||
|
if (addPad) {
|
||||||
|
width += 2;
|
||||||
|
rowBytes += 2*bytesPerPixel;
|
||||||
|
size += 2 * rowBytes;
|
||||||
|
height += 2;
|
||||||
|
size += 2 * (height + 2) * bytesPerPixel;
|
||||||
|
}
|
||||||
SkAutoSMalloc<1024> storage(size);
|
SkAutoSMalloc<1024> storage(size);
|
||||||
|
|
||||||
const SkGlyph& skGlyph = GrToSkGlyph(cache, glyph->fPackedID);
|
const SkGlyph& skGlyph = GrToSkGlyph(cache, glyph->fPackedID);
|
||||||
if (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(glyph->fPackedID)) {
|
if (isSDFGlyph) {
|
||||||
if (!get_packed_glyph_df_image(cache, skGlyph, glyph->width(), glyph->height(),
|
if (!get_packed_glyph_df_image(cache, skGlyph, width, height,
|
||||||
storage.get())) {
|
storage.get())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
void* dataPtr = storage.get();
|
||||||
|
if (addPad) {
|
||||||
|
sk_bzero(dataPtr, size);
|
||||||
|
dataPtr = (char*)(dataPtr) + rowBytes + bytesPerPixel;
|
||||||
|
}
|
||||||
if (!get_packed_glyph_image(cache, skGlyph, glyph->width(), glyph->height(),
|
if (!get_packed_glyph_image(cache, skGlyph, glyph->width(), glyph->height(),
|
||||||
glyph->width() * bytesPerPixel, expectedMaskFormat,
|
rowBytes, expectedMaskFormat,
|
||||||
storage.get())) {
|
dataPtr)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = fullAtlasManager->addToAtlas(resourceProvider, glyphCache, this,
|
bool success = fullAtlasManager->addToAtlas(resourceProvider, glyphCache, this,
|
||||||
&glyph->fID, target, expectedMaskFormat,
|
&glyph->fID, target, expectedMaskFormat,
|
||||||
glyph->width(), glyph->height(),
|
width, height,
|
||||||
storage.get(), &glyph->fAtlasLocation);
|
storage.get(), &glyph->fAtlasLocation);
|
||||||
if (success) {
|
if (success) {
|
||||||
|
if (addPad) {
|
||||||
|
glyph->fAtlasLocation.fX += 1;
|
||||||
|
glyph->fAtlasLocation.fY += 1;
|
||||||
|
}
|
||||||
SkASSERT(GrDrawOpAtlas::kInvalidAtlasID != glyph->fID);
|
SkASSERT(GrDrawOpAtlas::kInvalidAtlasID != glyph->fID);
|
||||||
fAtlasedGlyphs++;
|
fAtlasedGlyphs++;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ public:
|
|||||||
// get the actual glyph image itself when we get the glyph metrics.
|
// get the actual glyph image itself when we get the glyph metrics.
|
||||||
bool addGlyphToAtlas(GrResourceProvider*, GrDeferredUploadTarget*, GrGlyphCache*,
|
bool addGlyphToAtlas(GrResourceProvider*, GrDeferredUploadTarget*, GrGlyphCache*,
|
||||||
GrAtlasManager*, GrGlyph*,
|
GrAtlasManager*, GrGlyph*,
|
||||||
SkGlyphCache*, GrMaskFormat expectedMaskFormat);
|
SkGlyphCache*, GrMaskFormat expectedMaskFormat, bool isScaledGlyph);
|
||||||
|
|
||||||
// testing
|
// testing
|
||||||
int countGlyphs() const { return fCache.count(); }
|
int countGlyphs() const { return fCache.count(); }
|
||||||
|
Loading…
Reference in New Issue
Block a user