diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index 804c688320..895922c6b8 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -20,12 +20,138 @@ #include "effects/GrSimpleTextureEffect.h" #endif -size_t SkBitmapProcShader::ContextSize() { +static bool only_scale_and_translate(const SkMatrix& matrix) { + unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; + return (matrix.getType() & ~mask) == 0; +} + +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; + } + + if (1 == fInfo->fPixmap.height() && only_scale_and_translate(this->getTotalInverse())) { + fFlags |= SkShader::kConstInY32_Flag; + } + } + + ~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(); + } + + 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; + } + } + + ShadeProc asAShadeProc(void** ctx) override { + if (fState->getShaderProc32()) { + *ctx = fState; + return (ShadeProc)fState->getShaderProc32(); + } + return nullptr; + } + +private: + SkBitmapProcState* fState; + + 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, + TileMode tmx, TileMode tmy, + const SkBitmapProvider& provider, + const ContextRec& rec, void* storage) { + SkMatrix totalInverse; + // Do this first, so we know the matrix can be inverted. + if (!shader.computeTotalInverse(rec, &totalInverse)) { + return nullptr; + } + + void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); + SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tmx, tmy); + + SkASSERT(state); + if (!state->setup(totalInverse, *rec.fPaint)) { + state->~SkBitmapProcState(); + return nullptr; + } + + return new (storage) BitmapProcShaderContext(shader, rec, state); +} + +SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const { + return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY, + SkBitmapProvider(fRawBitmap), rec, storage); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMode tmy, const SkMatrix* localMatrix) : INHERITED(localMatrix) { @@ -72,123 +198,7 @@ bool SkBitmapProcShader::isOpaque() const { return fRawBitmap.isOpaque(); } -SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader, - TileMode tmx, TileMode tmy, - const SkBitmapProvider& provider, - const ContextRec& rec, void* storage) { - SkMatrix totalInverse; - // Do this first, so we know the matrix can be inverted. - if (!shader.computeTotalInverse(rec, &totalInverse)) { - return nullptr; - } - - void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); - SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tmx, tmy); - - SkASSERT(state); - if (!state->chooseProcs(totalInverse, *rec.fPaint)) { - state->~SkBitmapProcState(); - return nullptr; - } - - return new (storage) BitmapProcShaderContext(shader, rec, state); -} - -SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const { - return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY, - 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::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; - } - - if (1 == fState->fPixmap.height() && only_scale_and_translate(this->getTotalInverse())) { - fFlags |= kConstInY32_Flag; - } -} - -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; - } - - 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; - } -} - -SkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asAShadeProc(void** ctx) { - if (fState->getShaderProc32()) { - *ctx = fState; - return (ShadeProc)fState->getShaderProc32(); - } - return nullptr; -} - -/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// #include "SkUnPreMultiply.h" #include "SkColorShader.h" diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h index b897c6e500..9f4c16202c 100644 --- a/src/core/SkBitmapProcShader.h +++ b/src/core/SkBitmapProcShader.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,7 +5,6 @@ * found in the LICENSE file. */ - #ifndef SkBitmapProcShader_DEFINED #define SkBitmapProcShader_DEFINED @@ -23,7 +21,7 @@ public: bool isOpaque() const override; - size_t contextSize(const ContextRec&) const override { return ContextSize(); } + size_t contextSize(const ContextRec& rec) const override { return ContextSize(rec); } SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader) @@ -34,25 +32,6 @@ public: #endif protected: - class BitmapProcShaderContext : public SkShader::Context { - public: - // The context takes ownership of the state. It will call its destructor - // but will NOT free the memory. - BitmapProcShaderContext(const SkShader&, const ContextRec&, SkBitmapProcState*); - ~BitmapProcShaderContext() override; - - void shadeSpan(int x, int y, SkPMColor dstC[], int count) override; - ShadeProc asAShadeProc(void** ctx) override; - - uint32_t getFlags() const override { return fFlags; } - - private: - SkBitmapProcState* fState; - uint32_t fFlags; - - typedef SkShader::Context INHERITED; - }; - void flatten(SkWriteBuffer&) const override; Context* onCreateContext(const ContextRec&, void* storage) const override; bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode*) const override; @@ -63,7 +42,7 @@ protected: private: friend class SkImageShader; - static size_t ContextSize(); + static size_t ContextSize(const ContextRec&); static Context* MakeContext(const SkShader&, TileMode tmx, TileMode tmy, const SkBitmapProvider&, const ContextRec&, void* storage); diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp index 7c37a154d2..c1692881dc 100644 --- a/src/core/SkBitmapProcState.cpp +++ b/src/core/SkBitmapProcState.cpp @@ -36,25 +36,23 @@ extern void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const void*, int, int, u #include "SkBitmapProcState_filter.h" #include "SkBitmapProcState_procs.h" -SkBitmapProcState::SkBitmapProcState(const SkBitmapProvider& provider, - SkShader::TileMode tmx, SkShader::TileMode tmy) +SkBitmapProcInfo::SkBitmapProcInfo(const SkBitmapProvider& provider, + SkShader::TileMode tmx, SkShader::TileMode tmy) : fProvider(provider) + , fTileModeX(tmx) + , fTileModeY(tmy) , fBMState(nullptr) -{ - fTileModeX = tmx; - fTileModeY = tmy; -} +{} -SkBitmapProcState::SkBitmapProcState(const SkBitmap& bm, - SkShader::TileMode tmx, SkShader::TileMode tmy) +SkBitmapProcInfo::SkBitmapProcInfo(const SkBitmap& bm, + SkShader::TileMode tmx, SkShader::TileMode tmy) : fProvider(SkBitmapProvider(bm)) + , fTileModeX(tmx) + , fTileModeY(tmy) , fBMState(nullptr) -{ - fTileModeX = tmx; - fTileModeY = tmy; -} +{} -SkBitmapProcState::~SkBitmapProcState() { +SkBitmapProcInfo::~SkBitmapProcInfo() { SkInPlaceDeleteCheck(fBMState, fBMStateStorage.get()); } @@ -118,25 +116,16 @@ static bool valid_for_filtering(unsigned dimension) { return (dimension & ~0x3FFF) == 0; } -/* - * Analyze filter-quality and matrix, and decide how to implement that. - * - * In general, we cascade down the request level [ High ... None ] - * - for a given level, if we can fulfill it, fine, else - * - else we downgrade to the next lower level and try again. - * We can always fulfill requests for Low and None - * - sometimes we will "ignore" Low and give None, but this is likely a legacy perf hack - * and may be removed. - */ -bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { - fPixmap.reset(); - fInvMatrix = inv; - fFilterLevel = paint.getFilterQuality(); - +bool SkBitmapProcInfo::init(const SkMatrix& inv, const SkPaint& paint) { const int origW = fProvider.info().width(); const int origH = fProvider.info().height(); + + fPixmap.reset(); + fInvMatrix = inv; + fFilterQuality = paint.getFilterQuality(); + bool allow_ignore_fractional_translate = true; // historical default - if (kMedium_SkFilterQuality == fFilterLevel) { + if (kMedium_SkFilterQuality == fFilterQuality) { allow_ignore_fractional_translate = false; } @@ -149,9 +138,10 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { } fPixmap = fBMState->pixmap(); fInvMatrix = fBMState->invMatrix(); - fFilterLevel = fBMState->quality(); + fPaintColor = paint.getColor(); + fFilterQuality = fBMState->quality(); SkASSERT(fPixmap.addr()); - + bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && SkShader::kClamp_TileMode == fTileModeY; @@ -179,30 +169,14 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { SkMatrix forward; if (fInvMatrix.invert(&forward)) { if ((clampClamp && allow_ignore_fractional_translate) - ? just_trans_clamp(forward, fPixmap) - : just_trans_general(forward)) { + ? just_trans_clamp(forward, fPixmap) + : just_trans_general(forward)) { fInvMatrix.setTranslate(-forward.getTranslateX(), -forward.getTranslateY()); } } } - fInvProc = fInvMatrix.getMapXYProc(); - fInvType = fInvMatrix.getType(); - fInvSx = SkScalarToFixed(fInvMatrix.getScaleX()); - fInvSxFractionalInt = SkScalarToFractionalInt(fInvMatrix.getScaleX()); - fInvKy = SkScalarToFixed(fInvMatrix.getSkewY()); - fInvKyFractionalInt = SkScalarToFractionalInt(fInvMatrix.getSkewY()); - - fAlphaScale = SkAlpha255To256(paint.getAlpha()); - - fShaderProc32 = nullptr; - fShaderProc16 = nullptr; - fSampleProc32 = nullptr; - - // recompute the triviality of the matrix here because we may have - // changed it! - - trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; + fInvType = fInvMatrix.getType(); // If our target pixmap is the same as the original, then we revert back to legacy behavior // and allow the code to ignore fractional translate. @@ -214,22 +188,51 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { allow_ignore_fractional_translate = true; } - if (kLow_SkFilterQuality == fFilterLevel && allow_ignore_fractional_translate) { + if (kLow_SkFilterQuality == fFilterQuality && allow_ignore_fractional_translate) { // Only try bilerp if the matrix is "interesting" and // the image has a suitable size. if (fInvType <= SkMatrix::kTranslate_Mask || !valid_for_filtering(fPixmap.width() | fPixmap.height())) { - fFilterLevel = kNone_SkFilterQuality; + fFilterQuality = kNone_SkFilterQuality; } } - - return this->chooseScanlineProcs(trivialMatrix, clampClamp, paint); + + return true; } -bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp, - const SkPaint& paint) { +/* + * Analyze filter-quality and matrix, and decide how to implement that. + * + * In general, we cascade down the request level [ High ... None ] + * - for a given level, if we can fulfill it, fine, else + * - else we downgrade to the next lower level and try again. + * We can always fulfill requests for Low and None + * - sometimes we will "ignore" Low and give None, but this is likely a legacy perf hack + * and may be removed. + */ +bool SkBitmapProcState::chooseProcs() { + fInvProc = fInvMatrix.getMapXYProc(); + fInvSx = SkScalarToFixed(fInvMatrix.getScaleX()); + fInvSxFractionalInt = SkScalarToFractionalInt(fInvMatrix.getScaleX()); + fInvKy = SkScalarToFixed(fInvMatrix.getSkewY()); + fInvKyFractionalInt = SkScalarToFractionalInt(fInvMatrix.getSkewY()); + + fAlphaScale = SkAlpha255To256(SkColorGetA(fPaintColor)); + + fShaderProc32 = nullptr; + fShaderProc16 = nullptr; + fSampleProc32 = nullptr; + + const bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; + const bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && + SkShader::kClamp_TileMode == fTileModeY; + + return this->chooseScanlineProcs(trivialMatrix, clampClamp); +} + +bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp) { fMatrixProc = this->chooseMatrixProc(trivialMatrix); // TODO(dominikg): SkASSERT(fMatrixProc) instead? chooseMatrixProc never returns nullptr. if (nullptr == fMatrixProc) { @@ -244,7 +247,7 @@ bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp, // still set to HQ by the time we get here, then we must have installed // the shader procs above and can skip all this. - if (fFilterLevel < kHigh_SkFilterQuality) { + if (fFilterQuality < kHigh_SkFilterQuality) { int index = 0; if (fAlphaScale < 256) { // note: this distinction is not used for D16 @@ -253,7 +256,7 @@ bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp, if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { index |= 2; } - if (fFilterLevel > kNone_SkFilterQuality) { + if (fFilterQuality > kNone_SkFilterQuality) { index |= 4; } // bits 3,4,5 encoding the source bitmap format @@ -281,11 +284,11 @@ bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp, break; case kAlpha_8_SkColorType: index |= 32; - fPaintPMColor = SkPreMultiplyColor(paint.getColor()); + fPaintPMColor = SkPreMultiplyColor(fPaintColor); break; case kGray_8_SkColorType: index |= 40; - fPaintPMColor = SkPreMultiplyColor(paint.getColor()); + fPaintPMColor = SkPreMultiplyColor(fPaintColor); break; default: // TODO(dominikg): Should we ever get here? SkASSERT(false) instead? @@ -381,7 +384,7 @@ static void Clamp_S32_D32_nofilter_trans_shaderproc(const void* sIn, SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); SkASSERT(s.fInvKy == 0); SkASSERT(count > 0 && colors != nullptr); - SkASSERT(kNone_SkFilterQuality == s.fFilterLevel); + SkASSERT(kNone_SkFilterQuality == s.fFilterQuality); const int maxX = s.fPixmap.width() - 1; const int maxY = s.fPixmap.height() - 1; @@ -444,7 +447,7 @@ static void Repeat_S32_D32_nofilter_trans_shaderproc(const void* sIn, SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); SkASSERT(s.fInvKy == 0); SkASSERT(count > 0 && colors != nullptr); - SkASSERT(kNone_SkFilterQuality == s.fFilterLevel); + SkASSERT(kNone_SkFilterQuality == s.fFilterQuality); const int stopX = s.fPixmap.width(); const int stopY = s.fPixmap.height(); @@ -479,7 +482,7 @@ static void S32_D32_constX_shaderproc(const void* sIn, int iY1 SK_INIT_TO_AVOID_WARNING; int iSubY SK_INIT_TO_AVOID_WARNING; - if (kNone_SkFilterQuality != s.fFilterLevel) { + if (kNone_SkFilterQuality != s.fFilterQuality) { SkBitmapProcState::MatrixProc mproc = s.getMatrixProc(); uint32_t xy[2]; @@ -556,7 +559,7 @@ static void S32_D32_constX_shaderproc(const void* sIn, const SkPMColor* row0 = s.fPixmap.addr32(0, iY0); SkPMColor color; - if (kNone_SkFilterQuality != s.fFilterLevel) { + if (kNone_SkFilterQuality != s.fFilterQuality) { const SkPMColor* row1 = s.fPixmap.addr32(0, iY1); if (s.fAlphaScale < 256) { @@ -613,7 +616,7 @@ SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() { static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; if (1 == fPixmap.width() && 0 == (fInvType & ~kMask)) { - if (kNone_SkFilterQuality == fFilterLevel && + if (kNone_SkFilterQuality == fFilterQuality && fInvType <= SkMatrix::kTranslate_Mask && !this->setupForTranslate()) { return DoNothing_shaderproc; @@ -627,7 +630,7 @@ SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() { if (fInvType > SkMatrix::kTranslate_Mask) { return nullptr; } - if (kNone_SkFilterQuality != fFilterLevel) { + if (kNone_SkFilterQuality != fFilterQuality) { return nullptr; } @@ -723,9 +726,11 @@ void SkBitmapProcState::DebugMatrixProc(const SkBitmapProcState& state, // scale -vs- affine // filter -vs- nofilter if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { - proc = state.fFilterLevel != kNone_SkFilterQuality ? check_scale_filter : check_scale_nofilter; + proc = state.fFilterQuality != kNone_SkFilterQuality ? + check_scale_filter : check_scale_nofilter; } else { - proc = state.fFilterLevel != kNone_SkFilterQuality ? check_affine_filter : check_affine_nofilter; + proc = state.fFilterQuality != kNone_SkFilterQuality ? + check_affine_filter : check_affine_nofilter; } proc(bitmapXY, count, state.fPixmap.width(), state.fPixmap.height()); } @@ -760,7 +765,7 @@ int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const { size >>= 2; } - if (fFilterLevel != kNone_SkFilterQuality) { + if (fFilterQuality != kNone_SkFilterQuality) { size >>= 1; } diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h index a006e090b5..2d3d0e4347 100644 --- a/src/core/SkBitmapProcState.h +++ b/src/core/SkBitmapProcState.h @@ -27,10 +27,40 @@ typedef SkFixed3232 SkFractionalInt; class SkPaint; -struct SkBitmapProcState { - SkBitmapProcState(const SkBitmapProvider&, SkShader::TileMode tmx, SkShader::TileMode tmy); - SkBitmapProcState(const SkBitmap&, SkShader::TileMode tmx, SkShader::TileMode tmy); - ~SkBitmapProcState(); +struct SkBitmapProcInfo { + SkBitmapProcInfo(const SkBitmapProvider&, SkShader::TileMode tmx, SkShader::TileMode tmy); + SkBitmapProcInfo(const SkBitmap&, SkShader::TileMode tmx, SkShader::TileMode tmy); + ~SkBitmapProcInfo(); + + const SkBitmapProvider fProvider; + + SkPixmap fPixmap; + SkMatrix fInvMatrix; // copy of what is in fBMState, can we remove the dup? + SkColor fPaintColor; + SkShader::TileMode fTileModeX; + SkShader::TileMode fTileModeY; + SkFilterQuality fFilterQuality; + SkMatrix::TypeMask fInvType; + + bool init(const SkMatrix& inverse, const SkPaint&); + +private: + enum { + kBMStateSize = 136 // found by inspection. if too small, we will call new/delete + }; + SkAlignedSStorage fBMStateStorage; + SkBitmapController::State* fBMState; +}; + +struct SkBitmapProcState : public SkBitmapProcInfo { + SkBitmapProcState(const SkBitmapProvider& prov, SkShader::TileMode tmx, SkShader::TileMode tmy) + : SkBitmapProcInfo(prov, tmx, tmy) {} + SkBitmapProcState(const SkBitmap& bitmap, SkShader::TileMode tmx, SkShader::TileMode tmy) + : SkBitmapProcInfo(bitmap, tmx, tmy) {} + + bool setup(const SkMatrix& inv, const SkPaint& paint) { + return this->init(inv, paint) && this->chooseProcs(); + } typedef void (*ShaderProc32)(const void* ctx, int x, int y, SkPMColor[], int count); @@ -50,11 +80,7 @@ struct SkBitmapProcState { typedef U16CPU (*FixedTileLowBitsProc)(SkFixed, int); // returns 0..0xF typedef U16CPU (*IntTileProc)(int value, int count); // returns 0..count-1 - SkPixmap fPixmap; - SkMatrix fInvMatrix; // copy of what is in fBMState, can we remove the dup? - SkMatrix::MapXYProc fInvProc; // chooseProcs - SkFractionalInt fInvSxFractionalInt; SkFractionalInt fInvKyFractionalInt; @@ -66,14 +92,10 @@ struct SkBitmapProcState { SkFixed fFilterOneX; SkFixed fFilterOneY; - SkPMColor fPaintPMColor; // chooseProcs - A8 config SkFixed fInvSx; // chooseProcs SkFixed fInvKy; // chooseProcs + SkPMColor fPaintPMColor; // chooseProcs - A8 config uint16_t fAlphaScale; // chooseProcs - uint8_t fInvType; // chooseProcs - uint8_t fTileModeX; // CONSTRUCTOR - uint8_t fTileModeY; // CONSTRUCTOR - uint8_t fFilterLevel; // chooseProcs /** Platforms implement this, and can optionally overwrite only the following fields: @@ -114,26 +136,15 @@ struct SkBitmapProcState { SampleProc32 getSampleProc32() const { return fSampleProc32; } private: - friend class SkBitmapProcShader; - friend class SkLightingShaderImpl; - ShaderProc32 fShaderProc32; // chooseProcs ShaderProc16 fShaderProc16; // chooseProcs // These are used if the shaderproc is nullptr MatrixProc fMatrixProc; // chooseProcs SampleProc32 fSampleProc32; // chooseProcs - const SkBitmapProvider fProvider; - - enum { - kBMStateSize = 136 // found by inspection. if too small, we will call new/delete - }; - SkAlignedSStorage fBMStateStorage; - SkBitmapController::State* fBMState; - MatrixProc chooseMatrixProc(bool trivial_matrix); - bool chooseProcs(const SkMatrix& inv, const SkPaint&); - bool chooseScanlineProcs(bool trivialMatrix, bool clampClamp, const SkPaint& paint); + bool chooseProcs(); // caller must have called init() first (on our base-class) + bool chooseScanlineProcs(bool trivialMatrix, bool clampClamp); ShaderProc32 chooseShaderProc32(); // Return false if we failed to setup for fast translate (e.g. overflow) @@ -199,7 +210,7 @@ public: SkIntToScalar(y) + SK_ScalarHalf, &pt); SkFixed biasX, biasY; - if (s.fFilterLevel == kNone_SkFilterQuality) { + if (s.fFilterQuality == kNone_SkFilterQuality) { // SkFixed epsilon bias to ensure inverse-mapped bitmap coordinates are rounded // consistently WRT geometry. Note that we only need the bias for positive scales: // for negative scales, the rounding is intrinsically correct. diff --git a/src/core/SkBitmapProcState_matrixProcs.cpp b/src/core/SkBitmapProcState_matrixProcs.cpp index be0e371f7f..de97a905d4 100644 --- a/src/core/SkBitmapProcState_matrixProcs.cpp +++ b/src/core/SkBitmapProcState_matrixProcs.cpp @@ -485,7 +485,7 @@ static void mirrorx_nofilter_trans(const SkBitmapProcState& s, SkBitmapProcState::MatrixProc SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) { // test_int_tileprocs(); // check for our special case when there is no scale/affine/perspective - if (trivial_matrix && kNone_SkFilterQuality == fFilterLevel) { + if (trivial_matrix && kNone_SkFilterQuality == fFilterQuality) { fIntTileProcY = choose_int_tile_proc(fTileModeY); switch (fTileModeX) { case SkShader::kClamp_TileMode: @@ -498,7 +498,7 @@ SkBitmapProcState::MatrixProc SkBitmapProcState::chooseMatrixProc(bool trivial_m } int index = 0; - if (fFilterLevel != kNone_SkFilterQuality) { + if (fFilterQuality != kNone_SkFilterQuality) { index = 1; } if (fInvType & SkMatrix::kPerspective_Mask) { diff --git a/src/core/SkBitmapProcState_sample.h b/src/core/SkBitmapProcState_sample.h index 4a022884d5..8526c47cdb 100644 --- a/src/core/SkBitmapProcState_sample.h +++ b/src/core/SkBitmapProcState_sample.h @@ -25,7 +25,7 @@ void MAKENAME(_nofilter_DXDY)(const SkBitmapProcState& s, const uint32_t* SK_RESTRICT xy, int count, SkPMColor* SK_RESTRICT colors) { SkASSERT(count > 0 && colors != nullptr); - SkASSERT(kNone_SkFilterQuality == s.fFilterLevel); + SkASSERT(kNone_SkFilterQuality == s.fFilterQuality); SkDEBUGCODE(CHECKSTATE(s);) #ifdef PREAMBLE @@ -68,7 +68,7 @@ void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s, int count, SkPMColor* SK_RESTRICT colors) { SkASSERT(count > 0 && colors != nullptr); SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)); - SkASSERT(kNone_SkFilterQuality == s.fFilterLevel); + SkASSERT(kNone_SkFilterQuality == s.fFilterQuality); SkDEBUGCODE(CHECKSTATE(s);) #ifdef PREAMBLE @@ -122,7 +122,7 @@ void MAKENAME(_filter_DX)(const SkBitmapProcState& s, const uint32_t* SK_RESTRICT xy, int count, SkPMColor* SK_RESTRICT colors) { SkASSERT(count > 0 && colors != nullptr); - SkASSERT(s.fFilterLevel != kNone_SkFilterQuality); + SkASSERT(s.fFilterQuality != kNone_SkFilterQuality); SkDEBUGCODE(CHECKSTATE(s);) #ifdef PREAMBLE @@ -168,7 +168,7 @@ void MAKENAME(_filter_DXDY)(const SkBitmapProcState& s, const uint32_t* SK_RESTRICT xy, int count, SkPMColor* SK_RESTRICT colors) { SkASSERT(count > 0 && colors != nullptr); - SkASSERT(s.fFilterLevel != kNone_SkFilterQuality); + SkASSERT(s.fFilterQuality != kNone_SkFilterQuality); SkDEBUGCODE(CHECKSTATE(s);) #ifdef PREAMBLE diff --git a/src/core/SkBitmapProcState_shaderproc.h b/src/core/SkBitmapProcState_shaderproc.h index 5324456145..523b5621e2 100644 --- a/src/core/SkBitmapProcState_shaderproc.h +++ b/src/core/SkBitmapProcState_shaderproc.h @@ -19,7 +19,7 @@ void SCALE_FILTER_NAME(const void* sIn, int x, int y, SkPMColor* SK_RESTRICT col SkMatrix::kScale_Mask)) == 0); SkASSERT(s.fInvKy == 0); SkASSERT(count > 0 && colors != nullptr); - SkASSERT(s.fFilterLevel != kNone_SkFilterQuality); + SkASSERT(s.fFilterQuality != kNone_SkFilterQuality); SkDEBUGCODE(CHECKSTATE(s);) const unsigned maxX = s.fPixmap.width() - 1; diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp index 9d6c5864e2..c8a5a2b737 100644 --- a/src/core/SkLightingShader.cpp +++ b/src/core/SkLightingShader.cpp @@ -671,7 +671,7 @@ SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcState(fDiffuseMap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); SkASSERT(diffuseState); - if (!diffuseState->chooseProcs(diffTotalInv, *rec.fPaint)) { + if (!diffuseState->setup(diffTotalInv, *rec.fPaint)) { diffuseState->~SkBitmapProcState(); return nullptr; } @@ -680,7 +680,7 @@ SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState(fNormalMap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); SkASSERT(normalState); - if (!normalState->chooseProcs(normTotalInv, *rec.fPaint)) { + if (!normalState->setup(normTotalInv, *rec.fPaint)) { diffuseState->~SkBitmapProcState(); normalState->~SkBitmapProcState(); return nullptr; diff --git a/src/image/SkImageShader.cpp b/src/image/SkImageShader.cpp index 1c4d422b1e..a07603c671 100644 --- a/src/image/SkImageShader.cpp +++ b/src/image/SkImageShader.cpp @@ -42,8 +42,8 @@ bool SkImageShader::isOpaque() const { return fImage->isOpaque(); } -size_t SkImageShader::contextSize(const ContextRec&) const { - return SkBitmapProcShader::ContextSize(); +size_t SkImageShader::contextSize(const ContextRec& rec) const { + return SkBitmapProcShader::ContextSize(rec); } SkShader::Context* SkImageShader::onCreateContext(const ContextRec& rec, void* storage) const { diff --git a/src/opts/SkBitmapProcState_opts_SSE2.cpp b/src/opts/SkBitmapProcState_opts_SSE2.cpp index 8247d8796f..7a3bef0ddd 100644 --- a/src/opts/SkBitmapProcState_opts_SSE2.cpp +++ b/src/opts/SkBitmapProcState_opts_SSE2.cpp @@ -15,7 +15,7 @@ void S32_opaque_D32_filter_DX_SSE2(const SkBitmapProcState& s, const uint32_t* xy, int count, uint32_t* colors) { SkASSERT(count > 0 && colors != nullptr); - SkASSERT(s.fFilterLevel != kNone_SkFilterQuality); + SkASSERT(s.fFilterQuality != kNone_SkFilterQuality); SkASSERT(kN32_SkColorType == s.fPixmap.colorType()); SkASSERT(s.fAlphaScale == 256); @@ -121,7 +121,7 @@ void S32_alpha_D32_filter_DX_SSE2(const SkBitmapProcState& s, const uint32_t* xy, int count, uint32_t* colors) { SkASSERT(count > 0 && colors != nullptr); - SkASSERT(s.fFilterLevel != kNone_SkFilterQuality); + SkASSERT(s.fFilterQuality != kNone_SkFilterQuality); SkASSERT(kN32_SkColorType == s.fPixmap.colorType()); SkASSERT(s.fAlphaScale < 256); diff --git a/src/opts/SkBitmapProcState_opts_SSSE3.cpp b/src/opts/SkBitmapProcState_opts_SSSE3.cpp index 2de8e4049a..17d7da931a 100644 --- a/src/opts/SkBitmapProcState_opts_SSSE3.cpp +++ b/src/opts/SkBitmapProcState_opts_SSSE3.cpp @@ -394,7 +394,7 @@ void S32_generic_D32_filter_DX_SSSE3(const SkBitmapProcState& s, const uint32_t* xy, int count, uint32_t* colors) { SkASSERT(count > 0 && colors != nullptr); - SkASSERT(s.fFilterLevel != kNone_SkFilterQuality); + SkASSERT(s.fFilterQuality != kNone_SkFilterQuality); SkASSERT(kN32_SkColorType == s.fPixmap.colorType()); if (has_alpha) { SkASSERT(s.fAlphaScale < 256); @@ -586,7 +586,7 @@ void S32_generic_D32_filter_DXDY_SSSE3(const SkBitmapProcState& s, const uint32_t* xy, int count, uint32_t* colors) { SkASSERT(count > 0 && colors != nullptr); - SkASSERT(s.fFilterLevel != kNone_SkFilterQuality); + SkASSERT(s.fFilterQuality != kNone_SkFilterQuality); SkASSERT(kN32_SkColorType == s.fPixmap.colorType()); if (has_alpha) { SkASSERT(s.fAlphaScale < 256); diff --git a/src/opts/SkBitmapProcState_opts_mips_dsp.cpp b/src/opts/SkBitmapProcState_opts_mips_dsp.cpp index a80e955aeb..10f80c2a41 100644 --- a/src/opts/SkBitmapProcState_opts_mips_dsp.cpp +++ b/src/opts/SkBitmapProcState_opts_mips_dsp.cpp @@ -17,7 +17,7 @@ static void SI8_opaque_D32_nofilter_DX_mips_dsp(const SkBitmapProcState& s, int count, SkPMColor* SK_RESTRICT colors) { SkASSERT(count > 0 && colors != nullptr); SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)); - SkASSERT(kNone_SkFilterQuality == s.fFilterLevel); + SkASSERT(kNone_SkFilterQuality == s.fFilterQuality); const SkPMColor* SK_RESTRICT table = s.fPixmap.ctable()->readColors(); const uint8_t* SK_RESTRICT srcAddr = (const uint8_t*)s.fPixmap.addr(); srcAddr = (const uint8_t*)((const char*)srcAddr + xy[0] * s.fPixmap.rowBytes()); @@ -246,7 +246,7 @@ void SkBitmapProcState::platformProcs() { switch (fPixmap.colorType()) { case kIndex_8_SkColorType: - if (justDx && kNone_SkFilterQuality == fFilterLevel) { + if (justDx && kNone_SkFilterQuality == fFilterQuality) { if (isOpaque) { fSampleProc32 = SI8_opaque_D32_nofilter_DX_mips_dsp; fShaderProc32 = nullptr;