| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkBitmapProcShader.h" | 8 #include "SkBitmapProcShader.h" |
| 9 #include "SkBitmapProcState.h" | 9 #include "SkBitmapProcState.h" |
| 10 #include "SkBitmapProvider.h" | 10 #include "SkBitmapProvider.h" |
| 11 #include "SkColorPriv.h" | 11 #include "SkColorPriv.h" |
| 12 #include "SkErrorInternals.h" | 12 #include "SkErrorInternals.h" |
| 13 #include "SkPixelRef.h" | 13 #include "SkPixelRef.h" |
| 14 #include "SkReadBuffer.h" | 14 #include "SkReadBuffer.h" |
| 15 #include "SkWriteBuffer.h" | 15 #include "SkWriteBuffer.h" |
| 16 | 16 |
| 17 #if SK_SUPPORT_GPU | 17 #if SK_SUPPORT_GPU |
| 18 #include "SkGrPriv.h" | 18 #include "SkGrPriv.h" |
| 19 #include "effects/GrBicubicEffect.h" | 19 #include "effects/GrBicubicEffect.h" |
| 20 #include "effects/GrSimpleTextureEffect.h" | 20 #include "effects/GrSimpleTextureEffect.h" |
| 21 #endif | 21 #endif |
| 22 | 22 |
| 23 size_t SkBitmapProcShader::ContextSize() { | 23 static bool only_scale_and_translate(const SkMatrix& matrix) { |
| 24 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; |
| 25 return (matrix.getType() & ~mask) == 0; |
| 26 } |
| 27 |
| 28 class BitmapProcInfoContext : public SkShader::Context { |
| 29 public: |
| 30 // The context takes ownership of the info. It will call its destructor |
| 31 // but will NOT free the memory. |
| 32 BitmapProcInfoContext(const SkShader& shader, const SkShader::ContextRec& re
c, |
| 33 SkBitmapProcInfo* info) |
| 34 : INHERITED(shader, rec) |
| 35 , fInfo(info) |
| 36 { |
| 37 fFlags = 0; |
| 38 if (fInfo->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) { |
| 39 fFlags |= SkShader::kOpaqueAlpha_Flag; |
| 40 } |
| 41 |
| 42 if (1 == fInfo->fPixmap.height() && only_scale_and_translate(this->getTo
talInverse())) { |
| 43 fFlags |= SkShader::kConstInY32_Flag; |
| 44 } |
| 45 } |
| 46 |
| 47 ~BitmapProcInfoContext() override { |
| 48 // The bitmap proc state has been created outside of the context on memo
ry that will be freed |
| 49 // elsewhere. Only call the destructor but leave the freeing of the memo
ry to the caller. |
| 50 fInfo->~SkBitmapProcInfo(); |
| 51 } |
| 52 |
| 53 uint32_t getFlags() const override { return fFlags; } |
| 54 |
| 55 private: |
| 56 SkBitmapProcInfo* fInfo; |
| 57 uint32_t fFlags; |
| 58 |
| 59 typedef SkShader::Context INHERITED; |
| 60 }; |
| 61 |
| 62 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 63 |
| 64 class BitmapProcShaderContext : public BitmapProcInfoContext { |
| 65 public: |
| 66 // The context takes ownership of the state. It will call its destructor |
| 67 // but will NOT free the memory. |
| 68 BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec&
rec, |
| 69 SkBitmapProcState* state) |
| 70 : INHERITED(shader, rec, state) |
| 71 , fState(state) |
| 72 {} |
| 73 |
| 74 void shadeSpan(int x, int y, SkPMColor dstC[], int count) override { |
| 75 const SkBitmapProcState& state = *fState; |
| 76 if (state.getShaderProc32()) { |
| 77 state.getShaderProc32()(&state, x, y, dstC, count); |
| 78 return; |
| 79 } |
| 80 |
| 81 const int BUF_MAX = 128; |
| 82 uint32_t buffer[BUF_MAX]; |
| 83 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); |
| 84 SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); |
| 85 const int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX)
; |
| 86 |
| 87 SkASSERT(state.fPixmap.addr()); |
| 88 |
| 89 for (;;) { |
| 90 int n = SkTMin(count, max); |
| 91 SkASSERT(n > 0 && n < BUF_MAX*2); |
| 92 mproc(state, buffer, n, x, y); |
| 93 sproc(state, buffer, n, dstC); |
| 94 |
| 95 if ((count -= n) == 0) { |
| 96 break; |
| 97 } |
| 98 SkASSERT(count > 0); |
| 99 x += n; |
| 100 dstC += n; |
| 101 } |
| 102 } |
| 103 |
| 104 ShadeProc asAShadeProc(void** ctx) override { |
| 105 if (fState->getShaderProc32()) { |
| 106 *ctx = fState; |
| 107 return (ShadeProc)fState->getShaderProc32(); |
| 108 } |
| 109 return nullptr; |
| 110 } |
| 111 |
| 112 private: |
| 113 SkBitmapProcState* fState; |
| 114 |
| 115 typedef BitmapProcInfoContext INHERITED; |
| 116 }; |
| 117 |
| 118 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 119 |
| 120 size_t SkBitmapProcShader::ContextSize(const ContextRec& rec) { |
| 24 // The SkBitmapProcState is stored outside of the context object, with the c
ontext holding | 121 // The SkBitmapProcState is stored outside of the context object, with the c
ontext holding |
| 25 // a pointer to it. | 122 // a pointer to it. |
| 26 return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState); | 123 return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState); |
| 27 } | 124 } |
| 28 | 125 |
| 29 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMo
de tmy, | |
| 30 const SkMatrix* localMatrix) | |
| 31 : INHERITED(localMatrix) { | |
| 32 fRawBitmap = src; | |
| 33 fTileModeX = (uint8_t)tmx; | |
| 34 fTileModeY = (uint8_t)tmy; | |
| 35 } | |
| 36 | |
| 37 bool SkBitmapProcShader::onIsABitmap(SkBitmap* texture, SkMatrix* texM, TileMode
xy[]) const { | |
| 38 if (texture) { | |
| 39 *texture = fRawBitmap; | |
| 40 } | |
| 41 if (texM) { | |
| 42 texM->reset(); | |
| 43 } | |
| 44 if (xy) { | |
| 45 xy[0] = (TileMode)fTileModeX; | |
| 46 xy[1] = (TileMode)fTileModeY; | |
| 47 } | |
| 48 return true; | |
| 49 } | |
| 50 | |
| 51 SkFlattenable* SkBitmapProcShader::CreateProc(SkReadBuffer& buffer) { | |
| 52 SkMatrix lm; | |
| 53 buffer.readMatrix(&lm); | |
| 54 SkBitmap bm; | |
| 55 if (!buffer.readBitmap(&bm)) { | |
| 56 return nullptr; | |
| 57 } | |
| 58 bm.setImmutable(); | |
| 59 TileMode mx = (TileMode)buffer.readUInt(); | |
| 60 TileMode my = (TileMode)buffer.readUInt(); | |
| 61 return SkShader::CreateBitmapShader(bm, mx, my, &lm); | |
| 62 } | |
| 63 | |
| 64 void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { | |
| 65 buffer.writeMatrix(this->getLocalMatrix()); | |
| 66 buffer.writeBitmap(fRawBitmap); | |
| 67 buffer.writeUInt(fTileModeX); | |
| 68 buffer.writeUInt(fTileModeY); | |
| 69 } | |
| 70 | |
| 71 bool SkBitmapProcShader::isOpaque() const { | |
| 72 return fRawBitmap.isOpaque(); | |
| 73 } | |
| 74 | |
| 75 SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader, | 126 SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader, |
| 76 TileMode tmx, TileMode tmy, | 127 TileMode tmx, TileMode tmy, |
| 77 const SkBitmapProvider& provi
der, | 128 const SkBitmapProvider& provi
der, |
| 78 const ContextRec& rec, void*
storage) { | 129 const ContextRec& rec, void*
storage) { |
| 79 SkMatrix totalInverse; | 130 SkMatrix totalInverse; |
| 80 // Do this first, so we know the matrix can be inverted. | 131 // Do this first, so we know the matrix can be inverted. |
| 81 if (!shader.computeTotalInverse(rec, &totalInverse)) { | 132 if (!shader.computeTotalInverse(rec, &totalInverse)) { |
| 82 return nullptr; | 133 return nullptr; |
| 83 } | 134 } |
| 84 | 135 |
| 85 void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); | 136 void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); |
| 86 SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tm
x, tmy); | 137 SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tm
x, tmy); |
| 87 | 138 |
| 88 SkASSERT(state); | 139 SkASSERT(state); |
| 89 if (!state->chooseProcs(totalInverse, *rec.fPaint)) { | 140 if (!state->setup(totalInverse, *rec.fPaint)) { |
| 90 state->~SkBitmapProcState(); | 141 state->~SkBitmapProcState(); |
| 91 return nullptr; | 142 return nullptr; |
| 92 } | 143 } |
| 93 | 144 |
| 94 return new (storage) BitmapProcShaderContext(shader, rec, state); | 145 return new (storage) BitmapProcShaderContext(shader, rec, state); |
| 95 } | 146 } |
| 96 | 147 |
| 97 SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, vo
id* storage) const { | 148 SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, vo
id* storage) const { |
| 98 return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY, | 149 return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY, |
| 99 SkBitmapProvider(fRawBitmap), rec, storage); | 150 SkBitmapProvider(fRawBitmap), rec, storage); |
| 100 } | 151 } |
| 101 | 152 |
| 102 static bool only_scale_and_translate(const SkMatrix& matrix) { | 153 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 103 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; | 154 |
| 104 return (matrix.getType() & ~mask) == 0; | 155 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMo
de tmy, |
| 156 const SkMatrix* localMatrix) |
| 157 : INHERITED(localMatrix) { |
| 158 fRawBitmap = src; |
| 159 fTileModeX = (uint8_t)tmx; |
| 160 fTileModeY = (uint8_t)tmy; |
| 105 } | 161 } |
| 106 | 162 |
| 107 SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(const SkSha
der& shader, | 163 bool SkBitmapProcShader::onIsABitmap(SkBitmap* texture, SkMatrix* texM, TileMode
xy[]) const { |
| 108 const Conte
xtRec& rec, | 164 if (texture) { |
| 109 SkBitmapPro
cState* state) | 165 *texture = fRawBitmap; |
| 110 : INHERITED(shader, rec) | |
| 111 , fState(state) | |
| 112 { | |
| 113 fFlags = 0; | |
| 114 if (fState->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) { | |
| 115 fFlags |= kOpaqueAlpha_Flag; | |
| 116 } | 166 } |
| 117 | 167 if (texM) { |
| 118 if (1 == fState->fPixmap.height() && only_scale_and_translate(this->getTotal
Inverse())) { | 168 texM->reset(); |
| 119 fFlags |= kConstInY32_Flag; | |
| 120 } | 169 } |
| 170 if (xy) { |
| 171 xy[0] = (TileMode)fTileModeX; |
| 172 xy[1] = (TileMode)fTileModeY; |
| 173 } |
| 174 return true; |
| 121 } | 175 } |
| 122 | 176 |
| 123 SkBitmapProcShader::BitmapProcShaderContext::~BitmapProcShaderContext() { | 177 SkFlattenable* SkBitmapProcShader::CreateProc(SkReadBuffer& buffer) { |
| 124 // The bitmap proc state has been created outside of the context on memory t
hat will be freed | 178 SkMatrix lm; |
| 125 // elsewhere. Only call the destructor but leave the freeing of the memory t
o the caller. | 179 buffer.readMatrix(&lm); |
| 126 fState->~SkBitmapProcState(); | 180 SkBitmap bm; |
| 181 if (!buffer.readBitmap(&bm)) { |
| 182 return nullptr; |
| 183 } |
| 184 bm.setImmutable(); |
| 185 TileMode mx = (TileMode)buffer.readUInt(); |
| 186 TileMode my = (TileMode)buffer.readUInt(); |
| 187 return SkShader::CreateBitmapShader(bm, mx, my, &lm); |
| 127 } | 188 } |
| 128 | 189 |
| 129 #define BUF_MAX 128 | 190 void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { |
| 130 | 191 buffer.writeMatrix(this->getLocalMatrix()); |
| 131 #define TEST_BUFFER_OVERRITEx | 192 buffer.writeBitmap(fRawBitmap); |
| 132 | 193 buffer.writeUInt(fTileModeX); |
| 133 #ifdef TEST_BUFFER_OVERRITE | 194 buffer.writeUInt(fTileModeY); |
| 134 #define TEST_BUFFER_EXTRA 32 | |
| 135 #define TEST_PATTERN 0x88888888 | |
| 136 #else | |
| 137 #define TEST_BUFFER_EXTRA 0 | |
| 138 #endif | |
| 139 | |
| 140 void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan(int x, int y, SkPMCo
lor dstC[], | |
| 141 int count) { | |
| 142 const SkBitmapProcState& state = *fState; | |
| 143 if (state.getShaderProc32()) { | |
| 144 state.getShaderProc32()(&state, x, y, dstC, count); | |
| 145 return; | |
| 146 } | |
| 147 | |
| 148 uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; | |
| 149 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); | |
| 150 SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); | |
| 151 int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); | |
| 152 | |
| 153 SkASSERT(state.fPixmap.addr()); | |
| 154 | |
| 155 for (;;) { | |
| 156 int n = count; | |
| 157 if (n > max) { | |
| 158 n = max; | |
| 159 } | |
| 160 SkASSERT(n > 0 && n < BUF_MAX*2); | |
| 161 #ifdef TEST_BUFFER_OVERRITE | |
| 162 for (int i = 0; i < TEST_BUFFER_EXTRA; i++) { | |
| 163 buffer[BUF_MAX + i] = TEST_PATTERN; | |
| 164 } | |
| 165 #endif | |
| 166 mproc(state, buffer, n, x, y); | |
| 167 #ifdef TEST_BUFFER_OVERRITE | |
| 168 for (int j = 0; j < TEST_BUFFER_EXTRA; j++) { | |
| 169 SkASSERT(buffer[BUF_MAX + j] == TEST_PATTERN); | |
| 170 } | |
| 171 #endif | |
| 172 sproc(state, buffer, n, dstC); | |
| 173 | |
| 174 if ((count -= n) == 0) { | |
| 175 break; | |
| 176 } | |
| 177 SkASSERT(count > 0); | |
| 178 x += n; | |
| 179 dstC += n; | |
| 180 } | |
| 181 } | 195 } |
| 182 | 196 |
| 183 SkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asASha
deProc(void** ctx) { | 197 bool SkBitmapProcShader::isOpaque() const { |
| 184 if (fState->getShaderProc32()) { | 198 return fRawBitmap.isOpaque(); |
| 185 *ctx = fState; | |
| 186 return (ShadeProc)fState->getShaderProc32(); | |
| 187 } | |
| 188 return nullptr; | |
| 189 } | 199 } |
| 190 | 200 |
| 191 /////////////////////////////////////////////////////////////////////////////// | 201 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 192 | 202 |
| 193 #include "SkUnPreMultiply.h" | 203 #include "SkUnPreMultiply.h" |
| 194 #include "SkColorShader.h" | 204 #include "SkColorShader.h" |
| 195 #include "SkEmptyShader.h" | 205 #include "SkEmptyShader.h" |
| 196 | 206 |
| 197 // returns true and set color if the bitmap can be drawn as a single color | 207 // returns true and set color if the bitmap can be drawn as a single color |
| 198 // (for efficiency) | 208 // (for efficiency) |
| 199 static bool can_use_color_shader(const SkBitmap& bm, SkColor* color) { | 209 static bool can_use_color_shader(const SkBitmap& bm, SkColor* color) { |
| 200 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK | 210 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK |
| 201 // HWUI does not support color shaders (see b/22390304) | 211 // HWUI does not support color shaders (see b/22390304) |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 inner.reset(GrSimpleTextureEffect::Create(texture, matrix, params)); | 353 inner.reset(GrSimpleTextureEffect::Create(texture, matrix, params)); |
| 344 } | 354 } |
| 345 | 355 |
| 346 if (kAlpha_8_SkColorType == fRawBitmap.colorType()) { | 356 if (kAlpha_8_SkColorType == fRawBitmap.colorType()) { |
| 347 return GrFragmentProcessor::MulOutputByInputUnpremulColor(inner); | 357 return GrFragmentProcessor::MulOutputByInputUnpremulColor(inner); |
| 348 } | 358 } |
| 349 return GrFragmentProcessor::MulOutputByInputAlpha(inner); | 359 return GrFragmentProcessor::MulOutputByInputAlpha(inner); |
| 350 } | 360 } |
| 351 | 361 |
| 352 #endif | 362 #endif |
| OLD | NEW |