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