SkBitmapProcShader.cpp revision b630785db28d3dbd2ef9fa2b15eb7aea0def82e8
1#include "SkBitmapProcShader.h" 2#include "SkColorPriv.h" 3#include "SkPixelRef.h" 4 5bool SkBitmapProcShader::CanDo(const SkBitmap& bm, TileMode tx, TileMode ty) { 6 switch (bm.config()) { 7 case SkBitmap::kA8_Config: 8 case SkBitmap::kRGB_565_Config: 9 case SkBitmap::kIndex8_Config: 10 case SkBitmap::kARGB_8888_Config: 11 // if (tx == ty && (kClamp_TileMode == tx || kRepeat_TileMode == tx)) 12 return true; 13 default: 14 break; 15 } 16 return false; 17} 18 19SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, 20 TileMode tmx, TileMode tmy) { 21 fRawBitmap = src; 22 fState.fTileModeX = (uint8_t)tmx; 23 fState.fTileModeY = (uint8_t)tmy; 24 fFlags = 0; // computed in setContext 25} 26 27SkBitmapProcShader::SkBitmapProcShader(SkFlattenableReadBuffer& buffer) 28 : INHERITED(buffer) { 29 fRawBitmap.unflatten(buffer); 30 fState.fTileModeX = buffer.readU8(); 31 fState.fTileModeY = buffer.readU8(); 32 fFlags = 0; // computed in setContext 33} 34 35void SkBitmapProcShader::beginSession() { 36 this->INHERITED::beginSession(); 37 38 fRawBitmap.lockPixels(); 39} 40 41void SkBitmapProcShader::endSession() { 42 fRawBitmap.unlockPixels(); 43 44 this->INHERITED::endSession(); 45} 46 47bool SkBitmapProcShader::asABitmap(SkBitmap* texture, SkMatrix* texM, 48 TileMode xy[]) { 49 if (texture) { 50 *texture = fRawBitmap; 51 } 52 if (texM) { 53 texM->reset(); 54 } 55 if (xy) { 56 xy[0] = (TileMode)fState.fTileModeX; 57 xy[1] = (TileMode)fState.fTileModeY; 58 } 59 return true; 60} 61 62void SkBitmapProcShader::flatten(SkFlattenableWriteBuffer& buffer) { 63 this->INHERITED::flatten(buffer); 64 65 fRawBitmap.flatten(buffer); 66 buffer.write8(fState.fTileModeX); 67 buffer.write8(fState.fTileModeY); 68} 69 70bool SkBitmapProcShader::setContext(const SkBitmap& device, 71 const SkPaint& paint, 72 const SkMatrix& matrix) { 73 // do this first, so we have a correct inverse matrix 74 if (!this->INHERITED::setContext(device, paint, matrix)) { 75 return false; 76 } 77 78 fState.fOrigBitmap = fRawBitmap; 79 fState.fOrigBitmap.lockPixels(); 80 if (fState.fOrigBitmap.getPixels() == NULL) { 81 fState.fOrigBitmap.unlockPixels(); 82 return false; 83 } 84 85 if (!fState.chooseProcs(this->getTotalInverse(), paint)) { 86 return false; 87 } 88 89 bool bitmapIsOpaque = fState.fBitmap->isOpaque(); 90 91 // filtering doesn't guarantee that opaque stays opaque (finite precision) 92 // so pretend we're not opaque if we're being asked to filter. If we had 93 // more blit-procs, we could specialize on opaque src, and just OR in 0xFF 94 // after the filter to be sure... 95 if (paint.isFilterBitmap()) { 96 bitmapIsOpaque = false; 97 } 98 99 // update fFlags 100 fFlags = 0; 101 if (bitmapIsOpaque && (255 == this->getPaintAlpha())) { 102 fFlags |= kOpaqueAlpha_Flag; 103 } 104 105 switch (fState.fBitmap->config()) { 106 case SkBitmap::kRGB_565_Config: 107 fFlags |= (kHasSpan16_Flag | kIntrinsicly16_Flag); 108 break; 109 case SkBitmap::kIndex8_Config: 110 case SkBitmap::kARGB_8888_Config: 111 if (bitmapIsOpaque) { 112 fFlags |= kHasSpan16_Flag; 113 } 114 break; 115 case SkBitmap::kA8_Config: 116 break; // never set kHasSpan16_Flag 117 default: 118 break; 119 } 120 return true; 121} 122 123#define BUF_MAX 128 124 125void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { 126 uint32_t buffer[BUF_MAX]; 127 128 const SkBitmapProcState& state = fState; 129 SkBitmapProcState::MatrixProc mproc = state.fMatrixProc; 130 SkBitmapProcState::SampleProc32 sproc = state.fSampleProc32; 131 int max = fState.fDoFilter ? (BUF_MAX >> 1) : BUF_MAX; 132 133 SkASSERT(state.fBitmap->getPixels()); 134 SkASSERT(state.fBitmap->pixelRef() == NULL || 135 state.fBitmap->pixelRef()->getLockCount()); 136 137 for (;;) { 138 int n = count; 139 if (n > max) { 140 n = max; 141 } 142 mproc(state, buffer, n, x, y); 143 sproc(state, buffer, n, dstC); 144 145 if ((count -= n) == 0) { 146 break; 147 } 148 x += n; 149 dstC += n; 150 } 151} 152 153void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) { 154 uint32_t buffer[BUF_MAX]; 155 156 const SkBitmapProcState& state = fState; 157 SkBitmapProcState::MatrixProc mproc = state.fMatrixProc; 158 SkBitmapProcState::SampleProc16 sproc = state.fSampleProc16; 159 int max = fState.fDoFilter ? (BUF_MAX >> 1) : BUF_MAX; 160 161 SkASSERT(state.fBitmap->getPixels()); 162 SkASSERT(state.fBitmap->pixelRef() == NULL || 163 state.fBitmap->pixelRef()->getLockCount()); 164 165 for (;;) { 166 int n = count; 167 if (n > max) { 168 n = max; 169 } 170 mproc(state, buffer, n, x, y); 171 sproc(state, buffer, n, dstC); 172 173 if ((count -= n) == 0) { 174 break; 175 } 176 x += n; 177 dstC += n; 178 } 179} 180 181/////////////////////////////////////////////////////////////////////////////// 182 183#include "SkTemplatesPriv.h" 184 185SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, 186 TileMode tmx, TileMode tmy, 187 void* storage, size_t storageSize) { 188 SkShader* shader; 189 SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage, 190 storageSize, (src, tmx, tmy)); 191 return shader; 192} 193 194static SkFlattenable::Registrar gBitmapProcShaderReg("SkBitmapProcShader", 195 SkBitmapProcShader::CreateProc); 196 197/////////////////////////////////////////////////////////////////////////////// 198 199static const char* gTileModeName[] = { 200 "clamp", "repeat", "mirror" 201}; 202 203bool SkBitmapProcShader::toDumpString(SkString* str) const { 204 str->printf("BitmapShader: [%d %d %d", 205 fRawBitmap.width(), fRawBitmap.height(), 206 fRawBitmap.bytesPerPixel()); 207 208 // add the pixelref 209 SkPixelRef* pr = fRawBitmap.pixelRef(); 210 if (pr) { 211 const char* uri = pr->getURI(); 212 if (uri) { 213 str->appendf(" \"%s\"", uri); 214 } 215 } 216 217 // add the (optional) matrix 218 { 219 SkMatrix m; 220 if (this->getLocalMatrix(&m)) { 221 SkString info; 222 m.toDumpString(&info); 223 str->appendf(" %s", info.c_str()); 224 } 225 } 226 227 str->appendf(" [%s %s]]", 228 gTileModeName[fState.fTileModeX], 229 gTileModeName[fState.fTileModeY]); 230 return true; 231} 232 233