aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2015-05-11 08:58:08 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-05-11 08:58:08 -0700
commit79dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9 (patch)
treebf1ec134f83ef17f770b2114f54b5b407a70a640
parente590266294c4c92e4e4c2f06f267ac5751d07562 (diff)
Add unit tests to text context
TBR=bsalomon@google.com BUG=skia: Review URL: https://codereview.chromium.org/1128153005
-rw-r--r--src/gpu/GrAtlasTextContext.cpp220
-rw-r--r--src/gpu/GrAtlasTextContext.h27
-rw-r--r--src/gpu/GrBatchTest.h4
-rw-r--r--src/gpu/GrTextContext.cpp2
-rw-r--r--src/gpu/GrTextContext.h1
5 files changed, 194 insertions, 60 deletions
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
index bfe938131b..c908137477 100644
--- a/src/gpu/GrAtlasTextContext.cpp
+++ b/src/gpu/GrAtlasTextContext.cpp
@@ -9,6 +9,7 @@
#include "GrBatch.h"
#include "GrBatchFontCache.h"
#include "GrBatchTarget.h"
+#include "GrBatchTest.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrDrawTarget.h"
#include "GrFontScaler.h"
@@ -683,22 +684,22 @@ GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint,
return blob;
}
-void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
- const GrPaint& paint, const SkPaint& skPaint,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- SkScalar x, SkScalar y, const SkIRect& regionClipBounds) {
+inline GrAtlasTextContext::BitmapTextBlob*
+GrAtlasTextContext::createDrawTextBlob(GrRenderTarget* rt, const GrClip& clip,
+ const GrPaint& paint, const SkPaint& skPaint,
+ const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength,
+ SkScalar x, SkScalar y, const SkIRect& regionClipBounds) {
int glyphCount = skPaint.countText(text, byteLength);
SkIRect clipRect;
clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
- // setup cache
+ BitmapTextBlob* blob;
if (this->canDrawAsDistanceFields(skPaint, viewMatrix)) {
SkPaint dfPaint;
SkScalar textRatio;
SkGlyphCache* cache;
- SkAutoTUnref<BitmapTextBlob> blob(this->setupDFBlob(glyphCount, skPaint, viewMatrix, &cache,
- &dfPaint, &textRatio));
+ blob = this->setupDFBlob(glyphCount, skPaint, viewMatrix, &cache, &dfPaint, &textRatio);
SkTDArray<char> fallbackTxt;
SkTDArray<SkScalar> fallbackPos;
@@ -711,36 +712,36 @@ void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
this->fallbackDrawPosText(blob, 0, rt, clip, paint, skPaint, viewMatrix, fallbackTxt,
fallbackPos, 2, offset, clipRect);
}
- this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip);
} else {
- SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTextVASize));
+ blob = fCache->createBlob(glyphCount, 1, kGrayTextVASize);
blob->fViewMatrix = viewMatrix;
SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMatrix, false);
this->internalDrawBMPText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix, text,
byteLength, x, y, clipRect);
SkGlyphCache::AttachCache(cache);
- this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip);
}
+ return blob;
}
-void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
- const GrPaint& paint, const SkPaint& skPaint,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset, const SkIRect& regionClipBounds) {
+inline GrAtlasTextContext::BitmapTextBlob*
+GrAtlasTextContext::createDrawPosTextBlob(GrRenderTarget* rt, const GrClip& clip,
+ const GrPaint& paint, const SkPaint& skPaint,
+ const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset, const SkIRect& regionClipBounds) {
int glyphCount = skPaint.countText(text, byteLength);
SkIRect clipRect;
clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
+ BitmapTextBlob* blob;
if (this->canDrawAsDistanceFields(skPaint, viewMatrix)) {
SkPaint dfPaint;
SkScalar textRatio;
SkGlyphCache* cache;
- SkAutoTUnref<BitmapTextBlob> blob(this->setupDFBlob(glyphCount, skPaint, viewMatrix, &cache,
- &dfPaint, &textRatio));
+ blob = this->setupDFBlob(glyphCount, skPaint, viewMatrix, &cache, &dfPaint, &textRatio);
SkTDArray<char> fallbackTxt;
SkTDArray<SkScalar> fallbackPos;
@@ -752,16 +753,41 @@ void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
this->fallbackDrawPosText(blob, 0, rt, clip, paint, skPaint, viewMatrix, fallbackTxt,
fallbackPos, scalarsPerPosition, offset, clipRect);
}
- this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip);
} else {
- SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTextVASize));
+ blob = fCache->createBlob(glyphCount, 1, kGrayTextVASize);
blob->fViewMatrix = viewMatrix;
SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMatrix, false);
this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix, text,
byteLength, pos, scalarsPerPosition, offset, clipRect);
SkGlyphCache::AttachCache(cache);
- this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip);
}
+ return blob;
+}
+
+void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
+ const GrPaint& paint, const SkPaint& skPaint,
+ const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength,
+ SkScalar x, SkScalar y, const SkIRect& regionClipBounds) {
+ SkAutoTUnref<BitmapTextBlob> blob(
+ this->createDrawTextBlob(rt, clip, paint, skPaint, viewMatrix,
+ text, byteLength, x, y, regionClipBounds));
+ this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip);
+}
+
+void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
+ const GrPaint& paint, const SkPaint& skPaint,
+ const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset, const SkIRect& regionClipBounds) {
+ SkAutoTUnref<BitmapTextBlob> blob(
+ this->createDrawPosTextBlob(rt, clip, paint, skPaint, viewMatrix,
+ text, byteLength,
+ pos, scalarsPerPosition,
+ offset, regionClipBounds));
+
+ this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip);
}
void GrAtlasTextContext::internalDrawBMPText(BitmapTextBlob* blob, int runIndex,
@@ -2050,6 +2076,51 @@ void GrAtlasTextContext::flushRunAsPaths(const SkTextBlob::RunIterator& it, cons
}
}
+
+inline BitmapTextBatch*
+GrAtlasTextContext::createBatch(BitmapTextBlob* cacheBlob, const PerSubRunInfo& info,
+ int glyphCount, int run, int subRun,
+ GrColor color, SkScalar transX, SkScalar transY,
+ const SkPaint& skPaint) {
+ GrMaskFormat format = info.fMaskFormat;
+ GrColor subRunColor;
+ if (kARGB_GrMaskFormat == format) {
+ uint8_t paintAlpha = skPaint.getAlpha();
+ subRunColor = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha);
+ } else {
+ subRunColor = color;
+ }
+
+ BitmapTextBatch* batch;
+ if (info.fDrawAsDistanceFields) {
+ SkColor filteredColor;
+ SkColorFilter* colorFilter = skPaint.getColorFilter();
+ if (colorFilter) {
+ filteredColor = colorFilter->filterColor(skPaint.getColor());
+ } else {
+ filteredColor = skPaint.getColor();
+ }
+ bool useBGR = SkPixelGeometryIsBGR(fDeviceProperties.pixelGeometry());
+ float gamma = fDeviceProperties.gamma();
+ batch = BitmapTextBatch::Create(format, glyphCount, fContext->getBatchFontCache(),
+ fDistanceAdjustTable, filteredColor,
+ info.fUseLCDText, useBGR,
+ gamma);
+ } else {
+ batch = BitmapTextBatch::Create(format, glyphCount, fContext->getBatchFontCache());
+ }
+ BitmapTextBatch::Geometry& geometry = batch->geometry();
+ geometry.fBlob = SkRef(cacheBlob);
+ geometry.fRun = run;
+ geometry.fSubRun = subRun;
+ geometry.fColor = subRunColor;
+ geometry.fTransX = transX;
+ geometry.fTransY = transY;
+ batch->init();
+
+ return batch;
+}
+
inline void GrAtlasTextContext::flushRun(GrDrawTarget* target, GrPipelineBuilder* pipelineBuilder,
BitmapTextBlob* cacheBlob, int run, GrColor color,
SkScalar transX, SkScalar transY, const SkPaint& skPaint) {
@@ -2060,42 +2131,9 @@ inline void GrAtlasTextContext::flushRun(GrDrawTarget* target, GrPipelineBuilder
continue;
}
- GrMaskFormat format = info.fMaskFormat;
- GrColor subRunColor;
- if (kARGB_GrMaskFormat == format) {
- uint8_t paintAlpha = skPaint.getAlpha();
- subRunColor = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha);
- } else {
- subRunColor = color;
- }
-
- SkAutoTUnref<BitmapTextBatch> batch;
- if (info.fDrawAsDistanceFields) {
- SkColor filteredColor;
- SkColorFilter* colorFilter = skPaint.getColorFilter();
- if (colorFilter) {
- filteredColor = colorFilter->filterColor(skPaint.getColor());
- } else {
- filteredColor = skPaint.getColor();
- }
- bool useBGR = SkPixelGeometryIsBGR(fDeviceProperties.pixelGeometry());
- float gamma = fDeviceProperties.gamma();
- batch.reset(BitmapTextBatch::Create(format, glyphCount, fContext->getBatchFontCache(),
- fDistanceAdjustTable, filteredColor,
- info.fUseLCDText, useBGR,
- gamma));
- } else {
- batch.reset(BitmapTextBatch::Create(format, glyphCount, fContext->getBatchFontCache()));
- }
- BitmapTextBatch::Geometry& geometry = batch->geometry();
- geometry.fBlob = SkRef(cacheBlob);
- geometry.fRun = run;
- geometry.fSubRun = subRun;
- geometry.fColor = subRunColor;
- geometry.fTransX = transX;
- geometry.fTransY = transY;
- batch->init();
-
+ SkAutoTUnref<BitmapTextBatch> batch(this->createBatch(cacheBlob, info, glyphCount, run,
+ subRun, color, transX, transY,
+ skPaint));
target->drawBatch(pipelineBuilder, batch);
}
}
@@ -2167,3 +2205,69 @@ void GrAtlasTextContext::flush(GrDrawTarget* target,
// Now flush big glyphs
this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0);
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef GR_TEST_UTILS
+
+BATCH_TEST_DEFINE(TextBlob) {
+ static uint32_t gContextID = SK_InvalidGenID;
+ static GrAtlasTextContext* gTextContext = NULL;
+ static SkDeviceProperties gDeviceProperties(SkDeviceProperties::kLegacyLCD_InitType);
+
+ if (context->uniqueID() != gContextID) {
+ gContextID = context->uniqueID();
+ SkDELETE(gTextContext);
+ // We don't yet test the fall back to paths in the GrTextContext base class. This is mostly
+ // because we don't really want to have a gpu device here.
+ // We enable distance fields by twiddling a knob on the paint
+ gTextContext = GrAtlasTextContext::Create(context, NULL, gDeviceProperties, false);
+ }
+
+ // create dummy render target
+ GrSurfaceDesc desc;
+ desc.fFlags = kRenderTarget_GrSurfaceFlag;
+ desc.fWidth = 1024;
+ desc.fHeight = 1024;
+ desc.fConfig = kRGBA_8888_GrPixelConfig;
+ desc.fSampleCnt = 1;
+ SkAutoTUnref<GrTexture> texture(context->textureProvider()->createTexture(desc, true, NULL, 0));
+ SkASSERT(texture);
+ SkASSERT(NULL != texture->asRenderTarget());
+ GrRenderTarget* rt = texture->asRenderTarget();
+
+ // Setup dummy SkPaint / GrPaint
+ GrColor color = GrRandomColor(random);
+ SkMatrix viewMatrix = GrTest::TestMatrix(random);
+ SkPaint skPaint;
+ skPaint.setDistanceFieldTextTEMP(random->nextBool());
+ skPaint.setColor(color);
+ skPaint.setLCDRenderText(random->nextBool());
+ skPaint.setAntiAlias(skPaint.isLCDRenderText() ? true : random->nextBool());
+ skPaint.setSubpixelText(random->nextBool());
+
+ GrPaint grPaint;
+ if (!SkPaint2GrPaint(context, rt, skPaint, viewMatrix, true, &grPaint)) {
+ SkFAIL("couldn't convert paint\n");
+ }
+
+ const char* text = "The quick brown fox jumps over the lazy dog.";
+ int textLen = (int)strlen(text);
+
+ // Setup clip
+ GrClip clip;
+ SkIRect noClip = SkIRect::MakeLargest();
+
+ // right now we don't handle textblobs, nor do we handle drawPosText. Since we only
+ // intend to test the batch with this unit test, that is okay.
+ SkAutoTUnref<GrAtlasTextContext::BitmapTextBlob> blob(
+ gTextContext->createDrawTextBlob(rt, clip, grPaint, skPaint, viewMatrix, text,
+ static_cast<size_t>(textLen), 0, 0, noClip));
+
+ SkScalar transX = static_cast<SkScalar>(random->nextU());
+ SkScalar transY = static_cast<SkScalar>(random->nextU());
+ const GrAtlasTextContext::BitmapTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0];
+ return gTextContext->createBatch(blob, info, textLen, 0, 0, color, transX, transY, skPaint);
+}
+
+#endif
diff --git a/src/gpu/GrAtlasTextContext.h b/src/gpu/GrAtlasTextContext.h
index c6e1d2f0b2..55597cfccc 100644
--- a/src/gpu/GrAtlasTextContext.h
+++ b/src/gpu/GrAtlasTextContext.h
@@ -19,6 +19,11 @@
#include "SkTextBlob.h"
#include "SkTInternalLList.h"
+#ifdef GR_TEST_UTILS
+#include "GrBatchTest.h"
+#endif
+
+class BitmapTextBatch;
class GrPipelineBuilder;
class GrTextBlobCache;
@@ -265,6 +270,10 @@ private:
inline void flushRunAsPaths(const SkTextBlob::RunIterator&, const SkPaint&, SkDrawFilter*,
const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
SkScalar y);
+ inline BitmapTextBatch* createBatch(BitmapTextBlob*, const PerSubRunInfo&,
+ int glyphCount, int run, int subRun,
+ GrColor, SkScalar transX, SkScalar transY,
+ const SkPaint&);
inline void flushRun(GrDrawTarget*, GrPipelineBuilder*, BitmapTextBlob*, int run, GrColor,
SkScalar transX, SkScalar transY, const SkPaint&);
inline void flushBigGlyphs(BitmapTextBlob* cacheBlob, GrRenderTarget* rt,
@@ -332,6 +341,20 @@ private:
inline void initDistanceFieldPaint(BitmapTextBlob*, SkPaint*, SkScalar* textRatio,
const SkMatrix&);
+ // Test methods
+ // TODO this is really ugly. It'd be much nicer if positioning could be moved to batch
+ inline BitmapTextBlob* createDrawTextBlob(GrRenderTarget*, const GrClip&, const GrPaint&,
+ const SkPaint&, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength,
+ SkScalar x, SkScalar y,
+ const SkIRect& regionClipBounds);
+ inline BitmapTextBlob* createDrawPosTextBlob(GrRenderTarget*, const GrClip&, const GrPaint&,
+ const SkPaint&, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ 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
@@ -360,6 +383,10 @@ private:
friend class GrTextBlobCache;
friend class BitmapTextBatch;
+#ifdef GR_TEST_UTILS
+ BATCH_TEST_FRIEND(TextBlob);
+#endif
+
typedef GrTextContext INHERITED;
};
diff --git a/src/gpu/GrBatchTest.h b/src/gpu/GrBatchTest.h
index 3199354a8d..9daa9609ce 100644
--- a/src/gpu/GrBatchTest.h
+++ b/src/gpu/GrBatchTest.h
@@ -29,7 +29,9 @@ typedef GrBatch* (*BatchTestFunc)(SkRandom* random, GrContext* context);
#define BATCH_TEST_EXTERN(Batch) \
extern GrBatch* Batch##__Test(SkRandom*, GrContext* context);
#define BATCH_TEST_ENTRY(Batch) \
- Batch##__Test
+ Batch##__Test
+#define BATCH_TEST_FRIEND(Batch) \
+ friend GrBatch* Batch##__Test(SkRandom* random, GrContext* context);
GrBatch* GrRandomBatch(SkRandom*, GrContext*);
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 6153f3b05d..4c6dabcf7d 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -66,6 +66,7 @@ void GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPai
} while (textContext);
// fall back to drawing as a path
+ SkASSERT(fGpuDevice);
this->drawTextAsPath(skPaint, viewMatrix, text, byteLength, x, y, clipBounds);
}
@@ -89,6 +90,7 @@ void GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const Gr
} while (textContext);
// fall back to drawing as a path
+ SkASSERT(fGpuDevice);
this->drawPosTextAsPath(skPaint, viewMatrix, text, byteLength, pos, scalarsPerPosition, offset,
clipBounds);
}
diff --git a/src/gpu/GrTextContext.h b/src/gpu/GrTextContext.h
index 60714ca4ce..85295285a8 100644
--- a/src/gpu/GrTextContext.h
+++ b/src/gpu/GrTextContext.h
@@ -12,7 +12,6 @@
#include "GrGlyph.h"
#include "GrPaint.h"
#include "SkDeviceProperties.h"
-
#include "SkPostConfig.h"
class GrClip;