Home | History | Annotate | Download | only in core
      1 /* libs/graphics/sgl/SkBitmapShader16BilerpTemplate.h
      2 **
      3 ** Copyright 2006, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 #include "SkFilterProc.h"
     19 
     20 class BILERP_BITMAP16_SHADER_CLASS : public HasSpan16_Sampler_BitmapShader {
     21 public:
     22     BILERP_BITMAP16_SHADER_CLASS(const SkBitmap& src)
     23         : HasSpan16_Sampler_BitmapShader(src, true,
     24                                          SkShader::kClamp_TileMode,
     25                                          SkShader::kClamp_TileMode)
     26     {
     27     }
     28 
     29     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count)
     30     {
     31         SkASSERT(count > 0);
     32 
     33         U8CPU alpha = this->getPaintAlpha();
     34 
     35         const SkMatrix& inv = this->getTotalInverse();
     36         const SkBitmap& srcBitmap = this->getSrcBitmap();
     37         unsigned        srcMaxX = srcBitmap.width() - 1;
     38         unsigned        srcMaxY = srcBitmap.height() - 1;
     39         unsigned        srcRB = srcBitmap.rowBytes();
     40 
     41         BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap);
     42 
     43         const SkFilterProc* proc_table = SkGetBilinearFilterProcTable();
     44         const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels();
     45 
     46         if (this->getInverseClass() == kPerspective_MatrixClass)
     47         {
     48             SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
     49                                     SkIntToScalar(y) + SK_ScalarHalf, count);
     50             while ((count = iter.next()) != 0)
     51             {
     52                 const SkFixed* srcXY = iter.getXY();
     53                 while (--count >= 0)
     54                 {
     55                     SkFixed fx = *srcXY++ - SK_FixedHalf;
     56                     SkFixed fy = *srcXY++ - SK_FixedHalf;
     57                     int ix = fx >> 16;
     58                     int iy = fy >> 16;
     59                     int x = SkClampMax(ix, srcMaxX);
     60                     int y = SkClampMax(iy, srcMaxY);
     61 
     62                     const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
     63 
     64                     p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + y * srcRB)) + x;
     65                     if ((unsigned)ix < srcMaxX)
     66                         p01 += 1;
     67                     p10 = p00;
     68                     p11 = p01;
     69                     if ((unsigned)iy < srcMaxY)
     70                     {
     71                         p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
     72                         p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
     73                     }
     74 
     75                     SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
     76                     uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
     77                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
     78                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
     79                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
     80 
     81                     *dstC++ = expanded_rgb16_to_8888(c, alpha);
     82                 }
     83             }
     84         }
     85         else    // linear case
     86         {
     87             SkFixed fx, fy, dx, dy;
     88 
     89             // now init fx, fy, dx, dy
     90             {
     91                 SkPoint srcPt;
     92                 this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
     93                                                  SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
     94 
     95                 fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
     96                 fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
     97 
     98                 if (this->getInverseClass() == kFixedStepInX_MatrixClass)
     99                     (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
    100                 else
    101                 {
    102                     dx = SkScalarToFixed(inv.getScaleX());
    103                     dy = SkScalarToFixed(inv.getSkewY());
    104                 }
    105             }
    106 
    107             do {
    108                 int ix = fx >> 16;
    109                 int iy = fy >> 16;
    110 
    111                 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
    112 
    113                 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
    114                                                                    SkClampMax(iy, srcMaxY) * srcRB)) +
    115                                                                    SkClampMax(ix, srcMaxX);
    116                 if ((unsigned)ix < srcMaxX)
    117                     p01 += 1;
    118                 p10 = p00;
    119                 p11 = p01;
    120                 if ((unsigned)iy < srcMaxY)
    121                 {
    122                     p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
    123                     p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
    124                 }
    125 
    126                 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
    127                 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
    128                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
    129                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
    130                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
    131                 *dstC++ = expanded_rgb16_to_8888(c, alpha);
    132 
    133                 fx += dx;
    134                 fy += dy;
    135             } while (--count != 0);
    136         }
    137         BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap);
    138     }
    139 
    140     virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count)
    141     {
    142         SkASSERT(count > 0);
    143 
    144         const SkMatrix& inv = this->getTotalInverse();
    145         const SkBitmap& srcBitmap = this->getSrcBitmap();
    146         unsigned        srcMaxX = srcBitmap.width() - 1;
    147         unsigned        srcMaxY = srcBitmap.height() - 1;
    148         unsigned        srcRB = srcBitmap.rowBytes();
    149 
    150         BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap);
    151 
    152         const SkFilterProc* proc_table = SkGetBilinearFilterProcTable();
    153         const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels();
    154 
    155         if (this->getInverseClass() == kPerspective_MatrixClass)
    156         {
    157             SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
    158                                     SkIntToScalar(y) + SK_ScalarHalf, count);
    159             while ((count = iter.next()) != 0)
    160             {
    161                 const SkFixed* srcXY = iter.getXY();
    162                 while (--count >= 0)
    163                 {
    164                     SkFixed fx = *srcXY++ - SK_FixedHalf;
    165                     SkFixed fy = *srcXY++ - SK_FixedHalf;
    166                     int ix = fx >> 16;
    167                     int iy = fy >> 16;
    168 
    169                     const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
    170 
    171                     p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
    172                                                                       SkClampMax(iy, srcMaxY) * srcRB)) +
    173                                                                       SkClampMax(ix, srcMaxX);
    174                     if ((unsigned)ix < srcMaxX)
    175                         p01 += 1;
    176                     p10 = p00;
    177                     p11 = p01;
    178                     if ((unsigned)iy < srcMaxY)
    179                     {
    180                         p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
    181                         p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
    182                     }
    183 
    184                     SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
    185                     uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
    186                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
    187                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
    188                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
    189                     *dstC++ = SkCompact_rgb_16(c);
    190                 }
    191             }
    192         }
    193         else    // linear case
    194         {
    195             SkFixed fx, fy, dx, dy;
    196 
    197             // now init fx, fy, dx, dy
    198             {
    199                 SkPoint srcPt;
    200                 this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
    201                                                  SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
    202 
    203                 fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
    204                 fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
    205 
    206                 if (this->getInverseClass() == kFixedStepInX_MatrixClass)
    207                     (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
    208                 else
    209                 {
    210                     dx = SkScalarToFixed(inv.getScaleX());
    211                     dy = SkScalarToFixed(inv.getSkewY());
    212                 }
    213             }
    214 
    215             do {
    216                 int ix = fx >> 16;
    217                 int iy = fy >> 16;
    218 
    219                 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
    220 
    221                 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
    222                                                                   SkClampMax(iy, srcMaxY) * srcRB)) +
    223                                                                   SkClampMax(ix, srcMaxX);
    224                 if ((unsigned)ix < srcMaxX)
    225                     p01 += 1;
    226                 p10 = p00;
    227                 p11 = p01;
    228                 if ((unsigned)iy < srcMaxY)
    229                 {
    230                     p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
    231                     p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
    232                 }
    233 
    234                 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
    235                 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
    236                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
    237                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
    238                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
    239                 *dstC++ = SkCompact_rgb_16(c);
    240 
    241                 fx += dx;
    242                 fy += dy;
    243             } while (--count != 0);
    244         }
    245         BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap);
    246     }
    247 };
    248 
    249 #undef BILERP_BITMAP16_SHADER_CLASS
    250 #undef BILERP_BITMAP16_SHADER_TYPE
    251 #undef BILERP_BITMAP16_SHADER_PREAMBLE
    252 #undef BILERP_BITMAP16_SHADER_PIXEL
    253 #undef BILERP_BITMAP16_SHADER_POSTAMBLE
    254