Index: src/core/SkBitmapProcShader.cpp |
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp |
index 804c688320788eecb347ff1be37586ca57423def..895922c6b873a388210e0887d768f08dc05646c5 100644 |
--- a/src/core/SkBitmapProcShader.cpp |
+++ b/src/core/SkBitmapProcShader.cpp |
@@ -20,56 +20,107 @@ |
#include "effects/GrSimpleTextureEffect.h" |
#endif |
-size_t SkBitmapProcShader::ContextSize() { |
- // The SkBitmapProcState is stored outside of the context object, with the context holding |
- // a pointer to it. |
- return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState); |
+static bool only_scale_and_translate(const SkMatrix& matrix) { |
+ unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; |
+ return (matrix.getType() & ~mask) == 0; |
} |
-SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMode tmy, |
- const SkMatrix* localMatrix) |
- : INHERITED(localMatrix) { |
- fRawBitmap = src; |
- fTileModeX = (uint8_t)tmx; |
- fTileModeY = (uint8_t)tmy; |
-} |
+class BitmapProcInfoContext : public SkShader::Context { |
+public: |
+ // The context takes ownership of the info. It will call its destructor |
+ // but will NOT free the memory. |
+ BitmapProcInfoContext(const SkShader& shader, const SkShader::ContextRec& rec, |
+ SkBitmapProcInfo* info) |
+ : INHERITED(shader, rec) |
+ , fInfo(info) |
+ { |
+ fFlags = 0; |
+ if (fInfo->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) { |
+ fFlags |= SkShader::kOpaqueAlpha_Flag; |
+ } |
-bool SkBitmapProcShader::onIsABitmap(SkBitmap* texture, SkMatrix* texM, TileMode xy[]) const { |
- if (texture) { |
- *texture = fRawBitmap; |
+ if (1 == fInfo->fPixmap.height() && only_scale_and_translate(this->getTotalInverse())) { |
+ fFlags |= SkShader::kConstInY32_Flag; |
+ } |
} |
- if (texM) { |
- texM->reset(); |
+ |
+ ~BitmapProcInfoContext() override { |
+ // The bitmap proc state has been created outside of the context on memory that will be freed |
+ // elsewhere. Only call the destructor but leave the freeing of the memory to the caller. |
+ fInfo->~SkBitmapProcInfo(); |
} |
- if (xy) { |
- xy[0] = (TileMode)fTileModeX; |
- xy[1] = (TileMode)fTileModeY; |
+ |
+ uint32_t getFlags() const override { return fFlags; } |
+ |
+private: |
+ SkBitmapProcInfo* fInfo; |
+ uint32_t fFlags; |
+ |
+ typedef SkShader::Context INHERITED; |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+class BitmapProcShaderContext : public BitmapProcInfoContext { |
+public: |
+ // The context takes ownership of the state. It will call its destructor |
+ // but will NOT free the memory. |
+ BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec& rec, |
+ SkBitmapProcState* state) |
+ : INHERITED(shader, rec, state) |
+ , fState(state) |
+ {} |
+ |
+ void shadeSpan(int x, int y, SkPMColor dstC[], int count) override { |
+ const SkBitmapProcState& state = *fState; |
+ if (state.getShaderProc32()) { |
+ state.getShaderProc32()(&state, x, y, dstC, count); |
+ return; |
+ } |
+ |
+ const int BUF_MAX = 128; |
+ uint32_t buffer[BUF_MAX]; |
+ SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); |
+ SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); |
+ const int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); |
+ |
+ SkASSERT(state.fPixmap.addr()); |
+ |
+ for (;;) { |
+ int n = SkTMin(count, max); |
+ SkASSERT(n > 0 && n < BUF_MAX*2); |
+ mproc(state, buffer, n, x, y); |
+ sproc(state, buffer, n, dstC); |
+ |
+ if ((count -= n) == 0) { |
+ break; |
+ } |
+ SkASSERT(count > 0); |
+ x += n; |
+ dstC += n; |
+ } |
} |
- return true; |
-} |
-SkFlattenable* SkBitmapProcShader::CreateProc(SkReadBuffer& buffer) { |
- SkMatrix lm; |
- buffer.readMatrix(&lm); |
- SkBitmap bm; |
- if (!buffer.readBitmap(&bm)) { |
+ ShadeProc asAShadeProc(void** ctx) override { |
+ if (fState->getShaderProc32()) { |
+ *ctx = fState; |
+ return (ShadeProc)fState->getShaderProc32(); |
+ } |
return nullptr; |
} |
- bm.setImmutable(); |
- TileMode mx = (TileMode)buffer.readUInt(); |
- TileMode my = (TileMode)buffer.readUInt(); |
- return SkShader::CreateBitmapShader(bm, mx, my, &lm); |
-} |
-void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { |
- buffer.writeMatrix(this->getLocalMatrix()); |
- buffer.writeBitmap(fRawBitmap); |
- buffer.writeUInt(fTileModeX); |
- buffer.writeUInt(fTileModeY); |
-} |
+private: |
+ SkBitmapProcState* fState; |
-bool SkBitmapProcShader::isOpaque() const { |
- return fRawBitmap.isOpaque(); |
+ typedef BitmapProcInfoContext INHERITED; |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+size_t SkBitmapProcShader::ContextSize(const ContextRec& rec) { |
+ // The SkBitmapProcState is stored outside of the context object, with the context holding |
+ // a pointer to it. |
+ return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState); |
} |
SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader, |
@@ -86,7 +137,7 @@ SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader, |
SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tmx, tmy); |
SkASSERT(state); |
- if (!state->chooseProcs(totalInverse, *rec.fPaint)) { |
+ if (!state->setup(totalInverse, *rec.fPaint)) { |
state->~SkBitmapProcState(); |
return nullptr; |
} |
@@ -99,96 +150,55 @@ SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, vo |
SkBitmapProvider(fRawBitmap), rec, storage); |
} |
-static bool only_scale_and_translate(const SkMatrix& matrix) { |
- unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; |
- return (matrix.getType() & ~mask) == 0; |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMode tmy, |
+ const SkMatrix* localMatrix) |
+ : INHERITED(localMatrix) { |
+ fRawBitmap = src; |
+ fTileModeX = (uint8_t)tmx; |
+ fTileModeY = (uint8_t)tmy; |
} |
-SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(const SkShader& shader, |
- const ContextRec& rec, |
- SkBitmapProcState* state) |
- : INHERITED(shader, rec) |
- , fState(state) |
-{ |
- fFlags = 0; |
- if (fState->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) { |
- fFlags |= kOpaqueAlpha_Flag; |
+bool SkBitmapProcShader::onIsABitmap(SkBitmap* texture, SkMatrix* texM, TileMode xy[]) const { |
+ if (texture) { |
+ *texture = fRawBitmap; |
} |
- |
- if (1 == fState->fPixmap.height() && only_scale_and_translate(this->getTotalInverse())) { |
- fFlags |= kConstInY32_Flag; |
+ if (texM) { |
+ texM->reset(); |
} |
+ if (xy) { |
+ xy[0] = (TileMode)fTileModeX; |
+ xy[1] = (TileMode)fTileModeY; |
+ } |
+ return true; |
} |
-SkBitmapProcShader::BitmapProcShaderContext::~BitmapProcShaderContext() { |
- // The bitmap proc state has been created outside of the context on memory that will be freed |
- // elsewhere. Only call the destructor but leave the freeing of the memory to the caller. |
- fState->~SkBitmapProcState(); |
-} |
- |
-#define BUF_MAX 128 |
- |
-#define TEST_BUFFER_OVERRITEx |
- |
-#ifdef TEST_BUFFER_OVERRITE |
- #define TEST_BUFFER_EXTRA 32 |
- #define TEST_PATTERN 0x88888888 |
-#else |
- #define TEST_BUFFER_EXTRA 0 |
-#endif |
- |
-void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], |
- int count) { |
- const SkBitmapProcState& state = *fState; |
- if (state.getShaderProc32()) { |
- state.getShaderProc32()(&state, x, y, dstC, count); |
- return; |
+SkFlattenable* SkBitmapProcShader::CreateProc(SkReadBuffer& buffer) { |
+ SkMatrix lm; |
+ buffer.readMatrix(&lm); |
+ SkBitmap bm; |
+ if (!buffer.readBitmap(&bm)) { |
+ return nullptr; |
} |
+ bm.setImmutable(); |
+ TileMode mx = (TileMode)buffer.readUInt(); |
+ TileMode my = (TileMode)buffer.readUInt(); |
+ return SkShader::CreateBitmapShader(bm, mx, my, &lm); |
+} |
- uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; |
- SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); |
- SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); |
- int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); |
- |
- SkASSERT(state.fPixmap.addr()); |
- |
- for (;;) { |
- int n = count; |
- if (n > max) { |
- n = max; |
- } |
- SkASSERT(n > 0 && n < BUF_MAX*2); |
-#ifdef TEST_BUFFER_OVERRITE |
- for (int i = 0; i < TEST_BUFFER_EXTRA; i++) { |
- buffer[BUF_MAX + i] = TEST_PATTERN; |
- } |
-#endif |
- mproc(state, buffer, n, x, y); |
-#ifdef TEST_BUFFER_OVERRITE |
- for (int j = 0; j < TEST_BUFFER_EXTRA; j++) { |
- SkASSERT(buffer[BUF_MAX + j] == TEST_PATTERN); |
- } |
-#endif |
- sproc(state, buffer, n, dstC); |
- |
- if ((count -= n) == 0) { |
- break; |
- } |
- SkASSERT(count > 0); |
- x += n; |
- dstC += n; |
- } |
+void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { |
+ buffer.writeMatrix(this->getLocalMatrix()); |
+ buffer.writeBitmap(fRawBitmap); |
+ buffer.writeUInt(fTileModeX); |
+ buffer.writeUInt(fTileModeY); |
} |
-SkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asAShadeProc(void** ctx) { |
- if (fState->getShaderProc32()) { |
- *ctx = fState; |
- return (ShadeProc)fState->getShaderProc32(); |
- } |
- return nullptr; |
+bool SkBitmapProcShader::isOpaque() const { |
+ return fRawBitmap.isOpaque(); |
} |
-/////////////////////////////////////////////////////////////////////////////// |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
#include "SkUnPreMultiply.h" |
#include "SkColorShader.h" |