/*
 * 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);

    // We use 1 / (2^bitdepth-1) as the range since each channel can hold 2^bitdepth values
    switch (dstColorType) {
        // 4 bit
        case kARGB_4444_SkColorType:
            return 1 / 15.f;

        // 6 bit
        case kRGB_565_SkColorType:
            return 1 / 63.f;

        // 8 bit
        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;

        // 10 bit
        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;

        // 16 bit
        case kA16_unorm_SkColorType:
        case kR16_unorm_SkColorType:
        case kR16G16_unorm_SkColorType:
        case kR16G16B16A16_unorm_SkColorType:
            return 1 / 32767.f;

        // Unknown
        case kUnknown_SkColorType:
        // Half
        case kA16_float_SkColorType:
        case kR16G16_float_SkColorType:
        case kRGBA_F16_SkColorType:
        case kRGB_F16F16F16x_SkColorType:
        case kRGBA_F16Norm_SkColorType:
        // Float
        case kRGBA_F32_SkColorType:
            return 0.f; // no dithering
    }
    SkUNREACHABLE;
}

SkBitmap MakeDitherLUT() {
    static constexpr struct DitherTable {
        constexpr DitherTable() : data() {
            constexpr int kImgSize = 8; // if changed, also change value in sk_dither_shader

            for (int x = 0; x < kImgSize; ++x) {
                for (int y = 0; y < kImgSize; ++y) {
                    // The computation of 'm' and 'value' is lifted from CPU backend.
                    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;
                    // Bias by 0.5 to be in 0..1, mul by 255 and round to nearest int to make byte.
                    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;
}

}  // namespace skgpu

#endif // SK_IGNORE_GPU_DITHER
