Index: src/gpu/GrAtlasTextContext.cpp |
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp |
old mode 100755 |
new mode 100644 |
similarity index 65% |
copy from src/gpu/GrBitmapTextContext.cpp |
copy to src/gpu/GrAtlasTextContext.cpp |
index 605703d1c62906ff579c84a4e923d972e92003a3..5efb5b94250f2f9d9dcd171bc578769e13c49979 |
--- a/src/gpu/GrBitmapTextContext.cpp |
+++ b/src/gpu/GrAtlasTextContext.cpp |
@@ -1,10 +1,10 @@ |
/* |
- * Copyright 2013 Google Inc. |
+ * 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 "GrBitmapTextContext.h" |
+#include "GrAtlasTextContext.h" |
#include "GrAtlas.h" |
#include "GrBatch.h" |
@@ -12,7 +12,6 @@ |
#include "GrBatchTarget.h" |
#include "GrDefaultGeoProcFactory.h" |
#include "GrDrawTarget.h" |
-#include "GrFontCache.h" |
#include "GrFontScaler.h" |
#include "GrIndexBuffer.h" |
#include "GrStrokeInfo.h" |
@@ -35,9 +34,6 @@ |
#include "effects/GrBitmapTextGeoProc.h" |
#include "effects/GrSimpleTextureEffect.h" |
-SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, |
- "Dump the contents of the font cache before every purge."); |
- |
namespace { |
static const size_t kLCDTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16); |
@@ -48,6 +44,18 @@ static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + sizeof |
static const int kVerticesPerGlyph = 4; |
static const int kIndicesPerGlyph = 6; |
+ |
+static size_t get_vertex_stride(GrMaskFormat maskFormat) { |
+ switch (maskFormat) { |
+ case kA8_GrMaskFormat: |
+ return kGrayTextVASize; |
+ case kARGB_GrMaskFormat: |
+ return kColorTextVASize; |
+ default: |
+ return kLCDTextVASize; |
+ } |
+} |
+ |
}; |
// TODO |
@@ -415,7 +423,6 @@ void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde |
const char* stop = text + byteLength; |
SkTextAlignProc alignProc(skPaint.getTextAlign()); |
SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition); |
- SkScalar halfSampleX = 0, halfSampleY = 0; |
if (cache->isSubpixel()) { |
// maybe we should skip the rounding if linearText is set |
@@ -423,6 +430,8 @@ void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde |
SkFixed fxMask = ~0; |
SkFixed fyMask = ~0; |
+ SkScalar halfSampleX = SkFixedToScalar(SkGlyph::kSubpixelRound); |
+ SkScalar halfSampleY = SkFixedToScalar(SkGlyph::kSubpixelRound); |
if (kX_SkAxisAlignment == baseline) { |
fyMask = 0; |
halfSampleY = SK_ScalarHalf; |
@@ -550,17 +559,6 @@ void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde |
} |
} |
-static size_t get_vertex_stride(GrMaskFormat maskFormat) { |
- switch (maskFormat) { |
- case kA8_GrMaskFormat: |
- return kGrayTextVASize; |
- case kARGB_GrMaskFormat: |
- return kColorTextVASize; |
- default: |
- return kLCDTextVASize; |
- } |
-} |
- |
void GrBitmapTextContextB::appendGlyph(BitmapTextBlob* blob, int runIndex, GrGlyph::PackedID packed, |
int vx, int vy, GrFontScaler* scaler, |
const SkIRect& clipRect) { |
@@ -1055,587 +1053,3 @@ void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrR |
fContext->drawPath(rt, clip, paint, SkMatrix::I(), tmpPath, strokeInfo); |
} |
} |
- |
-GrBitmapTextContext::GrBitmapTextContext(GrContext* context, |
- SkGpuDevice* gpuDevice, |
- const SkDeviceProperties& properties) |
- : GrTextContext(context, gpuDevice, properties) { |
- fStrike = NULL; |
- |
- fCurrTexture = NULL; |
- fEffectTextureUniqueID = SK_InvalidUniqueID; |
- |
- fVertices = NULL; |
- fCurrVertex = 0; |
- fAllocVertexCount = 0; |
- fTotalVertexCount = 0; |
- |
- fVertexBounds.setLargestInverted(); |
-} |
- |
-GrBitmapTextContext* GrBitmapTextContext::Create(GrContext* context, |
- SkGpuDevice* gpuDevice, |
- const SkDeviceProperties& props) { |
- return SkNEW_ARGS(GrBitmapTextContext, (context, gpuDevice, props)); |
-} |
- |
-bool GrBitmapTextContext::canDraw(const GrRenderTarget* rt, |
- const GrClip& clip, |
- const GrPaint& paint, |
- const SkPaint& skPaint, |
- const SkMatrix& viewMatrix) { |
- return !SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix); |
-} |
- |
-inline void GrBitmapTextContext::init(GrRenderTarget* rt, const GrClip& clip, |
- const GrPaint& paint, const SkPaint& skPaint, |
- const SkIRect& regionClipBounds) { |
- GrTextContext::init(rt, clip, paint, skPaint, regionClipBounds); |
- |
- fStrike = NULL; |
- |
- fCurrTexture = NULL; |
- fCurrVertex = 0; |
- |
- fVertices = NULL; |
- fAllocVertexCount = 0; |
- fTotalVertexCount = 0; |
-} |
- |
-void GrBitmapTextContext::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) { |
- SkASSERT(byteLength == 0 || text != NULL); |
- |
- // nothing to draw |
- if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) { |
- return; |
- } |
- |
- this->init(rt, clip, paint, skPaint, regionClipBounds); |
- |
- SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
- |
- SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &viewMatrix); |
- SkGlyphCache* cache = autoCache.getCache(); |
- GrFontScaler* fontScaler = GetGrFontScaler(cache); |
- |
- // transform our starting point |
- { |
- SkPoint loc; |
- viewMatrix.mapXY(x, y, &loc); |
- x = loc.fX; |
- y = loc.fY; |
- } |
- |
- // need to measure first |
- int numGlyphs; |
- if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { |
- SkVector stopVector; |
- numGlyphs = MeasureText(cache, glyphCacheProc, text, byteLength, &stopVector); |
- |
- SkScalar stopX = stopVector.fX; |
- SkScalar stopY = stopVector.fY; |
- |
- if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) { |
- stopX = SkScalarHalf(stopX); |
- stopY = SkScalarHalf(stopY); |
- } |
- x -= stopX; |
- y -= stopY; |
- } else { |
- numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL); |
- } |
- fTotalVertexCount = kVerticesPerGlyph*numGlyphs; |
- |
- const char* stop = text + byteLength; |
- |
- SkAutoKern autokern; |
- |
- SkFixed fxMask = ~0; |
- SkFixed fyMask = ~0; |
- SkScalar halfSampleX, halfSampleY; |
- if (cache->isSubpixel()) { |
- halfSampleX = halfSampleY = SkFixedToScalar(SkGlyph::kSubpixelRound); |
- SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix); |
- if (kX_SkAxisAlignment == baseline) { |
- fyMask = 0; |
- halfSampleY = SK_ScalarHalf; |
- } else if (kY_SkAxisAlignment == baseline) { |
- fxMask = 0; |
- halfSampleX = SK_ScalarHalf; |
- } |
- } else { |
- halfSampleX = halfSampleY = SK_ScalarHalf; |
- } |
- |
- Sk48Dot16 fx = SkScalarTo48Dot16(x + halfSampleX); |
- Sk48Dot16 fy = SkScalarTo48Dot16(y + halfSampleY); |
- |
- // if we have RGB, then we won't have any SkShaders so no need to use a localmatrix, but for |
- // performance reasons we just invert here instead |
- if (!viewMatrix.invert(&fLocalMatrix)) { |
- SkDebugf("Cannot invert viewmatrix\n"); |
- return; |
- } |
- |
- while (text < stop) { |
- const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask); |
- |
- fx += autokern.adjust(glyph); |
- |
- if (glyph.fWidth) { |
- this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
- glyph.getSubXFixed(), |
- glyph.getSubYFixed(), |
- GrGlyph::kCoverage_MaskStyle), |
- Sk48Dot16FloorToInt(fx), |
- Sk48Dot16FloorToInt(fy), |
- fontScaler); |
- } |
- |
- fx += glyph.fAdvanceX; |
- fy += glyph.fAdvanceY; |
- } |
- |
- this->finish(); |
-} |
- |
-void GrBitmapTextContext::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) { |
- SkASSERT(byteLength == 0 || text != NULL); |
- SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
- |
- // nothing to draw |
- if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) { |
- return; |
- } |
- |
- this->init(rt, clip, paint, skPaint, regionClipBounds); |
- |
- SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
- |
- SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &viewMatrix); |
- SkGlyphCache* cache = autoCache.getCache(); |
- GrFontScaler* fontScaler = GetGrFontScaler(cache); |
- |
- // if we have RGB, then we won't have any SkShaders so no need to use a localmatrix, but for |
- // performance reasons we just invert here instead |
- if (!viewMatrix.invert(&fLocalMatrix)) { |
- SkDebugf("Cannot invert viewmatrix\n"); |
- return; |
- } |
- |
- int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL); |
- fTotalVertexCount = kVerticesPerGlyph*numGlyphs; |
- |
- const char* stop = text + byteLength; |
- SkTextAlignProc alignProc(fSkPaint.getTextAlign()); |
- SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition); |
- |
- if (cache->isSubpixel()) { |
- // maybe we should skip the rounding if linearText is set |
- SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix); |
- |
- SkFixed fxMask = ~0; |
- SkFixed fyMask = ~0; |
- SkScalar halfSampleX = SkFixedToScalar(SkGlyph::kSubpixelRound); |
- SkScalar halfSampleY = SkFixedToScalar(SkGlyph::kSubpixelRound); |
- if (kX_SkAxisAlignment == baseline) { |
- fyMask = 0; |
- halfSampleY = SK_ScalarHalf; |
- } else if (kY_SkAxisAlignment == baseline) { |
- fxMask = 0; |
- halfSampleX = SK_ScalarHalf; |
- } |
- |
- if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { |
- while (text < stop) { |
- SkPoint tmsLoc; |
- tmsProc(pos, &tmsLoc); |
- Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + halfSampleX); |
- Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + halfSampleY); |
- |
- const SkGlyph& glyph = glyphCacheProc(cache, &text, |
- fx & fxMask, fy & fyMask); |
- |
- if (glyph.fWidth) { |
- this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
- glyph.getSubXFixed(), |
- glyph.getSubYFixed(), |
- GrGlyph::kCoverage_MaskStyle), |
- Sk48Dot16FloorToInt(fx), |
- Sk48Dot16FloorToInt(fy), |
- fontScaler); |
- } |
- pos += scalarsPerPosition; |
- } |
- } else { |
- while (text < stop) { |
- const char* currentText = text; |
- const SkGlyph& metricGlyph = glyphCacheProc(cache, &text, 0, 0); |
- |
- if (metricGlyph.fWidth) { |
- SkDEBUGCODE(SkFixed prevAdvX = metricGlyph.fAdvanceX;) |
- SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;) |
- SkPoint tmsLoc; |
- tmsProc(pos, &tmsLoc); |
- SkPoint alignLoc; |
- alignProc(tmsLoc, metricGlyph, &alignLoc); |
- |
- Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + halfSampleX); |
- Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + halfSampleY); |
- |
- // have to call again, now that we've been "aligned" |
- const SkGlyph& glyph = glyphCacheProc(cache, ¤tText, |
- fx & fxMask, fy & fyMask); |
- // the assumption is that the metrics haven't changed |
- SkASSERT(prevAdvX == glyph.fAdvanceX); |
- SkASSERT(prevAdvY == glyph.fAdvanceY); |
- SkASSERT(glyph.fWidth); |
- |
- this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
- glyph.getSubXFixed(), |
- glyph.getSubYFixed(), |
- GrGlyph::kCoverage_MaskStyle), |
- Sk48Dot16FloorToInt(fx), |
- Sk48Dot16FloorToInt(fy), |
- fontScaler); |
- } |
- pos += scalarsPerPosition; |
- } |
- } |
- } else { // not subpixel |
- |
- if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { |
- while (text < stop) { |
- // the last 2 parameters are ignored |
- const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
- |
- if (glyph.fWidth) { |
- SkPoint tmsLoc; |
- tmsProc(pos, &tmsLoc); |
- |
- Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + SK_ScalarHalf); |
- Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + SK_ScalarHalf); |
- this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
- glyph.getSubXFixed(), |
- glyph.getSubYFixed(), |
- GrGlyph::kCoverage_MaskStyle), |
- Sk48Dot16FloorToInt(fx), |
- Sk48Dot16FloorToInt(fy), |
- fontScaler); |
- } |
- pos += scalarsPerPosition; |
- } |
- } else { |
- while (text < stop) { |
- // the last 2 parameters are ignored |
- const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
- |
- if (glyph.fWidth) { |
- SkPoint tmsLoc; |
- tmsProc(pos, &tmsLoc); |
- |
- SkPoint alignLoc; |
- alignProc(tmsLoc, glyph, &alignLoc); |
- |
- Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + SK_ScalarHalf); |
- Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + SK_ScalarHalf); |
- this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
- glyph.getSubXFixed(), |
- glyph.getSubYFixed(), |
- GrGlyph::kCoverage_MaskStyle), |
- Sk48Dot16FloorToInt(fx), |
- Sk48Dot16FloorToInt(fy), |
- fontScaler); |
- } |
- pos += scalarsPerPosition; |
- } |
- } |
- } |
- |
- this->finish(); |
-} |
- |
-static void* alloc_vertices(GrDrawTarget* drawTarget, |
- int numVertices, |
- GrMaskFormat maskFormat) { |
- if (numVertices <= 0) { |
- return NULL; |
- } |
- |
- // set up attributes |
- void* vertices = NULL; |
- bool success = drawTarget->reserveVertexAndIndexSpace(numVertices, |
- get_vertex_stride(maskFormat), |
- 0, |
- &vertices, |
- NULL); |
- GrAlwaysAssert(success); |
- return vertices; |
-} |
- |
-inline bool GrBitmapTextContext::uploadGlyph(GrGlyph* glyph, GrFontScaler* scaler) { |
- if (!fStrike->glyphTooLargeForAtlas(glyph)) { |
- if (fStrike->addGlyphToAtlas(glyph, scaler)) { |
- return true; |
- } |
- |
- // try to clear out an unused plot before we flush |
- if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) && |
- fStrike->addGlyphToAtlas(glyph, scaler)) { |
- return true; |
- } |
- |
- if (c_DumpFontCache) { |
-#ifdef SK_DEVELOPER |
- fContext->getFontCache()->dump(); |
-#endif |
- } |
- |
- // before we purge the cache, we must flush any accumulated draws |
- this->flush(); |
- fContext->flush(); |
- |
- // we should have an unused plot now |
- if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) && |
- fStrike->addGlyphToAtlas(glyph, scaler)) { |
- return true; |
- } |
- |
- // we should never get here |
- SkASSERT(false); |
- } |
- |
- return false; |
-} |
- |
-void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed, |
- int vx, int vy, |
- GrFontScaler* scaler) { |
- if (NULL == fDrawTarget) { |
- return; |
- } |
- |
- if (NULL == fStrike) { |
- fStrike = fContext->getFontCache()->getStrike(scaler); |
- } |
- |
- GrGlyph* glyph = fStrike->getGlyph(packed, scaler); |
- if (NULL == glyph || glyph->fBounds.isEmpty()) { |
- return; |
- } |
- |
- int x = vx + glyph->fBounds.fLeft; |
- int y = vy + glyph->fBounds.fTop; |
- |
- // keep them as ints until we've done the clip-test |
- int width = glyph->fBounds.width(); |
- int height = glyph->fBounds.height(); |
- |
- // check if we clipped out |
- if (fClipRect.quickReject(x, y, x + width, y + height)) { |
- return; |
- } |
- |
- // If the glyph is too large we fall back to paths |
- if (NULL == glyph->fPlot && !uploadGlyph(glyph, scaler)) { |
- if (NULL == glyph->fPath) { |
- SkPath* path = SkNEW(SkPath); |
- if (!scaler->getGlyphPath(glyph->glyphID(), path)) { |
- // flag the glyph as being dead? |
- delete path; |
- return; |
- } |
- glyph->fPath = path; |
- } |
- |
- // flush any accumulated draws before drawing this glyph as a path. |
- this->flush(); |
- |
- SkMatrix translate; |
- translate.setTranslate(SkIntToScalar(vx), SkIntToScalar(vy)); |
- SkPath tmpPath(*glyph->fPath); |
- tmpPath.transform(translate); |
- GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); |
- fContext->drawPath(fRenderTarget, fClip, fPaint, SkMatrix::I(), tmpPath, strokeInfo); |
- |
- // remove this glyph from the vertices we need to allocate |
- fTotalVertexCount -= kVerticesPerGlyph; |
- return; |
- } |
- |
- SkASSERT(glyph->fPlot); |
- GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); |
- glyph->fPlot->setDrawToken(drawToken); |
- |
- // the current texture/maskformat must match what the glyph needs |
- GrTexture* texture = glyph->fPlot->texture(); |
- SkASSERT(texture); |
- |
- if (fCurrTexture != texture || fCurrVertex + kVerticesPerGlyph > fAllocVertexCount) { |
- this->flush(); |
- fCurrTexture = texture; |
- fCurrTexture->ref(); |
- fCurrMaskFormat = glyph->fMaskFormat; |
- } |
- |
- if (NULL == fVertices) { |
- int maxQuadVertices = kVerticesPerGlyph * fContext->getQuadIndexBuffer()->maxQuads(); |
- fAllocVertexCount = SkMin32(fTotalVertexCount, maxQuadVertices); |
- fVertices = alloc_vertices(fDrawTarget, fAllocVertexCount, fCurrMaskFormat); |
- } |
- |
- SkRect r; |
- r.fLeft = SkIntToScalar(x); |
- r.fTop = SkIntToScalar(y); |
- r.fRight = r.fLeft + SkIntToScalar(width); |
- r.fBottom = r.fTop + SkIntToScalar(height); |
- |
- fVertexBounds.joinNonEmptyArg(r); |
- |
- int u0 = glyph->fAtlasLocation.fX; |
- int v0 = glyph->fAtlasLocation.fY; |
- int u1 = u0 + width; |
- int v1 = v0 + height; |
- |
- size_t vertSize = get_vertex_stride(fCurrMaskFormat); |
- intptr_t vertex = reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex; |
- |
- // V0 |
- SkPoint* position = reinterpret_cast<SkPoint*>(vertex); |
- position->set(r.fLeft, r.fTop); |
- if (kA8_GrMaskFormat == fCurrMaskFormat) { |
- SkColor* color = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); |
- *color = fPaint.getColor(); |
- } |
- SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + vertSize - |
- sizeof(SkIPoint16)); |
- textureCoords->set(u0, v0); |
- vertex += vertSize; |
- |
- // V1 |
- position = reinterpret_cast<SkPoint*>(vertex); |
- position->set(r.fLeft, r.fBottom); |
- if (kA8_GrMaskFormat == fCurrMaskFormat) { |
- SkColor* color = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); |
- *color = fPaint.getColor(); |
- } |
- textureCoords = reinterpret_cast<SkIPoint16*>(vertex + vertSize - sizeof(SkIPoint16)); |
- textureCoords->set(u0, v1); |
- vertex += vertSize; |
- |
- // V2 |
- position = reinterpret_cast<SkPoint*>(vertex); |
- position->set(r.fRight, r.fBottom); |
- if (kA8_GrMaskFormat == fCurrMaskFormat) { |
- SkColor* color = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); |
- *color = fPaint.getColor(); |
- } |
- textureCoords = reinterpret_cast<SkIPoint16*>(vertex + vertSize - sizeof(SkIPoint16)); |
- textureCoords->set(u1, v1); |
- vertex += vertSize; |
- |
- // V3 |
- position = reinterpret_cast<SkPoint*>(vertex); |
- position->set(r.fRight, r.fTop); |
- if (kA8_GrMaskFormat == fCurrMaskFormat) { |
- SkColor* color = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); |
- *color = fPaint.getColor(); |
- } |
- textureCoords = reinterpret_cast<SkIPoint16*>(vertex + vertSize - sizeof(SkIPoint16)); |
- textureCoords->set(u1, v0); |
- |
- fCurrVertex += 4; |
-} |
- |
-void GrBitmapTextContext::flush() { |
- if (NULL == fDrawTarget) { |
- return; |
- } |
- |
- if (fCurrVertex > 0) { |
- GrPipelineBuilder pipelineBuilder; |
- pipelineBuilder.setFromPaint(fPaint, fRenderTarget, fClip); |
- |
- // setup our sampler state for our text texture/atlas |
- SkASSERT(SkIsAlign4(fCurrVertex)); |
- SkASSERT(fCurrTexture); |
- |
- SkASSERT(fStrike); |
- GrColor color = fPaint.getColor(); |
- switch (fCurrMaskFormat) { |
- // Color bitmap text |
- case kARGB_GrMaskFormat: { |
- int a = fSkPaint.getAlpha(); |
- color = SkColorSetARGB(a, a, a, a); |
- break; |
- } |
- // LCD text |
- case kA565_GrMaskFormat: { |
- // TODO: move supportsRGBCoverage check to setupCoverageEffect and only add LCD |
- // processor if the xp can support it. For now we will simply assume that if |
- // fUseLCDText is true, then we have a known color output. |
- const GrXPFactory* xpFactory = pipelineBuilder.getXPFactory(); |
- if (!xpFactory->supportsRGBCoverage(0, kRGBA_GrColorComponentFlags)) { |
- SkDebugf("LCD Text will not draw correctly.\n"); |
- } |
- break; |
- } |
- // Grayscale/BW text |
- case kA8_GrMaskFormat: |
- break; |
- default: |
- SkFAIL("Unexpected mask format."); |
- } |
- |
- GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode); |
- uint32_t textureUniqueID = fCurrTexture->getUniqueID(); |
- if (textureUniqueID != fEffectTextureUniqueID || |
- fCachedGeometryProcessor->color() != color || |
- !fCachedGeometryProcessor->localMatrix().cheapEqualTo(fLocalMatrix)) { |
- // This will be ignored in the non A8 case |
- bool opaqueVertexColors = GrColorIsOpaque(fPaint.getColor()); |
- fCachedGeometryProcessor.reset(GrBitmapTextGeoProc::Create(color, |
- fCurrTexture, |
- params, |
- fCurrMaskFormat, |
- opaqueVertexColors, |
- fLocalMatrix)); |
- fEffectTextureUniqueID = textureUniqueID; |
- } |
- |
- int nGlyphs = fCurrVertex / kVerticesPerGlyph; |
- fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); |
- fDrawTarget->drawIndexedInstances(&pipelineBuilder, |
- fCachedGeometryProcessor.get(), |
- kTriangles_GrPrimitiveType, |
- nGlyphs, |
- kVerticesPerGlyph, |
- kIndicesPerGlyph, |
- &fVertexBounds); |
- |
- fDrawTarget->resetVertexSource(); |
- fVertices = NULL; |
- fAllocVertexCount = 0; |
- // reset to be those that are left |
- fTotalVertexCount -= fCurrVertex; |
- fCurrVertex = 0; |
- fVertexBounds.setLargestInverted(); |
- SkSafeSetNull(fCurrTexture); |
- } |
-} |
- |
-inline void GrBitmapTextContext::finish() { |
- this->flush(); |
- fTotalVertexCount = 0; |
- |
- GrTextContext::finish(); |
-} |