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 kRGB_F16F16F16x_SkColorType: 67 case kRGBA_F16Norm_SkColorType: 68 // Float 69 case kRGBA_F32_SkColorType: 70 return 0.f; // no dithering 71 } 72 SkUNREACHABLE; 73 } 74 MakeDitherLUT()75SkBitmap MakeDitherLUT() { 76 static constexpr struct DitherTable { 77 constexpr DitherTable() : data() { 78 constexpr int kImgSize = 8; // if changed, also change value in sk_dither_shader 79 80 for (int x = 0; x < kImgSize; ++x) { 81 for (int y = 0; y < kImgSize; ++y) { 82 // The computation of 'm' and 'value' is lifted from CPU backend. 83 unsigned int m = (y & 1) << 5 | (x & 1) << 4 | 84 (y & 2) << 2 | (x & 2) << 1 | 85 (y & 4) >> 1 | (x & 4) >> 2; 86 float value = float(m) * 1.0 / 64.0 - 63.0 / 128.0; 87 // Bias by 0.5 to be in 0..1, mul by 255 and round to nearest int to make byte. 88 data[y * 8 + x] = (uint8_t)((value + 0.5) * 255.f + 0.5f); 89 } 90 } 91 } 92 uint8_t data[64]; 93 } gTable; 94 95 SkBitmap bmp; 96 bmp.setInfo(SkImageInfo::MakeA8(8, 8)); 97 bmp.setPixels(const_cast<uint8_t*>(gTable.data)); 98 bmp.setImmutable(); 99 return bmp; 100 } 101 102 } // namespace skgpu 103 104 #endif // SK_IGNORE_GPU_DITHER 105