SkMaskCache.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Copyright 2014 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/core/SkMaskCache.h"
  8. #define CHECK_LOCAL(localCache, localName, globalName, ...) \
  9. ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::globalName(__VA_ARGS__))
  10. struct MaskValue {
  11. SkMask fMask;
  12. SkCachedData* fData;
  13. };
  14. namespace {
  15. static unsigned gRRectBlurKeyNamespaceLabel;
  16. struct RRectBlurKey : public SkResourceCache::Key {
  17. public:
  18. RRectBlurKey(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style)
  19. : fSigma(sigma)
  20. , fStyle(style)
  21. , fRRect(rrect)
  22. {
  23. this->init(&gRRectBlurKeyNamespaceLabel, 0,
  24. sizeof(fSigma) + sizeof(fStyle) + sizeof(fRRect));
  25. }
  26. SkScalar fSigma;
  27. int32_t fStyle;
  28. SkRRect fRRect;
  29. };
  30. struct RRectBlurRec : public SkResourceCache::Rec {
  31. RRectBlurRec(RRectBlurKey key, const SkMask& mask, SkCachedData* data)
  32. : fKey(key)
  33. {
  34. fValue.fMask = mask;
  35. fValue.fData = data;
  36. fValue.fData->attachToCacheAndRef();
  37. }
  38. ~RRectBlurRec() override {
  39. fValue.fData->detachFromCacheAndUnref();
  40. }
  41. RRectBlurKey fKey;
  42. MaskValue fValue;
  43. const Key& getKey() const override { return fKey; }
  44. size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
  45. const char* getCategory() const override { return "rrect-blur"; }
  46. SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
  47. return fValue.fData->diagnostic_only_getDiscardable();
  48. }
  49. static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
  50. const RRectBlurRec& rec = static_cast<const RRectBlurRec&>(baseRec);
  51. MaskValue* result = (MaskValue*)contextData;
  52. SkCachedData* tmpData = rec.fValue.fData;
  53. tmpData->ref();
  54. if (nullptr == tmpData->data()) {
  55. tmpData->unref();
  56. return false;
  57. }
  58. *result = rec.fValue;
  59. return true;
  60. }
  61. };
  62. } // namespace
  63. SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style,
  64. const SkRRect& rrect, SkMask* mask, SkResourceCache* localCache) {
  65. MaskValue result;
  66. RRectBlurKey key(sigma, rrect, style);
  67. if (!CHECK_LOCAL(localCache, find, Find, key, RRectBlurRec::Visitor, &result)) {
  68. return nullptr;
  69. }
  70. *mask = result.fMask;
  71. mask->fImage = (uint8_t*)(result.fData->data());
  72. return result.fData;
  73. }
  74. void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style,
  75. const SkRRect& rrect, const SkMask& mask, SkCachedData* data,
  76. SkResourceCache* localCache) {
  77. RRectBlurKey key(sigma, rrect, style);
  78. return CHECK_LOCAL(localCache, add, Add, new RRectBlurRec(key, mask, data));
  79. }
  80. //////////////////////////////////////////////////////////////////////////////////////////
  81. namespace {
  82. static unsigned gRectsBlurKeyNamespaceLabel;
  83. struct RectsBlurKey : public SkResourceCache::Key {
  84. public:
  85. RectsBlurKey(SkScalar sigma, SkBlurStyle style, const SkRect rects[], int count)
  86. : fSigma(sigma)
  87. , fStyle(style)
  88. {
  89. SkASSERT(1 == count || 2 == count);
  90. SkIRect ir;
  91. rects[0].roundOut(&ir);
  92. fSizes[0] = SkSize{rects[0].width(), rects[0].height()};
  93. if (2 == count) {
  94. fSizes[1] = SkSize{rects[1].width(), rects[1].height()};
  95. fSizes[2] = SkSize{rects[0].x() - rects[1].x(), rects[0].y() - rects[1].y()};
  96. } else {
  97. fSizes[1] = SkSize{0, 0};
  98. fSizes[2] = SkSize{0, 0};
  99. }
  100. fSizes[3] = SkSize{rects[0].x() - ir.x(), rects[0].y() - ir.y()};
  101. this->init(&gRectsBlurKeyNamespaceLabel, 0,
  102. sizeof(fSigma) + sizeof(fStyle) + sizeof(fSizes));
  103. }
  104. SkScalar fSigma;
  105. int32_t fStyle;
  106. SkSize fSizes[4];
  107. };
  108. struct RectsBlurRec : public SkResourceCache::Rec {
  109. RectsBlurRec(RectsBlurKey key, const SkMask& mask, SkCachedData* data)
  110. : fKey(key)
  111. {
  112. fValue.fMask = mask;
  113. fValue.fData = data;
  114. fValue.fData->attachToCacheAndRef();
  115. }
  116. ~RectsBlurRec() override {
  117. fValue.fData->detachFromCacheAndUnref();
  118. }
  119. RectsBlurKey fKey;
  120. MaskValue fValue;
  121. const Key& getKey() const override { return fKey; }
  122. size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
  123. const char* getCategory() const override { return "rects-blur"; }
  124. SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
  125. return fValue.fData->diagnostic_only_getDiscardable();
  126. }
  127. static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
  128. const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec);
  129. MaskValue* result = static_cast<MaskValue*>(contextData);
  130. SkCachedData* tmpData = rec.fValue.fData;
  131. tmpData->ref();
  132. if (nullptr == tmpData->data()) {
  133. tmpData->unref();
  134. return false;
  135. }
  136. *result = rec.fValue;
  137. return true;
  138. }
  139. };
  140. } // namespace
  141. SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style,
  142. const SkRect rects[], int count, SkMask* mask,
  143. SkResourceCache* localCache) {
  144. MaskValue result;
  145. RectsBlurKey key(sigma, style, rects, count);
  146. if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) {
  147. return nullptr;
  148. }
  149. *mask = result.fMask;
  150. mask->fImage = (uint8_t*)(result.fData->data());
  151. return result.fData;
  152. }
  153. void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style,
  154. const SkRect rects[], int count, const SkMask& mask, SkCachedData* data,
  155. SkResourceCache* localCache) {
  156. RectsBlurKey key(sigma, style, rects, count);
  157. return CHECK_LOCAL(localCache, add, Add, new RectsBlurRec(key, mask, data));
  158. }