1 /* 2 * Copyright 2023 Google LLC 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 8 #include "src/gpu/DitherUtils.h" 9 10 #ifndef SK_IGNORE_GPU_DITHER 11 12 #include "include/core/SkBitmap.h" 13 #include "include/core/SkColorType.h" 14 #include "include/core/SkImageInfo.h" 15 16 #include <cstdint> 17 18 namespace skgpu { 19 DitherRangeForConfig(SkColorType dstColorType)20float DitherRangeForConfig(SkColorType dstColorType) { 21 SkASSERT(dstColorType != kUnknown_SkColorType); 22 23 // We use 1 / (2^bitdepth-1) as the range since each channel can hold 2^bitdepth values 24 switch (dstColorType) { 25 // 4 bit 26 case kARGB_4444_SkColorType: 27 return 1 / 15.f; 28 29 // 6 bit 30 case kRGB_565_SkColorType: 31 return 1 / 63.f; 32 33 // 8 bit 34 case kAlpha_8_SkColorType: 35 case kGray_8_SkColorType: 36 case kR8_unorm_SkColorType: 37 case kR8G8_unorm_SkColorType: 38 case kRGB_888x_SkColorType: 39 case kRGBA_8888_SkColorType: 40 case kSRGBA_8888_SkColorType: 41 case kBGRA_8888_SkColorType: 42 return 1 / 255.f; 43 44 // 10 bit 45 case kRGBA_1010102_SkColorType: 46 case kBGRA_1010102_SkColorType: 47 case kRGB_101010x_SkColorType: 48 case kBGR_101010x_SkColorType: 49 case kBGR_101010x_XR_SkColorType: 50 case kBGRA_10101010_XR_SkColorType: 51 case kRGBA_10x6_SkColorType: 52 return 1 / 1023.f; 53 54 // 16 bit 55 case kA16_unorm_SkColorType: 56 case kR16G16_unorm_SkColorType: 57 case kR16G16B16A16_unorm_SkColorType: 58 return 1 / 32767.f; 59 60 // Unknown 61 case kUnknown_SkColorType: 62 // Half 63 case kA16_float_SkColorType: 64 case kR16G16_float_SkColorType: 65 case kRGBA_F16_SkColorType: 66 case kRGBA_F16Norm_SkColorType: 67 // Float 68 case kRGBA_F32_SkColorType: 69 return 0.f; // no dithering 70 } 71 SkUNREACHABLE; 72 } 73 MakeDitherLUT()74SkBitmap MakeDitherLUT() { 75 static constexpr struct DitherTable { 76 constexpr DitherTable() : data() { 77 constexpr int kImgSize = 8; // if changed, also change value in sk_dither_shader 78 79 for (int x = 0; x < kImgSize; ++x) { 80 for (int y = 0; y < kImgSize; ++y) { 81 // The computation of 'm' and 'value' is lifted from CPU backend. 82 unsigned int m = (y & 1) << 5 | (x & 1) << 4 | 83 (y & 2) << 2 | (x & 2) << 1 | 84 (y & 4) >> 1 | (x & 4) >> 2; 85 float value = float(m) * 1.0 / 64.0 - 63.0 / 128.0; 86 // Bias by 0.5 to be in 0..1, mul by 255 and round to nearest int to make byte. 87 data[y * 8 + x] = (uint8_t)((value + 0.5) * 255.f + 0.5f); 88 } 89 } 90 } 91 uint8_t data[64]; 92 } gTable; 93 94 SkBitmap bmp; 95 bmp.setInfo(SkImageInfo::MakeA8(8, 8)); 96 bmp.setPixels(const_cast<uint8_t*>(gTable.data)); 97 bmp.setImmutable(); 98 return bmp; 99 } 100 101 } // namespace skgpu 102 103 #endif // SK_IGNORE_GPU_DITHER 104