LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkBitmapProcShader.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 156 2 1.3 %
Date: 2012-06-02 Functions: 18 2 11.1 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2011 Google Inc.
       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                 : #include "SkBitmapProcShader.h"
       9                 : #include "SkColorPriv.h"
      10                 : #include "SkPixelRef.h"
      11                 : 
      12               0 : bool SkBitmapProcShader::CanDo(const SkBitmap& bm, TileMode tx, TileMode ty) {
      13               0 :     switch (bm.config()) {
      14                 :         case SkBitmap::kA8_Config:
      15                 :         case SkBitmap::kRGB_565_Config:
      16                 :         case SkBitmap::kIndex8_Config:
      17                 :         case SkBitmap::kARGB_8888_Config:
      18                 :     //        if (tx == ty && (kClamp_TileMode == tx || kRepeat_TileMode == tx))
      19               0 :                 return true;
      20                 :         default:
      21                 :             break;
      22                 :     }
      23               0 :     return false;
      24                 : }
      25                 : 
      26               0 : SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src,
      27               0 :                                        TileMode tmx, TileMode tmy) {
      28               0 :     fRawBitmap = src;
      29               0 :     fState.fTileModeX = (uint8_t)tmx;
      30               0 :     fState.fTileModeY = (uint8_t)tmy;
      31               0 :     fFlags = 0; // computed in setContext
      32               0 : }
      33                 : 
      34               0 : SkBitmapProcShader::SkBitmapProcShader(SkFlattenableReadBuffer& buffer)
      35               0 :         : INHERITED(buffer) {
      36               0 :     fRawBitmap.unflatten(buffer);
      37               0 :     fState.fTileModeX = buffer.readU8();
      38               0 :     fState.fTileModeY = buffer.readU8();
      39               0 :     fFlags = 0; // computed in setContext
      40               0 : }
      41                 : 
      42               0 : void SkBitmapProcShader::beginSession() {
      43               0 :     this->INHERITED::beginSession();
      44                 : 
      45               0 :     fRawBitmap.lockPixels();
      46               0 : }
      47                 : 
      48               0 : void SkBitmapProcShader::endSession() {
      49               0 :     fRawBitmap.unlockPixels();
      50                 : 
      51               0 :     this->INHERITED::endSession();
      52               0 : }
      53                 : 
      54               0 : SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture,
      55                 :                                                    SkMatrix* texM,
      56                 :                                                    TileMode xy[],
      57                 :                                        SkScalar* twoPointRadialParams) const {
      58               0 :     if (texture) {
      59               0 :         *texture = fRawBitmap;
      60                 :     }
      61               0 :     if (texM) {
      62               0 :         texM->reset();
      63                 :     }
      64               0 :     if (xy) {
      65               0 :         xy[0] = (TileMode)fState.fTileModeX;
      66               0 :         xy[1] = (TileMode)fState.fTileModeY;
      67                 :     }
      68               0 :     return kDefault_BitmapType;
      69                 : }
      70                 : 
      71               0 : void SkBitmapProcShader::flatten(SkFlattenableWriteBuffer& buffer) {
      72               0 :     this->INHERITED::flatten(buffer);
      73                 : 
      74               0 :     fRawBitmap.flatten(buffer);
      75               0 :     buffer.write8(fState.fTileModeX);
      76               0 :     buffer.write8(fState.fTileModeY);
      77               0 : }
      78                 : 
      79               0 : static bool only_scale_and_translate(const SkMatrix& matrix) {
      80               0 :     unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
      81               0 :     return (matrix.getType() & ~mask) == 0;
      82                 : }
      83                 : 
      84               0 : bool SkBitmapProcShader::isOpaque() const {
      85               0 :     return fRawBitmap.isOpaque();
      86                 : }
      87                 : 
      88               0 : bool SkBitmapProcShader::setContext(const SkBitmap& device,
      89                 :                                     const SkPaint& paint,
      90                 :                                     const SkMatrix& matrix) {
      91                 :     // do this first, so we have a correct inverse matrix
      92               0 :     if (!this->INHERITED::setContext(device, paint, matrix)) {
      93               0 :         return false;
      94                 :     }
      95                 : 
      96               0 :     fState.fOrigBitmap = fRawBitmap;
      97               0 :     fState.fOrigBitmap.lockPixels();
      98               0 :     if (!fState.fOrigBitmap.getTexture() && !fState.fOrigBitmap.readyToDraw()) {
      99               0 :         fState.fOrigBitmap.unlockPixels();
     100               0 :         return false;
     101                 :     }
     102                 : 
     103               0 :     if (!fState.chooseProcs(this->getTotalInverse(), paint)) {
     104               0 :         return false;
     105                 :     }
     106                 : 
     107               0 :     const SkBitmap& bitmap = *fState.fBitmap;
     108               0 :     bool bitmapIsOpaque = bitmap.isOpaque();
     109                 : 
     110                 :     // update fFlags
     111               0 :     uint32_t flags = 0;
     112               0 :     if (bitmapIsOpaque && (255 == this->getPaintAlpha())) {
     113               0 :         flags |= kOpaqueAlpha_Flag;
     114                 :     }
     115                 : 
     116               0 :     switch (bitmap.config()) {
     117                 :         case SkBitmap::kRGB_565_Config:
     118               0 :             flags |= (kHasSpan16_Flag | kIntrinsicly16_Flag);
     119               0 :             break;
     120                 :         case SkBitmap::kIndex8_Config:
     121                 :         case SkBitmap::kARGB_8888_Config:
     122               0 :             if (bitmapIsOpaque) {
     123               0 :                 flags |= kHasSpan16_Flag;
     124                 :             }
     125               0 :             break;
     126                 :         case SkBitmap::kA8_Config:
     127               0 :             break;  // never set kHasSpan16_Flag
     128                 :         default:
     129               0 :             break;
     130                 :     }
     131                 : 
     132               0 :     if (paint.isDither() && bitmap.config() != SkBitmap::kRGB_565_Config) {
     133                 :         // gradients can auto-dither in their 16bit sampler, but we don't so
     134                 :         // we clear the flag here.
     135               0 :         flags &= ~kHasSpan16_Flag;
     136                 :     }
     137                 : 
     138                 :     // if we're only 1-pixel heigh, and we don't rotate, then we can claim this
     139               0 :     if (1 == bitmap.height() &&
     140               0 :             only_scale_and_translate(this->getTotalInverse())) {
     141               0 :         flags |= kConstInY32_Flag;
     142               0 :         if (flags & kHasSpan16_Flag) {
     143               0 :             flags |= kConstInY16_Flag;
     144                 :         }
     145                 :     }
     146                 : 
     147               0 :     fFlags = flags;
     148               0 :     return true;
     149                 : }
     150                 : 
     151                 : #define BUF_MAX     128
     152                 : 
     153                 : #define TEST_BUFFER_OVERRITEx
     154                 : 
     155                 : #ifdef TEST_BUFFER_OVERRITE
     156                 :     #define TEST_BUFFER_EXTRA   32
     157                 :     #define TEST_PATTERN    0x88888888
     158                 : #else
     159                 :     #define TEST_BUFFER_EXTRA   0
     160                 : #endif
     161                 : 
     162               0 : void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
     163               0 :     const SkBitmapProcState& state = fState;
     164               0 :     if (state.fShaderProc32) {
     165               0 :         state.fShaderProc32(state, x, y, dstC, count);
     166               0 :         return;
     167                 :     }
     168                 : 
     169                 :     uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA];
     170               0 :     SkBitmapProcState::MatrixProc   mproc = state.fMatrixProc;
     171               0 :     SkBitmapProcState::SampleProc32 sproc = state.fSampleProc32;
     172               0 :     int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
     173                 : 
     174               0 :     SkASSERT(state.fBitmap->getPixels());
     175               0 :     SkASSERT(state.fBitmap->pixelRef() == NULL ||
     176                 :              state.fBitmap->pixelRef()->getLockCount());
     177                 : 
     178               0 :     for (;;) {
     179               0 :         int n = count;
     180               0 :         if (n > max) {
     181               0 :             n = max;
     182                 :         }
     183               0 :         SkASSERT(n > 0 && n < BUF_MAX*2);
     184                 : #ifdef TEST_BUFFER_OVERRITE
     185                 :         for (int i = 0; i < TEST_BUFFER_EXTRA; i++) {
     186                 :             buffer[BUF_MAX + i] = TEST_PATTERN;
     187                 :         }
     188                 : #endif
     189               0 :         mproc(state, buffer, n, x, y);
     190                 : #ifdef TEST_BUFFER_OVERRITE
     191                 :         for (int j = 0; j < TEST_BUFFER_EXTRA; j++) {
     192                 :             SkASSERT(buffer[BUF_MAX + j] == TEST_PATTERN);
     193                 :         }
     194                 : #endif
     195               0 :         sproc(state, buffer, n, dstC);
     196                 : 
     197               0 :         if ((count -= n) == 0) {
     198               0 :             break;
     199                 :         }
     200               0 :         SkASSERT(count > 0);
     201               0 :         x += n;
     202               0 :         dstC += n;
     203                 :     }
     204                 : }
     205                 : 
     206               0 : void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) {
     207               0 :     const SkBitmapProcState& state = fState;
     208               0 :     if (state.fShaderProc16) {
     209               0 :         state.fShaderProc16(state, x, y, dstC, count);
     210               0 :         return;
     211                 :     }
     212                 : 
     213                 :     uint32_t buffer[BUF_MAX];
     214               0 :     SkBitmapProcState::MatrixProc   mproc = state.fMatrixProc;
     215               0 :     SkBitmapProcState::SampleProc16 sproc = state.fSampleProc16;
     216               0 :     int max = fState.maxCountForBufferSize(sizeof(buffer));
     217                 : 
     218               0 :     SkASSERT(state.fBitmap->getPixels());
     219               0 :     SkASSERT(state.fBitmap->pixelRef() == NULL ||
     220                 :              state.fBitmap->pixelRef()->getLockCount());
     221                 : 
     222               0 :     for (;;) {
     223               0 :         int n = count;
     224               0 :         if (n > max) {
     225               0 :             n = max;
     226                 :         }
     227               0 :         mproc(state, buffer, n, x, y);
     228               0 :         sproc(state, buffer, n, dstC);
     229                 : 
     230               0 :         if ((count -= n) == 0) {
     231               0 :             break;
     232                 :         }
     233               0 :         x += n;
     234               0 :         dstC += n;
     235                 :     }
     236                 : }
     237                 : 
     238                 : ///////////////////////////////////////////////////////////////////////////////
     239                 : 
     240                 : #include "SkUnPreMultiply.h"
     241                 : #include "SkColorShader.h"
     242                 : #include "SkEmptyShader.h"
     243                 : 
     244                 : // returns true and set color if the bitmap can be drawn as a single color
     245                 : // (for efficiency)
     246               0 : static bool canUseColorShader(const SkBitmap& bm, SkColor* color) {
     247               0 :     if (1 != bm.width() || 1 != bm.height()) {
     248               0 :         return false;
     249                 :     }
     250                 : 
     251               0 :     SkAutoLockPixels alp(bm);
     252               0 :     if (!bm.readyToDraw()) {
     253               0 :         return false;
     254                 :     }
     255                 : 
     256               0 :     switch (bm.config()) {
     257                 :         case SkBitmap::kARGB_8888_Config:
     258               0 :             *color = SkUnPreMultiply::PMColorToColor(*bm.getAddr32(0, 0));
     259               0 :             return true;
     260                 :         case SkBitmap::kRGB_565_Config:
     261               0 :             *color = SkPixel16ToColor(*bm.getAddr16(0, 0));
     262               0 :             return true;
     263                 :         case SkBitmap::kIndex8_Config:
     264               0 :             *color = SkUnPreMultiply::PMColorToColor(bm.getIndex8Color(0, 0));
     265               0 :             return true;
     266                 :         default: // just skip the other configs for now
     267                 :             break;
     268                 :     }
     269               0 :     return false;
     270                 : }
     271                 : 
     272                 : #include "SkTemplatesPriv.h"
     273                 : 
     274               0 : SkShader* SkShader::CreateBitmapShader(const SkBitmap& src,
     275                 :                                        TileMode tmx, TileMode tmy,
     276                 :                                        void* storage, size_t storageSize) {
     277                 :     SkShader* shader;
     278                 :     SkColor color;
     279               0 :     if (src.isNull()) {
     280               0 :         SK_PLACEMENT_NEW(shader, SkEmptyShader, storage, storageSize);
     281                 :     }
     282               0 :     else if (canUseColorShader(src, &color)) {
     283               0 :         SK_PLACEMENT_NEW_ARGS(shader, SkColorShader, storage, storageSize,
     284                 :                               (color));
     285                 :     } else {
     286               0 :         SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage,
     287                 :                               storageSize, (src, tmx, tmy));
     288                 :     }
     289               0 :     return shader;
     290                 : }
     291                 : 
     292            1464 : SK_DEFINE_FLATTENABLE_REGISTRAR(SkBitmapProcShader)
     293                 : 
     294                 : ///////////////////////////////////////////////////////////////////////////////
     295                 : 
     296                 : static const char* gTileModeName[] = {
     297                 :     "clamp", "repeat", "mirror"
     298                 : };
     299                 : 
     300               0 : bool SkBitmapProcShader::toDumpString(SkString* str) const {
     301                 :     str->printf("BitmapShader: [%d %d %d",
     302                 :                 fRawBitmap.width(), fRawBitmap.height(),
     303               0 :                 fRawBitmap.bytesPerPixel());
     304                 : 
     305                 :     // add the pixelref
     306               0 :     SkPixelRef* pr = fRawBitmap.pixelRef();
     307               0 :     if (pr) {
     308               0 :         const char* uri = pr->getURI();
     309               0 :         if (uri) {
     310               0 :             str->appendf(" \"%s\"", uri);
     311                 :         }
     312                 :     }
     313                 : 
     314                 :     // add the (optional) matrix
     315                 :     {
     316                 :         SkMatrix m;
     317               0 :         if (this->getLocalMatrix(&m)) {
     318               0 :             SkString info;
     319               0 :             m.toDumpString(&info);
     320               0 :             str->appendf(" %s", info.c_str());
     321                 :         }
     322                 :     }
     323                 : 
     324                 :     str->appendf(" [%s %s]]",
     325                 :                  gTileModeName[fState.fTileModeX],
     326               0 :                  gTileModeName[fState.fTileModeY]);
     327               0 :     return true;
     328            4392 : }
     329                 : 

Generated by: LCOV version 1.7