SkInternalAtlasTextContext.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Copyright 2017 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/atlastext/SkAtlasTextContext.h"
  8. #include "include/atlastext/SkAtlasTextRenderer.h"
  9. #include "include/gpu/GrContext.h"
  10. #include "src/atlastext/SkInternalAtlasTextContext.h"
  11. #include "src/gpu/GrContextPriv.h"
  12. #include "src/gpu/text/GrStrikeCache.h"
  13. SkAtlasTextRenderer* SkGetAtlasTextRendererFromInternalContext(
  14. class SkInternalAtlasTextContext& internal) {
  15. return internal.renderer();
  16. }
  17. //////////////////////////////////////////////////////////////////////////////
  18. std::unique_ptr<SkInternalAtlasTextContext> SkInternalAtlasTextContext::Make(
  19. sk_sp<SkAtlasTextRenderer> renderer) {
  20. return std::unique_ptr<SkInternalAtlasTextContext>(
  21. new SkInternalAtlasTextContext(std::move(renderer)));
  22. }
  23. SkInternalAtlasTextContext::SkInternalAtlasTextContext(sk_sp<SkAtlasTextRenderer> renderer)
  24. : fRenderer(std::move(renderer)) {
  25. GrContextOptions options;
  26. options.fAllowMultipleGlyphCacheTextures = GrContextOptions::Enable::kNo;
  27. options.fMinDistanceFieldFontSize = 0.f;
  28. options.fGlyphsAsPathsFontSize = SK_ScalarInfinity;
  29. options.fDistanceFieldGlyphVerticesAlwaysHaveW = GrContextOptions::Enable::kYes;
  30. fGrContext = GrContext::MakeMock(nullptr, options);
  31. }
  32. SkInternalAtlasTextContext::~SkInternalAtlasTextContext() {
  33. if (fDistanceFieldAtlas.fProxy) {
  34. #ifdef SK_DEBUG
  35. auto atlasManager = fGrContext->priv().getAtlasManager();
  36. if (atlasManager) {
  37. unsigned int numProxies;
  38. atlasManager->getProxies(kA8_GrMaskFormat, &numProxies);
  39. SkASSERT(1 == numProxies);
  40. }
  41. #endif
  42. fRenderer->deleteTexture(fDistanceFieldAtlas.fTextureHandle);
  43. }
  44. }
  45. GrStrikeCache* SkInternalAtlasTextContext::glyphCache() {
  46. return fGrContext->priv().getGrStrikeCache();
  47. }
  48. GrTextBlobCache* SkInternalAtlasTextContext::textBlobCache() {
  49. return fGrContext->priv().getTextBlobCache();
  50. }
  51. GrDeferredUploadToken SkInternalAtlasTextContext::addInlineUpload(
  52. GrDeferredTextureUploadFn&& upload) {
  53. auto token = fTokenTracker.nextDrawToken();
  54. fInlineUploads.append(&fArena, InlineUpload{std::move(upload), token});
  55. return token;
  56. }
  57. GrDeferredUploadToken SkInternalAtlasTextContext::addASAPUpload(
  58. GrDeferredTextureUploadFn&& upload) {
  59. fASAPUploads.append(&fArena, std::move(upload));
  60. return fTokenTracker.nextTokenToFlush();
  61. }
  62. void SkInternalAtlasTextContext::recordDraw(const void* srcVertexData, int glyphCnt,
  63. const SkMatrix& matrix, void* targetHandle) {
  64. auto vertexDataSize = sizeof(SkAtlasTextRenderer::SDFVertex) * 4 * glyphCnt;
  65. auto vertexData = fArena.makeArrayDefault<char>(vertexDataSize);
  66. memcpy(vertexData, srcVertexData, vertexDataSize);
  67. for (int i = 0; i < 4 * glyphCnt; ++i) {
  68. auto* vertex = reinterpret_cast<SkAtlasTextRenderer::SDFVertex*>(vertexData) + i;
  69. // GrTextContext encodes a texture index into the lower bit of each texture coord.
  70. // This isn't expected by SkAtlasTextRenderer subclasses.
  71. vertex->fTextureCoordX /= 2;
  72. vertex->fTextureCoordY /= 2;
  73. matrix.mapHomogeneousPoints(&vertex->fPosition, &vertex->fPosition, 1);
  74. }
  75. fDraws.append(&fArena,
  76. Draw{glyphCnt, fTokenTracker.issueDrawToken(), targetHandle, vertexData});
  77. }
  78. void SkInternalAtlasTextContext::flush() {
  79. auto* atlasManager = fGrContext->priv().getAtlasManager();
  80. if (!fDistanceFieldAtlas.fProxy) {
  81. unsigned int numProxies;
  82. fDistanceFieldAtlas.fProxy = atlasManager->getProxies(kA8_GrMaskFormat, &numProxies)->get();
  83. SkASSERT(1 == numProxies);
  84. fDistanceFieldAtlas.fTextureHandle =
  85. fRenderer->createTexture(SkAtlasTextRenderer::AtlasFormat::kA8,
  86. fDistanceFieldAtlas.fProxy->width(),
  87. fDistanceFieldAtlas.fProxy->height());
  88. }
  89. GrDeferredTextureUploadWritePixelsFn writePixelsFn =
  90. [this](GrTextureProxy* proxy, int left, int top, int width, int height,
  91. GrColorType colorType, const void* data, size_t rowBytes) -> bool {
  92. SkASSERT(GrColorType::kAlpha_8 == colorType);
  93. SkASSERT(proxy == this->fDistanceFieldAtlas.fProxy);
  94. void* handle = fDistanceFieldAtlas.fTextureHandle;
  95. this->fRenderer->setTextureData(handle, data, left, top, width, height, rowBytes);
  96. return true;
  97. };
  98. for (const auto& upload : fASAPUploads) {
  99. upload(writePixelsFn);
  100. }
  101. auto inlineUpload = fInlineUploads.begin();
  102. for (const auto& draw : fDraws) {
  103. while (inlineUpload != fInlineUploads.end() && inlineUpload->fToken == draw.fToken) {
  104. inlineUpload->fUpload(writePixelsFn);
  105. ++inlineUpload;
  106. }
  107. auto vertices = reinterpret_cast<const SkAtlasTextRenderer::SDFVertex*>(draw.fVertexData);
  108. fRenderer->drawSDFGlyphs(draw.fTargetHandle, fDistanceFieldAtlas.fTextureHandle, vertices,
  109. draw.fGlyphCnt);
  110. fTokenTracker.flushToken();
  111. }
  112. fASAPUploads.reset();
  113. fInlineUploads.reset();
  114. fDraws.reset();
  115. fArena.reset();
  116. }