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

#include "SkBlitRect_opts_SSE2.h"
#include "SkBlitRow.h"
#include "SkColorPriv.h"

#include <emmintrin.h>

/** Simple blitting of opaque rectangles less than 31 pixels wide:
    inlines and merges sections of Color32_SSE2 and sk_memset32_SSE2.
*/
static void BlitRect32_OpaqueNarrow_SSE2(SkPMColor* SK_RESTRICT destination,
                                  int width, int height,
                                  size_t rowBytes, uint32_t color) {
    SkASSERT(255 == SkGetPackedA32(color));
    SkASSERT(width > 0);
    SkASSERT(width < 31);

    while (--height >= 0) {
        SkPMColor* dst = destination;
        int count = width;

        while (count > 4) {
            *dst++ = color;
            *dst++ = color;
            *dst++ = color;
            *dst++ = color;
            count -= 4;
        }

        while (count > 0) {
            *dst++ = color;
            --count;
        }

        destination = (uint32_t*)((char*)destination + rowBytes);
    }
}

/**
  Fast blitting of opaque rectangles at least 31 pixels wide:
  inlines and merges sections of Color32_SSE2 and sk_memset32_SSE2.
  A 31 pixel rectangle is guaranteed to have at least one
  16-pixel aligned span that can take advantage of mm_store.
*/
static void BlitRect32_OpaqueWide_SSE2(SkPMColor* SK_RESTRICT destination,
                                int width, int height,
                                size_t rowBytes, uint32_t color) {
    SkASSERT(255 == SkGetPackedA32(color));
    SkASSERT(width >= 31);

    __m128i color_wide = _mm_set1_epi32(color);
    while (--height >= 0) {
        // Prefetching one row ahead to L1 cache can equal hardware
        // performance for large/tall rects, but never *beats*
        // hardware performance.
        SkPMColor* dst = destination;
        int count = width;

        while (((size_t)dst) & 0x0F) {
            *dst++ = color;
            --count;
        }
        __m128i *d = reinterpret_cast<__m128i*>(dst);

        // Googling suggests _mm_stream is only going to beat _mm_store
        // for things that wouldn't fit in L2 cache anyway, typically
        // >500kB, and precisely fill cache lines.  For us, with
        // arrays > 100k elements _mm_stream is still 100%+ slower than
        // mm_store.

        // Unrolling to count >= 64 is a break-even for most
        // input patterns; we seem to be saturating the bus and having
        // low enough overhead at 32.

        while (count >= 32) {
            _mm_store_si128(d++, color_wide);
            _mm_store_si128(d++, color_wide);
            _mm_store_si128(d++, color_wide);
            _mm_store_si128(d++, color_wide);
            _mm_store_si128(d++, color_wide);
            _mm_store_si128(d++, color_wide);
            _mm_store_si128(d++, color_wide);
            _mm_store_si128(d++, color_wide);
            count -= 32;
        }
        if (count >= 16) {
            _mm_store_si128(d++, color_wide);
            _mm_store_si128(d++, color_wide);
            _mm_store_si128(d++, color_wide);
            _mm_store_si128(d++, color_wide);
            count -= 16;
        }
        dst = reinterpret_cast<uint32_t*>(d);

        // Unrolling the loop in the Narrow code is a significant performance
        // gain, but unrolling this loop appears to make no difference in
        // benchmarks with either mm_store_si128 or individual sets.

        while (count > 0) {
            *dst++ = color;
            --count;
        }

        destination = (uint32_t*)((char*)destination + rowBytes);
    }
}

void ColorRect32_SSE2(SkPMColor* destination,
                      int width, int height,
                      size_t rowBytes, uint32_t color) {
    if (0 == height || 0 == width || 0 == color) {
        return;
    }
    unsigned colorA = SkGetPackedA32(color);
    if (false && 255 == colorA) { // disabled but compilable to suppress warning
        if (width < 31) {
            BlitRect32_OpaqueNarrow_SSE2(destination, width, height,
                                         rowBytes, color);
        } else {
            BlitRect32_OpaqueWide_SSE2(destination, width, height,
                                       rowBytes, color);
        }
    } else {
        SkBlitRow::ColorRect32(destination, width, height, rowBytes, color);
    }
}
