/*
 * Copyright 2009 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBitmapFilter_opts_SSE2.h"
#include "SkBitmapProcState_opts_SSE2.h"
#include "SkBitmapProcState_opts_SSSE3.h"
#include "SkBitmapScaler.h"
#include "SkBlitMask.h"
#include "SkBlitRow.h"
#include "SkBlitRow_opts_SSE2.h"
#include "SkCpu.h"


/*
 *****************************************
 *********This file is deprecated*********
 *****************************************
 * New CPU-specific work should be done in
 * SkOpts framework. Run-time detection of
 * available instruction set extensions is
 * implemented in src/core/SkOpts.cpp file
 *****************************************
 */


/* This file must *not* be compiled with -msse or any other optional SIMD
   extension, otherwise gcc may generate SIMD instructions even for scalar ops
   (and thus give an invalid instruction on Pentium3 on the code below).
   For example, only files named *_SSE2.cpp in this directory should be
   compiled with -msse2 or higher. */

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

void SkBitmapScaler::PlatformConvolutionProcs(SkConvolutionProcs* procs) {
    if (SkCpu::Supports(SkCpu::SSE2)) {
        procs->fExtraHorizontalReads = 3;
        procs->fConvolveVertically = &convolveVertically_SSE2;
        procs->fConvolve4RowsHorizontally = &convolve4RowsHorizontally_SSE2;
        procs->fConvolveHorizontally = &convolveHorizontally_SSE2;
        procs->fApplySIMDPadding = &applySIMDPadding_SSE2;
    }
}

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

void SkBitmapProcState::platformProcs() {
    /* Every optimization in the function requires at least SSE2 */
    if (!SkCpu::Supports(SkCpu::SSE2)) {
        return;
    }
    const bool ssse3 = SkCpu::Supports(SkCpu::SSSE3);

    /* Check fSampleProc32 */
    if (fSampleProc32 == S32_opaque_D32_filter_DX) {
        if (ssse3) {
            fSampleProc32 = S32_opaque_D32_filter_DX_SSSE3;
        } else {
            fSampleProc32 = S32_opaque_D32_filter_DX_SSE2;
        }
    } else if (fSampleProc32 == S32_opaque_D32_filter_DXDY) {
        if (ssse3) {
            fSampleProc32 = S32_opaque_D32_filter_DXDY_SSSE3;
        }
    } else if (fSampleProc32 == S32_alpha_D32_filter_DX) {
        if (ssse3) {
            fSampleProc32 = S32_alpha_D32_filter_DX_SSSE3;
        } else {
            fSampleProc32 = S32_alpha_D32_filter_DX_SSE2;
        }
    } else if (fSampleProc32 == S32_alpha_D32_filter_DXDY) {
        if (ssse3) {
            fSampleProc32 = S32_alpha_D32_filter_DXDY_SSSE3;
        }
    }

    /* Check fMatrixProc */
    if (fMatrixProc == ClampX_ClampY_filter_scale) {
        fMatrixProc = ClampX_ClampY_filter_scale_SSE2;
    } else if (fMatrixProc == ClampX_ClampY_nofilter_scale) {
        fMatrixProc = ClampX_ClampY_nofilter_scale_SSE2;
    } else if (fMatrixProc == ClampX_ClampY_filter_affine) {
        fMatrixProc = ClampX_ClampY_filter_affine_SSE2;
    } else if (fMatrixProc == ClampX_ClampY_nofilter_affine) {
        fMatrixProc = ClampX_ClampY_nofilter_affine_SSE2;
    }
}

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

static const SkBlitRow::Proc16 platform_16_procs[] = {
    S32_D565_Opaque_SSE2,               // S32_D565_Opaque
    nullptr,                               // S32_D565_Blend
    S32A_D565_Opaque_SSE2,              // S32A_D565_Opaque
    nullptr,                               // S32A_D565_Blend
    S32_D565_Opaque_Dither_SSE2,        // S32_D565_Opaque_Dither
    nullptr,                               // S32_D565_Blend_Dither
    S32A_D565_Opaque_Dither_SSE2,       // S32A_D565_Opaque_Dither
    nullptr,                               // S32A_D565_Blend_Dither
};

SkBlitRow::Proc16 SkBlitRow::PlatformFactory565(unsigned flags) {
    if (SkCpu::Supports(SkCpu::SSE2)) {
        return platform_16_procs[flags];
    } else {
        return nullptr;
    }
}

static const SkBlitRow::ColorProc16 platform_565_colorprocs_SSE2[] = {
    Color32A_D565_SSE2,                 // Color32A_D565,
    nullptr,                               // Color32A_D565_Dither
};

SkBlitRow::ColorProc16 SkBlitRow::PlatformColorFactory565(unsigned flags) {
/* If you're thinking about writing an SSE4 version of this, do check it's
 * actually faster on Atom. Our original SSE4 version was slower than this
 * SSE2 version on Silvermont, and only marginally faster on a Core i7,
 * mainly due to the MULLD timings.
 */
    if (SkCpu::Supports(SkCpu::SSE2)) {
        return platform_565_colorprocs_SSE2[flags];
    } else {
        return nullptr;
    }
}

static const SkBlitRow::Proc32 platform_32_procs_SSE2[] = {
    nullptr,                               // S32_Opaque,
    S32_Blend_BlitRow32_SSE2,           // S32_Blend,
    nullptr,                            // Ported to SkOpts
    S32A_Blend_BlitRow32_SSE2,          // S32A_Blend,
};

SkBlitRow::Proc32 SkBlitRow::PlatformProcs32(unsigned flags) {
    if (SkCpu::Supports(SkCpu::SSE2)) {
        return platform_32_procs_SSE2[flags];
    } else {
        return nullptr;
    }
}

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

SkBlitMask::BlitLCD16RowProc SkBlitMask::PlatformBlitRowProcs16(bool isOpaque) {
    if (SkCpu::Supports(SkCpu::SSE2)) {
        if (isOpaque) {
            return SkBlitLCD16OpaqueRow_SSE2;
        } else {
            return SkBlitLCD16Row_SSE2;
        }
    } else {
        return nullptr;
    }

}

SkBlitMask::RowProc SkBlitMask::PlatformRowProcs(SkColorType, SkMask::Format, RowFlags) {
    return nullptr;
}
