GrAtlasManager.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright 2018 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 "src/gpu/text/GrAtlasManager.h"
  8. #include "src/gpu/GrGlyph.h"
  9. #include "src/gpu/text/GrStrikeCache.h"
  10. GrAtlasManager::GrAtlasManager(GrProxyProvider* proxyProvider, GrStrikeCache* glyphCache,
  11. size_t maxTextureBytes,
  12. GrDrawOpAtlas::AllowMultitexturing allowMultitexturing)
  13. : fAllowMultitexturing{allowMultitexturing}
  14. , fProxyProvider{proxyProvider}
  15. , fCaps{fProxyProvider->refCaps()}
  16. , fGlyphCache{glyphCache}
  17. , fAtlasConfig{fCaps->maxTextureSize(), maxTextureBytes} { }
  18. GrAtlasManager::~GrAtlasManager() = default;
  19. static GrColorType mask_format_to_gr_color_type(GrMaskFormat format) {
  20. switch (format) {
  21. case kA8_GrMaskFormat:
  22. return GrColorType::kAlpha_8;
  23. case kA565_GrMaskFormat:
  24. return GrColorType::kBGR_565;
  25. case kARGB_GrMaskFormat:
  26. return GrColorType::kRGBA_8888;
  27. default:
  28. SkDEBUGFAIL("unsupported GrMaskFormat");
  29. return GrColorType::kAlpha_8;
  30. }
  31. }
  32. void GrAtlasManager::freeAll() {
  33. for (int i = 0; i < kMaskFormatCount; ++i) {
  34. fAtlases[i] = nullptr;
  35. }
  36. }
  37. bool GrAtlasManager::hasGlyph(GrGlyph* glyph) {
  38. SkASSERT(glyph);
  39. return this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID);
  40. }
  41. // add to texture atlas that matches this format
  42. GrDrawOpAtlas::ErrorCode GrAtlasManager::addToAtlas(
  43. GrResourceProvider* resourceProvider,
  44. GrStrikeCache* glyphCache,
  45. GrTextStrike* strike, GrDrawOpAtlas::AtlasID* id,
  46. GrDeferredUploadTarget* target, GrMaskFormat format,
  47. int width, int height, const void* image, SkIPoint16* loc) {
  48. glyphCache->setStrikeToPreserve(strike);
  49. return this->getAtlas(format)->addToAtlas(resourceProvider, id, target, width, height,
  50. image, loc);
  51. }
  52. void GrAtlasManager::addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpdater* updater,
  53. GrGlyph* glyph,
  54. GrDeferredUploadToken token) {
  55. SkASSERT(glyph);
  56. if (updater->add(glyph->fID)) {
  57. this->getAtlas(glyph->fMaskFormat)->setLastUseToken(glyph->fID, token);
  58. }
  59. }
  60. #ifdef SK_DEBUG
  61. #include "src/gpu/GrContextPriv.h"
  62. #include "src/gpu/GrSurfaceContext.h"
  63. #include "src/gpu/GrSurfaceProxy.h"
  64. #include "src/gpu/GrTextureProxy.h"
  65. #include "include/core/SkBitmap.h"
  66. #include "include/core/SkImageEncoder.h"
  67. #include "include/core/SkStream.h"
  68. #include <stdio.h>
  69. /**
  70. * Write the contents of the surface proxy to a PNG. Returns true if successful.
  71. * @param filename Full path to desired file
  72. */
  73. static bool save_pixels(GrContext* context, GrSurfaceProxy* sProxy, GrColorType colorType,
  74. const char* filename) {
  75. if (!sProxy) {
  76. return false;
  77. }
  78. SkImageInfo ii = SkImageInfo::Make(sProxy->width(), sProxy->height(),
  79. kRGBA_8888_SkColorType, kPremul_SkAlphaType);
  80. SkBitmap bm;
  81. if (!bm.tryAllocPixels(ii)) {
  82. return false;
  83. }
  84. sk_sp<GrSurfaceContext> sContext(context->priv().makeWrappedSurfaceContext(
  85. sk_ref_sp(sProxy), colorType, kUnknown_SkAlphaType));
  86. if (!sContext || !sContext->asTextureProxy()) {
  87. return false;
  88. }
  89. bool result = sContext->readPixels(ii, bm.getPixels(), bm.rowBytes(), {0, 0});
  90. if (!result) {
  91. SkDebugf("------ failed to read pixels for %s\n", filename);
  92. return false;
  93. }
  94. // remove any previous version of this file
  95. remove(filename);
  96. SkFILEWStream file(filename);
  97. if (!file.isValid()) {
  98. SkDebugf("------ failed to create file: %s\n", filename);
  99. remove(filename); // remove any partial file
  100. return false;
  101. }
  102. if (!SkEncodeImage(&file, bm, SkEncodedImageFormat::kPNG, 100)) {
  103. SkDebugf("------ failed to encode %s\n", filename);
  104. remove(filename); // remove any partial file
  105. return false;
  106. }
  107. return true;
  108. }
  109. void GrAtlasManager::dump(GrContext* context) const {
  110. static int gDumpCount = 0;
  111. for (int i = 0; i < kMaskFormatCount; ++i) {
  112. if (fAtlases[i]) {
  113. const sk_sp<GrTextureProxy>* proxies = fAtlases[i]->getProxies();
  114. for (uint32_t pageIdx = 0; pageIdx < fAtlases[i]->numActivePages(); ++pageIdx) {
  115. SkASSERT(proxies[pageIdx]);
  116. SkString filename;
  117. #ifdef SK_BUILD_FOR_ANDROID
  118. filename.printf("/sdcard/fontcache_%d%d%d.png", gDumpCount, i, pageIdx);
  119. #else
  120. filename.printf("fontcache_%d%d%d.png", gDumpCount, i, pageIdx);
  121. #endif
  122. auto ct = mask_format_to_gr_color_type(AtlasIndexToMaskFormat(i));
  123. save_pixels(context, proxies[pageIdx].get(), ct, filename.c_str());
  124. }
  125. }
  126. }
  127. ++gDumpCount;
  128. }
  129. #endif
  130. void GrAtlasManager::setAtlasSizesToMinimum_ForTesting() {
  131. // Delete any old atlases.
  132. // This should be safe to do as long as we are not in the middle of a flush.
  133. for (int i = 0; i < kMaskFormatCount; i++) {
  134. fAtlases[i] = nullptr;
  135. }
  136. // Set all the atlas sizes to 1x1 plot each.
  137. new (&fAtlasConfig) GrDrawOpAtlasConfig{};
  138. }
  139. bool GrAtlasManager::initAtlas(GrMaskFormat format) {
  140. int index = MaskFormatToAtlasIndex(format);
  141. if (fAtlases[index] == nullptr) {
  142. GrColorType grColorType = mask_format_to_gr_color_type(format);
  143. SkISize atlasDimensions = fAtlasConfig.atlasDimensions(format);
  144. SkISize plotDimensions = fAtlasConfig.plotDimensions(format);
  145. const GrBackendFormat format = fCaps->getBackendFormatFromColorType(grColorType);
  146. fAtlases[index] = GrDrawOpAtlas::Make(
  147. fProxyProvider, format, grColorType,
  148. atlasDimensions.width(), atlasDimensions.height(),
  149. plotDimensions.width(), plotDimensions.height(),
  150. fAllowMultitexturing, &GrStrikeCache::HandleEviction, fGlyphCache);
  151. if (!fAtlases[index]) {
  152. return false;
  153. }
  154. }
  155. return true;
  156. }