Only use fake gamma with linear devices.
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1711223003 Review URL: https://codereview.chromium.org/1711223003
This commit is contained in:
parent
933ad4389f
commit
f6d1e60531
@ -139,6 +139,9 @@ private:
|
||||
bool SK_WARN_UNUSED_RESULT
|
||||
computeConservativeLocalClipBounds(SkRect* bounds) const;
|
||||
|
||||
/** Returns the current setting for using fake gamma. */
|
||||
SkPaint::FakeGamma SK_WARN_UNUSED_RESULT fakeGamma() const;
|
||||
|
||||
public:
|
||||
SkPixmap fDst;
|
||||
const SkMatrix* fMatrix; // required
|
||||
|
@ -1072,19 +1072,24 @@ private:
|
||||
SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
|
||||
int* count, SkRect* bounds) const;
|
||||
|
||||
enum class FakeGamma {
|
||||
Off = 0, On
|
||||
};
|
||||
|
||||
/*
|
||||
* Allocs an SkDescriptor on the heap and return it to the caller as a refcnted
|
||||
* SkData. Caller is responsible for managing the lifetime of this object.
|
||||
*/
|
||||
void getScalerContextDescriptor(SkAutoDescriptor*, const SkSurfaceProps& surfaceProps,
|
||||
const SkMatrix*, bool ignoreGamma) const;
|
||||
FakeGamma fakeGamma, const SkMatrix*) const;
|
||||
|
||||
SkGlyphCache* detachCache(const SkSurfaceProps* surfaceProps, const SkMatrix*,
|
||||
bool ignoreGamma) const;
|
||||
SkGlyphCache* detachCache(const SkSurfaceProps* surfaceProps, FakeGamma fakeGamma,
|
||||
const SkMatrix*) const;
|
||||
|
||||
void descriptorProc(const SkSurfaceProps* surfaceProps, const SkMatrix* deviceMatrix,
|
||||
void descriptorProc(const SkSurfaceProps* surfaceProps, FakeGamma fakeGamma,
|
||||
const SkMatrix* deviceMatrix,
|
||||
void (*proc)(SkTypeface*, const SkDescriptor*, void*),
|
||||
void* context, bool ignoreGamma) const;
|
||||
void* context) const;
|
||||
|
||||
/*
|
||||
* The luminance color is used to determine which Gamma Canonical color to map to. This is
|
||||
|
@ -1556,6 +1556,10 @@ private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkPaint::FakeGamma SkDraw::fakeGamma() const {
|
||||
return fDevice->imageInfo().isLinear() ? SkPaint::FakeGamma::On : SkPaint::FakeGamma::Off;
|
||||
}
|
||||
|
||||
void SkDraw::drawText(const char text[], size_t byteLength,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) const {
|
||||
SkASSERT(byteLength == 0 || text != nullptr);
|
||||
@ -1574,17 +1578,16 @@ void SkDraw::drawText(const char text[], size_t byteLength,
|
||||
return;
|
||||
}
|
||||
|
||||
SkAutoGlyphCache autoCache(paint, &fDevice->surfaceProps(), fMatrix);
|
||||
SkGlyphCache* cache = autoCache.getCache();
|
||||
SkAutoGlyphCache cache(paint, &fDevice->surfaceProps(), this->fakeGamma(), fMatrix);
|
||||
|
||||
// The Blitter Choose needs to be live while using the blitter below.
|
||||
SkAutoBlitterChoose blitterChooser(fDst, *fMatrix, paint);
|
||||
SkAAClipBlitterWrapper wrapper(*fRC, blitterChooser.get());
|
||||
DrawOneGlyph drawOneGlyph(*this, paint, cache, wrapper.getBlitter());
|
||||
DrawOneGlyph drawOneGlyph(*this, paint, cache.get(), wrapper.getBlitter());
|
||||
|
||||
SkFindAndPlaceGlyph::ProcessText(
|
||||
paint.getTextEncoding(), text, byteLength,
|
||||
{x, y}, *fMatrix, paint.getTextAlign(), cache, drawOneGlyph);
|
||||
{x, y}, *fMatrix, paint.getTextAlign(), cache.get(), drawOneGlyph);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -1604,8 +1607,7 @@ void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength,
|
||||
paint.setPathEffect(nullptr);
|
||||
|
||||
SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
|
||||
SkAutoGlyphCache autoCache(paint, &fDevice->surfaceProps(), nullptr);
|
||||
SkGlyphCache* cache = autoCache.getCache();
|
||||
SkAutoGlyphCache cache(paint, &fDevice->surfaceProps(), this->fakeGamma(), nullptr);
|
||||
|
||||
const char* stop = text + byteLength;
|
||||
SkTextAlignProc alignProc(paint.getTextAlign());
|
||||
@ -1616,7 +1618,7 @@ void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength,
|
||||
paint.setPathEffect(origPaint.getPathEffect());
|
||||
|
||||
while (text < stop) {
|
||||
const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
|
||||
const SkGlyph& glyph = glyphCacheProc(cache.get(), &text, 0, 0);
|
||||
if (glyph.fWidth) {
|
||||
const SkPath* path = cache->findPath(glyph);
|
||||
if (path) {
|
||||
@ -1656,18 +1658,17 @@ void SkDraw::drawPosText(const char text[], size_t byteLength,
|
||||
return;
|
||||
}
|
||||
|
||||
SkAutoGlyphCache autoCache(paint, &fDevice->surfaceProps(), fMatrix);
|
||||
SkGlyphCache* cache = autoCache.getCache();
|
||||
SkAutoGlyphCache cache(paint, &fDevice->surfaceProps(), this->fakeGamma(), fMatrix);
|
||||
|
||||
// The Blitter Choose needs to be live while using the blitter below.
|
||||
SkAutoBlitterChoose blitterChooser(fDst, *fMatrix, paint);
|
||||
SkAAClipBlitterWrapper wrapper(*fRC, blitterChooser.get());
|
||||
DrawOneGlyph drawOneGlyph(*this, paint, cache, wrapper.getBlitter());
|
||||
DrawOneGlyph drawOneGlyph(*this, paint, cache.get(), wrapper.getBlitter());
|
||||
SkPaint::Align textAlignment = paint.getTextAlign();
|
||||
|
||||
SkFindAndPlaceGlyph::ProcessPosText(
|
||||
paint.getTextEncoding(), text, byteLength,
|
||||
offset, *fMatrix, pos, scalarsPerPosition, textAlignment, cache, drawOneGlyph);
|
||||
offset, *fMatrix, pos, scalarsPerPosition, textAlignment, cache.get(), drawOneGlyph);
|
||||
}
|
||||
|
||||
#if defined _WIN32 && _MSC_VER >= 1300
|
||||
|
@ -11,12 +11,12 @@
|
||||
#include "SkChunkAlloc.h"
|
||||
#include "SkDescriptor.h"
|
||||
#include "SkGlyph.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkTHash.h"
|
||||
#include "SkScalerContext.h"
|
||||
#include "SkTemplates.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
class SkPaint;
|
||||
class SkTraceMemoryDump;
|
||||
|
||||
class SkGlyphCache_Globals;
|
||||
@ -137,6 +137,7 @@ public:
|
||||
the global cache list (after which the caller should not reference it anymore.
|
||||
*/
|
||||
static void AttachCache(SkGlyphCache*);
|
||||
using AttachCacheFunctor = SkFunctionWrapper<void, SkGlyphCache, AttachCache>;
|
||||
|
||||
/** Detach a strike from the global cache matching the specified descriptor. Once detached,
|
||||
it can be queried/modified by the current thread, and when finished, be reattached to the
|
||||
@ -271,74 +272,40 @@ private:
|
||||
AuxProcRec* fAuxProcList;
|
||||
};
|
||||
|
||||
class SkAutoGlyphCacheBase {
|
||||
class SkAutoGlyphCache : public skstd::unique_ptr<SkGlyphCache, SkGlyphCache::AttachCacheFunctor> {
|
||||
public:
|
||||
SkGlyphCache* getCache() const { return fCache; }
|
||||
/** deprecated: use get() */
|
||||
SkGlyphCache* getCache() const { return this->get(); }
|
||||
|
||||
void release() {
|
||||
if (fCache) {
|
||||
SkGlyphCache::AttachCache(fCache);
|
||||
fCache = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// Hide the constructors so we can't create one of these directly. Create SkAutoGlyphCache or
|
||||
// SkAutoGlyphCacheNoCache instead.
|
||||
SkAutoGlyphCacheBase(SkGlyphCache* cache) : fCache(cache) {}
|
||||
SkAutoGlyphCacheBase(SkTypeface* typeface, const SkDescriptor* desc) {
|
||||
fCache = SkGlyphCache::DetachCache(typeface, desc);
|
||||
}
|
||||
SkAutoGlyphCacheBase(const SkPaint& /*paint*/,
|
||||
const SkSurfaceProps* /*surfaceProps*/,
|
||||
const SkMatrix* /*matrix*/) {
|
||||
fCache = nullptr;
|
||||
}
|
||||
SkAutoGlyphCacheBase() {
|
||||
fCache = nullptr;
|
||||
}
|
||||
~SkAutoGlyphCacheBase() {
|
||||
if (fCache) {
|
||||
SkGlyphCache::AttachCache(fCache);
|
||||
}
|
||||
}
|
||||
|
||||
SkGlyphCache* fCache;
|
||||
|
||||
private:
|
||||
static bool DetachProc(const SkGlyphCache*, void*);
|
||||
};
|
||||
|
||||
class SkAutoGlyphCache : public SkAutoGlyphCacheBase {
|
||||
public:
|
||||
SkAutoGlyphCache(SkGlyphCache* cache) : SkAutoGlyphCacheBase(cache) {}
|
||||
SkAutoGlyphCache(SkTypeface* typeface, const SkDescriptor* desc) :
|
||||
SkAutoGlyphCacheBase(typeface, desc) {}
|
||||
SkAutoGlyphCache(SkGlyphCache* cache) : INHERITED(cache) {}
|
||||
SkAutoGlyphCache(SkTypeface* typeface, const SkDescriptor* desc)
|
||||
: INHERITED(SkGlyphCache::DetachCache(typeface, desc))
|
||||
{}
|
||||
/** deprecated: always enables fake gamma */
|
||||
SkAutoGlyphCache(const SkPaint& paint,
|
||||
const SkSurfaceProps* surfaceProps,
|
||||
const SkMatrix* matrix) {
|
||||
fCache = paint.detachCache(surfaceProps, matrix, false);
|
||||
}
|
||||
|
||||
const SkMatrix* matrix)
|
||||
: INHERITED(paint.detachCache(surfaceProps, SkPaint::FakeGamma::On, matrix))
|
||||
{}
|
||||
SkAutoGlyphCache(const SkPaint& paint,
|
||||
const SkSurfaceProps* surfaceProps,
|
||||
SkPaint::FakeGamma fakeGamma,
|
||||
const SkMatrix* matrix)
|
||||
: INHERITED(paint.detachCache(surfaceProps, fakeGamma, matrix))
|
||||
{}
|
||||
private:
|
||||
SkAutoGlyphCache() : SkAutoGlyphCacheBase() {}
|
||||
using INHERITED = skstd::unique_ptr<SkGlyphCache, SkGlyphCache::AttachCacheFunctor>;
|
||||
};
|
||||
#define SkAutoGlyphCache(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCache)
|
||||
|
||||
class SkAutoGlyphCacheNoGamma : public SkAutoGlyphCacheBase {
|
||||
class SkAutoGlyphCacheNoGamma : public SkAutoGlyphCache {
|
||||
public:
|
||||
SkAutoGlyphCacheNoGamma(SkGlyphCache* cache) : SkAutoGlyphCacheBase(cache) {}
|
||||
SkAutoGlyphCacheNoGamma(SkTypeface* typeface, const SkDescriptor* desc) :
|
||||
SkAutoGlyphCacheBase(typeface, desc) {}
|
||||
SkAutoGlyphCacheNoGamma(const SkPaint& paint,
|
||||
const SkSurfaceProps* surfaceProps,
|
||||
const SkMatrix* matrix) {
|
||||
fCache = paint.detachCache(surfaceProps, matrix, true);
|
||||
}
|
||||
|
||||
private:
|
||||
SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {}
|
||||
const SkMatrix* matrix)
|
||||
: SkAutoGlyphCache(paint, surfaceProps, SkPaint::FakeGamma::Off, matrix)
|
||||
{}
|
||||
};
|
||||
#define SkAutoGlyphCache(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCache)
|
||||
#define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamma)
|
||||
|
||||
#endif
|
||||
|
@ -1098,7 +1098,7 @@ SkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const {
|
||||
metrics = &storage;
|
||||
}
|
||||
|
||||
paint.descriptorProc(nullptr, zoomPtr, FontMetricsDescProc, metrics, true);
|
||||
paint.descriptorProc(nullptr, FakeGamma::Off, zoomPtr, FontMetricsDescProc, metrics);
|
||||
|
||||
if (scale) {
|
||||
metrics->fTop = SkScalarMul(metrics->fTop, scale);
|
||||
@ -1690,12 +1690,13 @@ static void write_out_descriptor(SkDescriptor* desc, const SkScalerContext::Rec&
|
||||
|
||||
static size_t fill_out_rec(const SkPaint& paint, SkScalerContext::Rec* rec,
|
||||
const SkSurfaceProps* surfaceProps,
|
||||
const SkMatrix* deviceMatrix, bool ignoreGamma,
|
||||
bool fakeGamma,
|
||||
const SkMatrix* deviceMatrix,
|
||||
const SkPathEffect* pe, SkWriteBuffer* peBuffer,
|
||||
const SkMaskFilter* mf, SkWriteBuffer* mfBuffer,
|
||||
const SkRasterizer* ra, SkWriteBuffer* raBuffer) {
|
||||
SkScalerContext::MakeRec(paint, surfaceProps, deviceMatrix, rec);
|
||||
if (ignoreGamma) {
|
||||
if (!fakeGamma) {
|
||||
rec->ignorePreBlend();
|
||||
}
|
||||
|
||||
@ -1785,7 +1786,8 @@ static void test_desc(const SkScalerContext::Rec& rec,
|
||||
/* see the note on ignoreGamma on descriptorProc */
|
||||
void SkPaint::getScalerContextDescriptor(SkAutoDescriptor* ad,
|
||||
const SkSurfaceProps& surfaceProps,
|
||||
const SkMatrix* deviceMatrix, bool ignoreGamma) const {
|
||||
FakeGamma fakeGamma,
|
||||
const SkMatrix* deviceMatrix) const {
|
||||
SkScalerContext::Rec rec;
|
||||
|
||||
SkPathEffect* pe = this->getPathEffect();
|
||||
@ -1793,7 +1795,8 @@ void SkPaint::getScalerContextDescriptor(SkAutoDescriptor* ad,
|
||||
SkRasterizer* ra = this->getRasterizer();
|
||||
|
||||
SkWriteBuffer peBuffer, mfBuffer, raBuffer;
|
||||
size_t descSize = fill_out_rec(*this, &rec, &surfaceProps, deviceMatrix, ignoreGamma,
|
||||
size_t descSize = fill_out_rec(*this, &rec,
|
||||
&surfaceProps, FakeGamma::On == fakeGamma, deviceMatrix,
|
||||
pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer);
|
||||
|
||||
ad->reset(descSize);
|
||||
@ -1814,9 +1817,10 @@ void SkPaint::getScalerContextDescriptor(SkAutoDescriptor* ad,
|
||||
* contrast = 0, luminanceColor = transparent black.
|
||||
*/
|
||||
void SkPaint::descriptorProc(const SkSurfaceProps* surfaceProps,
|
||||
FakeGamma fakeGamma,
|
||||
const SkMatrix* deviceMatrix,
|
||||
void (*proc)(SkTypeface*, const SkDescriptor*, void*),
|
||||
void* context, bool ignoreGamma) const {
|
||||
void* context) const {
|
||||
SkScalerContext::Rec rec;
|
||||
|
||||
SkPathEffect* pe = this->getPathEffect();
|
||||
@ -1824,7 +1828,8 @@ void SkPaint::descriptorProc(const SkSurfaceProps* surfaceProps,
|
||||
SkRasterizer* ra = this->getRasterizer();
|
||||
|
||||
SkWriteBuffer peBuffer, mfBuffer, raBuffer;
|
||||
size_t descSize = fill_out_rec(*this, &rec, surfaceProps, deviceMatrix, ignoreGamma,
|
||||
size_t descSize = fill_out_rec(*this, &rec,
|
||||
surfaceProps, FakeGamma::On == fakeGamma, deviceMatrix,
|
||||
pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer);
|
||||
|
||||
SkAutoDescriptor ad(descSize);
|
||||
@ -1842,10 +1847,10 @@ void SkPaint::descriptorProc(const SkSurfaceProps* surfaceProps,
|
||||
}
|
||||
|
||||
SkGlyphCache* SkPaint::detachCache(const SkSurfaceProps* surfaceProps,
|
||||
const SkMatrix* deviceMatrix,
|
||||
bool ignoreGamma) const {
|
||||
FakeGamma fakeGamma,
|
||||
const SkMatrix* deviceMatrix) const {
|
||||
SkGlyphCache* cache;
|
||||
this->descriptorProc(surfaceProps, deviceMatrix, DetachDescProc, &cache, ignoreGamma);
|
||||
this->descriptorProc(surfaceProps, fakeGamma, deviceMatrix, DetachDescProc, &cache);
|
||||
return cache;
|
||||
}
|
||||
|
||||
@ -2417,7 +2422,7 @@ SkTextBaseIter::SkTextBaseIter(const char text[], size_t length,
|
||||
fPaint.setPathEffect(nullptr);
|
||||
}
|
||||
|
||||
fCache = fPaint.detachCache(nullptr, nullptr, false);
|
||||
fCache = fPaint.detachCache(nullptr, SkPaint::FakeGamma::On, nullptr);
|
||||
|
||||
SkPaint::Style style = SkPaint::kFill_Style;
|
||||
SkPathEffect* pe = nullptr;
|
||||
|
@ -51,15 +51,15 @@ GrAtlasTextBlob* GrAtlasTextBlob::Create(GrMemoryPool* pool, int glyphCount, int
|
||||
|
||||
SkGlyphCache* GrAtlasTextBlob::setupCache(int runIndex,
|
||||
const SkSurfaceProps& props,
|
||||
SkPaint::FakeGamma fakeGamma,
|
||||
const SkPaint& skPaint,
|
||||
const SkMatrix* viewMatrix,
|
||||
bool noGamma) {
|
||||
const SkMatrix* viewMatrix) {
|
||||
GrAtlasTextBlob::Run* run = &fRuns[runIndex];
|
||||
|
||||
// if we have an override descriptor for the run, then we should use that
|
||||
SkAutoDescriptor* desc = run->fOverrideDescriptor.get() ? run->fOverrideDescriptor.get() :
|
||||
&run->fDescriptor;
|
||||
skPaint.getScalerContextDescriptor(desc, props, viewMatrix, noGamma);
|
||||
skPaint.getScalerContextDescriptor(desc, props, fakeGamma, viewMatrix);
|
||||
run->fTypeface.reset(SkSafeRef(skPaint.getTypeface()));
|
||||
return SkGlyphCache::DetachCache(run->fTypeface, desc->getDesc());
|
||||
}
|
||||
|
@ -148,9 +148,9 @@ public:
|
||||
|
||||
SkGlyphCache* setupCache(int runIndex,
|
||||
const SkSurfaceProps& props,
|
||||
SkPaint::FakeGamma fakeGamma,
|
||||
const SkPaint& skPaint,
|
||||
const SkMatrix* viewMatrix,
|
||||
bool noGamma);
|
||||
const SkMatrix* viewMatrix);
|
||||
|
||||
// Appends a glyph to the blob. If the glyph is too large, the glyph will be appended
|
||||
// as a path.
|
||||
|
@ -629,7 +629,7 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
|
||||
|
||||
SkGlyphCache* GrStencilAndCoverTextContext::TextRun::getGlyphCache() const {
|
||||
if (!fDetachedGlyphCache) {
|
||||
fDetachedGlyphCache = fFont.detachCache(nullptr, nullptr, true /*ignoreGamma*/);
|
||||
fDetachedGlyphCache = fFont.detachCache(nullptr, SkPaint::FakeGamma::Off, nullptr);
|
||||
}
|
||||
return fDetachedGlyphCache;
|
||||
}
|
||||
|
@ -57,7 +57,8 @@ void GrTextUtils::DrawBmpText(GrAtlasTextBlob* blob, int runIndex,
|
||||
GrBatchTextStrike* currStrike = nullptr;
|
||||
|
||||
// Get GrFontScaler from cache
|
||||
SkGlyphCache* cache = blob->setupCache(runIndex, props, skPaint, &viewMatrix, false);
|
||||
SkGlyphCache* cache = blob->setupCache(runIndex, props, SkPaint::FakeGamma::On,
|
||||
skPaint, &viewMatrix);
|
||||
GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache);
|
||||
|
||||
SkFindAndPlaceGlyph::ProcessText(
|
||||
@ -98,7 +99,8 @@ void GrTextUtils::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex,
|
||||
GrBatchTextStrike* currStrike = nullptr;
|
||||
|
||||
// Get GrFontScaler from cache
|
||||
SkGlyphCache* cache = blob->setupCache(runIndex, props, skPaint, &viewMatrix, false);
|
||||
SkGlyphCache* cache = blob->setupCache(runIndex, props, SkPaint::FakeGamma::On,
|
||||
skPaint, &viewMatrix);
|
||||
GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache);
|
||||
|
||||
SkFindAndPlaceGlyph::ProcessPosText(
|
||||
@ -258,7 +260,7 @@ void GrTextUtils::DrawDFText(GrAtlasTextBlob* blob, int runIndex,
|
||||
|
||||
SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc();
|
||||
SkAutoDescriptor desc;
|
||||
skPaint.getScalerContextDescriptor(&desc, props, nullptr, true);
|
||||
skPaint.getScalerContextDescriptor(&desc, props, SkPaint::FakeGamma::Off, nullptr);
|
||||
SkGlyphCache* origPaintCache = SkGlyphCache::DetachCache(skPaint.getTypeface(),
|
||||
desc.getDesc());
|
||||
|
||||
@ -339,7 +341,8 @@ void GrTextUtils::DrawDFPosText(GrAtlasTextBlob* blob, int runIndex,
|
||||
|
||||
GrBatchTextStrike* currStrike = nullptr;
|
||||
|
||||
SkGlyphCache* cache = blob->setupCache(runIndex, props, dfPaint, nullptr, true);
|
||||
SkGlyphCache* cache = blob->setupCache(runIndex, props, SkPaint::FakeGamma::Off,
|
||||
dfPaint, nullptr);
|
||||
SkDrawCacheProc glyphCacheProc = dfPaint.getDrawCacheProc();
|
||||
GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user