OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #include "GrAtlasTextContext.h" | 7 #include "GrAtlasTextContext.h" |
8 | 8 |
9 #include "GrBatch.h" | 9 #include "GrBatch.h" |
10 #include "GrBatchFontCache.h" | 10 #include "GrBatchFontCache.h" |
(...skipping 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 } else if (GrColor_ILLEGAL != init.fOverrideColor) { | 1467 } else if (GrColor_ILLEGAL != init.fOverrideColor) { |
1468 fBatch.fColor = init.fOverrideColor; | 1468 fBatch.fColor = init.fOverrideColor; |
1469 } | 1469 } |
1470 | 1470 |
1471 // setup batch properties | 1471 // setup batch properties |
1472 fBatch.fColorIgnored = init.fColorIgnored; | 1472 fBatch.fColorIgnored = init.fColorIgnored; |
1473 fBatch.fUsesLocalCoords = init.fUsesLocalCoords; | 1473 fBatch.fUsesLocalCoords = init.fUsesLocalCoords; |
1474 fBatch.fCoverageIgnored = init.fCoverageIgnored; | 1474 fBatch.fCoverageIgnored = init.fCoverageIgnored; |
1475 } | 1475 } |
1476 | 1476 |
1477 struct FlushInfo { | |
1478 SkAutoTUnref<const GrVertexBuffer> fVertexBuffer; | |
1479 SkAutoTUnref<const GrIndexBuffer> fIndexBuffer; | |
1480 int fGlyphsToFlush; | |
1481 int fVertexOffset; | |
1482 }; | |
1483 | |
1484 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline
) override { | 1477 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline
) override { |
1485 // if we have RGB, then we won't have any SkShaders so no need to use a
localmatrix. | 1478 // if we have RGB, then we won't have any SkShaders so no need to use a
localmatrix. |
1486 // TODO actually only invert if we don't have RGBA | 1479 // TODO actually only invert if we don't have RGBA |
1487 SkMatrix localMatrix; | 1480 SkMatrix localMatrix; |
1488 if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix))
{ | 1481 if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix))
{ |
1489 SkDebugf("Cannot invert viewmatrix\n"); | 1482 SkDebugf("Cannot invert viewmatrix\n"); |
1490 return; | 1483 return; |
1491 } | 1484 } |
1492 | 1485 |
1493 GrTexture* texture = fFontCache->getTexture(fMaskFormat); | 1486 GrTexture* texture = fFontCache->getTexture(fMaskFormat); |
(...skipping 12 matching lines...) Expand all Loading... |
1506 // This will be ignored in the non A8 case | 1499 // This will be ignored in the non A8 case |
1507 bool opaqueVertexColors = GrColorIsOpaque(this->color()); | 1500 bool opaqueVertexColors = GrColorIsOpaque(this->color()); |
1508 gp.reset(GrBitmapTextGeoProc::Create(this->color(), | 1501 gp.reset(GrBitmapTextGeoProc::Create(this->color(), |
1509 texture, | 1502 texture, |
1510 params, | 1503 params, |
1511 fMaskFormat, | 1504 fMaskFormat, |
1512 opaqueVertexColors, | 1505 opaqueVertexColors, |
1513 localMatrix)); | 1506 localMatrix)); |
1514 } | 1507 } |
1515 | 1508 |
1516 FlushInfo flushInfo; | |
1517 flushInfo.fGlyphsToFlush = 0; | |
1518 size_t vertexStride = gp->getVertexStride(); | 1509 size_t vertexStride = gp->getVertexStride(); |
1519 SkASSERT(vertexStride == (fUseDistanceFields ? | 1510 SkASSERT(vertexStride == (fUseDistanceFields ? |
1520 get_vertex_stride_df(fMaskFormat, fUseLCDText)
: | 1511 get_vertex_stride_df(fMaskFormat, fUseLCDText)
: |
1521 get_vertex_stride(fMaskFormat))); | 1512 get_vertex_stride(fMaskFormat))); |
1522 | 1513 |
1523 this->initDraw(batchTarget, gp, pipeline); | 1514 this->initDraw(batchTarget, gp, pipeline); |
1524 | 1515 |
1525 int glyphCount = this->numGlyphs(); | 1516 int glyphCount = this->numGlyphs(); |
1526 int instanceCount = fInstanceCount; | 1517 int instanceCount = fInstanceCount; |
| 1518 SkAutoTUnref<const GrIndexBuffer> indexBuffer( |
| 1519 batchTarget->resourceProvider()->refQuadIndexBuffer()); |
| 1520 |
1527 const GrVertexBuffer* vertexBuffer; | 1521 const GrVertexBuffer* vertexBuffer; |
1528 | 1522 int firstVertex; |
1529 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | 1523 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
1530 glyphCount * kVert
icesPerGlyph, | 1524 glyphCount * kVert
icesPerGlyph, |
1531 &vertexBuffer, | 1525 &vertexBuffer, |
1532 &flushInfo.fVertex
Offset); | 1526 &firstVertex); |
1533 flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer)); | 1527 if (!vertices || !indexBuffer) { |
1534 flushInfo.fIndexBuffer.reset(batchTarget->resourceProvider()->refQuadInd
exBuffer()); | |
1535 if (!vertices || !flushInfo.fVertexBuffer) { | |
1536 SkDebugf("Could not allocate vertices\n"); | 1528 SkDebugf("Could not allocate vertices\n"); |
1537 return; | 1529 return; |
1538 } | 1530 } |
1539 | 1531 |
1540 unsigned char* currVertex = reinterpret_cast<unsigned char*>(vertices); | 1532 unsigned char* currVertex = reinterpret_cast<unsigned char*>(vertices); |
1541 | 1533 |
| 1534 // setup drawinfo |
| 1535 int maxInstancesPerDraw = indexBuffer->maxQuads(); |
| 1536 |
| 1537 GrDrawTarget::DrawInfo drawInfo; |
| 1538 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
| 1539 drawInfo.setStartVertex(0); |
| 1540 drawInfo.setStartIndex(0); |
| 1541 drawInfo.setVerticesPerInstance(kVerticesPerGlyph); |
| 1542 drawInfo.setIndicesPerInstance(kIndicesPerGlyph); |
| 1543 drawInfo.adjustStartVertex(firstVertex); |
| 1544 drawInfo.setVertexBuffer(vertexBuffer); |
| 1545 drawInfo.setIndexBuffer(indexBuffer); |
| 1546 |
1542 // We cache some values to avoid going to the glyphcache for the same fo
ntScaler twice | 1547 // We cache some values to avoid going to the glyphcache for the same fo
ntScaler twice |
1543 // in a row | 1548 // in a row |
1544 const SkDescriptor* desc = NULL; | 1549 const SkDescriptor* desc = NULL; |
1545 SkGlyphCache* cache = NULL; | 1550 SkGlyphCache* cache = NULL; |
1546 GrFontScaler* scaler = NULL; | 1551 GrFontScaler* scaler = NULL; |
1547 SkTypeface* typeface = NULL; | 1552 SkTypeface* typeface = NULL; |
1548 | 1553 |
| 1554 int instancesToFlush = 0; |
1549 for (int i = 0; i < instanceCount; i++) { | 1555 for (int i = 0; i < instanceCount; i++) { |
1550 Geometry& args = fGeoData[i]; | 1556 Geometry& args = fGeoData[i]; |
1551 Blob* blob = args.fBlob; | 1557 Blob* blob = args.fBlob; |
1552 Run& run = blob->fRuns[args.fRun]; | 1558 Run& run = blob->fRuns[args.fRun]; |
1553 TextInfo& info = run.fSubRunInfo[args.fSubRun]; | 1559 TextInfo& info = run.fSubRunInfo[args.fSubRun]; |
1554 | 1560 |
1555 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); | 1561 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); |
1556 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas
Gen; | 1562 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas
Gen; |
1557 bool regenerateColors; | 1563 bool regenerateColors; |
1558 if (fUseDistanceFields) { | 1564 if (fUseDistanceFields) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1622 // the glyph. | 1628 // the glyph. |
1623 glyph = blob->fGlyphs[glyphOffset]; | 1629 glyph = blob->fGlyphs[glyphOffset]; |
1624 blob->fGlyphs[glyphOffset] = strike->getGlyph(glyph-
>fPackedID, | 1630 blob->fGlyphs[glyphOffset] = strike->getGlyph(glyph-
>fPackedID, |
1625 scaler
); | 1631 scaler
); |
1626 } | 1632 } |
1627 glyph = blob->fGlyphs[glyphOffset]; | 1633 glyph = blob->fGlyphs[glyphOffset]; |
1628 SkASSERT(glyph); | 1634 SkASSERT(glyph); |
1629 | 1635 |
1630 if (!fFontCache->hasGlyph(glyph) && | 1636 if (!fFontCache->hasGlyph(glyph) && |
1631 !strike->addGlyphToAtlas(batchTarget, glyph, scaler)
) { | 1637 !strike->addGlyphToAtlas(batchTarget, glyph, scaler)
) { |
1632 this->flush(batchTarget, &flushInfo); | 1638 this->flush(batchTarget, &drawInfo, instancesToFlush
, |
| 1639 maxInstancesPerDraw); |
1633 this->initDraw(batchTarget, gp, pipeline); | 1640 this->initDraw(batchTarget, gp, pipeline); |
| 1641 instancesToFlush = 0; |
1634 brokenRun = glyphIdx > 0; | 1642 brokenRun = glyphIdx > 0; |
1635 | 1643 |
1636 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(
batchTarget, | 1644 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(
batchTarget, |
1637
glyph, | 1645
glyph, |
1638
scaler); | 1646
scaler); |
1639 SkASSERT(success); | 1647 SkASSERT(success); |
1640 } | 1648 } |
1641 fFontCache->addGlyphToBulkAndSetUseToken(&info.fBulkUseT
oken, glyph, | 1649 fFontCache->addGlyphToBulkAndSetUseToken(&info.fBulkUseT
oken, glyph, |
1642 batchTarget->cu
rrentToken()); | 1650 batchTarget->cu
rrentToken()); |
1643 | 1651 |
(...skipping 15 matching lines...) Expand all Loading... |
1659 } | 1667 } |
1660 | 1668 |
1661 if (regeneratePositions) { | 1669 if (regeneratePositions) { |
1662 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert
ices); | 1670 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert
ices); |
1663 vertex += info.fVertexStartIndex; | 1671 vertex += info.fVertexStartIndex; |
1664 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; | 1672 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; |
1665 SkScalar transX = args.fTransX; | 1673 SkScalar transX = args.fTransX; |
1666 SkScalar transY = args.fTransY; | 1674 SkScalar transY = args.fTransY; |
1667 this->regeneratePositions(vertex, vertexStride, transX,
transY); | 1675 this->regeneratePositions(vertex, vertexStride, transX,
transY); |
1668 } | 1676 } |
1669 flushInfo.fGlyphsToFlush++; | 1677 instancesToFlush++; |
1670 } | 1678 } |
1671 | 1679 |
1672 // We my have changed the color so update it here | 1680 // We my have changed the color so update it here |
1673 run.fColor = args.fColor; | 1681 run.fColor = args.fColor; |
1674 if (regenerateTextureCoords) { | 1682 if (regenerateTextureCoords) { |
1675 if (regenerateGlyphs) { | 1683 if (regenerateGlyphs) { |
1676 run.fStrike.reset(SkRef(strike)); | 1684 run.fStrike.reset(SkRef(strike)); |
1677 } | 1685 } |
1678 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt
lasGeneration : | 1686 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt
lasGeneration : |
1679 fFontCache->atlasGenerat
ion(fMaskFormat); | 1687 fFontCache->atlasGenerat
ion(fMaskFormat); |
1680 } | 1688 } |
1681 } else { | 1689 } else { |
1682 flushInfo.fGlyphsToFlush += glyphCount; | 1690 instancesToFlush += glyphCount; |
1683 | 1691 |
1684 // set use tokens for all of the glyphs in our subrun. This is
only valid if we | 1692 // set use tokens for all of the glyphs in our subrun. This is
only valid if we |
1685 // have a valid atlas generation | 1693 // have a valid atlas generation |
1686 fFontCache->setUseTokenBulk(info.fBulkUseToken, | 1694 fFontCache->setUseTokenBulk(info.fBulkUseToken, |
1687 batchTarget->currentToken(), | 1695 batchTarget->currentToken(), |
1688 fMaskFormat); | 1696 fMaskFormat); |
1689 } | 1697 } |
1690 | 1698 |
1691 // now copy all vertices | 1699 // now copy all vertices |
1692 size_t byteCount = info.fVertexEndIndex - info.fVertexStartIndex; | 1700 size_t byteCount = info.fVertexEndIndex - info.fVertexStartIndex; |
1693 memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCou
nt); | 1701 memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCou
nt); |
1694 | 1702 |
1695 currVertex += byteCount; | 1703 currVertex += byteCount; |
1696 } | 1704 } |
1697 // Make sure to attach the last cache if applicable | 1705 // Make sure to attach the last cache if applicable |
1698 if (cache) { | 1706 if (cache) { |
1699 SkGlyphCache::AttachCache(cache); | 1707 SkGlyphCache::AttachCache(cache); |
1700 } | 1708 } |
1701 this->flush(batchTarget, &flushInfo); | 1709 this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDra
w); |
1702 } | 1710 } |
1703 | 1711 |
1704 // The minimum number of Geometry we will try to allocate. | 1712 // The minimum number of Geometry we will try to allocate. |
1705 static const int kMinAllocated = 32; | 1713 static const int kMinAllocated = 32; |
1706 | 1714 |
1707 // Total number of Geometry this Batch owns | 1715 // Total number of Geometry this Batch owns |
1708 int instanceCount() const { return fInstanceCount; } | 1716 int instanceCount() const { return fInstanceCount; } |
1709 SkAutoSTMalloc<kMinAllocated, Geometry>* geoData() { return &fGeoData; } | 1717 SkAutoSTMalloc<kMinAllocated, Geometry>* geoData() { return &fGeoData; } |
1710 | 1718 |
1711 // to avoid even the initial copy of the struct, we have a getter for the fi
rst item which | 1719 // to avoid even the initial copy of the struct, we have a getter for the fi
rst item which |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1818 | 1826 |
1819 // TODO remove this when batch is everywhere | 1827 // TODO remove this when batch is everywhere |
1820 GrPipelineInfo init; | 1828 GrPipelineInfo init; |
1821 init.fColorIgnored = fBatch.fColorIgnored; | 1829 init.fColorIgnored = fBatch.fColorIgnored; |
1822 init.fOverrideColor = GrColor_ILLEGAL; | 1830 init.fOverrideColor = GrColor_ILLEGAL; |
1823 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 1831 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
1824 init.fUsesLocalCoords = this->usesLocalCoords(); | 1832 init.fUsesLocalCoords = this->usesLocalCoords(); |
1825 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 1833 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
1826 } | 1834 } |
1827 | 1835 |
1828 void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) { | 1836 void flush(GrBatchTarget* batchTarget, |
1829 GrDrawTarget::DrawInfo drawInfo; | 1837 GrDrawTarget::DrawInfo* drawInfo, |
1830 int glyphsToFlush = flushInfo->fGlyphsToFlush; | 1838 int instanceCount, |
1831 int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads(); | 1839 int maxInstancesPerDraw) { |
1832 drawInfo.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuf
fer, | 1840 while (instanceCount) { |
1833 flushInfo->fIndexBuffer, flushInfo->fVertexOffset
, | 1841 drawInfo->setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw
)); |
1834 kVerticesPerGlyph, kIndicesPerGlyph, &glyphsToFlu
sh, | 1842 drawInfo->setVertexCount(drawInfo->instanceCount() * drawInfo->verti
cesPerInstance()); |
1835 maxGlyphsPerDraw); | 1843 drawInfo->setIndexCount(drawInfo->instanceCount() * drawInfo->indice
sPerInstance()); |
1836 do { | 1844 |
1837 batchTarget->draw(drawInfo); | 1845 batchTarget->draw(*drawInfo); |
1838 } while (drawInfo.nextInstances(&glyphsToFlush, maxGlyphsPerDraw)); | 1846 |
1839 flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlus
h; | 1847 drawInfo->setStartVertex(drawInfo->startVertex() + drawInfo->vertexC
ount()); |
1840 flushInfo->fGlyphsToFlush = 0; | 1848 instanceCount -= drawInfo->instanceCount(); |
| 1849 } |
1841 } | 1850 } |
1842 | 1851 |
1843 GrColor color() const { return fBatch.fColor; } | 1852 GrColor color() const { return fBatch.fColor; } |
1844 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } | 1853 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } |
1845 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 1854 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
1846 int numGlyphs() const { return fBatch.fNumGlyphs; } | 1855 int numGlyphs() const { return fBatch.fNumGlyphs; } |
1847 | 1856 |
1848 bool onCombineIfPossible(GrBatch* t) override { | 1857 bool onCombineIfPossible(GrBatch* t) override { |
1849 BitmapTextBatch* that = t->cast<BitmapTextBatch>(); | 1858 BitmapTextBatch* that = t->cast<BitmapTextBatch>(); |
1850 | 1859 |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2152 pipelineBuilder.setFromPaint(grPaint, rt, clip); | 2161 pipelineBuilder.setFromPaint(grPaint, rt, clip); |
2153 | 2162 |
2154 GrColor color = grPaint.getColor(); | 2163 GrColor color = grPaint.getColor(); |
2155 for (int run = 0; run < cacheBlob->fRunCount; run++) { | 2164 for (int run = 0; run < cacheBlob->fRunCount; run++) { |
2156 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, 0, 0, sk
Paint); | 2165 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, 0, 0, sk
Paint); |
2157 } | 2166 } |
2158 | 2167 |
2159 // Now flush big glyphs | 2168 // Now flush big glyphs |
2160 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); | 2169 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); |
2161 } | 2170 } |
OLD | NEW |