diff options
-rw-r--r-- | include/core/SkShader.h | 1 | ||||
-rw-r--r-- | src/core/SkBitmapController.h | 8 | ||||
-rw-r--r-- | src/core/SkBitmapProcShader.cpp | 32 | ||||
-rw-r--r-- | src/core/SkBitmapProcShader.h | 16 | ||||
-rw-r--r-- | src/core/SkBitmapProcState.cpp | 20 | ||||
-rw-r--r-- | src/core/SkBitmapProcState.h | 5 | ||||
-rw-r--r-- | src/core/SkLightingShader.cpp | 14 |
7 files changed, 62 insertions, 34 deletions
diff --git a/include/core/SkShader.h b/include/core/SkShader.h index 47934dd9ad..a95e7e713e 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -439,6 +439,7 @@ private: // So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor. friend class SkLocalMatrixShader; + friend class SkBitmapProcShader; // for computeTotalInverse() typedef SkFlattenable INHERITED; }; diff --git a/src/core/SkBitmapController.h b/src/core/SkBitmapController.h index 435d9e72af..e6c4443872 100644 --- a/src/core/SkBitmapController.h +++ b/src/core/SkBitmapController.h @@ -16,8 +16,12 @@ class SkBitmapProvider { public: - SkBitmapProvider(const SkBitmap& bm) : fBitmap(bm) {} - SkBitmapProvider(const SkImage* img) : fImage(SkRef(img)) {} + explicit SkBitmapProvider(const SkBitmap& bm) : fBitmap(bm) {} + explicit SkBitmapProvider(const SkImage* img) : fImage(SkSafeRef(img)) {} + SkBitmapProvider(const SkBitmapProvider& other) + : fBitmap(other.fBitmap) + , fImage(SkSafeRef(other.fImage.get())) + {} int width() const; int height() const; diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index 97abbf9675..36bfb1e7d6 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -19,6 +19,12 @@ #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); +} + SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMode tmy, const SkMatrix* localMatrix) : INHERITED(localMatrix) { @@ -70,36 +76,36 @@ bool SkBitmapProcShader::isOpaque() const { return fRawBitmap.isOpaque(); } -SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const { +SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader, + TileMode tmx, TileMode tmy, + const SkBitmap& bitmap, + const ContextRec& rec, void* storage) { SkMatrix totalInverse; // Do this first, so we know the matrix can be inverted. - if (!this->computeTotalInverse(rec, &totalInverse)) { + if (!shader.computeTotalInverse(rec, &totalInverse)) { return nullptr; } void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); - SkBitmapProcState* state = new (stateStorage) SkBitmapProcState; + SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(SkBitmapProvider(bitmap), + tmx, tmy); SkASSERT(state); - state->fTileModeX = fTileModeX; - state->fTileModeY = fTileModeY; - state->fOrigBitmap = fRawBitmap; if (!state->chooseProcs(totalInverse, *rec.fPaint)) { state->~SkBitmapProcState(); return nullptr; } - return new (storage) BitmapProcShaderContext(*this, rec, state); + return new (storage) BitmapProcShaderContext(shader, rec, state); } -size_t SkBitmapProcShader::contextSize() const { - // 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::onCreateContext(const ContextRec& rec, void* storage) const { + return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY, fRawBitmap, rec, storage); } -SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext( - const SkBitmapProcShader& shader, const ContextRec& rec, SkBitmapProcState* state) +SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(const SkShader& shader, + const ContextRec& rec, + SkBitmapProcState* state) : INHERITED(shader, rec) , fState(state) { diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h index 63985c06c5..9e90f9faac 100644 --- a/src/core/SkBitmapProcShader.h +++ b/src/core/SkBitmapProcShader.h @@ -22,7 +22,7 @@ public: bool isOpaque() const override; - size_t contextSize() const override; + size_t contextSize() const override { return ContextSize(); } SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader) @@ -33,11 +33,12 @@ public: GrProcessorDataManager*) const override; #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 SkBitmapProcShader&, const ContextRec&, SkBitmapProcState*); + BitmapProcShaderContext(const SkShader&, const ContextRec&, SkBitmapProcState*); ~BitmapProcShaderContext() override; void shadeSpan(int x, int y, SkPMColor dstC[], int count) override; @@ -52,8 +53,7 @@ public: typedef SkShader::Context INHERITED; }; - -protected: + void flatten(SkWriteBuffer&) const override; Context* onCreateContext(const ContextRec&, void* storage) const override; bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode*) const override; @@ -62,6 +62,12 @@ protected: uint8_t fTileModeX, fTileModeY; private: + friend class SkImageShader; + + static size_t ContextSize(); + static Context* MakeContext(const SkShader&, TileMode tmx, TileMode tmy, const SkBitmap&, + const ContextRec&, void* storage); + typedef SkShader INHERITED; }; @@ -70,7 +76,7 @@ private: // an Sk3DBlitter in SkDraw.cpp // Note that some contexts may contain other contexts (e.g. for compose shaders), but we've not // yet found a situation where the size below isn't big enough. -typedef SkSmallAllocator<3, 1152> SkTBlitterAllocator; +typedef SkSmallAllocator<3, 1160> SkTBlitterAllocator; // If alloc is non-nullptr, it will be used to allocate the returned SkShader, and MUST outlive // the SkShader. diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp index 31109aaee9..5ec6721436 100644 --- a/src/core/SkBitmapProcState.cpp +++ b/src/core/SkBitmapProcState.cpp @@ -37,7 +37,23 @@ extern void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const SkBitmapProcState& #include "SkBitmapProcState_filter.h" #include "SkBitmapProcState_procs.h" -SkBitmapProcState::SkBitmapProcState() : fBMState(nullptr) {} +SkBitmapProcState::SkBitmapProcState(const SkBitmapProvider& provider, + SkShader::TileMode tmx, SkShader::TileMode tmy) + : fProvider(provider) + , fBMState(nullptr) +{ + fTileModeX = tmx; + fTileModeY = tmy; +} + +SkBitmapProcState::SkBitmapProcState(const SkBitmap& bm, + SkShader::TileMode tmx, SkShader::TileMode tmy) + : fProvider(SkBitmapProvider(bm)) + , fBMState(nullptr) +{ + fTileModeX = tmx; + fTileModeY = tmy; +} SkBitmapProcState::~SkBitmapProcState() { SkInPlaceDeleteCheck(fBMState, fBMStateStorage.get()); @@ -119,7 +135,7 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { fFilterLevel = paint.getFilterQuality(); SkDefaultBitmapController controller; - fBMState = controller.requestBitmap(fOrigBitmap, inv, paint.getFilterQuality(), + fBMState = controller.requestBitmap(fProvider, inv, paint.getFilterQuality(), fBMStateStorage.get(), fBMStateStorage.size()); // Note : we allow the controller to return an empty (zero-dimension) result. Should we? if (nullptr == fBMState || fBMState->pixmap().info().isEmpty()) { diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h index 814c79a92c..b66299cbff 100644 --- a/src/core/SkBitmapProcState.h +++ b/src/core/SkBitmapProcState.h @@ -25,7 +25,8 @@ typedef SkFixed3232 SkFractionalInt; class SkPaint; struct SkBitmapProcState { - SkBitmapProcState(); + SkBitmapProcState(const SkBitmapProvider&, SkShader::TileMode tmx, SkShader::TileMode tmy); + SkBitmapProcState(const SkBitmap&, SkShader::TileMode tmx, SkShader::TileMode tmy); ~SkBitmapProcState(); typedef void (*ShaderProc32)(const SkBitmapProcState&, int x, int y, @@ -128,7 +129,7 @@ private: SampleProc32 fSampleProc32; // chooseProcs SampleProc16 fSampleProc16; // chooseProcs - SkBitmap fOrigBitmap; // CONSTRUCTOR + const SkBitmapProvider fProvider; enum { kBMStateSize = 136 // found by inspection. if too small, we will call new/delete diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp index 4ab233a828..2907dba7d5 100644 --- a/src/core/SkLightingShader.cpp +++ b/src/core/SkLightingShader.cpp @@ -664,24 +664,18 @@ SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, } void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext); - SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcState; + SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcState(fDiffuseMap, + SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); SkASSERT(diffuseState); - - diffuseState->fTileModeX = SkShader::kClamp_TileMode; - diffuseState->fTileModeY = SkShader::kClamp_TileMode; - diffuseState->fOrigBitmap = fDiffuseMap; if (!diffuseState->chooseProcs(diffTotalInv, *rec.fPaint)) { diffuseState->~SkBitmapProcState(); return nullptr; } void* normalStateStorage = (char*)storage + sizeof(LightingShaderContext) + sizeof(SkBitmapProcState); - SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState; + SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState(fNormalMap, + SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); SkASSERT(normalState); - - normalState->fTileModeX = SkShader::kClamp_TileMode; - normalState->fTileModeY = SkShader::kClamp_TileMode; - normalState->fOrigBitmap = fNormalMap; if (!normalState->chooseProcs(normTotalInv, *rec.fPaint)) { diffuseState->~SkBitmapProcState(); normalState->~SkBitmapProcState(); |