Move DistanceAdjustTable to its own file
BUG=skia:
Review URL: https://codereview.chromium.org/1512823004
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
index 153d0fe..38b9c04 100644
--- a/src/gpu/GrAtlasTextContext.cpp
+++ b/src/gpu/GrAtlasTextContext.cpp
@@ -46,13 +46,11 @@
#else
static const int kLargeDFFontLimit = 2 * kLargeDFFontSize;
#endif
-
-SkDEBUGCODE(static const int kExpectedDistanceAdjustTableSize = 8;)
};
GrAtlasTextContext::GrAtlasTextContext(GrContext* context, const SkSurfaceProps& surfaceProps)
: INHERITED(context, surfaceProps)
- , fDistanceAdjustTable(new DistanceAdjustTable) {
+ , fDistanceAdjustTable(new GrDistanceFieldAdjustTable) {
// We overallocate vertices in our textblobs based on the assumption that A8 has the greatest
// vertexStride
static_assert(GrAtlasTextBlob::kGrayTextVASize >= GrAtlasTextBlob::kColorTextVASize &&
@@ -62,87 +60,6 @@
fCache = context->getTextBlobCache();
}
-void GrAtlasTextContext::DistanceAdjustTable::buildDistanceAdjustTable() {
-
- // This is used for an approximation of the mask gamma hack, used by raster and bitmap
- // text. The mask gamma hack is based off of guessing what the blend color is going to
- // be, and adjusting the mask so that when run through the linear blend will
- // produce the value closest to the desired result. However, in practice this means
- // that the 'adjusted' mask is just increasing or decreasing the coverage of
- // the mask depending on what it is thought it will blit against. For black (on
- // assumed white) this means that coverages are decreased (on a curve). For white (on
- // assumed black) this means that coverages are increased (on a a curve). At
- // middle (perceptual) gray (which could be blit against anything) the coverages
- // remain the same.
- //
- // The idea here is that instead of determining the initial (real) coverage and
- // then adjusting that coverage, we determine an adjusted coverage directly by
- // essentially manipulating the geometry (in this case, the distance to the glyph
- // edge). So for black (on assumed white) this thins a bit; for white (on
- // assumed black) this fake bolds the geometry a bit.
- //
- // The distance adjustment is calculated by determining the actual coverage value which
- // when fed into in the mask gamma table gives us an 'adjusted coverage' value of 0.5. This
- // actual coverage value (assuming it's between 0 and 1) corresponds to a distance from the
- // actual edge. So by subtracting this distance adjustment and computing without the
- // the coverage adjustment we should get 0.5 coverage at the same point.
- //
- // This has several implications:
- // For non-gray lcd smoothed text, each subpixel essentially is using a
- // slightly different geometry.
- //
- // For black (on assumed white) this may not cover some pixels which were
- // previously covered; however those pixels would have been only slightly
- // covered and that slight coverage would have been decreased anyway. Also, some pixels
- // which were previously fully covered may no longer be fully covered.
- //
- // For white (on assumed black) this may cover some pixels which weren't
- // previously covered at all.
-
- int width, height;
- size_t size;
-
-#ifdef SK_GAMMA_CONTRAST
- SkScalar contrast = SK_GAMMA_CONTRAST;
-#else
- SkScalar contrast = 0.5f;
-#endif
- SkScalar paintGamma = SK_GAMMA_EXPONENT;
- SkScalar deviceGamma = SK_GAMMA_EXPONENT;
-
- size = SkScalerContext::GetGammaLUTSize(contrast, paintGamma, deviceGamma,
- &width, &height);
-
- SkASSERT(kExpectedDistanceAdjustTableSize == height);
- fTable = new SkScalar[height];
-
- SkAutoTArray<uint8_t> data((int)size);
- SkScalerContext::GetGammaLUTData(contrast, paintGamma, deviceGamma, data.get());
-
- // find the inverse points where we cross 0.5
- // binsearch might be better, but we only need to do this once on creation
- for (int row = 0; row < height; ++row) {
- uint8_t* rowPtr = data.get() + row*width;
- for (int col = 0; col < width - 1; ++col) {
- if (rowPtr[col] <= 127 && rowPtr[col + 1] >= 128) {
- // compute point where a mask value will give us a result of 0.5
- float interp = (127.5f - rowPtr[col]) / (rowPtr[col + 1] - rowPtr[col]);
- float borderAlpha = (col + interp) / 255.f;
-
- // compute t value for that alpha
- // this is an approximate inverse for smoothstep()
- float t = borderAlpha*(borderAlpha*(4.0f*borderAlpha - 6.0f) + 5.0f) / 3.0f;
-
- // compute distance which gives us that t value
- const float kDistanceFieldAAFactor = 0.65f; // should match SK_DistanceFieldAAFactor
- float d = 2.0f*kDistanceFieldAAFactor*t - kDistanceFieldAAFactor;
-
- fTable[row] = d;
- break;
- }
- }
- }
-}
GrAtlasTextContext* GrAtlasTextContext::Create(GrContext* context,
const SkSurfaceProps& surfaceProps) {
diff --git a/src/gpu/GrAtlasTextContext.h b/src/gpu/GrAtlasTextContext.h
index 20f747f..82283bc 100644
--- a/src/gpu/GrAtlasTextContext.h
+++ b/src/gpu/GrAtlasTextContext.h
@@ -11,6 +11,7 @@
#include "GrTextContext.h"
#include "GrAtlasTextBlob.h"
+#include "GrDistanceFieldAdjustTable.h"
#include "GrGeometryProcessor.h"
#include "SkTextBlobRunIterator.h"
@@ -148,29 +149,9 @@
const SkPoint& offset,
const SkIRect& regionClipBounds);
- // Distance field text needs this table to compute a value for use in the fragment shader.
- // Because the GrAtlasTextContext can go out of scope before the final flush, this needs to be
- // refcnted and malloced
- struct DistanceAdjustTable : public SkNVRefCnt<DistanceAdjustTable> {
- DistanceAdjustTable() { this->buildDistanceAdjustTable(); }
- ~DistanceAdjustTable() { delete[] fTable; }
-
- const SkScalar& operator[] (int i) const {
- return fTable[i];
- }
-
- private:
- void buildDistanceAdjustTable();
-
- SkScalar* fTable;
- };
-
GrBatchTextStrike* fCurrStrike;
GrTextBlobCache* fCache;
- SkAutoTUnref<const DistanceAdjustTable> fDistanceAdjustTable;
-
- friend class GrTextBlobCache;
- friend class GrAtlasTextBatch;
+ SkAutoTUnref<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
#ifdef GR_TEST_UTILS
DRAW_BATCH_TEST_FRIEND(TextBlobBatch);
diff --git a/src/gpu/GrDistanceFieldAdjustTable.cpp b/src/gpu/GrDistanceFieldAdjustTable.cpp
new file mode 100644
index 0000000..1c5aece
--- /dev/null
+++ b/src/gpu/GrDistanceFieldAdjustTable.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrDistanceFieldAdjustTable.h"
+
+#include "SkScalerContext.h"
+
+SkDEBUGCODE(static const int kExpectedDistanceAdjustTableSize = 8;)
+
+void GrDistanceFieldAdjustTable::buildDistanceAdjustTable() {
+ // This is used for an approximation of the mask gamma hack, used by raster and bitmap
+ // text. The mask gamma hack is based off of guessing what the blend color is going to
+ // be, and adjusting the mask so that when run through the linear blend will
+ // produce the value closest to the desired result. However, in practice this means
+ // that the 'adjusted' mask is just increasing or decreasing the coverage of
+ // the mask depending on what it is thought it will blit against. For black (on
+ // assumed white) this means that coverages are decreased (on a curve). For white (on
+ // assumed black) this means that coverages are increased (on a a curve). At
+ // middle (perceptual) gray (which could be blit against anything) the coverages
+ // remain the same.
+ //
+ // The idea here is that instead of determining the initial (real) coverage and
+ // then adjusting that coverage, we determine an adjusted coverage directly by
+ // essentially manipulating the geometry (in this case, the distance to the glyph
+ // edge). So for black (on assumed white) this thins a bit; for white (on
+ // assumed black) this fake bolds the geometry a bit.
+ //
+ // The distance adjustment is calculated by determining the actual coverage value which
+ // when fed into in the mask gamma table gives us an 'adjusted coverage' value of 0.5. This
+ // actual coverage value (assuming it's between 0 and 1) corresponds to a distance from the
+ // actual edge. So by subtracting this distance adjustment and computing without the
+ // the coverage adjustment we should get 0.5 coverage at the same point.
+ //
+ // This has several implications:
+ // For non-gray lcd smoothed text, each subpixel essentially is using a
+ // slightly different geometry.
+ //
+ // For black (on assumed white) this may not cover some pixels which were
+ // previously covered; however those pixels would have been only slightly
+ // covered and that slight coverage would have been decreased anyway. Also, some pixels
+ // which were previously fully covered may no longer be fully covered.
+ //
+ // For white (on assumed black) this may cover some pixels which weren't
+ // previously covered at all.
+
+ int width, height;
+ size_t size;
+
+#ifdef SK_GAMMA_CONTRAST
+ SkScalar contrast = SK_GAMMA_CONTRAST;
+#else
+ SkScalar contrast = 0.5f;
+#endif
+ SkScalar paintGamma = SK_GAMMA_EXPONENT;
+ SkScalar deviceGamma = SK_GAMMA_EXPONENT;
+
+ size = SkScalerContext::GetGammaLUTSize(contrast, paintGamma, deviceGamma,
+ &width, &height);
+
+ SkASSERT(kExpectedDistanceAdjustTableSize == height);
+ fTable = new SkScalar[height];
+
+ SkAutoTArray<uint8_t> data((int)size);
+ SkScalerContext::GetGammaLUTData(contrast, paintGamma, deviceGamma, data.get());
+
+ // find the inverse points where we cross 0.5
+ // binsearch might be better, but we only need to do this once on creation
+ for (int row = 0; row < height; ++row) {
+ uint8_t* rowPtr = data.get() + row*width;
+ for (int col = 0; col < width - 1; ++col) {
+ if (rowPtr[col] <= 127 && rowPtr[col + 1] >= 128) {
+ // compute point where a mask value will give us a result of 0.5
+ float interp = (127.5f - rowPtr[col]) / (rowPtr[col + 1] - rowPtr[col]);
+ float borderAlpha = (col + interp) / 255.f;
+
+ // compute t value for that alpha
+ // this is an approximate inverse for smoothstep()
+ float t = borderAlpha*(borderAlpha*(4.0f*borderAlpha - 6.0f) + 5.0f) / 3.0f;
+
+ // compute distance which gives us that t value
+ const float kDistanceFieldAAFactor = 0.65f; // should match SK_DistanceFieldAAFactor
+ float d = 2.0f*kDistanceFieldAAFactor*t - kDistanceFieldAAFactor;
+
+ fTable[row] = d;
+ break;
+ }
+ }
+ }
+}
diff --git a/src/gpu/GrDistanceFieldAdjustTable.h b/src/gpu/GrDistanceFieldAdjustTable.h
new file mode 100644
index 0000000..f7d8bee
--- /dev/null
+++ b/src/gpu/GrDistanceFieldAdjustTable.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrDistanceFieldAdjustTable_DEFINED
+#define GrDistanceFieldAdjustTable_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkScalar.h"
+
+// Distance field text needs this table to compute a value for use in the fragment shader.
+// Because the GrAtlasTextContext can go out of scope before the final flush, this needs to be
+// refcnted and malloced
+struct GrDistanceFieldAdjustTable : public SkNVRefCnt<GrDistanceFieldAdjustTable> {
+ GrDistanceFieldAdjustTable() { this->buildDistanceAdjustTable(); }
+ ~GrDistanceFieldAdjustTable() { delete[] fTable; }
+
+ const SkScalar& operator[] (int i) const {
+ return fTable[i];
+ }
+
+private:
+ void buildDistanceAdjustTable();
+
+ SkScalar* fTable;
+};
+
+#endif
diff --git a/src/gpu/batches/GrAtlasTextBatch.h b/src/gpu/batches/GrAtlasTextBatch.h
index 5fd3d61..edbe3d7 100644
--- a/src/gpu/batches/GrAtlasTextBatch.h
+++ b/src/gpu/batches/GrAtlasTextBatch.h
@@ -11,6 +11,7 @@
#include "batches/GrVertexBatch.h"
#include "GrAtlasTextContext.h"
+#include "GrDistanceFieldAdjustTable.h"
class GrAtlasTextBatch : public GrVertexBatch {
public:
@@ -19,7 +20,6 @@
static const int kVerticesPerGlyph = GrAtlasTextBlob::kVerticesPerGlyph;
static const int kIndicesPerGlyph = 6;
- typedef GrAtlasTextContext::DistanceAdjustTable DistanceAdjustTable;
typedef GrAtlasTextBlob Blob;
typedef Blob::Run Run;
typedef Run::SubRunInfo TextInfo;
@@ -56,10 +56,11 @@
return batch;
}
- static GrAtlasTextBatch* CreateDistanceField(int glyphCount, GrBatchFontCache* fontCache,
- const DistanceAdjustTable* distanceAdjustTable,
- SkColor filteredColor, bool isLCD,
- bool useBGR) {
+ static GrAtlasTextBatch* CreateDistanceField(
+ int glyphCount, GrBatchFontCache* fontCache,
+ const GrDistanceFieldAdjustTable* distanceAdjustTable,
+ SkColor filteredColor, bool isLCD,
+ bool useBGR) {
GrAtlasTextBatch* batch = new GrAtlasTextBatch;
batch->fFontCache = fontCache;
@@ -196,7 +197,7 @@
GrBatchFontCache* fFontCache;
// Distance field properties
- SkAutoTUnref<const DistanceAdjustTable> fDistanceAdjustTable;
+ SkAutoTUnref<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
SkColor fFilteredColor;
typedef GrVertexBatch INHERITED;