blob: 2f5128cc0f4ed89e9453155491597789a9f3175e [file] [log] [blame]
/*
* 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 "SkUtils.h"
// declare functions externally to suppress warnings.
void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s,
const uint32_t* SK_RESTRICT xy,
int count, SkPMColor* SK_RESTRICT colors);
void MAKENAME(_filter_DX)(const SkBitmapProcState& s,
const uint32_t* SK_RESTRICT xy,
int count, SkPMColor* SK_RESTRICT colors);
void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s,
const uint32_t* SK_RESTRICT xy,
int count, SkPMColor* SK_RESTRICT colors) {
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
SkASSERT(kNone_SkFilterQuality == s.fFilterQuality);
SkDEBUGCODE(CHECKSTATE(s);)
#ifdef PREAMBLE
PREAMBLE(s);
#endif
const SRCTYPE* SK_RESTRICT srcAddr = (const SRCTYPE*)s.fPixmap.addr();
// buffer is y32, x16, x16, x16, x16, x16
// bump srcAddr to the proper row, since we're told Y never changes
SkASSERT((unsigned)xy[0] < (unsigned)s.fPixmap.height());
srcAddr = (const SRCTYPE*)((const char*)srcAddr +
xy[0] * s.fPixmap.rowBytes());
xy += 1;
SRCTYPE src;
if (1 == s.fPixmap.width()) {
src = srcAddr[0];
SkPMColor dstValue = RETURNDST(src);
sk_memset32(colors, dstValue, count);
} else {
int i;
for (i = (count >> 2); i > 0; --i) {
uint32_t xx0 = *xy++;
uint32_t xx1 = *xy++;
SRCTYPE x0 = srcAddr[UNPACK_PRIMARY_SHORT(xx0)];
SRCTYPE x1 = srcAddr[UNPACK_SECONDARY_SHORT(xx0)];
SRCTYPE x2 = srcAddr[UNPACK_PRIMARY_SHORT(xx1)];
SRCTYPE x3 = srcAddr[UNPACK_SECONDARY_SHORT(xx1)];
*colors++ = RETURNDST(x0);
*colors++ = RETURNDST(x1);
*colors++ = RETURNDST(x2);
*colors++ = RETURNDST(x3);
}
const uint16_t* SK_RESTRICT xx = (const uint16_t*)(xy);
for (i = (count & 3); i > 0; --i) {
SkASSERT(*xx < (unsigned)s.fPixmap.width());
src = srcAddr[*xx++]; *colors++ = RETURNDST(src);
}
}
#ifdef POSTAMBLE
POSTAMBLE(s);
#endif
}
///////////////////////////////////////////////////////////////////////////////
void MAKENAME(_filter_DX)(const SkBitmapProcState& s,
const uint32_t* SK_RESTRICT xy,
int count, SkPMColor* SK_RESTRICT colors) {
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(s.fFilterQuality != kNone_SkFilterQuality);
SkDEBUGCODE(CHECKSTATE(s);)
#ifdef PREAMBLE
PREAMBLE(s);
#endif
const char* SK_RESTRICT srcAddr = (const char*)s.fPixmap.addr();
size_t rb = s.fPixmap.rowBytes();
unsigned subY;
const SRCTYPE* SK_RESTRICT row0;
const SRCTYPE* SK_RESTRICT row1;
// setup row ptrs and update proc_table
{
uint32_t XY = *xy++;
unsigned y0 = XY >> 14;
row0 = (const SRCTYPE*)(srcAddr + (y0 >> 4) * rb);
row1 = (const SRCTYPE*)(srcAddr + (XY & 0x3FFF) * rb);
subY = y0 & 0xF;
}
do {
uint32_t XX = *xy++; // x0:14 | 4 | x1:14
unsigned x0 = XX >> 14;
unsigned x1 = XX & 0x3FFF;
unsigned subX = x0 & 0xF;
x0 >>= 4;
FILTER_PROC(subX, subY,
SRC_TO_FILTER(row0[x0]),
SRC_TO_FILTER(row0[x1]),
SRC_TO_FILTER(row1[x0]),
SRC_TO_FILTER(row1[x1]),
colors);
colors += 1;
} while (--count != 0);
#ifdef POSTAMBLE
POSTAMBLE(s);
#endif
}
#undef MAKENAME
#undef SRCTYPE
#undef CHECKSTATE
#undef RETURNDST
#undef SRC_TO_FILTER
#undef FILTER_TO_DST
#ifdef PREAMBLE
#undef PREAMBLE
#endif
#ifdef POSTAMBLE
#undef POSTAMBLE
#endif
#undef FILTER_PROC_TYPE
#undef GET_FILTER_TABLE
#undef GET_FILTER_ROW
#undef GET_FILTER_ROW_PROC
#undef GET_FILTER_PROC