* Copyright 2023 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/DitherUtils.h"
#ifndef SK_IGNORE_GPU_DITHER
#include "include/core/SkBitmap.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImageInfo.h"
#include <cstdint>
namespace skgpu {
float DitherRangeForConfig(SkColorType dstColorType) {
SkASSERT(dstColorType != kUnknown_SkColorType);
switch (dstColorType) {
case kARGB_4444_SkColorType:
return 1 / 15.f;
case kRGB_565_SkColorType:
return 1 / 63.f;
case kAlpha_8_SkColorType:
case kGray_8_SkColorType:
case kR8_unorm_SkColorType:
case kR8G8_unorm_SkColorType:
case kRGB_888x_SkColorType:
case kRGBA_8888_SkColorType:
case kSRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
return 1 / 255.f;
case kRGBA_1010102_SkColorType:
case kBGRA_1010102_SkColorType:
case kRGB_101010x_SkColorType:
case kBGR_101010x_SkColorType:
case kBGR_101010x_XR_SkColorType:
case kBGRA_10101010_XR_SkColorType:
case kRGBA_10x6_SkColorType:
return 1 / 1023.f;
case kA16_unorm_SkColorType:
case kR16G16_unorm_SkColorType:
case kR16G16B16A16_unorm_SkColorType:
return 1 / 32767.f;
case kUnknown_SkColorType:
case kA16_float_SkColorType:
case kR16G16_float_SkColorType:
case kRGBA_F16_SkColorType:
case kRGB_F16F16F16x_SkColorType:
case kRGBA_F16Norm_SkColorType:
case kRGBA_F32_SkColorType:
return 0.f;
}
SkUNREACHABLE;
}
SkBitmap MakeDitherLUT() {
static constexpr struct DitherTable {
constexpr DitherTable() : data() {
constexpr int kImgSize = 8;
for (int x = 0; x < kImgSize; ++x) {
for (int y = 0; y < kImgSize; ++y) {
unsigned int m = (y & 1) << 5 | (x & 1) << 4 |
(y & 2) << 2 | (x & 2) << 1 |
(y & 4) >> 1 | (x & 4) >> 2;
float value = float(m) * 1.0 / 64.0 - 63.0 / 128.0;
data[y * 8 + x] = (uint8_t)((value + 0.5) * 255.f + 0.5f);
}
}
}
uint8_t data[64];
} gTable;
SkBitmap bmp;
bmp.setInfo(SkImageInfo::MakeA8(8, 8));
bmp.setPixels(const_cast<uint8_t*>(gTable.data));
bmp.setImmutable();
return bmp;
}
}
#endif