SkSpriteBlitter_RGB565.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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/core/SkColorFilter.h"
  8. #include "include/core/SkPaint.h"
  9. #include "include/private/SkColorData.h"
  10. #include "include/private/SkTemplates.h"
  11. #include "src/core/SkArenaAlloc.h"
  12. #include "src/core/SkBlitRow.h"
  13. #include "src/core/SkSpriteBlitter.h"
  14. #include "src/core/SkXfermodePriv.h"
  15. #include "src/utils/SkUTF.h"
  16. ///////////////////////////////////////////////////////////////////////////////
  17. static void S32_src(uint16_t dst[], const SkPMColor src[], int count) {
  18. for (int i = 0; i < count; ++i) {
  19. dst[i] = SkPixel32ToPixel16(src[i]);
  20. }
  21. }
  22. static void S32_srcover(uint16_t dst[], const SkPMColor src[], int count) {
  23. for (int i = 0; i < count; ++i) {
  24. dst[i] = SkSrcOver32To16(src[i], dst[i]);
  25. }
  26. }
  27. class Sprite_D16_S32 : public SkSpriteBlitter {
  28. public:
  29. Sprite_D16_S32(const SkPixmap& src, SkBlendMode mode) : INHERITED(src) {
  30. SkASSERT(src.colorType() == kN32_SkColorType);
  31. SkASSERT(mode == SkBlendMode::kSrc || mode == SkBlendMode::kSrcOver);
  32. fUseSrcOver = (mode == SkBlendMode::kSrcOver) && !src.isOpaque();
  33. }
  34. void blitRect(int x, int y, int width, int height) override {
  35. SkASSERT(width > 0 && height > 0);
  36. uint16_t* SK_RESTRICT dst = fDst.writable_addr16(x, y);
  37. const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop);
  38. size_t dstRB = fDst.rowBytes();
  39. size_t srcRB = fSource.rowBytes();
  40. do {
  41. if (fUseSrcOver) {
  42. S32_srcover(dst, src, width);
  43. } else {
  44. S32_src(dst, src, width);
  45. }
  46. dst = (uint16_t* SK_RESTRICT)((char*)dst + dstRB);
  47. src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
  48. } while (--height != 0);
  49. }
  50. private:
  51. bool fUseSrcOver;
  52. typedef SkSpriteBlitter INHERITED;
  53. };
  54. SkSpriteBlitter* SkSpriteBlitter::ChooseL565(const SkPixmap& source, const SkPaint& paint,
  55. SkArenaAlloc* allocator) {
  56. SkASSERT(allocator != nullptr);
  57. if (paint.getColorFilter() != nullptr) {
  58. return nullptr;
  59. }
  60. if (paint.getMaskFilter() != nullptr) {
  61. return nullptr;
  62. }
  63. U8CPU alpha = paint.getAlpha();
  64. if (alpha != 0xFF) {
  65. return nullptr;
  66. }
  67. if (source.colorType() == kN32_SkColorType) {
  68. switch (paint.getBlendMode()) {
  69. case SkBlendMode::kSrc:
  70. case SkBlendMode::kSrcOver:
  71. return allocator->make<Sprite_D16_S32>(source, paint.getBlendMode());
  72. default:
  73. break;
  74. }
  75. }
  76. return nullptr;
  77. }
  78. //////////////////////////////////////////////////////////////////////////////////////////////////
  79. static unsigned div255(unsigned a, unsigned b) {
  80. return (a * b * 257 + 127) >> 16;
  81. }
  82. static void S32_src_da8(uint8_t dst[], const SkPMColor src[], int count) {
  83. for (int i = 0; i < count; ++i) {
  84. dst[i] = SkGetPackedA32(src[i]);
  85. }
  86. }
  87. static void S32_srcover_da8(uint8_t dst[], const SkPMColor src[], int count) {
  88. for (int i = 0; i < count; ++i) {
  89. SkPMColor c = src[i];
  90. if (c) {
  91. unsigned a = SkGetPackedA32(c);
  92. if (a == 0xFF) {
  93. dst[i] = 0xFF;
  94. } else {
  95. dst[i] = a + div255(255 - a, dst[i]);
  96. }
  97. }
  98. }
  99. }
  100. class Sprite_D8_S32 : public SkSpriteBlitter {
  101. public:
  102. Sprite_D8_S32(const SkPixmap& src, SkBlendMode mode) : INHERITED(src) {
  103. SkASSERT(src.colorType() == kN32_SkColorType);
  104. SkASSERT(mode == SkBlendMode::kSrc || mode == SkBlendMode::kSrcOver);
  105. fUseSrcOver = (mode == SkBlendMode::kSrcOver) && !src.isOpaque();
  106. }
  107. void blitRect(int x, int y, int width, int height) override {
  108. SkASSERT(width > 0 && height > 0);
  109. uint8_t* SK_RESTRICT dst = fDst.writable_addr8(x, y);
  110. const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop);
  111. size_t dstRB = fDst.rowBytes();
  112. size_t srcRB = fSource.rowBytes();
  113. do {
  114. if (fUseSrcOver) {
  115. S32_srcover_da8(dst, src, width);
  116. } else {
  117. S32_src_da8(dst, src, width);
  118. }
  119. dst = (uint8_t* SK_RESTRICT)((char*)dst + dstRB);
  120. src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
  121. } while (--height != 0);
  122. }
  123. private:
  124. bool fUseSrcOver;
  125. typedef SkSpriteBlitter INHERITED;
  126. };
  127. SkSpriteBlitter* SkSpriteBlitter::ChooseLA8(const SkPixmap& source, const SkPaint& paint,
  128. SkArenaAlloc* allocator) {
  129. SkASSERT(allocator != nullptr);
  130. if (paint.getColorFilter() != nullptr) {
  131. return nullptr;
  132. }
  133. if (paint.getMaskFilter() != nullptr) {
  134. return nullptr;
  135. }
  136. U8CPU alpha = paint.getAlpha();
  137. if (alpha != 0xFF) {
  138. return nullptr;
  139. }
  140. if (source.colorType() == kN32_SkColorType) {
  141. switch (paint.getBlendMode()) {
  142. case SkBlendMode::kSrc:
  143. case SkBlendMode::kSrcOver:
  144. return allocator->make<Sprite_D8_S32>(source, paint.getBlendMode());
  145. default:
  146. break;
  147. }
  148. }
  149. return nullptr;
  150. }