From f444e8ccda8905a8ce16bac368e09f205786db31 Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Fri, 9 Mar 2012 19:59:46 +0000 Subject: [PATCH] don't flip the fractional bits (low 4) for bilerp when in kMirror_TileMode Review URL: https://codereview.appspot.com/5795043 git-svn-id: http://skia.googlecode.com/svn/trunk@3357 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/core/SkBitmapProcState.h | 3 +++ src/core/SkBitmapProcState_matrixProcs.cpp | 37 ++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h index 7556042..8d18526 100644 --- a/src/core/SkBitmapProcState.h +++ b/src/core/SkBitmapProcState.h @@ -55,6 +55,7 @@ struct SkBitmapProcState { uint16_t colors[]); typedef U16CPU (*FixedTileProc)(SkFixed); // returns 0..0xFFFF + typedef U16CPU (*FixedTileLowBitsProc)(SkFixed, int); // returns 0..0xF typedef U16CPU (*IntTileProc)(int value, int count); // returns 0..count-1 // If a shader proc is present, then the corresponding matrix/sample procs @@ -75,6 +76,8 @@ struct SkBitmapProcState { FixedTileProc fTileProcX; // chooseProcs FixedTileProc fTileProcY; // chooseProcs + FixedTileLowBitsProc fTileLowBitsProcX; // chooseProcs + FixedTileLowBitsProc fTileLowBitsProcY; // chooseProcs IntTileProc fIntTileProcY; // chooseProcs SkFixed fFilterOneX; SkFixed fFilterOneY; diff --git a/src/core/SkBitmapProcState_matrixProcs.cpp b/src/core/SkBitmapProcState_matrixProcs.cpp index bda2438..9a15ad2 100644 --- a/src/core/SkBitmapProcState_matrixProcs.cpp +++ b/src/core/SkBitmapProcState_matrixProcs.cpp @@ -56,15 +56,17 @@ void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); #define MAKENAME(suffix) GeneralXY ## suffix #define PREAMBLE(state) SkBitmapProcState::FixedTileProc tileProcX = (state).fTileProcX; \ - SkBitmapProcState::FixedTileProc tileProcY = (state).fTileProcY -#define PREAMBLE_PARAM_X , SkBitmapProcState::FixedTileProc tileProcX -#define PREAMBLE_PARAM_Y , SkBitmapProcState::FixedTileProc tileProcY -#define PREAMBLE_ARG_X , tileProcX -#define PREAMBLE_ARG_Y , tileProcY + SkBitmapProcState::FixedTileProc tileProcY = (state).fTileProcY; \ + SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcX = (state).fTileLowBitsProcX; \ + SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcY = (state).fTileLowBitsProcY +#define PREAMBLE_PARAM_X , SkBitmapProcState::FixedTileProc tileProcX, SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcX +#define PREAMBLE_PARAM_Y , SkBitmapProcState::FixedTileProc tileProcY, SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcY +#define PREAMBLE_ARG_X , tileProcX, tileLowBitsProcX +#define PREAMBLE_ARG_Y , tileProcY, tileLowBitsProcY #define TILEX_PROCF(fx, max) (tileProcX(fx) * ((max) + 1) >> 16) #define TILEY_PROCF(fy, max) (tileProcY(fy) * ((max) + 1) >> 16) -#define TILEX_LOW_BITS(fx, max) ((tileProcX(fx) * ((max) + 1) >> 12) & 0xF) -#define TILEY_LOW_BITS(fy, max) ((tileProcY(fy) * ((max) + 1) >> 12) & 0xF) +#define TILEX_LOW_BITS(fx, max) tileLowBitsProcX(fx, (max) + 1) +#define TILEY_LOW_BITS(fy, max) tileLowBitsProcY(fy, (max) + 1) #include "SkBitmapProcState_matrix.h" static inline U16CPU fixed_clamp(SkFixed x) @@ -108,6 +110,25 @@ static SkBitmapProcState::FixedTileProc choose_tile_proc(unsigned m) return fixed_mirror; } +static inline U16CPU fixed_clamp_lowbits(SkFixed x, int) { + return (x >> 12) & 0xF; +} + +static inline U16CPU fixed_repeat_or_mirrow_lowbits(SkFixed x, int scale) { + return ((x * scale) >> 12) & 0xF; +} + +static SkBitmapProcState::FixedTileLowBitsProc choose_tile_lowbits_proc(unsigned m) { + if (SkShader::kClamp_TileMode == m) { + return fixed_clamp_lowbits; + } else { + SkASSERT(SkShader::kMirror_TileMode == m || + SkShader::kRepeat_TileMode == m); + // mirror and repeat have the same behavior for the low bits. + return fixed_repeat_or_mirrow_lowbits; + } +} + static inline U16CPU int_clamp(int x, int n) { #ifdef SK_CPU_HAS_CONDITIONAL_INSTR if (x >= n) @@ -522,6 +543,8 @@ SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) { fTileProcX = choose_tile_proc(fTileModeX); fTileProcY = choose_tile_proc(fTileModeY); + fTileLowBitsProcX = choose_tile_lowbits_proc(fTileModeX); + fTileLowBitsProcY = choose_tile_lowbits_proc(fTileModeY); return GeneralXY_Procs[index]; } -- 2.7.4