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