LCOV - app.info - gfx/skia/src/core/SkBitmapProcShader.cpp

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-07-07 | 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