/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef Sk4fGradientPriv_DEFINED
#define Sk4fGradientPriv_DEFINED

#include "SkColor.h"
#include "SkColorData.h"
#include "SkHalf.h"
#include "SkImageInfo.h"
#include "SkNx.h"
#include "SkUtils.h"

// Templates shared by various 4f gradient flavors.

namespace {  // NOLINT(google-build-namespaces)

enum class ApplyPremul { True, False };

template <ApplyPremul>
struct PremulTraits;

template <>
struct PremulTraits<ApplyPremul::False> {
    static Sk4f apply(const Sk4f& c) { return c; }
};

template <>
struct PremulTraits<ApplyPremul::True> {
    static Sk4f apply(const Sk4f& c) {
        const float alpha = c[3];
        // FIXME: portable swizzle?
        return c * Sk4f(alpha, alpha, alpha, 1);
    }
};

// Struct encapsulating various dest-dependent ops:
//
//   - load()       Load a SkPMColor4f value into Sk4f.  Normally called once per interval
//                  advance.  Also applies a scale and swizzle suitable for DstType.
//
//   - store()      Store one Sk4f to dest.  Optionally handles premul, color space
//                  conversion, etc.
//
//   - store(count) Store the Sk4f value repeatedly to dest, count times.
//
//   - store4x()    Store 4 Sk4f values to dest (opportunistic optimization).
//

template <ApplyPremul premul>
struct DstTraits {
    using PM   = PremulTraits<premul>;

    // For L32, prescaling by 255 saves a per-pixel multiplication when premul is not needed.
    static Sk4f load(const SkPMColor4f& c) {
        Sk4f c4f = swizzle_rb_if_bgra(Sk4f::Load(c.vec()));
        return premul == ApplyPremul::False
            ? c4f * Sk4f(255)
            : c4f;
    }

    static void store(const Sk4f& c, SkPMColor* dst, const Sk4f& bias) {
        if (premul == ApplyPremul::False) {
            // c is pre-scaled by 255 and pre-biased, just store.
            SkNx_cast<uint8_t>(c).store(dst);
        } else {
            *dst = Sk4f_toL32(PM::apply(c) + bias);
        }
    }

    static void store(const Sk4f& c, SkPMColor* dst, int n) {
        SkPMColor pmc;
        store(c, &pmc, Sk4f(0));
        sk_memset32(dst, pmc, n);
    }

    static void store4x(const Sk4f& c0, const Sk4f& c1,
                        const Sk4f& c2, const Sk4f& c3,
                        SkPMColor* dst,
                        const Sk4f& bias0,
                        const Sk4f& bias1) {
        if (premul == ApplyPremul::False) {
            // colors are pre-scaled and pre-biased.
            Sk4f_ToBytes((uint8_t*)dst, c0, c1, c2, c3);
        } else {
            store(c0, dst + 0, bias0);
            store(c1, dst + 1, bias1);
            store(c2, dst + 2, bias0);
            store(c3, dst + 3, bias1);
        }
    }

    static Sk4f pre_lerp_bias(const Sk4f& bias) {
        // We can apply the bias before interpolation when the colors are premultiplied.
        return premul == ApplyPremul::False ? bias : 0;
    }
};

} // anonymous namespace

#endif // Sk4fGradientPriv_DEFINED
