SkBitmapProcState_matrix_template.h revision 3e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577
1d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com/* 2d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com * Copyright 2013 Google Inc. 3d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com * 4d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com * Use of this source code is governed by a BSD-style license that can be 5d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com * found in the LICENSE file. 6d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com */ 7d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 8d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#ifndef SkBitmapProcState_MatrixTemplates_DEFINED 9d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#define SkBitmapProcState_MatrixTemplates_DEFINED 10d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 11d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#include "SkMath.h" 12d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#include "SkMathPriv.h" 13d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 14d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comtemplate <typename TileProc, bool tryDecal> 15d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comvoid NoFilterProc_Scale(const SkBitmapProcState& s, uint32_t xy[], 16d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com int count, int x, int y) { 17d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 18d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkMatrix::kScale_Mask)) == 0); 19d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 20d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com // we store y, x, x, x, x, x 21d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 22ad7ae6c821c530dd6cb54b0e8931ba8b10e8d87dreed const unsigned maxX = s.fPixmap.width() - 1; 23d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkFractionalInt fx; 24d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com { 253e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita SkPoint pt; 263e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 273e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita SkIntToScalar(y) + SK_ScalarHalf, &pt); 283e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita fx = SkScalarToFractionalInt(pt.fY); 29ad7ae6c821c530dd6cb54b0e8931ba8b10e8d87dreed const unsigned maxY = s.fPixmap.height() - 1; 303e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita *xy++ = TileProc::Y(s, SkFractionalIntToFixed(fx), maxY); 313e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita fx = SkScalarToFractionalInt(pt.fX); 32d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 33d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 34d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com if (0 == maxX) { 35d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com // all of the following X values must be 0 36d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com memset(xy, 0, count * sizeof(uint16_t)); 37d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com return; 38d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 39d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 40d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com const SkFractionalInt dx = s.fInvSxFractionalInt; 41d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 42d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com if (tryDecal && can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) { 43d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com decal_nofilter_scale(xy, SkFractionalIntToFixed(fx), 44d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkFractionalIntToFixed(dx), count); 45d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } else { 46d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com int i; 47d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com for (i = (count >> 2); i > 0; --i) { 48d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com unsigned a, b; 49d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx; 50d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx; 51d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#ifdef SK_CPU_BENDIAN 52d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com *xy++ = (a << 16) | b; 53d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#else 54d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com *xy++ = (b << 16) | a; 55d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#endif 56d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx; 57d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx; 58d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#ifdef SK_CPU_BENDIAN 59d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com *xy++ = (a << 16) | b; 60d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#else 61d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com *xy++ = (b << 16) | a; 62d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#endif 63d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 64d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com uint16_t* xx = (uint16_t*)xy; 65d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com for (i = (count & 3); i > 0; --i) { 66d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com *xx++ = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx; 67d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 68d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 69d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com} 70d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 71d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com// note: we could special-case on a matrix which is skewed in X but not Y. 72d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com// this would require a more general setup thatn SCALE does, but could use 73d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com// SCALE's inner loop that only looks at dx 74d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 75d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comtemplate <typename TileProc> 76d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comvoid NoFilterProc_Affine(const SkBitmapProcState& s, uint32_t xy[], 77d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com int count, int x, int y) { 78d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); 79d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 80d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkMatrix::kScale_Mask | 81d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkMatrix::kAffine_Mask)) == 0); 82d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 833e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita SkPoint srcPt; 843e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita s.fInvProc(s.fInvMatrix, 853e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita SkIntToScalar(x) + SK_ScalarHalf, 863e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita SkIntToScalar(y) + SK_ScalarHalf, &srcPt); 873e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita 883e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita SkFractionalInt fx = SkScalarToFractionalInt(srcPt.fX); 893e6be16e6d4dda6a27f0e1dbfe7c87fecfbf5577fmalita SkFractionalInt fy = SkScalarToFractionalInt(srcPt.fY); 90d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkFractionalInt dx = s.fInvSxFractionalInt; 91d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkFractionalInt dy = s.fInvKyFractionalInt; 92ad7ae6c821c530dd6cb54b0e8931ba8b10e8d87dreed int maxX = s.fPixmap.width() - 1; 93ad7ae6c821c530dd6cb54b0e8931ba8b10e8d87dreed int maxY = s.fPixmap.height() - 1; 94d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 95d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com for (int i = count; i > 0; --i) { 96d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com *xy++ = (TileProc::Y(s, SkFractionalIntToFixed(fy), maxY) << 16) | 97d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com TileProc::X(s, SkFractionalIntToFixed(fx), maxX); 98d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com fx += dx; fy += dy; 99d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 100d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com} 101d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 102d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comtemplate <typename TileProc> 103d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comvoid NoFilterProc_Persp(const SkBitmapProcState& s, uint32_t* SK_RESTRICT xy, 104d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com int count, int x, int y) { 105d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); 106d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 107ad7ae6c821c530dd6cb54b0e8931ba8b10e8d87dreed int maxX = s.fPixmap.width() - 1; 108ad7ae6c821c530dd6cb54b0e8931ba8b10e8d87dreed int maxY = s.fPixmap.height() - 1; 109d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 110d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkPerspIter iter(s.fInvMatrix, 111d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkIntToScalar(x) + SK_ScalarHalf, 112d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com SkIntToScalar(y) + SK_ScalarHalf, count); 113d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 114d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com while ((count = iter.next()) != 0) { 115d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com const SkFixed* SK_RESTRICT srcXY = iter.getXY(); 116d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com while (--count >= 0) { 117d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com *xy++ = (TileProc::Y(s, srcXY[1], maxY) << 16) | 118d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com TileProc::X(s, srcXY[0], maxX); 119d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com srcXY += 2; 120d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 121d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 122d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com} 123d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 124d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#endif 125