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:
bungeman 2016-02-22 13:20:28 -08:00 committed by Commit bot
parent 933ad4389f
commit f6d1e60531
9 changed files with 79 additions and 95 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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());
}

View File

@ -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.

View File

@ -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;
}

View File

@ -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);