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