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

#include "SkColorFilter.h"
#include "SkHalf.h"
#include "SkNx.h"
#include "SkPaint.h"
#include "SkPixmap.h"
#include "SkPM4f.h"
#include "SkPM4fPriv.h"
#include "SkSpanProcs.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

static void load_l32(const SkPixmap& src, int x, int y, SkPM4f span[], int count) {
    SkASSERT(count > 0);
    const uint32_t* addr = src.addr32(x, y);
    SkASSERT(src.addr32(x + count - 1, y));

    for (int i = 0; i < count; ++i) {
        swizzle_rb_if_bgra(Sk4f_fromL32(addr[i])).store(span[i].fVec);
    }
}

static void load_s32(const SkPixmap& src, int x, int y, SkPM4f span[], int count) {
    SkASSERT(count > 0);
    const uint32_t* addr = src.addr32(x, y);
    SkASSERT(src.addr32(x + count - 1, y));

    for (int i = 0; i < count; ++i) {
        swizzle_rb_if_bgra(Sk4f_fromS32(addr[i])).store(span[i].fVec);
    }
}

static void load_f16(const SkPixmap& src, int x, int y, SkPM4f span[], int count) {
    SkASSERT(count > 0);
    const uint64_t* addr = src.addr64(x, y);
    SkASSERT(src.addr64(x + count - 1, y));

    for (int i = 0; i < count; ++i) {
        SkHalfToFloat_finite_ftz(addr[i]).store(span[i].fVec);
    }
}

SkLoadSpanProc SkLoadSpanProc_Choose(const SkImageInfo& info) {
    switch (info.colorType()) {
        case kN32_SkColorType:
            return info.gammaCloseToSRGB() ? load_s32 : load_l32;
        case kRGBA_F16_SkColorType:
            return load_f16;
        default:
            return nullptr;
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////

static void noop_filterspan(const SkPaint& paint, SkPM4f[], int) {
    SkASSERT(!paint.getColorFilter());
    SkASSERT(0xFF == paint.getAlpha());
}

static void alpha_filterspan(const SkPaint& paint, SkPM4f span[], int count) {
    SkASSERT(!paint.getColorFilter());
    SkASSERT(0xFF != paint.getAlpha());
    const Sk4f scale = Sk4f(paint.getAlpha() * (1.0f/255));
    for (int i = 0; i < count; ++i) {
        (Sk4f::Load(span[i].fVec) * scale).store(span[i].fVec);
    }
}

static void colorfilter_filterspan(const SkPaint& paint, SkPM4f span[], int count) {
    SkASSERT(paint.getColorFilter());
    SkASSERT(0xFF == paint.getAlpha());
    paint.getColorFilter()->filterSpan4f(span, count, span);
}

static void colorfilter_alpha_filterspan(const SkPaint& paint, SkPM4f span[], int count) {
    SkASSERT(paint.getColorFilter());
    SkASSERT(0xFF != paint.getAlpha());
    alpha_filterspan(paint, span, count);
    paint.getColorFilter()->filterSpan4f(span, count, span);
}

SkFilterSpanProc SkFilterSpanProc_Choose(const SkPaint& paint) {
    if (paint.getColorFilter()) {
        return 0xFF == paint.getAlpha() ? colorfilter_filterspan : colorfilter_alpha_filterspan;
    } else {
        return 0xFF == paint.getAlpha() ? noop_filterspan : alpha_filterspan;
    }
}
