Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 #include "SkColorPriv.h" | 8 #include "SkColorPriv.h" |
| 9 #include "SkReadBuffer.h" | 9 #include "SkReadBuffer.h" |
| 10 #include "SkWriteBuffer.h" | 10 #include "SkWriteBuffer.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 return true; | 27 return true; |
| 28 default: | 28 default: |
| 29 break; | 29 break; |
| 30 } | 30 } |
| 31 return false; | 31 return false; |
| 32 } | 32 } |
| 33 | 33 |
| 34 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, | 34 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, |
| 35 TileMode tmx, TileMode tmy) { | 35 TileMode tmx, TileMode tmy) { |
| 36 fRawBitmap = src; | 36 fRawBitmap = src; |
| 37 fState.fTileModeX = (uint8_t)tmx; | 37 fTileModeX = (uint8_t)tmx; |
| 38 fState.fTileModeY = (uint8_t)tmy; | 38 fTileModeY = (uint8_t)tmy; |
| 39 fFlags = 0; // computed in setContext | |
| 40 } | 39 } |
| 41 | 40 |
| 42 SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer) | 41 SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer) |
| 43 : INHERITED(buffer) { | 42 : INHERITED(buffer) { |
| 44 buffer.readBitmap(&fRawBitmap); | 43 buffer.readBitmap(&fRawBitmap); |
| 45 fRawBitmap.setImmutable(); | 44 fRawBitmap.setImmutable(); |
| 46 fState.fTileModeX = buffer.readUInt(); | 45 fTileModeX = buffer.readUInt(); |
| 47 fState.fTileModeY = buffer.readUInt(); | 46 fTileModeY = buffer.readUInt(); |
| 48 fFlags = 0; // computed in setContext | |
| 49 } | 47 } |
| 50 | 48 |
| 51 SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture, | 49 SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture, |
| 52 SkMatrix* texM, | 50 SkMatrix* texM, |
| 53 TileMode xy[]) const { | 51 TileMode xy[]) const { |
| 54 if (texture) { | 52 if (texture) { |
| 55 *texture = fRawBitmap; | 53 *texture = fRawBitmap; |
| 56 } | 54 } |
| 57 if (texM) { | 55 if (texM) { |
| 58 texM->reset(); | 56 texM->reset(); |
| 59 } | 57 } |
| 60 if (xy) { | 58 if (xy) { |
| 61 xy[0] = (TileMode)fState.fTileModeX; | 59 xy[0] = (TileMode)fTileModeX; |
| 62 xy[1] = (TileMode)fState.fTileModeY; | 60 xy[1] = (TileMode)fTileModeY; |
| 63 } | 61 } |
| 64 return kDefault_BitmapType; | 62 return kDefault_BitmapType; |
| 65 } | 63 } |
| 66 | 64 |
| 67 void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { | 65 void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { |
| 68 this->INHERITED::flatten(buffer); | 66 this->INHERITED::flatten(buffer); |
| 69 | 67 |
| 70 buffer.writeBitmap(fRawBitmap); | 68 buffer.writeBitmap(fRawBitmap); |
| 71 buffer.writeUInt(fState.fTileModeX); | 69 buffer.writeUInt(fTileModeX); |
| 72 buffer.writeUInt(fState.fTileModeY); | 70 buffer.writeUInt(fTileModeY); |
| 73 } | 71 } |
| 74 | 72 |
| 75 static bool only_scale_and_translate(const SkMatrix& matrix) { | 73 static bool only_scale_and_translate(const SkMatrix& matrix) { |
| 76 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; | 74 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; |
| 77 return (matrix.getType() & ~mask) == 0; | 75 return (matrix.getType() & ~mask) == 0; |
| 78 } | 76 } |
| 79 | 77 |
| 80 bool SkBitmapProcShader::isOpaque() const { | 78 bool SkBitmapProcShader::isOpaque() const { |
| 81 return fRawBitmap.isOpaque(); | 79 return fRawBitmap.isOpaque(); |
| 82 } | 80 } |
| 83 | 81 |
| 84 static bool valid_for_drawing(const SkBitmap& bm) { | 82 static bool valid_for_drawing(const SkBitmap& bm) { |
| 85 if (0 == bm.width() || 0 == bm.height()) { | 83 if (0 == bm.width() || 0 == bm.height()) { |
| 86 return false; // nothing to draw | 84 return false; // nothing to draw |
| 87 } | 85 } |
| 88 if (NULL == bm.pixelRef()) { | 86 if (NULL == bm.pixelRef()) { |
| 89 return false; // no pixels to read | 87 return false; // no pixels to read |
| 90 } | 88 } |
| 91 if (kIndex_8_SkColorType == bm.colorType()) { | 89 if (kIndex_8_SkColorType == bm.colorType()) { |
| 92 // ugh, I have to lock-pixels to inspect the colortable | 90 // ugh, I have to lock-pixels to inspect the colortable |
| 93 SkAutoLockPixels alp(bm); | 91 SkAutoLockPixels alp(bm); |
| 94 if (!bm.getColorTable()) { | 92 if (!bm.getColorTable()) { |
| 95 return false; | 93 return false; |
| 96 } | 94 } |
| 97 } | 95 } |
| 98 return true; | 96 return true; |
| 99 } | 97 } |
| 100 | 98 |
| 101 bool SkBitmapProcShader::setContext(const SkBitmap& device, | 99 bool SkBitmapProcShader::validContext(const SkBitmap& device, |
| 102 const SkPaint& paint, | 100 const SkPaint& paint, |
| 103 const SkMatrix& matrix) { | 101 const SkMatrix& matrix) const { |
| 104 if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) { | 102 if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) { |
| 105 return false; | 103 return false; |
| 106 } | 104 } |
| 107 | 105 |
| 108 // do this first, so we have a correct inverse matrix | 106 // Do this first, so we know the matrix can be inverted. |
| 109 if (!this->INHERITED::setContext(device, paint, matrix)) { | 107 if (!this->INHERITED::validContext(device, paint, matrix)) { |
| 110 return false; | 108 return false; |
| 111 } | 109 } |
| 112 | 110 |
| 113 fState.fOrigBitmap = fRawBitmap; | 111 // TODO(dominikg): Can we avoid re-computing the inverse? |
|
scroggo
2014/03/26 23:13:09
One way would be for validContext to have an out p
Dominik Grewe
2014/03/27 14:27:20
I gave that a try. PTAL.
| |
| 114 if (!fState.chooseProcs(this->getTotalInverse(), paint)) { | 112 SkMatrix inverse; |
| 115 this->INHERITED::endContext(); | 113 SkASSERT(matrix.invert(&inverse)); |
|
scroggo
2014/03/26 23:13:09
As in the SkTriColorShader, this should be SkAsser
| |
| 114 | |
| 115 SkBitmapProcState state; | |
| 116 state.fTileModeX = fTileModeX; | |
| 117 state.fTileModeY = fTileModeY; | |
| 118 state.fOrigBitmap = fRawBitmap; | |
| 119 // TODO(dominikg): Could we have a more light-weight method instead of choos eProcs that only | |
| 120 // validates the inputs? | |
| 121 if (!state.chooseProcs(inverse, paint)) { | |
| 116 return false; | 122 return false; |
| 117 } | 123 } |
| 118 | 124 |
| 125 return true; | |
| 126 } | |
| 127 | |
| 128 SkShader::Context* SkBitmapProcShader::createContext(const SkBitmap& device, con st SkPaint& paint, | |
| 129 const SkMatrix& matrix, voi d* storage) const { | |
| 130 if (!this->validContext(device, paint, matrix)) { | |
| 131 return NULL; | |
| 132 } | |
| 133 | |
| 134 return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext, (*this, device , paint, matrix)); | |
| 135 } | |
| 136 | |
| 137 size_t SkBitmapProcShader::contextSize() const { | |
| 138 return sizeof(BitmapProcShaderContext); | |
| 139 } | |
| 140 | |
| 141 SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext( | |
| 142 const SkBitmapProcShader& shader, const SkBitmap& device, | |
| 143 const SkPaint& paint, const SkMatrix& matrix) | |
| 144 : INHERITED(shader, device, paint, matrix) { | |
| 145 | |
| 146 fState.fTileModeX = shader.fTileModeX; | |
| 147 fState.fTileModeY = shader.fTileModeY; | |
| 148 fState.fOrigBitmap = shader.fRawBitmap; | |
| 149 SkASSERT(fState.chooseProcs(this->getTotalInverse(), paint)); | |
| 150 | |
| 119 const SkBitmap& bitmap = *fState.fBitmap; | 151 const SkBitmap& bitmap = *fState.fBitmap; |
| 120 bool bitmapIsOpaque = bitmap.isOpaque(); | 152 bool bitmapIsOpaque = bitmap.isOpaque(); |
| 121 | 153 |
| 122 // update fFlags | 154 // update fFlags |
| 123 uint32_t flags = 0; | 155 uint32_t flags = 0; |
| 124 if (bitmapIsOpaque && (255 == this->getPaintAlpha())) { | 156 if (bitmapIsOpaque && (255 == this->getPaintAlpha())) { |
| 125 flags |= kOpaqueAlpha_Flag; | 157 flags |= kOpaqueAlpha_Flag; |
| 126 } | 158 } |
| 127 | 159 |
| 128 switch (bitmap.colorType()) { | 160 switch (bitmap.colorType()) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 150 // if we're only 1-pixel high, and we don't rotate, then we can claim this | 182 // if we're only 1-pixel high, and we don't rotate, then we can claim this |
| 151 if (1 == bitmap.height() && | 183 if (1 == bitmap.height() && |
| 152 only_scale_and_translate(this->getTotalInverse())) { | 184 only_scale_and_translate(this->getTotalInverse())) { |
| 153 flags |= kConstInY32_Flag; | 185 flags |= kConstInY32_Flag; |
| 154 if (flags & kHasSpan16_Flag) { | 186 if (flags & kHasSpan16_Flag) { |
| 155 flags |= kConstInY16_Flag; | 187 flags |= kConstInY16_Flag; |
| 156 } | 188 } |
| 157 } | 189 } |
| 158 | 190 |
| 159 fFlags = flags; | 191 fFlags = flags; |
| 160 return true; | |
| 161 } | |
| 162 | |
| 163 void SkBitmapProcShader::endContext() { | |
| 164 fState.endContext(); | |
| 165 this->INHERITED::endContext(); | |
| 166 } | 192 } |
| 167 | 193 |
| 168 #define BUF_MAX 128 | 194 #define BUF_MAX 128 |
| 169 | 195 |
| 170 #define TEST_BUFFER_OVERRITEx | 196 #define TEST_BUFFER_OVERRITEx |
| 171 | 197 |
| 172 #ifdef TEST_BUFFER_OVERRITE | 198 #ifdef TEST_BUFFER_OVERRITE |
| 173 #define TEST_BUFFER_EXTRA 32 | 199 #define TEST_BUFFER_EXTRA 32 |
| 174 #define TEST_PATTERN 0x88888888 | 200 #define TEST_PATTERN 0x88888888 |
| 175 #else | 201 #else |
| 176 #define TEST_BUFFER_EXTRA 0 | 202 #define TEST_BUFFER_EXTRA 0 |
| 177 #endif | 203 #endif |
| 178 | 204 |
| 179 void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { | 205 void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan(int x, int y, SkPMCo lor dstC[], |
| 206 int count) { | |
| 180 const SkBitmapProcState& state = fState; | 207 const SkBitmapProcState& state = fState; |
| 181 if (state.getShaderProc32()) { | 208 if (state.getShaderProc32()) { |
| 182 state.getShaderProc32()(state, x, y, dstC, count); | 209 state.getShaderProc32()(state, x, y, dstC, count); |
| 183 return; | 210 return; |
| 184 } | 211 } |
| 185 | 212 |
| 186 uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; | 213 uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; |
| 187 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); | 214 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); |
| 188 SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); | 215 SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); |
| 189 int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); | 216 int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 213 | 240 |
| 214 if ((count -= n) == 0) { | 241 if ((count -= n) == 0) { |
| 215 break; | 242 break; |
| 216 } | 243 } |
| 217 SkASSERT(count > 0); | 244 SkASSERT(count > 0); |
| 218 x += n; | 245 x += n; |
| 219 dstC += n; | 246 dstC += n; |
| 220 } | 247 } |
| 221 } | 248 } |
| 222 | 249 |
| 223 SkShader::ShadeProc SkBitmapProcShader::asAShadeProc(void** ctx) { | 250 SkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asASha deProc(void** ctx) { |
| 224 if (fState.getShaderProc32()) { | 251 if (fState.getShaderProc32()) { |
| 225 *ctx = &fState; | 252 *ctx = &fState; |
| 226 return (ShadeProc)fState.getShaderProc32(); | 253 return (ShadeProc)fState.getShaderProc32(); |
| 227 } | 254 } |
| 228 return NULL; | 255 return NULL; |
| 229 } | 256 } |
| 230 | 257 |
| 231 void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) { | 258 void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan16(int x, int y, uint 16_t dstC[], |
| 259 int count) { | |
| 232 const SkBitmapProcState& state = fState; | 260 const SkBitmapProcState& state = fState; |
| 233 if (state.getShaderProc16()) { | 261 if (state.getShaderProc16()) { |
| 234 state.getShaderProc16()(state, x, y, dstC, count); | 262 state.getShaderProc16()(state, x, y, dstC, count); |
| 235 return; | 263 return; |
| 236 } | 264 } |
| 237 | 265 |
| 238 uint32_t buffer[BUF_MAX]; | 266 uint32_t buffer[BUF_MAX]; |
| 239 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); | 267 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); |
| 240 SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16(); | 268 SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16(); |
| 241 int max = fState.maxCountForBufferSize(sizeof(buffer)); | 269 int max = fState.maxCountForBufferSize(sizeof(buffer)); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 335 | 363 |
| 336 #ifdef SK_DEVELOPER | 364 #ifdef SK_DEVELOPER |
| 337 void SkBitmapProcShader::toString(SkString* str) const { | 365 void SkBitmapProcShader::toString(SkString* str) const { |
| 338 static const char* gTileModeName[SkShader::kTileModeCount] = { | 366 static const char* gTileModeName[SkShader::kTileModeCount] = { |
| 339 "clamp", "repeat", "mirror" | 367 "clamp", "repeat", "mirror" |
| 340 }; | 368 }; |
| 341 | 369 |
| 342 str->append("BitmapShader: ("); | 370 str->append("BitmapShader: ("); |
| 343 | 371 |
| 344 str->appendf("(%s, %s)", | 372 str->appendf("(%s, %s)", |
| 345 gTileModeName[fState.fTileModeX], | 373 gTileModeName[fTileModeX], |
| 346 gTileModeName[fState.fTileModeY]); | 374 gTileModeName[fTileModeY]); |
| 347 | 375 |
| 348 str->append(" "); | 376 str->append(" "); |
| 349 fRawBitmap.toString(str); | 377 fRawBitmap.toString(str); |
| 350 | 378 |
| 351 this->INHERITED::toString(str); | 379 this->INHERITED::toString(str); |
| 352 | 380 |
| 353 str->append(")"); | 381 str->append(")"); |
| 354 } | 382 } |
| 355 #endif | 383 #endif |
| 356 | 384 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 377 SkMatrix matrix; | 405 SkMatrix matrix; |
| 378 matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); | 406 matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); |
| 379 | 407 |
| 380 SkMatrix lmInverse; | 408 SkMatrix lmInverse; |
| 381 if (!this->getLocalMatrix().invert(&lmInverse)) { | 409 if (!this->getLocalMatrix().invert(&lmInverse)) { |
| 382 return NULL; | 410 return NULL; |
| 383 } | 411 } |
| 384 matrix.preConcat(lmInverse); | 412 matrix.preConcat(lmInverse); |
| 385 | 413 |
| 386 SkShader::TileMode tm[] = { | 414 SkShader::TileMode tm[] = { |
| 387 (TileMode)fState.fTileModeX, | 415 (TileMode)fTileModeX, |
| 388 (TileMode)fState.fTileModeY, | 416 (TileMode)fTileModeY, |
| 389 }; | 417 }; |
| 390 | 418 |
| 391 // Must set wrap and filter on the sampler before requesting a texture. In t wo places below | 419 // Must set wrap and filter on the sampler before requesting a texture. In t wo places below |
| 392 // we check the matrix scale factors to determine how to interpret the filte r quality setting. | 420 // we check the matrix scale factors to determine how to interpret the filte r quality setting. |
| 393 // This completely ignores the complexity of the drawVertices case where exp licit local coords | 421 // This completely ignores the complexity of the drawVertices case where exp licit local coords |
| 394 // are provided by the caller. | 422 // are provided by the caller. |
| 395 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); | 423 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); |
| 396 GrTextureParams::FilterMode textureFilterMode; | 424 GrTextureParams::FilterMode textureFilterMode; |
| 397 switch(paintFilterLevel) { | 425 switch(paintFilterLevel) { |
| 398 case SkPaint::kNone_FilterLevel: | 426 case SkPaint::kNone_FilterLevel: |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 444 GrEffectRef* effect = NULL; | 472 GrEffectRef* effect = NULL; |
| 445 if (paintFilterLevel == SkPaint::kHigh_FilterLevel) { | 473 if (paintFilterLevel == SkPaint::kHigh_FilterLevel) { |
| 446 effect = GrBicubicEffect::Create(texture, matrix, tm); | 474 effect = GrBicubicEffect::Create(texture, matrix, tm); |
| 447 } else { | 475 } else { |
| 448 effect = GrSimpleTextureEffect::Create(texture, matrix, params); | 476 effect = GrSimpleTextureEffect::Create(texture, matrix, params); |
| 449 } | 477 } |
| 450 GrUnlockAndUnrefCachedBitmapTexture(texture); | 478 GrUnlockAndUnrefCachedBitmapTexture(texture); |
| 451 return effect; | 479 return effect; |
| 452 } | 480 } |
| 453 #endif | 481 #endif |
| OLD | NEW |