Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 
     11 #ifndef NOFILTER_BITMAP_SHADER_PREAMBLE
     12     #define NOFILTER_BITMAP_SHADER_PREAMBLE(bitmap, rb)
     13 #endif
     14 #ifndef NOFILTER_BITMAP_SHADER_POSTAMBLE
     15     #define NOFILTER_BITMAP_SHADER_POSTAMBLE(bitmap)
     16 #endif
     17 #ifndef NOFILTER_BITMAP_SHADER_PREAMBLE16
     18     #define NOFILTER_BITMAP_SHADER_PREAMBLE16(bitmap, rb)
     19 #endif
     20 #ifndef NOFILTER_BITMAP_SHADER_POSTAMBLE16
     21     #define NOFILTER_BITMAP_SHADER_POSTAMBLE16(bitmap)
     22 #endif
     23 
     24 class NOFILTER_BITMAP_SHADER_CLASS : public HasSpan16_Sampler_BitmapShader {
     25 public:
     26     NOFILTER_BITMAP_SHADER_CLASS(const SkBitmap& src)
     27         : HasSpan16_Sampler_BitmapShader(src, false,
     28                                          NOFILTER_BITMAP_SHADER_TILEMODE,
     29                                          NOFILTER_BITMAP_SHADER_TILEMODE)
     30     {
     31     }
     32 
     33     virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix)
     34     {
     35         if (!this->INHERITED::setContext(device, paint, matrix))
     36             return false;
     37 
     38 #ifdef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
     39         this->computeUnitInverse();
     40 #endif
     41         return true;
     42     }
     43 
     44     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count)
     45     {
     46         SkASSERT(count > 0);
     47 
     48 #ifdef NOFILTER_BITMAP_SHADER_SPRITEPROC32
     49         if ((this->getTotalInverse().getType() & ~SkMatrix::kTranslate_Mask) == 0)
     50         {
     51             NOFILTER_BITMAP_SHADER_SPRITEPROC32(this, x, y, dstC, count);
     52             return;
     53         }
     54 #endif
     55 
     56         unsigned        scale = SkAlpha255To256(this->getPaintAlpha());
     57 #ifdef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
     58         const SkMatrix& inv = this->getUnitInverse();
     59         SkMatrix::MapPtProc invProc = this->getUnitInverseProc();
     60 #else
     61         const SkMatrix& inv = this->getTotalInverse();
     62         SkMatrix::MapPtProc invProc = this->getInverseMapPtProc();
     63 #endif
     64         const SkBitmap& srcBitmap = this->getSrcBitmap();
     65         unsigned        srcMaxX = srcBitmap.width() - 1;
     66         unsigned        srcMaxY = srcBitmap.height() - 1;
     67         unsigned        srcRB = srcBitmap.rowBytes();
     68         SkFixed         fx, fy, dx, dy;
     69 
     70         const NOFILTER_BITMAP_SHADER_TYPE* srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)srcBitmap.getPixels();
     71         NOFILTER_BITMAP_SHADER_PREAMBLE(srcBitmap, srcRB);
     72 
     73         if (this->getInverseClass() == kPerspective_MatrixClass)
     74         {
     75             SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
     76                                     SkIntToScalar(y) + SK_ScalarHalf, count);
     77             while ((count = iter.next()) != 0)
     78             {
     79                 const SkFixed* srcXY = iter.getXY();
     80 
     81 /*  Do I need this?
     82 #ifndef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
     83             fx >>= level;
     84             fy >>= level;
     85 #endif
     86 */
     87                 if (256 == scale)
     88                 {
     89                     while (--count >= 0)
     90                     {
     91                         fx = *srcXY++;
     92                         fy = *srcXY++;
     93                         unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
     94                         unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
     95                         *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB);
     96                     }
     97                 }
     98                 else
     99                 {
    100                     while (--count >= 0)
    101                     {
    102                         fx = *srcXY++;
    103                         fy = *srcXY++;
    104                         unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
    105                         unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
    106                         uint32_t c = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB);
    107                         *dstC++ = SkAlphaMulQ(c, scale);
    108                     }
    109                 }
    110             }
    111             return;
    112         }
    113 
    114         // now init fx, fy, dx, dy
    115         {
    116             SkPoint srcPt;
    117             invProc(inv, SkIntToScalar(x) + SK_ScalarHalf,
    118                          SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
    119 
    120             fx = SkScalarToFixed(srcPt.fX);
    121             fy = SkScalarToFixed(srcPt.fY);
    122 
    123             if (this->getInverseClass() == kFixedStepInX_MatrixClass)
    124                 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
    125             else
    126             {
    127                 dx = SkScalarToFixed(inv.getScaleX());
    128                 dy = SkScalarToFixed(inv.getSkewY());
    129             }
    130         }
    131 
    132 #ifndef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
    133         {   int level = this->getMipLevel() >> 16;
    134             fx >>= level;
    135             fy >>= level;
    136             dx >>= level;
    137             dy >>= level;
    138         }
    139 #endif
    140 
    141         if (dy == 0)
    142         {
    143             int y_index = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
    144 //          SkDEBUGF(("fy = %g, srcMaxY = %d, y_index = %d\n", SkFixedToFloat(fy), srcMaxY, y_index));
    145             srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)((const char*)srcPixels + y_index * srcRB);
    146             if (scale == 256)
    147                 while (--count >= 0)
    148                 {
    149                     unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
    150                     fx += dx;
    151                     *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_X(srcPixels, x);
    152                 }
    153             else
    154                 while (--count >= 0)
    155                 {
    156                     unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
    157                     SkPMColor c = NOFILTER_BITMAP_SHADER_SAMPLE_X(srcPixels, x);
    158                     fx += dx;
    159                     *dstC++ = SkAlphaMulQ(c, scale);
    160                 }
    161         }
    162         else    // dy != 0
    163         {
    164             if (scale == 256)
    165                 while (--count >= 0)
    166                 {
    167                     unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
    168                     unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
    169                     fx += dx;
    170                     fy += dy;
    171                     *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB);
    172                 }
    173             else
    174                 while (--count >= 0)
    175                 {
    176                     unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
    177                     unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
    178                     SkPMColor c = NOFILTER_BITMAP_SHADER_SAMPLE_XY(srcPixels, x, y, srcRB);
    179                     fx += dx;
    180                     fy += dy;
    181                     *dstC++ = SkAlphaMulQ(c, scale);
    182                 }
    183         }
    184 
    185         NOFILTER_BITMAP_SHADER_POSTAMBLE(srcBitmap);
    186     }
    187 
    188     virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count)
    189     {
    190         SkASSERT(count > 0);
    191         SkASSERT(this->getFlags() & SkShader::kHasSpan16_Flag);
    192 
    193 #ifdef NOFILTER_BITMAP_SHADER_SPRITEPROC16
    194         if ((this->getTotalInverse().getType() & ~SkMatrix::kTranslate_Mask) == 0)
    195         {
    196             NOFILTER_BITMAP_SHADER_SPRITEPROC16(this, x, y, dstC, count);
    197             return;
    198         }
    199 #endif
    200 
    201 #ifdef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
    202         const SkMatrix& inv = this->getUnitInverse();
    203         SkMatrix::MapPtProc invProc = this->getUnitInverseProc();
    204 #else
    205         const SkMatrix& inv = this->getTotalInverse();
    206         SkMatrix::MapPtProc invProc = this->getInverseMapPtProc();
    207 #endif
    208         const SkBitmap& srcBitmap = this->getSrcBitmap();
    209         unsigned        srcMaxX = srcBitmap.width() - 1;
    210         unsigned        srcMaxY = srcBitmap.height() - 1;
    211         unsigned        srcRB = srcBitmap.rowBytes();
    212         SkFixed         fx, fy, dx, dy;
    213 
    214         const NOFILTER_BITMAP_SHADER_TYPE* srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)srcBitmap.getPixels();
    215         NOFILTER_BITMAP_SHADER_PREAMBLE16(srcBitmap, srcRB);
    216 
    217         if (this->getInverseClass() == kPerspective_MatrixClass)
    218         {
    219             SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
    220                                     SkIntToScalar(y) + SK_ScalarHalf, count);
    221             while ((count = iter.next()) != 0)
    222             {
    223                 const SkFixed* srcXY = iter.getXY();
    224 
    225                 while (--count >= 0)
    226                 {
    227                     fx = *srcXY++;
    228                     fy = *srcXY++;
    229                     unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
    230                     unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
    231                     *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY16(srcPixels, x, y, srcRB);
    232                 }
    233             }
    234             return;
    235         }
    236 
    237         // now init fx, fy, dx, dy
    238         {
    239             SkPoint srcPt;
    240             invProc(inv, SkIntToScalar(x) + SK_ScalarHalf,
    241                          SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
    242 
    243             fx = SkScalarToFixed(srcPt.fX);
    244             fy = SkScalarToFixed(srcPt.fY);
    245 
    246             if (this->getInverseClass() == kFixedStepInX_MatrixClass)
    247                 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
    248             else
    249             {
    250                 dx = SkScalarToFixed(inv.getScaleX());
    251                 dy = SkScalarToFixed(inv.getSkewY());
    252             }
    253         }
    254 
    255 #ifndef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
    256         {   int level = this->getMipLevel() >> 16;
    257             fx >>= level;
    258             fy >>= level;
    259             dx >>= level;
    260             dy >>= level;
    261         }
    262 #endif
    263 
    264         if (dy == 0)
    265         {
    266             srcPixels = (const NOFILTER_BITMAP_SHADER_TYPE*)((const char*)srcPixels + NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY) * srcRB);
    267             do {
    268                 unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
    269                 fx += dx;
    270                 *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_X16(srcPixels, x);
    271             } while (--count != 0);
    272         }
    273         else    // dy != 0
    274         {
    275             do {
    276                 unsigned x = NOFILTER_BITMAP_SHADER_TILEPROC(fx, srcMaxX);
    277                 unsigned y = NOFILTER_BITMAP_SHADER_TILEPROC(fy, srcMaxY);
    278                 fx += dx;
    279                 fy += dy;
    280                 *dstC++ = NOFILTER_BITMAP_SHADER_SAMPLE_XY16(srcPixels, x, y, srcRB);
    281             } while (--count != 0);
    282         }
    283 
    284         NOFILTER_BITMAP_SHADER_POSTAMBLE16(srcBitmap);
    285     }
    286 private:
    287     typedef HasSpan16_Sampler_BitmapShader INHERITED;
    288 };
    289 
    290 #undef NOFILTER_BITMAP_SHADER_CLASS
    291 #undef NOFILTER_BITMAP_SHADER_TYPE
    292 #undef NOFILTER_BITMAP_SHADER_PREAMBLE
    293 #undef NOFILTER_BITMAP_SHADER_POSTAMBLE
    294 #undef NOFILTER_BITMAP_SHADER_SAMPLE_X      //(x)
    295 #undef NOFILTER_BITMAP_SHADER_SAMPLE_XY     //(x, y, rowBytes)
    296 #undef NOFILTER_BITMAP_SHADER_TILEMODE
    297 #undef NOFILTER_BITMAP_SHADER_TILEPROC
    298 
    299 #undef NOFILTER_BITMAP_SHADER_PREAMBLE16
    300 #undef NOFILTER_BITMAP_SHADER_POSTAMBLE16
    301 #undef NOFILTER_BITMAP_SHADER_SAMPLE_X16        //(x)
    302 #undef NOFILTER_BITMAP_SHADER_SAMPLE_XY16       //(x, y, rowBytes)
    303 
    304 #undef NOFILTER_BITMAP_SHADER_USE_UNITINVERSE
    305 #undef NOFILTER_BITMAP_SHADER_SPRITEPROC16
    306 #undef NOFILTER_BITMAP_SHADER_SPRITEPROC32
    307